Whamcloud - gitweb
- make HEAD from b_post_cmd3
[fs/lustre-release.git] / lustre / tests / sanity-sec.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting SEC_ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6
7 set -e
8
9 SRCDIR=`dirname $0`
10 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
11
12 SEC_ONLY=${SEC_ONLY:-"$*"}
13 ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-""}
14 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
15
16 [ "$ALWAYS_EXCEPT$EXCEPT" ] && \
17         echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`"
18
19 TMP=${TMP:-/tmp}
20 LFS=${LFS:-lfs}
21 LCTL=${LCTL:-lctl}
22 RUNAS=${RUNAS:-runas}
23
24 log() {
25         echo "$*"
26         $LCTL mark "$*" 2> /dev/null || true
27 }
28
29 SANITYSECLOG=${SANITYSECLOG:-/tmp/sanity-sec.log}
30
31 [ "$SANITYSECLOG" ] && rm -f $SANITYSECLOG || true
32
33 sec_error() { 
34         log "FAIL: $TESTNAME $@"
35         if [ "$SANITYSECLOG" ]; then
36                 echo "FAIL: $TESTNAME $@" >> $SANITYSECLOG
37         else
38                 exit 1
39         fi
40 }
41
42 pass() { 
43         echo PASS $@
44 }
45
46 ID1=500
47 ID2=501
48
49 USER1=`cat /etc/passwd|grep :$ID1:$ID1:|cut -d: -f1`
50 USER2=`cat /etc/passwd|grep :$ID2:$ID2:|cut -d: -f1`
51
52 if [ ! "$USER1" ]; then
53         echo "===== Please add user1 (uid=$ID1 gid=$ID1)! Skip sanity-sec ====="
54         sec_error "===== Please add user1 (uid=$ID1 gid=$ID1)! ====="
55         exit 0
56 fi
57
58 if [ ! "$USER2" ]; then
59         echo "===== Please add user2 (uid=$ID2 gid=$ID2)! Skip sanity-sec ====="
60         sec_error "===== Please add user2 (uid=$ID2 gid=$ID2)! ====="
61         exit 0
62 fi
63
64 export NAME=${NAME:-local}
65
66 LUSTRE=${LUSTRE:-`dirname $0`/..} 
67 . $LUSTRE/tests/test-framework.sh
68 init_test_env $@
69 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
70
71 if [ ! -z "$USING_KRB5" ]; then
72     $RUNAS -u $ID1 krb5_login.sh || exit 1
73     $RUNAS -u $ID2 krb5_login.sh || exit 1
74 fi
75
76 sec_run_one() {
77         BEFORE=`date +%s`
78         log "== test $1 $2= `date +%H:%M:%S` ($BEFORE)"
79         export TESTNAME=test_$1
80         test_$1 || sec_error "exit with rc=$?"
81         unset TESTNAME
82         pass "($((`date +%s` - $BEFORE))s)"
83 }
84
85 build_test_filter() {
86         for O in $SEC_ONLY; do
87             eval SEC_ONLY_${O}=true
88         done
89         for E in $EXCEPT $ALWAYS_EXCEPT; do
90             eval EXCEPT_${E}=true
91         done
92 }
93
94 _basetest() {
95         echo $*
96 }
97
98 basetest() {
99         IFS=abcdefghijklmnopqrstuvwxyz _basetest $1
100 }
101
102 sec_run_test() {
103          base=`basetest $1`
104          if [ "$SEC_ONLY" ]; then
105                  testname=SEC_ONLY_$1
106                  if [ ${!testname}x != x ]; then
107                         sec_run_one $1 "$2"
108                         return $?
109                  fi
110                  testname=SEC_ONLY_$base
111                  if [ ${!testname}x != x ]; then
112                          sec_run_one $1 "$2"
113                          return $?
114                  fi
115                  echo -n "."
116                  return 0
117         fi
118         testname=EXCEPT_$1
119         if [ ${!testname}x != x ]; then
120                  echo "skipping excluded test $1"
121                  return 0
122         fi
123         testname=EXCEPT_$base
124         if [ ${!testname}x != x ]; then
125                  echo "skipping excluded test $1 (base $base)"
126                  return 0
127         fi
128         sec_run_one $1 "$2"
129         return $?
130 }
131
132 mounted_lustre_filesystems() {
133         awk '($3 ~ "lustre" && $1 ~ ":") { print $2 }' /proc/mounts
134 }
135
136 MOUNTED="`mounted_lustre_filesystems`"
137 if [ -z "$MOUNTED" ]; then
138         formatall
139         setupall
140         MOUNTED="`mounted_lustre_filesystems`"
141         [ -z "$MOUNTED" ] && sec_error "NAME=$NAME not mounted"
142         S_MOUNTED=yes
143 fi
144
145 [ `echo $MOUNT | wc -w` -gt 1 ] && sec_error "NAME=$NAME mounted more than once"
146
147 DIR=${DIR:-$MOUNT}
148 [ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && \
149         sec_cleanup && exit 99
150
151 [ `ls -l $LPROC/ldlm 2> /dev/null | grep lustre-MDT | wc -l` -gt 1 ] \
152         && echo "skip multi-MDS test" && sec_cleanup && exit 0
153
154 if [ -z "`lsmod | grep mdt`" ]; then
155         LOCAL_MDT=0
156         echo "remote mdt"
157         EXCEPT="$EXCEPT 1 3"
158 else
159         LOCAL_MDT=1
160         echo "local mdt"
161         EXCEPT="$EXCEPT 1 2 3"
162 fi
163
164 LPROC=/proc/fs/lustre
165 ENABLE_IDENTITY=/usr/sbin/l_getidentity
166 DISABLE_IDENTITY=NONE
167 LUSTRE_CONF_DIR=/etc/lustre
168 SETXID_CONF=$LUSTRE_CONF_DIR/setxid.conf
169 SETXID_CONF_BAK=$LUSTRE_CONF_DIR/setxid.conf.bak
170
171 if [ $LOCAL_MDT -eq 1 ]; then
172         MDT=$(\ls $LPROC/mdt 2> /dev/null | grep -v num_refs | tail -n 1)
173         IDENTITY_UPCALL=$LPROC/mdt/$MDT/identity_upcall
174         IDENTITY_UPCALL_BAK=`more $IDENTITY_UPCALL`
175         IDENTITY_FLUSH=$LPROC/mdt/$MDT/identity_flush
176         ROOTSQUASH_UID=$LPROC/mdt/$MDT/rootsquash_uid
177         ROOTSQUASH_GID=$LPROC/mdt/$MDT/rootsquash_gid
178         NOSQUASH_NIDS=$LPROC/mdt/$MDT/nosquash_nids
179 fi
180
181 CLIENT_TYPE=$LPROC/llite/*/client_type
182 grep "local client" $CLIENT_TYPE > /dev/null 2>&1 && EXCEPT="$EXCEPT 2"
183 grep "remote client" $CLIENT_TYPE > /dev/null 2>&1 && EXCEPT="$EXCEPT 1 3"
184
185 build_test_filter
186
187 setup() {
188         if [ -f "$SETXID_CONF" ]; then
189                 mv -f $SETXID_CONF $SETXID_CONF_BAK
190         else
191                 rm -f $SETXID_CONF_BAK
192         fi
193
194         if [ $LOCAL_MDT -eq 1 ]; then
195                 echo $ENABLE_IDENTITY > $IDENTITY_UPCALL
196                 echo -1 > $IDENTITY_FLUSH
197         fi
198
199         $RUNAS -u $ID1 ls $DIR
200         $RUNAS -u $ID2 ls $DIR
201 }
202 setup
203
204 # run as different user
205 test_0() {
206         rm -rf $DIR/d0
207         mkdir $DIR/d0
208
209         chown $USER1 $DIR/d0 || sec_error
210         $RUNAS -u $ID1 ls $DIR || sec_error
211         $RUNAS -u $ID1 touch $DIR/f0 && sec_error
212         $RUNAS -u $ID1 touch $DIR/d0/f1 || sec_error
213         $RUNAS -u $ID2 touch $DIR/d0/f2 && sec_error
214         touch $DIR/d0/f3 || sec_error
215         chown root $DIR/d0
216         chgrp $USER1 $DIR/d0
217         chmod 775 $DIR/d0
218         $RUNAS -u $ID1 touch $DIR/d0/f4 || sec_error
219         $RUNAS -u $ID2 touch $DIR/d0/f5 && sec_error
220         touch $DIR/d0/f6 || sec_error
221
222         rm -rf $DIR/d0
223 }
224 sec_run_test 0 "uid permission ============================="
225
226 # setuid/gid
227 test_1() {
228         rm -rf $DIR/d1
229         mkdir $DIR/d1
230
231         chown $USER1 $DIR/d1 || sec_error
232         $RUNAS -u $ID2 -v $ID1 touch $DIR/d1/f0 && sec_error
233         echo "* $ID2 setuid" > $SETXID_CONF
234         echo "enable uid $ID2 setuid"
235         echo -1 > $IDENTITY_FLUSH
236         $RUNAS -u $ID2 -v $ID1 touch $DIR/d1/f1 || sec_error
237
238         chown root $DIR/d1
239         chgrp $USER1 $DIR/d1
240         chmod 770 $DIR/d1
241         $RUNAS -u $ID2 -g $ID2 touch $DIR/d1/f2 && sec_error
242         echo "* $ID2 setuid,setgid" > $SETXID_CONF
243         echo "enable uid $ID2 setuid,setgid"
244         echo -1 > $IDENTITY_FLUSH
245         $RUNAS -u $ID2 -g $ID2 -j $ID1 touch $DIR/d1/f3 || sec_error
246         $RUNAS -u $ID2 -v $ID1 -g $ID2 -j $ID1 touch $DIR/d1/f4 || sec_error
247
248         rm -f $SETXID_CONF
249         rm -rf $DIR/d1
250         echo -1 > $IDENTITY_FLUSH
251 }
252 sec_run_test 1 "setuid/gid ============================="
253
254 # lfs getfacl/setfacl
255 test_2() {
256         rm -rf $DIR/d2
257         mkdir $DIR/d2
258         chmod 755 $DIR/d2
259         echo xxx > $DIR/d2/f0
260         chmod 644 $DIR/d2/f0
261
262         $LFS getfacl $DIR/d2/f0 || sec_error
263         $RUNAS -u $ID1 cat $DIR/d2/f0 || sec_error
264         $RUNAS -u $ID1 touch $DIR/d2/f0 && sec_error
265
266         $LFS setfacl -m u:$USER1:w $DIR/d2/f0 || sec_error
267         $LFS getfacl $DIR/d2/f0 || sec_error
268         echo "set user $USER1 write permission on file $DIR/d2/fo"
269         $RUNAS -u $ID1 touch $DIR/d2/f0 || sec_error
270         $RUNAS -u $ID1 cat $DIR/d2/f0 && sec_error
271
272         rm -rf $DIR/d2
273 }
274 sec_run_test 2 "lfs getfacl/setfacl ============================="
275
276 # rootsquash
277 test_3() {
278         $LCTL conf_param $MDT.mdt.nosquash_nids=none
279         while grep LNET_NID_ANY $NOSQUASH_NIDS > /dev/null; do sleep 1; done
280         $LCTL conf_param $MDT.mdt.rootsquash_uid=0
281         while [ "`cat $ROOTSQUASH_UID`" -ne 0 ]; do sleep 1; done
282         $LCTL conf_param $MDT.mdt.rootsquash_gid=0
283         while [ "`cat $ROOTSQUASH_GID`" -ne 0 ]; do sleep 1; done
284
285         rm -rf $DIR/d3
286         mkdir $DIR/d3
287         chown $USER1 $DIR/d3
288         chmod 700 $DIR/d3
289         $LCTL conf_param $MDT.mdt.rootsquash_uid=$ID1
290         echo "set rootsquash uid = $ID1"
291         while [ "`cat $ROOTSQUASH_UID`" -ne $ID1 ]; do sleep 1; done
292         touch $DIR/f3_0 && sec_error
293         touch $DIR/d3/f3_1 || sec_error
294
295         $LCTL conf_param $MDT.mdt.rootsquash_uid=0
296         echo "disable rootsquash"
297         while [ "`cat $ROOTSQUASH_UID`" -ne 0 ]; do sleep 1; done
298         chown root $DIR/d3
299         chgrp $USER2 $DIR/d3
300         chmod 770 $DIR/d3
301
302         $LCTL conf_param $MDT.mdt.rootsquash_uid=$ID1
303         echo "set rootsquash uid = $ID1"
304         while [ "`cat $ROOTSQUASH_UID`" -ne $ID1 ]; do sleep 1; done
305         touch $DIR/d3/f3_2 && sec_error
306         $LCTL conf_param $MDT.mdt.rootsquash_gid=$ID2
307         echo "set rootsquash gid = $ID2"
308         while [ "`cat $ROOTSQUASH_GID`" -ne $ID2 ]; do sleep 1; done
309         touch $DIR/d3/f3_3 || sec_error
310
311         $LCTL conf_param $MDT.mdt.nosquash_nids=*
312         echo "add host in rootsquash skip list"
313         while ! grep LNET_NID_ANY $NOSQUASH_NIDS > /dev/null;
314                 do sleep 1;
315         done
316         touch $DIR/f3_4 || sec_error
317
318         $LCTL conf_param $MDT.mdt.rootsquash_uid=0
319         while [ "`cat $ROOTSQUASH_UID`" -ne 0 ]; do sleep 1; done
320         $LCTL conf_param $MDT.mdt.rootsquash_gid=0
321         while [ "`cat $ROOTSQUASH_GID`" -ne 0 ]; do sleep 1; done
322         $LCTL conf_param $MDT.mdt.nosquash_nids=none
323         rm -rf $DIR/d3
324         rm -f $DIR/f3_?
325 }
326 sec_run_test 3 "rootsquash ============================="
327
328 # bug 3285 - supplementary group should always succeed (see do_init_ucred),
329 # NB: the supplementary groups are set for local client only, as for remote
330 # client, the groups of the specified uid on MDT will be obtained by
331 # upcall /sbin/l_getidentity and used.
332 test_4() {
333         mkdir $DIR/d4
334         chmod 771 $DIR/d4
335         chgrp $ID1 $DIR/d4
336         $RUNAS -u $ID1 ls $DIR/d4 || sec_error "setgroups(1) failed"
337         grep "local client" $CLIENT_TYPE > /dev/null 2>&1 && \
338                 ($RUNAS -u $ID2 -G1,2,$ID1 ls $DIR/d4 || \
339                         sec_error "setgroups(2) failed")
340         $RUNAS -u $ID2 -G1,2 ls $DIR/d4 && sec_error "setgroups(3) failed"
341         rm -rf $DIR/d4
342 }
343 sec_run_test 4 "set supplementary group ==============="
344
345 log "cleanup: ======================================================"
346
347 unsetup() {
348         if [ -f "$SETXID_CONF_BAK" ]; then
349                 mv -f $SETXID_CONF_BAK $SETXID_CONF
350         fi
351
352         if [ $LOCAL_MDT -eq 1 ]; then
353                 echo $IDENTITY_UPCALL_BAK > $IDENTITY_UPCALL
354                 echo -1 > $IDENTITY_FLUSH
355         fi
356
357         $RUNAS -u $ID1 ls $DIR
358         $RUNAS -u $ID2 ls $DIR
359 }
360 unsetup
361
362 sec_cleanup() {
363         if [ "$S_MOUNTED" = "yes" ]; then
364                 cleanupall -f || sec_error "cleanup failed"
365         fi
366 }
367 sec_cleanup
368
369 echo '=========================== finished ==============================='
370 [ -f "$SANITYSECLOG" ] && cat $SANITYSECLOG && exit 1 || true