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
44builddir=`pwd`
45cd "$builddir" ||
46  {
47    echo "$0: cannot determine build directory (unreadable parent dir?)" >&2
48    exit 1
49  }
50# Switch to a temporary directory, to increase the likelihood that ACLs are
51# supported on the current file system. (/tmp is usually locally mounted,
52# whereas the build dir is sometimes NFS-mounted.)
53( cd "$tmp"
54
55  # Prepare tmpfile0.
56  rm -f tmpfile[0-9] tmpaclout[0-2]
57  echo "Simple contents" > tmpfile0
58  chmod 600 tmpfile0
59
60  # Classification of the platform according to the programs available for
61  # manipulating ACLs.
62  # Possible values are:
63  #   linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, none.
64  # TODO: Support also native Windows platforms (mingw).
65  acl_flavor=none
66  if (getfacl tmpfile0 >/dev/null) 2>/dev/null; then
67    # Platforms with the getfacl and setfacl programs.
68    # Linux, FreeBSD, Solaris, Cygwin.
69    if (setfacl --help >/dev/null) 2>/dev/null; then
70      # Linux, Cygwin.
71      if (LC_ALL=C setfacl --help | grep ' --set-file' >/dev/null) 2>/dev/null; then
72        # Linux.
73        acl_flavor=linux
74      else
75        acl_flavor=cygwin
76      fi
77    else
78      # FreeBSD, Solaris.
79      if (LC_ALL=C setfacl 2>&1 | grep '\-x entries' >/dev/null) 2>/dev/null; then
80        # FreeBSD.
81        acl_flavor=freebsd
82      else
83        # Solaris.
84        acl_flavor=solaris
85      fi
86    fi
87  else
88    if (lsacl / >/dev/null) 2>/dev/null; then
89      # Platforms with the lsacl and chacl programs.
90      # HP-UX, sometimes also IRIX.
91      if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
92        # HP-UX 11.11 or newer.
93        acl_flavor=hpuxjfs
94      else
95        # HP-UX 11.00.
96        acl_flavor=hpux
97      fi
98    else
99      if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
100        # Tru64, NonStop Kernel.
101        if (getacl -m tmpfile0 >/dev/null) 2>/dev/null; then
102          # Tru64.
103          acl_flavor=osf1
104        else
105          # NonStop Kernel.
106          acl_flavor=nsk
107        fi
108      else
109        if (aclget tmpfile0 >/dev/null) 2>/dev/null; then
110          # AIX.
111          acl_flavor=aix
112        else
113          if (fsaclctl -v >/dev/null) 2>/dev/null; then
114            # Mac OS X.
115            acl_flavor=macosx
116          else
117            if test -f /sbin/chacl; then
118              # IRIX.
119              acl_flavor=irix
120            fi
121          fi
122        fi
123      fi
124    fi
125  fi
126
127  # Define a function to test for the same ACLs, from the point of view of
128  # the programs.
129  # func_test_same_acls file1 file2
130  case $acl_flavor in
131    linux | cygwin | freebsd | solaris)
132      func_test_same_acls ()
133      {
134        getfacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
135        getfacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
136        cmp tmpaclout1 tmpaclout2 > /dev/null
137      }
138      ;;
139    hpux)
140      func_test_same_acls ()
141      {
142        lsacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
143        lsacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
144        cmp tmpaclout1 tmpaclout2 > /dev/null
145      }
146      ;;
147    hpuxjfs)
148      func_test_same_acls ()
149      {
150        { lsacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
151          lsacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
152          cmp tmpaclout1 tmpaclout2 > /dev/null
153        } &&
154        { getacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
155          getacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
156          cmp tmpaclout1 tmpaclout2 > /dev/null
157        }
158      }
159      ;;
160    osf1 | nsk)
161      func_test_same_acls ()
162      {
163        getacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
164        getacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
165        cmp tmpaclout1 tmpaclout2 > /dev/null
166      }
167      ;;
168    aix)
169      func_test_same_acls ()
170      {
171        aclget "$1" > tmpaclout1
172        aclget "$2" > tmpaclout2
173        cmp tmpaclout1 tmpaclout2 > /dev/null
174      }
175      ;;
176    macosx)
177      func_test_same_acls ()
178      {
179        /bin/ls -le "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
180        /bin/ls -le "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
181        cmp tmpaclout1 tmpaclout2 > /dev/null
182      }
183      ;;
184    irix)
185      func_test_same_acls ()
186      {
187        /bin/ls -lD "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
188        /bin/ls -lD "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
189        cmp tmpaclout1 tmpaclout2 > /dev/null
190      }
191      ;;
192    none)
193      func_test_same_acls ()
194      {
195        :
196      }
197      ;;
198  esac
199
200  # func_test_copy file1 file2
201  # copies file1 to file2 and verifies the permissions and ACLs are the same
202  # on both.
203  func_test_copy ()
204  {
205    echo "Simple contents" > "$2"
206    chmod 600 "$2"
207    "$builddir"/test-copy-acl${EXEEXT} "$1" "$2" || exit 1
208    "$builddir"/test-sameacls${EXEEXT} "$1" "$2" || exit 1
209    func_test_same_acls                "$1" "$2" || exit 1
210  }
211
212  func_test_copy tmpfile0 tmpfile1
213
214  if test $acl_flavor != none; then
215    # A POSIX compliant 'id' program.
216    if test -f /usr/xpg4/bin/id; then
217      ID=/usr/xpg4/bin/id
218    else
219      ID=id
220    fi
221    # Use a user and group id different from the current one, to avoid
222    # redundant/ambiguous ACLs.
223    myuid=`$ID -u`
224    mygid=`$ID -g`
225    auid=1
226    if test "$auid" = "$myuid"; then auid=2; fi
227    agid=1
228    if test "$agid" = "$mygid"; then agid=2; fi
229
230    case $acl_flavor in
231      linux | freebsd | solaris)
232
233        # Set an ACL for a user.
234        setfacl -m user:$auid:1 tmpfile0
235
236        func_test_copy tmpfile0 tmpfile2
237
238        # Set an ACL for a group.
239        setfacl -m group:$agid:4 tmpfile0
240
241        func_test_copy tmpfile0 tmpfile3
242
243        # Set an ACL for other.
244        case $acl_flavor in
245          freebsd) setfacl -m other::4 tmpfile0 ;;
246          solaris) chmod o+r tmpfile0 ;;
247          *)       setfacl -m other:4 tmpfile0 ;;
248        esac
249
250        func_test_copy tmpfile0 tmpfile4
251
252        # Remove the ACL for the user.
253        case $acl_flavor in
254          linux)   setfacl -x user:$auid tmpfile0 ;;
255          freebsd) setfacl -x user:$auid:1 tmpfile0 ;;
256          *)       setfacl -d user:$auid:1 tmpfile0 ;;
257        esac
258
259        func_test_copy tmpfile0 tmpfile5
260
261        # Remove the ACL for other.
262        case $acl_flavor in
263          linux | solaris) ;; # impossible
264          freebsd) setfacl -x other::4 tmpfile0 ;;
265          *)       setfacl -d other:4 tmpfile0 ;;
266        esac
267
268        func_test_copy tmpfile0 tmpfile6
269
270        # Remove the ACL for the group.
271        case $acl_flavor in
272          linux)   setfacl -x group:$agid tmpfile0 ;;
273          freebsd) setfacl -x group:$agid:4 tmpfile0 ;;
274          *)       setfacl -d group:$agid:4 tmpfile0 ;;
275        esac
276
277        func_test_copy tmpfile0 tmpfile7
278
279        # Delete all optional ACLs.
280        case $acl_flavor in
281          linux | freebsd)
282            setfacl -m user:$auid:1 tmpfile0
283            setfacl -b tmpfile0
284            ;;
285          *)
286            setfacl -s user::6,group::0,other:0 tmpfile0 ;;
287        esac
288
289        func_test_copy tmpfile0 tmpfile8
290
291        # Copy ACLs from a file that has no ACLs.
292        echo > tmpfile9
293        chmod a+x tmpfile9
294        case $acl_flavor in
295          linux)   getfacl tmpfile9 | setfacl --set-file=- tmpfile0 ;;
296          freebsd) ;;
297          *)       getfacl tmpfile9 | setfacl -f - tmpfile0 ;;
298        esac
299        rm -f tmpfile9
300
301        func_test_copy tmpfile0 tmpfile9
302
303        ;;
304
305      cygwin)
306
307        # Set an ACL for a group.
308        setfacl -m group:0:1 tmpfile0
309
310        func_test_copy tmpfile0 tmpfile2
311
312        # Set an ACL for other.
313        setfacl -m other:4 tmpfile0
314
315        func_test_copy tmpfile0 tmpfile4
316
317        # Remove the ACL for the group.
318        setfacl -d group:0 tmpfile0
319
320        func_test_copy tmpfile0 tmpfile5
321
322        # Remove the ACL for other.
323        setfacl -d other:4 tmpfile0
324
325        func_test_copy tmpfile0 tmpfile6
326
327        # Delete all optional ACLs.
328        setfacl -s user::6,group::0,other:0 tmpfile0
329
330        func_test_copy tmpfile0 tmpfile8
331
332        # Copy ACLs from a file that has no ACLs.
333        echo > tmpfile9
334        chmod a+x tmpfile9
335        getfacl tmpfile9 | setfacl -f - tmpfile0
336        rm -f tmpfile9
337
338        func_test_copy tmpfile0 tmpfile9
339
340        ;;
341
342      hpux)
343
344        # Set an ACL for a user.
345        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
346        chacl -r "${orig}($auid.%,--x)" tmpfile0
347
348        func_test_copy tmpfile0 tmpfile2
349
350        # Set an ACL for a group.
351        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
352        chacl -r "${orig}(%.$agid,r--)" tmpfile0
353
354        func_test_copy tmpfile0 tmpfile3
355
356        # Set an ACL for other.
357        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
358        chacl -r "${orig}(%.%,r--)" tmpfile0
359
360        func_test_copy tmpfile0 tmpfile4
361
362        # Remove the ACL for the user.
363        chacl -d "($auid.%,--x)" tmpfile0
364
365        func_test_copy tmpfile0 tmpfile5
366
367        # Remove the ACL for the group.
368        chacl -d "(%.$agid,r--)" tmpfile0
369
370        func_test_copy tmpfile0 tmpfile6
371
372        # Delete all optional ACLs.
373        chacl -z tmpfile0
374
375        func_test_copy tmpfile0 tmpfile8
376
377        # Copy ACLs from a file that has no ACLs.
378        echo > tmpfile9
379        chmod a+x tmpfile9
380        orig=`lsacl tmpfile9 | sed -e 's/ tmpfile9$//'`
381        rm -f tmpfile9
382        chacl -r "${orig}" tmpfile0
383
384        func_test_copy tmpfile0 tmpfile9
385
386        ;;
387
388      hpuxjfs)
389
390        # Set an ACL for a user.
391        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
392        chacl -r "${orig}($auid.%,--x)" tmpfile0 \
393          || setacl -m user:$auid:1 tmpfile0
394
395        func_test_copy tmpfile0 tmpfile2
396
397        # Set an ACL for a group.
398        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
399        chacl -r "${orig}(%.$agid,r--)" tmpfile0 \
400          || setacl -m group:$agid:4 tmpfile0
401
402        func_test_copy tmpfile0 tmpfile3
403
404        # Set an ACL for other.
405        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
406        chacl -r "${orig}(%.%,r--)" tmpfile0 \
407          || setacl -m other:4 tmpfile0
408
409        func_test_copy tmpfile0 tmpfile4
410
411        # Remove the ACL for the user.
412        chacl -d "($auid.%,--x)" tmpfile0 \
413          || setacl -d user:$auid tmpfile0
414
415        func_test_copy tmpfile0 tmpfile5
416
417        # Remove the ACL for the group.
418        chacl -d "(%.$agid,r--)" tmpfile0 \
419          || setacl -d group:$agid tmpfile0
420
421        func_test_copy tmpfile0 tmpfile6
422
423        # Delete all optional ACLs.
424        chacl -z tmpfile0 \
425          || { setacl -m user:$auid:1 tmpfile0
426               setacl -s user::6,group::0,class:7,other:0 tmpfile0
427             }
428
429        func_test_copy tmpfile0 tmpfile8
430
431        # Copy ACLs from a file that has no ACLs.
432        echo > tmpfile9
433        chmod a+x tmpfile9
434        orig=`lsacl tmpfile9 | sed -e 's/ tmpfile9$//'`
435        getacl tmpfile9 > tmpaclout0
436        rm -f tmpfile9
437        chacl -r "${orig}" tmpfile0 \
438          || setacl -f tmpaclout0 tmpfile0
439
440        func_test_copy tmpfile0 tmpfile9
441
442        ;;
443
444      osf1)
445
446        # Set an ACL for a user.
447        setacl -u user:$auid:1 tmpfile0
448
449        func_test_copy tmpfile0 tmpfile2
450
451        # Set an ACL for a group.
452        setacl -u group:$agid:4 tmpfile0
453
454        func_test_copy tmpfile0 tmpfile3
455
456        # Set an ACL for other.
457        setacl -u other::4 tmpfile0
458
459        func_test_copy tmpfile0 tmpfile4
460
461        # Remove the ACL for the user.
462        setacl -x user:$auid:1 tmpfile0
463
464        func_test_copy tmpfile0 tmpfile5
465
466        if false; then # would give an error "can't set ACL: Invalid argument"
467          # Remove the ACL for other.
468          setacl -x other::4 tmpfile0
469
470          func_test_copy tmpfile0 tmpfile6
471        fi
472
473        # Remove the ACL for the group.
474        setacl -x group:$agid:4 tmpfile0
475
476        func_test_copy tmpfile0 tmpfile7
477
478        # Delete all optional ACLs.
479        setacl -u user:$auid:1 tmpfile0
480        setacl -b tmpfile0
481
482        func_test_copy tmpfile0 tmpfile8
483
484        # Copy ACLs from a file that has no ACLs.
485        echo > tmpfile9
486        chmod a+x tmpfile9
487        getacl tmpfile9 > tmpaclout0
488        setacl -b -U tmpaclout0 tmpfile0
489        rm -f tmpfile9
490
491        func_test_copy tmpfile0 tmpfile9
492
493        ;;
494
495      nsk)
496
497        # Set an ACL for a user.
498        setacl -m user:$auid:1 tmpfile0
499
500        func_test_copy tmpfile0 tmpfile2
501
502        # Set an ACL for a group.
503        setacl -m group:$agid:4 tmpfile0
504
505        func_test_copy tmpfile0 tmpfile3
506
507        # Set an ACL for other.
508        setacl -m other:4 tmpfile0
509
510        func_test_copy tmpfile0 tmpfile4
511
512        # Remove the ACL for the user.
513        setacl -d user:$auid tmpfile0
514
515        func_test_copy tmpfile0 tmpfile5
516
517        # Remove the ACL for the group.
518        setacl -d group:$agid tmpfile0
519
520        func_test_copy tmpfile0 tmpfile6
521
522        # Delete all optional ACLs.
523        setacl -m user:$auid:1 tmpfile0
524        setacl -s user::6,group::0,class:7,other:0 tmpfile0
525
526        func_test_copy tmpfile0 tmpfile8
527
528        # Copy ACLs from a file that has no ACLs.
529        echo > tmpfile9
530        chmod a+x tmpfile9
531        getacl tmpfile9 > tmpaclout0
532        setacl -f tmpaclout0 tmpfile0
533        rm -f tmpfile9
534
535        func_test_copy tmpfile0 tmpfile9
536
537        ;;
538
539      aix)
540
541        # Set an ACL for a user.
542        { aclget tmpfile0 | sed -e 's/disabled$/enabled/'; echo "        permit --x u:$auid"; } | aclput tmpfile0
543
544        func_test_copy tmpfile0 tmpfile2
545
546        # Set an ACL for a group.
547        { aclget tmpfile0 | sed -e 's/disabled$/enabled/'; echo "        permit r-- g:$agid"; } | aclput tmpfile0
548
549        func_test_copy tmpfile0 tmpfile3
550
551        # Set an ACL for other.
552        chmod o+r tmpfile0
553
554        func_test_copy tmpfile0 tmpfile4
555
556        # Remove the ACL for the user.
557        aclget tmpfile0 | grep -v ' u:[^ ]*$' | aclput tmpfile0
558
559        func_test_copy tmpfile0 tmpfile5
560
561        # Remove the ACL for the group.
562        aclget tmpfile0 | grep -v ' g:[^ ]*$' | aclput tmpfile0
563
564        func_test_copy tmpfile0 tmpfile7
565
566        # Delete all optional ACLs.
567        aclget tmpfile0 | sed -e 's/enabled$/disabled/' | sed -e '/disabled$/q' | aclput tmpfile0
568
569        func_test_copy tmpfile0 tmpfile8
570
571        # Copy ACLs from a file that has no ACLs.
572        echo > tmpfile9
573        chmod a+x tmpfile9
574        aclget tmpfile9 | aclput tmpfile0
575        rm -f tmpfile9
576
577        func_test_copy tmpfile0 tmpfile9
578
579        ;;
580
581      macosx)
582
583        # Set an ACL for a user.
584        /bin/chmod +a "user:daemon allow execute" tmpfile0
585
586        func_test_copy tmpfile0 tmpfile2
587
588        # Set an ACL for a group.
589        /bin/chmod +a "group:daemon allow read" tmpfile0
590
591        func_test_copy tmpfile0 tmpfile3
592
593        # Set an ACL for other.
594        chmod o+r tmpfile0
595
596        func_test_copy tmpfile0 tmpfile4
597
598        # Remove the ACL for the user.
599        /bin/chmod -a "user:daemon allow execute" tmpfile0
600
601        func_test_copy tmpfile0 tmpfile5
602
603        # Remove the ACL for the group.
604        /bin/chmod -a "group:daemon allow read" tmpfile0
605
606        func_test_copy tmpfile0 tmpfile7
607
608        # Delete all optional ACLs.
609        /bin/chmod -N tmpfile0
610
611        func_test_copy tmpfile0 tmpfile8
612
613        # Copy ACLs from a file that has no ACLs.
614        echo > tmpfile9
615        chmod a+x tmpfile9
616        { /bin/ls -le tmpfile9 | sed -n -e 's/^ [0-9][0-9]*: //p'; echo; } | /bin/chmod -E tmpfile0
617        rm -f tmpfile9
618
619        func_test_copy tmpfile0 tmpfile9
620
621        ;;
622
623      irix)
624
625        # Set an ACL for a user.
626        /sbin/chacl user::rw-,group::---,other::---,user:$auid:--x tmpfile0
627
628        func_test_copy tmpfile0 tmpfile2
629
630        # Set an ACL for a group.
631        /sbin/chacl user::rw-,group::---,other::---,user:$auid:--x,group:$agid:r-- tmpfile0
632
633        func_test_copy tmpfile0 tmpfile3
634
635        # Set an ACL for other.
636        /sbin/chacl user::rw-,group::---,user:$auid:--x,group:$agid:r--,other::r-- tmpfile0
637
638        func_test_copy tmpfile0 tmpfile4
639
640        # Remove the ACL for the user.
641        /sbin/chacl user::rw-,group::---,group:$agid:r--,other::r-- tmpfile0
642
643        func_test_copy tmpfile0 tmpfile5
644
645        # Remove the ACL for the group.
646        /sbin/chacl user::rw-,group::---,other::r-- tmpfile0
647
648        func_test_copy tmpfile0 tmpfile7
649
650        ;;
651
652    esac
653  fi
654
655  rm -f tmpfile[0-9] tmpaclout[0-2]
656) || exit 1
657
658rm -rf "$tmp"
659exit 0
660