1#!/bin/sh 2 3# Show all commands when run with environment variable VERBOSE=yes. 4test -z "$VERBOSE" || set -x 5 6test "$USE_ACL" = 0 && 7 { 8 echo "Skipping test: insufficient ACL support" 9 exit 77 10 } 11 12# func_tmpdir 13# creates a temporary directory. 14# Sets variable 15# - tmp pathname of freshly created temporary directory 16func_tmpdir () 17{ 18 # Use the environment variable TMPDIR, falling back to /tmp. This allows 19 # users to specify a different temporary directory, for example, if their 20 # /tmp is filled up or too small. 21 : ${TMPDIR=/tmp} 22 { 23 # Use the mktemp program if available. If not available, hide the error 24 # message. 25 tmp=`(umask 077 && mktemp -d "$TMPDIR/glXXXXXX") 2>/dev/null` && 26 test -n "$tmp" && test -d "$tmp" 27 } || 28 { 29 # Use a simple mkdir command. It is guaranteed to fail if the directory 30 # already exists. $RANDOM is bash specific and expands to empty in shells 31 # other than bash, ksh and zsh. Its use does not increase security; 32 # rather, it minimizes the probability of failure in a very cluttered /tmp 33 # directory. 34 tmp=$TMPDIR/gl$$-$RANDOM 35 (umask 077 && mkdir "$tmp") 36 } || 37 { 38 echo "$0: cannot create a temporary directory in $TMPDIR" >&2 39 exit 1 40 } 41} 42 43func_tmpdir 44# builddir may already be set by the script that invokes this one. 45case "$builddir" in 46 '') builddir=`pwd` ;; 47 /* | ?:*) ;; 48 *) builddir=`pwd`/$builddir ;; 49esac 50cd "$builddir" || 51 { 52 echo "$0: cannot determine build directory (unreadable parent dir?)" >&2 53 exit 1 54 } 55# Switch to a temporary directory, to increase the likelihood that ACLs are 56# supported on the current file system. (/tmp is usually locally mounted, 57# whereas the build dir is sometimes NFS-mounted.) 58( cd "$tmp" 59 60 # Prepare tmpfile0. 61 rm -f tmpfile[0-9] tmp.err 62 echo "Simple contents" > tmpfile0 63 chmod 600 tmpfile0 64 65 # Classification of the platform according to the programs available for 66 # manipulating ACLs. 67 # Possible values are: 68 # linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, none. 69 # TODO: Support also native Windows platforms (mingw). 70 acl_flavor=none 71 if (getfacl tmpfile0 >/dev/null) 2>/dev/null; then 72 # Platforms with the getfacl and setfacl programs. 73 # Linux, FreeBSD, Solaris, Cygwin. 74 if (setfacl --help >/dev/null) 2>/dev/null; then 75 # Linux, Cygwin. 76 if (LC_ALL=C setfacl --help | grep ' --set-file' >/dev/null) 2>/dev/null; then 77 # Linux. 78 acl_flavor=linux 79 else 80 acl_flavor=cygwin 81 fi 82 else 83 # FreeBSD, Solaris. 84 if (LC_ALL=C setfacl 2>&1 | grep '\-x entries' >/dev/null) 2>/dev/null; then 85 # FreeBSD. 86 acl_flavor=freebsd 87 else 88 # Solaris. 89 acl_flavor=solaris 90 fi 91 fi 92 else 93 if (lsacl / >/dev/null) 2>/dev/null; then 94 # Platforms with the lsacl and chacl programs. 95 # HP-UX, sometimes also IRIX. 96 if (getacl tmpfile0 >/dev/null) 2>/dev/null; then 97 # HP-UX 11.11 or newer. 98 acl_flavor=hpuxjfs 99 else 100 # HP-UX 11.00. 101 acl_flavor=hpux 102 fi 103 else 104 if (getacl tmpfile0 >/dev/null) 2>/dev/null; then 105 # Tru64, NonStop Kernel. 106 if (getacl -m tmpfile0 >/dev/null) 2>/dev/null; then 107 # Tru64. 108 acl_flavor=osf1 109 else 110 # NonStop Kernel. 111 acl_flavor=nsk 112 fi 113 else 114 if (aclget tmpfile0 >/dev/null) 2>/dev/null; then 115 # AIX. 116 acl_flavor=aix 117 else 118 if (fsaclctl -v >/dev/null) 2>/dev/null; then 119 # Mac OS X. 120 acl_flavor=macosx 121 else 122 if test -f /sbin/chacl; then 123 # IRIX. 124 acl_flavor=irix 125 fi 126 fi 127 fi 128 fi 129 fi 130 fi 131 132 # func_test_file_has_acl file expected 133 # tests the result of the file_has_acl function on file, and checks that it 134 # matches the expected value. 135 func_test_file_has_acl () 136 { 137 res=`${CHECKER} "$builddir"/test-file-has-acl${EXEEXT} "$1"` 138 test "$res" = "$2" || { 139 echo "file_has_acl(\"$1\") returned $res, expected $2" 1>&2 140 exit 1 141 } 142 } 143 144 # func_test_has_acl file expected 145 # tests the result of the file_has_acl function on file, and checks that it 146 # matches the expected value, also taking into account the system's 'ls' 147 # program. 148 case $acl_flavor in 149 freebsd | solaris | hpux | macosx) 150 case $acl_flavor in 151 freebsd | solaris | hpux) acl_ls_option="-ld" ;; 152 macosx) acl_ls_option="-lde" ;; 153 esac 154 func_test_has_acl () 155 { 156 func_test_file_has_acl "$1" "$2" 157 case `/bin/ls $acl_ls_option "$1" | sed 1q` in 158 ??????????+*) 159 test "$2" = yes || { 160 echo "/bin/ls $acl_ls_option $1 shows an ACL, but expected $2" 1>&2 161 exit 1 162 } 163 ;; 164 ??????????" "*) 165 test "$2" = no || { 166 echo "/bin/ls $acl_ls_option $1 shows no ACL, but expected $2" 1>&2 167 exit 1 168 } 169 ;; 170 esac 171 } 172 ;; 173 irix) 174 func_test_has_acl () 175 { 176 func_test_file_has_acl "$1" "$2" 177 case `/bin/ls -ldD "$1" | sed 1q` in 178 *" []") 179 test "$2" = no || { 180 echo "/bin/ls -ldD $1 shows no ACL, but expected $2" 1>&2 181 exit 1 182 } 183 ;; 184 *) 185 test "$2" = yes || { 186 echo "/bin/ls -ldD $1 shows an ACL, but expected $2" 1>&2 187 exit 1 188 } 189 ;; 190 esac 191 } 192 ;; 193 *) 194 func_test_has_acl () 195 { 196 func_test_file_has_acl "$1" "$2" 197 } 198 ;; 199 esac 200 201 func_test_has_acl tmpfile0 no 202 203 mkdir tmpdir0 204 func_test_has_acl tmpdir0 no 205 206 if test $acl_flavor != none; then 207 # A POSIX compliant 'id' program. 208 if test -f /usr/xpg4/bin/id; then 209 ID=/usr/xpg4/bin/id 210 else 211 ID=id 212 fi 213 # Use a user and group id different from the current one, to avoid 214 # redundant/ambiguous ACLs. 215 myuid=`$ID -u` 216 mygid=`$ID -g` 217 auid=1 218 if test "$auid" = "$myuid"; then auid=2; fi 219 agid=1 220 if test "$agid" = "$mygid"; then agid=2; fi 221 222 case $acl_flavor in 223 linux | freebsd | solaris) 224 225 # Set an ACL for a user. 226 if setfacl -m user:$auid:1 tmpfile0; then 227 228 func_test_has_acl tmpfile0 yes 229 230 # Remove the ACL for the user. 231 case $acl_flavor in 232 linux) setfacl -x user:$auid tmpfile0 ;; 233 freebsd) setfacl -x user:$auid:1 tmpfile0 ;; 234 *) setfacl -d user:$auid:1 tmpfile0 ;; 235 esac 236 237 # On Linux and FreeBSD, the ACL for the mask is implicitly added. 238 # On Solaris, it is always there. 239 case $acl_flavor in 240 linux | freebsd) func_test_has_acl tmpfile0 yes ;; 241 *) func_test_has_acl tmpfile0 no ;; 242 esac 243 244 # Remove the ACL for the mask, if it was implicitly added. 245 case $acl_flavor in 246 linux | freebsd) setfacl -x mask: tmpfile0 ;; 247 *) setfacl -d mask: tmpfile0 ;; 248 esac 249 250 func_test_has_acl tmpfile0 no 251 252 fi 253 ;; 254 255 cygwin) 256 257 # Set an ACL for a group. 258 if setfacl -m group:0:1 tmpfile0; then 259 260 func_test_has_acl tmpfile0 yes 261 262 # Remove the ACL for the group. 263 setfacl -d group:0 tmpfile0 264 265 func_test_has_acl tmpfile0 no 266 267 fi 268 ;; 269 270 hpux | hpuxjfs) 271 272 # Set an ACL for a user. 273 orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'` 274 if chacl -r "${orig}($auid.%,--x)" tmpfile0; then 275 276 func_test_has_acl tmpfile0 yes 277 278 # Remove the ACL for the user. 279 chacl -d "($auid.%,--x)" tmpfile0 280 281 func_test_has_acl tmpfile0 no 282 283 else 284 if test $acl_flavor = hpuxjfs; then 285 286 # Set an ACL for a user. 287 setacl -m user:$auid:1 tmpfile0 288 289 func_test_has_acl tmpfile0 yes 290 291 # Remove the ACL for the user. 292 setacl -d user:$auid tmpfile0 293 294 func_test_has_acl tmpfile0 no 295 296 fi 297 fi 298 ;; 299 300 osf1) 301 302 # Set an ACL for a user. 303 setacl -u user:$auid:1 tmpfile0 2> tmp.err 304 cat tmp.err 1>&2 305 if grep 'Error:' tmp.err > /dev/null \ 306 || grep 'Operation not supported' tmp.err > /dev/null; then 307 : 308 else 309 310 func_test_has_acl tmpfile0 yes 311 312 # Remove the ACL for the user. 313 setacl -x user:$auid:1 tmpfile0 314 315 func_test_has_acl tmpfile0 no 316 317 fi 318 ;; 319 320 nsk) 321 322 # Set an ACL for a user. 323 setacl -m user:$auid:1 tmpfile0 324 325 func_test_has_acl tmpfile0 yes 326 327 # Remove the ACL for the user. 328 setacl -d user:$auid tmpfile0 329 330 func_test_has_acl tmpfile0 no 331 332 ;; 333 334 aix) 335 336 # Set an ACL for a user. 337 { aclget tmpfile0 | sed -e 's/disabled$/enabled/'; echo " permit --x u:$auid"; } | aclput tmpfile0 338 if aclget tmpfile0 | grep enabled > /dev/null; then 339 340 func_test_has_acl tmpfile0 yes 341 342 # Remove the ACL for the user. 343 aclget tmpfile0 | grep -v ' u:[^ ]*$' | aclput tmpfile0 344 345 func_test_has_acl tmpfile0 no 346 347 fi 348 ;; 349 350 macosx) 351 352 # Set an ACL for a user. 353 /bin/chmod +a "user:daemon allow execute" tmpfile0 354 355 func_test_has_acl tmpfile0 yes 356 357 # Remove the ACL for the user. 358 /bin/chmod -a "user:daemon allow execute" tmpfile0 359 360 func_test_has_acl tmpfile0 no 361 362 ;; 363 364 irix) 365 366 # Set an ACL for a user. 367 /sbin/chacl user::rw-,group::---,other::---,user:$auid:--x tmpfile0 2> tmp.err 368 cat tmp.err 1>&2 369 if test -s tmp.err; then :; else 370 371 func_test_has_acl tmpfile0 yes 372 373 # Remove the ACL for the user. 374 /sbin/chacl user::rw-,group::---,other::--- tmpfile0 375 376 func_test_has_acl tmpfile0 no 377 378 fi 379 ;; 380 381 esac 382 fi 383 384 rm -f tmpfile[0-9] tmp.err 385 rm -rf tmpdir0 386) || exit 1 387 388rm -rf "$tmp" 389exit 0 390