Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / tests / sanity-sec.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10 [ "$EXCEPT" ] && echo "Skipping tests: `echo $EXCEPT`"
11
12 SRCDIR=`dirname $0`
13 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
14 export NAME=${NAME:-local}
15
16 LUSTRE=${LUSTRE:-`dirname $0`/..} 
17 . $LUSTRE/tests/test-framework.sh
18 init_test_env $@
19 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
20
21 RUNAS=${RUNAS:-"$LUSTRE/tests/runas"}
22 WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
23
24 CONFDIR=/etc/lustre
25 PERM_CONF=$CONFDIR/perm.conf
26 SANITYSECLOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
27 FAIL_ON_ERROR=false
28
29 remote_mds_nodsh && skip "remote MDS with nodsh" && exit 0
30 remote_ost_nodsh && skip "remote OST with nodsh" && exit 0
31
32 ID0=${ID0:-500}
33 ID1=${ID1:-501}
34 USER0=`cat /etc/passwd|grep :$ID0:$ID0:|cut -d: -f1`
35 USER1=`cat /etc/passwd|grep :$ID1:$ID1:|cut -d: -f1`
36
37 [ -z "$USER0" ] && \
38         echo "Please add user0 (uid=$ID0 gid=$ID0)! Skip sanity-sec" && exit 0
39
40 [ -z "$USER1" ] && \
41         echo "Please add user1 (uid=$ID1 gid=$ID1)! Skip sanity-sec" && exit 0
42
43 check_and_setup_lustre
44
45 DIR=${DIR:-$MOUNT}
46 [ -z "`echo $DIR | grep $MOUNT`" ] && \
47         error "$DIR not in $MOUNT" && sec_cleanup && exit 1
48
49 [ `echo $MOUNT | wc -w` -gt 1 ] && \
50         echo "NAME=$MOUNT mounted more than once" && sec_cleanup && exit 0
51
52 [ $MDSCOUNT -gt 1 ] && \
53         echo "skip multi-MDS test" && sec_cleanup && exit 0
54
55 # for GSS_SUP
56 GSS_REF=$(lsmod | grep ^ptlrpc_gss | awk '{print $3}')
57 if [ ! -z "$GSS_REF" -a "$GSS_REF" != "0" ]; then
58         GSS_SUP=1
59         echo "with GSS support"
60 else
61         GSS_SUP=0
62         echo "without GSS support"
63 fi
64
65 MDT="`do_facet $SINGLEMDS "lctl get_param -N mdt.\*MDT\*/stats 2>/dev/null | cut -d"." -f2" || true`"
66 if [ ! -z "$MDT" ]; then
67         do_facet $SINGLEMDS "mkdir -p $CONFDIR"
68         IDENTITY_FLUSH=mdt.$MDT.identity_flush
69         MDSCAPA=mdt.$MDT.capa
70         CAPA_TIMEOUT=mdt.$MDT.capa_timeout
71 fi
72
73 # for CLIENT_TYPE
74 if [ -z "$(lctl get_param -n llite.*.client_type | grep remote 2>/dev/null)" ]; then
75         CLIENT_TYPE="local"
76         echo "local client"
77 else
78         CLIENT_TYPE="remote"
79         echo "remote client"
80 fi
81
82 SAVE_PWD=$PWD
83
84 build_test_filter
85
86 sec_login() {
87         local user=$1
88         local group=$2
89
90         if ! $RUNAS -u $user krb5_login.sh; then
91                 error "$user login kerberos failed."
92                 exit 1
93         fi
94
95         if ! $RUNAS -u $user -g $group ls $DIR > /dev/null 2>&1; then
96                 $RUNAS -u $user lfs flushctx -k
97                 $RUNAS -u $user krb5_login.sh
98                 if ! $RUNAS -u $user -g $group ls $DIR > /dev/null 2>&1; then
99                         error "init $user $group failed."
100                         exit 2
101                 fi
102         fi
103 }
104
105 declare -a identity_old
106
107 sec_setup() {
108         for num in `seq $MDSCOUNT`; do
109                 switch_identity $num true || identity_old[$num]=$?
110         done
111
112         if ! $RUNAS -u $ID0 ls $DIR > /dev/null 2>&1; then
113                 sec_login $USER0 $USER0
114         fi
115
116         if ! $RUNAS -u $ID1 ls $DIR > /dev/null 2>&1; then
117                 sec_login $USER1 $USER1
118         fi
119 }
120 sec_setup
121
122 # run as different user
123 test_0() {
124         umask 0022
125
126         chmod 0755 $DIR || error "chmod (1)"
127         rm -rf $DIR/$tdir || error "rm (1)"
128         mkdir -p $DIR/$tdir || error "mkdir (1)"
129         chown $USER0 $DIR/$tdir || error "chown (1)"
130         $RUNAS -u $ID0 ls $DIR || error "ls (1)"
131         rm -f $DIR/f0 || error "rm (2)"
132         $RUNAS -u $ID0 touch $DIR/f0 && error "touch (1)"
133         $RUNAS -u $ID0 touch $DIR/$tdir/f1 || error "touch (2)"
134         $RUNAS -u $ID1 touch $DIR/$tdir/f2 && error "touch (3)"
135         touch $DIR/$tdir/f3 || error "touch (4)"
136         chown root $DIR/$tdir || error "chown (2)"
137         chgrp $USER0 $DIR/$tdir || error "chgrp (1)"
138         chmod 0775 $DIR/$tdir || error "chmod (2)"
139         $RUNAS -u $ID0 touch $DIR/$tdir/f4 || error "touch (5)"
140         $RUNAS -u $ID1 touch $DIR/$tdir/f5 && error "touch (6)"
141         touch $DIR/$tdir/f6 || error "touch (7)"
142         rm -rf $DIR/$tdir || error "rm (3)"
143 }
144 run_test 0 "uid permission ============================="
145
146 # setuid/gid
147 test_1() {
148         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
149         [ -z "$MDT" ] && skip "do not support do_facet operations." && return
150         [ "$CLIENT_TYPE" = "remote" ] && \
151                 skip "test_1 for local client only" && return
152
153         do_facet $SINGLEMDS "rm -f $PERM_CONF"
154         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
155
156         rm -rf $DIR/$tdir
157         mkdir -p $DIR/$tdir
158
159         chown $USER0 $DIR/$tdir || error "chown (1)"
160         $RUNAS -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
161         echo "enable uid $ID1 setuid"
162         do_facet $SINGLEMDS "echo '* $ID1 setuid' > $PERM_CONF"
163         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
164         $RUNAS -u $ID1 -v $ID0 touch $DIR/$tdir/f1 || error "touch (3)"
165
166         chown root $DIR/$tdir || error "chown (4)"
167         chgrp $USER0 $DIR/$tdir || error "chgrp (5)"
168         chmod 0770 $DIR/$tdir || error "chmod (6)"
169         $RUNAS -u $ID1 -g $ID1 touch $DIR/$tdir/f2 && error "touch (7)"
170         $RUNAS -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f3 && error "touch (8)"
171         echo "enable uid $ID1 setuid,setgid"
172         do_facet $SINGLEMDS "echo '* $ID1 setuid,setgid' > $PERM_CONF"
173         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
174         $RUNAS -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f4 || error "touch (9)"
175         $RUNAS -u $ID1 -v $ID0 -g $ID1 -j $ID0 touch $DIR/$tdir/f5 || error "touch (10)"
176
177         rm -rf $DIR/$tdir
178
179         do_facet $SINGLEMDS "rm -f $PERM_CONF"
180         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
181 }
182 run_test 1 "setuid/gid ============================="
183
184 run_rmtacl_subtest() {
185     $SAVE_PWD/rmtacl/run $SAVE_PWD/rmtacl/$1.test
186     return $?
187 }
188
189 # remote_acl
190 # for remote client only
191 test_2 () {
192         [ "$CLIENT_TYPE" = "local" ] && \
193                 skip "remote_acl for remote client only" && return
194         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep ^acl)" ] && \
195                 skip "must have acl enabled" && return
196         [ -z "$(which setfacl 2>/dev/null)" ] && \
197                 skip "could not find setfacl" && return
198         [ "$UID" != 0 ] && skip "must run as root" && return
199
200         sec_login root root
201         sec_login bin bin
202         sec_login daemon daemon
203         sec_login games users
204
205         SAVE_UMASK=`umask`
206         umask 0022
207         cd $DIR
208
209         if [ ! -z "$MDT" ]; then
210                 do_facet $SINGLEMDS "echo '* 0 rmtacl' > $PERM_CONF"
211                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
212         fi
213
214         if lfs rgetfacl $DIR; then
215                 echo "performing cp ..."
216                 run_rmtacl_subtest cp || error "cp"
217         else
218                 echo "server doesn't permit current user 'lfs r{s,g}etfacl', skip cp test."
219         fi
220         echo "performing getfacl-noacl..."
221         run_rmtacl_subtest getfacl-noacl || error "getfacl-noacl"
222         echo "performing misc..."
223         run_rmtacl_subtest misc || error "misc"
224         echo "performing permissions..."
225         run_rmtacl_subtest permissions || error "permissions"
226         echo "performing setfacl..."
227         run_rmtacl_subtest setfacl || error "setfacl"
228
229         # inheritance test got from HP
230         echo "performing inheritance..."
231         cp $SAVE_PWD/rmtacl/make-tree .
232         chmod +x make-tree
233         run_rmtacl_subtest inheritance || error "inheritance"
234         rm -f make-tree
235
236         if [ ! -z "$MDT" ]; then
237                 do_facet $SINGLEMDS "rm -f $PERM_CONF"
238                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
239         fi
240
241         cd $SAVE_PWD
242         umask $SAVE_UMASK
243 }
244 run_test 2 "rmtacl ============================="
245
246 # rootsquash
247 # root_squash will be redesigned in Lustre 1.7
248 test_3() {
249         skip "root_squash will be redesigned in Lustre 1.7" && return
250 }
251 run_test 3 "rootsquash ============================="
252
253 # bug 3285 - supplementary group should always succeed.
254 # NB: the supplementary groups are set for local client only,
255 # as for remote client, the groups of the specified uid on MDT
256 # will be obtained by upcall /sbin/l_getidentity and used.
257 test_4() {
258         rm -rf $DIR/$tdir
259         mkdir -p $DIR/$tdir
260         chmod 0771 $DIR/$tdir
261         chgrp $ID0 $DIR/$tdir
262         $RUNAS -u $ID0 ls $DIR/$tdir || error "setgroups (1)"
263         if [ "$CLIENT_TYPE" != "remote" ]; then
264                 if [ ! -z "$MDT" ]; then
265                         do_facet $SINGLEMDS "echo '* $ID1 setgrp' > $PERM_CONF"
266                         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
267                         $RUNAS -u $ID1 -G1,2,$ID0 ls $DIR/$tdir || error "setgroups (2)"
268                         do_facet $SINGLEMDS "rm -f $PERM_CONF"
269                         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
270                 fi
271         fi
272         $RUNAS -u $ID1 -G1,2 ls $DIR/$tdir && error "setgroups (3)"
273         rm -rf $DIR/$tdir
274 }
275 run_test 4 "set supplementary group ==============="
276
277 mds_capability_timeout() {
278         [ $# -lt 1 ] && echo "Miss mds capability timeout value" && return 1
279
280         echo "Set mds capability timeout as $1 seconds"
281         do_facet $SINGLEMDS "lctl set_param -n $CAPA_TIMEOUT=$1"
282         return 0
283 }
284
285 mds_capability_switch() {
286         [ $# -lt 1 ] && echo "Miss mds capability switch value" && return 1
287
288         case $1 in
289                 0) echo "Turn off mds capability";;
290                 3) echo "Turn on mds capability";;
291                 *) echo "Invalid mds capability switch value" && return 2;;
292         esac
293
294         do_facet $SINGLEMDS "lctl set_param -n $MDSCAPA=$1"
295         return 0
296 }
297
298 oss_capability_switch() {
299         [ $# -lt 1 ] && echo "Miss oss capability switch value" && return 1
300
301         case $1 in
302                 0) echo "Turn off oss capability";;
303                 1) echo "Turn on oss capability";;
304                 *) echo "Invalid oss capability switch value" && return 2;;
305         esac
306
307         for i in `seq $OSTCOUNT`; do
308                 local j=`expr $i - 1`
309                 local OST="`do_facet ost$i "lctl get_param -N obdfilter.\*OST\*$j/stats | cut -d"." -f2" || true`"
310                 do_facet ost$i "lctl set_param -n obdfilter.$OST.capa=$1"
311         done
312         return 0
313 }
314
315 turn_capability_on() {
316         local capa_timeout=${1:-"1800"}
317
318         # To turn on fid capability for the system,
319         # there is a requirement that fid capability
320         # is turned on on all MDS/OSS servers before
321         # client mount.
322
323         umount $MOUNT || return 1
324
325         mds_capability_switch 3 || return 2
326         oss_capability_switch 1 || return 3
327         mds_capability_timeout $capa_timeout || return 4
328
329         mount_client $MOUNT || return 5
330         return 0
331 }
332
333 turn_capability_off() {
334         # to turn off fid capability, you can just do
335         # it in a live system. But, please turn off
336         # capability of all OSS servers before MDS servers.
337
338         oss_capability_switch 0 || return 1
339         mds_capability_switch 0 || return 2
340         return 0
341 }
342
343 # We demonstrate that access to the objects in the filesystem are not
344 # accessible without supplying secrets from the MDS by disabling a
345 # proc variable on the mds so that it does not supply secrets. We then
346 # try and access objects which result in failure.
347 test_5() {
348         local file=$DIR/f5
349
350         [ -z "$MDT" ] && skip "do not support do_facet operations." && return
351         turn_capability_off
352         if [ $? != 0 ]; then
353                 error "turn_capability_off"
354                 return 1
355         fi
356         rm -f $file
357
358         # Disable proc variable
359         mds_capability_switch 0
360         if [ $? != 0 ]; then
361                 error "mds_capability_switch 0"
362                 return 2
363         fi
364         oss_capability_switch 1
365         if [ $? != 0 ]; then
366                 error "oss_capability_switch 1"
367                 return 3
368         fi
369
370         # proc variable disabled -- access to the objects in the filesystem
371         # is not allowed 
372         echo "Should get Write error here : (proc variable are disabled "\
373              "-- access to the objects in the filesystem is denied."
374         $WTL $file 30
375         if [ $? == 0 ]; then
376                 error "Write worked well even though secrets not supplied."
377                 return 4
378         fi
379
380         turn_capability_on
381         if [ $? != 0 ]; then
382                 error "turn_capability_on"
383                 return 4
384         fi
385         sleep 5
386
387         # proc variable enabled, secrets supplied -- write should work now
388         echo "Should not fail here : (proc variable enabled, secrets supplied "\
389              "-- write should work now)."
390         $WTL $file 30
391         if [ $? != 0 ]; then
392                 error "Write failed even though secrets supplied."
393                 return 5
394         fi
395
396         turn_capability_off
397         if [ $? != 0 ]; then
398                 error "turn_capability_off"
399                 return 7
400         fi
401         rm -f $file
402 }
403 run_test 5 "capa secrets ========================="
404
405 # Expiry: A test program is performing I/O on a file. It has credential
406 # with an expiry half a minute later. While the program is running the
407 # credentials expire and no automatic extensions or renewals are
408 # enabled. The program will demonstrate an I/O failure.
409 test_6() {
410         local file=$DIR/f6
411
412         [ -z "$MDT" ] && skip "do not support do_facet operations." && return
413         turn_capability_off
414         if [ $? != 0 ]; then
415                 error "turn_capability_off"
416                 return 1
417         fi
418         rm -f $file
419
420         turn_capability_on 30
421         if [ $? != 0 ]; then
422                 error "turn_capability_on 30"
423                 return 2
424         fi
425         # Token expiry
426         $WTL $file 60
427         if [ $? != 0 ]; then
428                 error "$WTL $file 60"
429                 return 3
430         fi
431
432         # Reset MDS capability timeout
433         mds_capability_timeout 30
434         if [ $? != 0 ]; then
435                 error "mds_capability_timeout 30"
436                 return 4
437         fi
438         $WTL $file 60 &
439         local PID=$!
440         sleep 5
441
442         # To disable automatic renew, only need turn capa off on MDS.
443         mds_capability_switch 0
444         if [ $? != 0 ]; then
445                 error "mds_capability_switch 0"
446                 return 5
447         fi
448
449         echo "We expect I/O failure."
450         wait $PID
451         if [ $? == 0 ]; then
452                 echo "no I/O failure got."
453                 return 6
454         fi
455
456         turn_capability_off
457         if [ $? != 0 ]; then
458                 error "turn_capability_off"
459                 return 7
460         fi
461         rm -f $file
462 }
463 run_test 6 "capa expiry ========================="
464
465 log "cleanup: ======================================================"
466
467 sec_unsetup() {
468         for num in `seq $MDSCOUNT`; do
469                 if [ "${identity_old[$num]}" = 1 ]; then
470                         switch_identity $num false || identity_old[$num]=$?
471                 fi
472         done
473
474         $RUNAS -u $ID0 ls $DIR
475         $RUNAS -u $ID1 ls $DIR
476 }
477 sec_unsetup
478
479 sec_cleanup() {
480         if [ "$I_MOUNTED" = "yes" ]; then
481                 cleanupall -f || error "sec_cleanup"
482         fi
483 }
484 sec_cleanup
485
486 echo '=========================== finished ==============================='
487 [ -f "$SANITYSECLOG" ] && \
488         cat $SANITYSECLOG && grep -q FAIL $SANITYSECLOG && exit 1 || true
489 echo "$0 completed"