--- /dev/null	Mon Aug  5 17:19:20 2019
+++ new/usr/src/test/nfsgen-tests/tests/acl/acl_common.kshlib	Mon Aug  5 17:19:20 2019
@@ -0,0 +1,741 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/nfsgen.kshlib
+
+# TX doesn't allow a regular user to access zone path
+# we need to enter mount point first, then access other
+# directories or files with relative path
+cd $MNTDIR
+
+#
+# Get the given file/directory access mode
+#
+# $1 object -- file or directroy
+#
+function get_mode #<obj>
+{
+	FNAME=get_mode
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset obj=$1
+	if (( ${#obj} == 0 )); then
+		return 1
+	fi
+
+	$LS -ld $obj | $AWK '{print $1}'
+	return $?
+}
+
+#
+# Get the given file/directory ACL
+#
+# $1 object -- file or directroy
+#
+function get_acl #<obj>
+{
+	FNAME=get_acl
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+        typeset obj=$1
+	if (( ${#obj} == 0 )); then
+		return 1
+	fi
+
+	$LS -vd $obj | $NAWK '(NR != 1) {print $0}'
+	return $?
+}
+
+#
+# Get the given file/directory ACL
+#
+# $1 object -- file or directroy
+#
+function get_compact_acl #<obj>
+{
+	FNAME=get_compact_acl
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+        typeset obj=$1
+	if (( ${#obj} == 0 )); then
+		return 1
+	fi
+
+	$LS -Vd $obj | $NAWK '(NR != 1) {print $0}' 
+	return $?
+}
+
+#
+# Check the given two files/directories have the same ACLs
+#
+# Return 0, if source object acl is equal to target object acl.
+# 
+# $1 source object
+# $2 target object
+#
+function compare_acls #<src> <tgt>
+{
+	FNAME=compare_acls
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+        typeset src=$1
+        typeset tgt=$2
+
+	(( ${#src} == 0 || ${#tgt} == 0 )) && return 1
+	[[ $src == $tgt ]] && return 0
+
+	typeset tmpsrc=/tmp/compare_acls.src.$$
+	typeset tmptgt=/tmp/compare_acls.tgt.$$
+
+	get_acl $src > $tmpsrc
+	get_acl $tgt > $tmptgt
+	typeset -i ret=0
+	$DIFF $tmpsrc $tmptgt > /dev/null 2>&1
+	ret=$?	
+	$RM -f $tmpsrc $tmptgt
+
+	if (( ret != 0 )); then
+		return $ret
+	fi
+
+	RUN_CHECK get_compact_acl $src > $tmpsrc || return 1
+	RUN_CHECK get_compact_acl $tgt > $tmptgt || return 1
+	$DIFF $tmpsrc $tmptgt > /dev/null 2>&1
+	ret=$?	
+	$RM -f $tmpsrc $tmptgt
+
+	return $ret
+}
+
+#
+# Check that the given two objects have the same modes.
+# Return 0, if their modes are equal with each other. Otherwise, return 1.
+#
+# $1 source object
+# $2 target object
+#
+function compare_modes #<src> <tgt>
+{
+	FNAME=compare_modes
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+        typeset src=$1
+        typeset tgt=$2
+        typeset -i i=0
+        set -A mode
+
+	(( ${#src} == 0 || ${#tgt} == 0 )) && return 1
+	[[ $src == $tgt ]] && return 0
+
+	typeset obj
+        for obj in $src $tgt
+        do
+                mode[i]=$(get_mode $obj)
+
+                (( i = i + 1 ))
+        done
+
+        [[ ${mode[0]} != ${mode[1]} ]] && return 1
+
+        return 0
+}
+
+#
+# Check that the given two objects have the same xattrs.
+# Return 0, if their xattrs are equal with each other. Otherwise, return 1.
+#
+# $1 source object
+# $2 target object
+#
+function compare_xattrs #<src> <tgt>
+{
+	FNAME=compare_xattrs
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+        typeset src=$1
+        typeset tgt=$2
+
+	(( ${#src} == 0 || ${#tgt} == 0 )) && return 1
+	[[ $src == $tgt ]] && return 0
+
+	typeset tmpsrc=/tmp/compare_xattrs.src.$$
+	typeset tmptgt=/tmp/compare_xattrs.tgt.$$
+
+	RUN_CHECK get_xattr $src > $tmpsrc || return 1
+	RUN_CHECK get_xattr $tgt > $tmptgt || return 1
+	typeset -i ret=0
+	$DIFF $tmpsrc $tmptgt > /dev/null 2>&1
+	ret=$?	
+	$RM -f $tmpsrc $tmptgt
+
+        return $ret
+}
+
+#
+# Check '+' is set for a given file/directory with 'ls [-l]' command
+#
+# $1 object -- file or directory.
+#
+function plus_sign_check_l #<obj>
+{
+	FNAME=plus_sign_check_l
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset obj=$1
+	if (( ${#obj} == 0 )); then
+		return 1
+	fi
+
+	$LS -ld $obj | $AWK '{print $1}' | $GREP "+\>" > /dev/null
+        return $?
+}
+
+#
+# Check '+' is set for a given file/directory with 'ls [-v]' command
+#
+# $1 object -- file or directory.
+#
+function plus_sign_check_v #<obj>
+{
+	FNAME=plus_sign_check_v
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset obj=$1
+	if (( ${#obj} == 0 )); then
+		return 1
+	fi
+
+	$LS -vd $obj | $NAWK '(NR == 1) {print $1}' | $GREP "+\>" > /dev/null
+        return $?
+}
+
+#
+# Export the current user for the following usr_exec operating.
+#
+# $1 legal login name
+#
+function set_cur_usr #<login_name>
+{
+	FNAME=set_cur_usr
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	export ACL_CUR_USER=$1
+}
+
+#
+# Run commands by $ACL_CUR_USER
+#
+# $1-n commands and options
+#
+function usr_exec #<commands> [...]
+{
+	FNAME=usr_exec
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+	
+	[[ $IS_KRB5 == 1 && $ACL_CUR_USER != root ]] \
+		&& chg_usr_exec -k $KPASSWORD "$ACL_CUR_USER" $@   \
+		|| chg_usr_exec "$ACL_CUR_USER" $@
+
+	return $?
+}
+
+#
+# Count how many ACEs for the speficied file or directory.
+#
+# $1 file or directroy name
+#
+function count_ACE #<file or dir name>
+{
+	FNAME=count_ACE
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	if [[ ! -e $1 ]]; then
+		echo "Need input file or directroy name."
+		return 1
+	fi
+
+	$LS -vd $1 | $NAWK 'BEGIN {count=0}
+			(NR != 1)&&(/[0-9]:/) {count++}
+			END {print count}'
+
+	return 0
+}
+
+#
+# Get specified number ACE content of specified file or directory.
+#
+# $1 file or directory name
+# $2 specified number
+#
+function get_ACE #<file or dir name> <specified number> <verbose|compact>
+{
+	FNAME=get_ACE
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	if [[ ! -e $1 || $2 -ge $(count_ACE $1) ]]; then
+		return 1
+	fi
+
+	typeset file=$1
+	typeset -i num=$2
+	typeset format=${3:-verbose}
+	typeset -i next_num=-1
+
+        typeset tmpfile=/tmp/tmp_get_ACE.$$
+        typeset line=""
+	typeset args
+
+	case $format in
+		verbose) args="-vd"
+			;;
+		compact) args="-Vd"
+			;;
+		*) echo "Invalid parameter as ($format), " \
+			"only verbose|compact is supported."
+			exit $STF_FAIL
+			;;
+	esac
+
+	$LS $args $file > $tmpfile
+	if (( $? != 0 )) then
+		echo "FAIL: $LS $args $file > $tmpfile"
+		exit $STF_FAIL
+	fi
+	while read line; do
+		[[ -z $line ]] && continue
+		if [[ $args == -vd ]]; then
+			if [[ $line == "$num":* ]]; then
+				(( next_num = num + 1 ))
+			fi
+			if [[ $line == "$next_num":* ]]; then
+				break
+			fi
+			if (( next_num != -1 )); then
+				print -n $line
+			fi
+		else
+			if (( next_num == num )); then
+				print -n $line
+			fi
+			(( next_num += 1 ))
+		fi
+	done < $tmpfile
+
+	$RM -f $tmpfile
+	if (( $? != 0 )); then
+		echo "FAIL: $RM -f $tmpfile"
+		exit $STF_FAIL
+	fi
+}
+
+#
+# Cleanup exist user/group.
+#
+function cleanup_user_group
+{
+	FNAME=cleanup_user_group
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	del_user $ACL_ADMIN
+
+	del_user $ACL_STAFF1
+	del_user $ACL_STAFF2
+	del_group $ACL_STAFF_GROUP
+
+	del_user $ACL_OTHER1
+	del_user $ACL_OTHER2
+	del_group $ACL_OTHER_GROUP
+
+	return 0
+}
+
+#
+# According to specified access or acl_spec, do relevant operating by using the
+# specified user.
+#
+# $1 specified user
+# $2 node
+# $3 acl_spec or access
+#
+function rwx_node #user node acl_spec|access
+{
+	FNAME=rwx_node
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset user=$1
+	typeset node=$2
+	typeset acl_spec=$3
+
+	if [[ $user == "" || $node == "" || $acl_spec == "" ]]; then
+		echo "node or acl_spec are not defined."
+		return 1
+	fi
+
+	if [[ -d $node ]]; then
+		case $acl_spec in
+		*:read_data:*|read_data)
+			RUN_CHECK chgusr_exec $user $LS -l $node
+			return $? ;;
+		*:write_data:*|write_data)
+			if [[ -f ${node}/tmpfile ]]; then
+				RUN_CHECK $RM -f ${node}/tmpfile \
+					|| exit $STF_FAIL
+			fi
+			RUN_CHECK chgusr_exec $user $TOUCH ${node}/tmpfile 
+			return $? ;;
+		*"execute:"*|execute)
+			RUN_CHECK chgusr_exec $user $FIND $node
+			return $? ;;
+		esac
+	else
+		case $acl_spec in
+		*:read_data:*|read_data)
+			RUN_CHECK chgusr_exec $user $CAT $node
+			return $? ;;
+		*:write_data:*|write_data)
+			RUN_CHECK chgusr_exec $user $DD if=/usr/bin/ls of=$node
+			return $? ;;
+		*"execute:"*|execute)
+			ACL_ERR_STR=$(chgusr_exec $user $node 2>&1) 
+			return $? ;;
+		esac
+	fi
+}
+
+#
+# Get the given file/directory xattr
+#
+# $1 object -- file or directroy
+#
+function get_xattr #<obj>
+{
+	FNAME=get_xattr
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+        typeset obj=$1
+	typeset xattr
+	if (( ${#obj} == 0 )); then
+		return 1
+	fi
+
+	for xattr in `$RUNAT $obj $LS | \
+		/usr/xpg4/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
+		$RUNAT $obj $SUM $xattr || return 1
+	done
+}
+
+#
+# Get the owner of a file/directory
+#
+function get_owner #node
+{
+	FNAME=get_owner
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset node=$1
+	typeset value
+
+	if [[ -z $node ]]; then
+		echo "node are not defined."
+		exit $STF_FAIL
+	fi
+
+	if [[ -d $node ]]; then
+		value=$($LS -dl $node | $AWK '{print $3}')
+	elif [[ -e $node ]]; then
+		value=$($LS -l $node | $AWK '{print $3}')
+	fi
+
+	$ECHO $value
+}
+
+#
+# Get the group of a file/directory
+#
+function get_group #node
+{
+	FNAME=get_group
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset node=$1
+	typeset value
+
+	if [[ -z $node ]]; then
+		echo "node are not defined."
+		exit $STF_FAIL
+	fi
+
+	if [[ -d $node ]]; then
+		value=$($LS -dl $node | $AWK '{print $4}')
+	elif [[ -e $node ]]; then
+		value=$($LS -l $node | $AWK '{print $4}')
+	fi
+
+	$ECHO $value
+}
+
+
+#
+# Get the group name that a UID belongs to
+#
+function get_user_group #uid
+{
+	FNAME=get_user_group
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset uid=$1
+	typeset value
+
+	if [[ -z $uid ]]; then
+		echo "UID not defined."
+		exit $STF_FAIL
+	fi
+
+	value=$(id $uid)
+
+	if [[ $? -eq 0 ]]; then
+		value=${value##*\(}
+		value=${value%%\)*}
+		$ECHO $value
+	else
+		echo "Invalid UID (uid)."
+		exit $STF_FAIL
+	fi
+}
+
+#
+# Get the specified item of the specified string
+#
+# $1:	Item number, count from 0.
+# $2-n: strings
+#
+function getitem
+{
+	FNAME=getitem
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset -i n=$1
+	shift
+
+	(( n += 1 ))
+	eval echo \${$n}
+}
+
+#
+# This function calculate the specified directory files checksum and write
+# to the specified array.
+#
+# $1 directory in which the files will be cksum.
+# $2 file array name which was used to store file cksum information.
+# $3 attribute array name which was used to store attribute information.
+#
+function cksum_files #<dir> <file_array_name> <attribute_array_name>
+{
+	FNAME=cksum_files
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset dir=$1
+	typeset farr_name=$2
+	typeset aarr_name=$3
+
+	[[ ! -d $dir ]] && return
+	typeset files=$($LS $dir/file*)
+
+	typeset -i i=0
+	typeset -i n=0
+	while (( i < NUM_FILE )); do
+		typeset f=$(getitem $i $files)
+		RUN_CHECK eval $farr_name[$i]=\$\(\$CKSUM $f\) \
+			|| cleanup $STF_FAIL
+
+		typeset -i j=0
+		while (( j < NUM_ATTR )); do
+			RUN_CHECK eval $aarr_name[$n]=\$\(\$RUNAT \$f \$CKSUM \
+				attribute.$j\) || cleanup $STF_FAIL
+
+			(( j += 1 ))
+			(( n += 1 ))
+		done
+
+		(( i += 1 ))
+	done
+}
+
+#
+# This function compare two cksum results array.
+#
+# $1 The array name which stored the cksum before operation.
+# $2 The array name which stored the cksum after operation.
+#
+function compare_cksum #<array1> <array2>
+{
+	FNAME=compare_cksum
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset before=$1
+	typeset after=$2
+	eval typeset -i count=\${#$before[@]}
+
+	typeset -i i=0
+	while (( i < count )); do
+		eval typeset var1=\${$before[$i]}
+		eval typeset var2=\${$after[$i]}
+
+		if [[ $var1 != $var2 ]]; then
+			return 1
+		fi
+
+		(( i += 1 ))
+	done
+
+	return 0
+}
+
+#
+# This function calculate all the files cksum information in current directory 
+# and output them to the specified file.
+#
+# $1 directory from which the files will be cksum.
+# $2 cksum output file
+#
+function record_cksum #<outfile>
+{
+	FNAME=record_cksum
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset dir=$1
+	typeset outfile=$2
+
+	[[ ! -d ${outfile%/*} ]] && usr_exec $MKDIR -p ${outfile%/*}
+
+	usr_exec $FIND $dir -depth -type f -exec cksum {} \\\; \
+		> $STF_TMPDIR/cksum.$$ || return 1
+	$SORT $STF_TMPDIR/cksum.$$ > $outfile
+	usr_exec $FIND $dir -depth -type f -xattr -exec runat {} \
+		cksum attribute* \\\; > $STF_TMPDIR/cksum.$$ \
+		|| return 1
+	$SORT $STF_TMPDIR/cksum.$$ >> $outfile
+	return 0
+}
+
+#
+# The function create_files creates the directories and files that the script 
+# will operate on to test extended attribute functionality.
+#
+# $1 The base directory in which to create directories and files.
+#
+function create_files #<directory>
+{
+	FNAME=create_files
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+
+	typeset basedir=$1
+
+	[[ ! -d $basedir ]] && RUN_CHECK usr_exec $MKDIR -m 777 $basedir
+	[[ ! -d $RES_DIR  ]] && RUN_CHECK usr_exec $MKDIR -m 777 $RES_DIR
+	[[ ! -d $INI_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $INI_DIR
+	[[ ! -d $TST_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $TST_DIR
+	[[ ! -d $TMP_DIR  ]] && RUN_CHECK usr_exec $MKDIR -m 777 $TMP_DIR
+
+	#
+	# Create the original file and its attribute files.
+	#
+	if [[ ! -a $RES_DIR/file ]]; then 
+		RUN_CHECK "usr_exec \"$FILE_WRITE -W -c -o 4 -B \\\"1024 1 -1\\\" $RES_DIR/file\"" \
+			|| cleanup $STF_FAIL
+	fi
+	if [[ ! -a $RES_DIR/attribute ]]; then
+		RUN_CHECK usr_exec $CP $RES_DIR/file $RES_DIR/attribute \
+			|| cleanup $STF_FAIL
+	fi
+
+	typeset -i i=0
+	while (( i < NUM_FILE )); do
+		typeset dstfile=$INI_DIR/file.$$.$i
+		RUN_CHECK usr_exec $CP $RES_DIR/file $dstfile \
+			|| cleanup $STF_FAIL
+
+		typeset -i j=0
+		while (( j < NUM_ATTR )); do
+			RUN_CHECK usr_exec $RUNAT $dstfile \
+				$CP $STF_SUITE/STF.INFO ./attribute.$j \
+				|| cleanup $STF_FAIL
+			(( j += 1 ))
+		done
+
+		(( i += 1 ))
+	done
+}
+
+
+#
+# The function remount the server's fs with appended option, which can be 
+# used to disable the attribute cache with "noac" option for some tests 
+#
+# $1 the option which is appended.
+#
+function do_remount #<option>
+{
+	FNAME=do_remount
+	[[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
+		&& set -x
+	
+	typeset opt=$1
+	typeset mntdir
+
+	[[ $opt != "" ]] && opt=",$opt"
+	[[ $SETUP == none ]] && mntdir=$realMNT || mntdir=$MNTDIR
+	[[ $MNTOPT == "" ]] && MNTOPT="rw"
+
+	RUN_CHECK $UMOUNT $mntdir || return 1
+        RUN_CHECK $MOUNT -o $MNTOPT$opt $SERVER:$SHRDIR $mntdir \
+		|| return 1
+
+	return 0
+}
