Whamcloud - gitweb
7d9ef93c1697de90eb795288c2a131d4fbabfc9a
[fs/lustre-release.git] / lustre / tests / sanity-selinux.sh
1 #!/bin/bash
2 #
3 # NOTE
4 # In order to be able to do the runcon commands in test_4,
5 # the SELinux policy must allow transitions from unconfined_t
6 # to user_t and guest_t:
7 # #============= unconfined_r ==============
8 # allow unconfined_r guest_r;
9 # allow unconfined_r user_r;
10 #
11 # Run select tests by setting ONLY, or as arguments to the script.
12 # Skip specific tests by setting EXCEPT.
13 #
14 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
15 set -e
16
17 ONLY=${ONLY:-"$*"}
18 # bug number for skipped test:
19 ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"$SANITY_SELINUX_EXCEPT"}
20 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
21
22 SRCDIR=$(dirname $0)
23 SAVE_PWD=$PWD
24
25 LUSTRE=${LUSTRE:-$(dirname $0)/..}
26 . $LUSTRE/tests/test-framework.sh
27 init_test_env $@
28 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
29 init_logging
30
31 require_dsh_mds || exit 0
32
33 [ "$SLOW" = "no" ] && EXCEPT_SLOW="xxx"
34
35 RUNAS_CMD=${RUNAS_CMD:-runas}
36 # $RUNAS_ID may get set incorrectly somewhere else
37 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
38         error "RUNAS_ID set to 0, but UID is also 0!"
39
40 #
41 # global variables of this  sanity
42 #
43
44 check_selinux() {
45         echo -n "Checking SELinux environment... "
46         local selinux_status=$(getenforce)
47         if [ "$selinux_status" != "Enforcing" ]; then
48             skip "SELinux is currently in $selinux_status mode," \
49                  "but it must be enforced to run sanity-selinux" && exit 0
50         fi
51         local selinux_policy=$(sestatus |
52                 awk -F':' '$1 == "Loaded policy name" {print $2}' | xargs)
53         if [ -z "$selinux_policy" ]; then
54             selinux_policy=$(sestatus |
55                 awk -F':' '$1 == "Policy from config file" {print $2}' | xargs)
56         fi
57         [ "$selinux_policy" == "targeted" ] ||
58                 error "Accepting only targeted policy"
59         echo "$selinux_status, $selinux_policy"
60 }
61
62 check_selinux
63
64 # we want double mount
65 MOUNT_2=${MOUNT_2:-"yes"}
66 check_and_setup_lustre
67
68 rm -rf $DIR/[df][0-9]*
69
70 check_runas_id $RUNAS_ID $RUNAS_ID $RUNAS
71
72 build_test_filter
73
74 umask 077
75
76 check_selinux_xattr() {
77         local mds=$1
78         local mds_path=$2
79         local mds_dev=$(facet_device $mds)
80         local mntpt="/tmp/mdt_"
81         local opts
82
83         do_facet $mds mkdir -p $mntpt  || error "mkdir $mntpt failed"
84         mount_fstype $mds $mntpt  || error "mount $mds failed"
85
86         local xattrval=$(do_facet $mds getfattr -n security.selinux \
87                                 ${mntpt}/ROOT/$mds_path |
88                          awk -F"=" '$1=="security.selinux" {print $2}')
89
90         unmount_fstype $mds $mntpt || error "umount $mds failed"
91         do_facet $mds rmdir $mntpt || error "rmdir $mntpt failed"
92
93         echo $xattrval
94 }
95
96 get_sel_ctx() {
97         local file=$1
98
99         [ -n "$file" ] || return;
100         [ -f $file ] || return;
101         stat $file | awk '$1 == "Context:" {print $2}'
102 }
103
104 test_1() {
105         local devname=$(mdsdevname 1)
106         local filename=${DIR}/${tdir}/df1
107         local mds_path=${filename#$MOUNT}
108
109         mds_path=${mds_path#/}
110
111         $LFS setdirstripe -i0 -c1 ${DIR}/$tdir || error "create dir $tdir failed"
112         touch $filename || error "cannot touch $filename"
113
114         local xattrval=$(check_selinux_xattr "mds1" $mds_path)
115
116         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
117                 error "security.selinux xattr is not set"
118 }
119 run_test 1 "create file and check security.selinux xattr is set on MDT"
120
121 test_2a() {
122         local devname=$(mdsdevname 1)
123         local dirname=${DIR}/${tdir}/dir2a
124         local mds_path=${dirname#$MOUNT}
125
126         mds_path=${mds_path#/}
127
128         $LFS setdirstripe -i0 -c1 ${DIR}/$tdir || error "create dir failed"
129         mkdir $dirname || error "cannot mkdir $dirname"
130
131         local xattrval=$(check_selinux_xattr "mds1" $mds_path)
132
133         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
134                 error "security.selinux xattr is not set"
135 }
136 run_test 2a "create dir (mkdir) and check security.selinux xattr is set on MDT"
137
138 test_2b() {
139         local devname=$(mdsdevname 1)
140         local dirname1=${DIR}/$tdir/dir2b1
141         local dirname2=${DIR}/$tdir/dir2b2
142         local mds_path=${dirname1#$MOUNT}
143
144         mds_path=${mds_path#/}
145
146         $LFS setdirstripe -i0 -c1 ${DIR}/$tdir || error "create dir failed"
147         $LFS mkdir -c0 -i0 $dirname1 || error "cannot 'lfs mkdir' $dirname1"
148
149         local xattrval=$(check_selinux_xattr "mds1" $mds_path)
150
151         mds_path=${dirname2#$MOUNT}
152         mds_path=${mds_path#/}
153
154         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
155                 error "security.selinux xattr is not set"
156
157         $LFS setdirstripe -i0 $dirname2 ||
158             error "cannot 'lfs setdirstripe' $dirname2"
159
160         xattrval=$(check_selinux_xattr "mds1" $mds_path)
161
162         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
163                 error "security.selinux xattr is not set"
164 }
165 run_test 2b "create dir with lfs and check security.selinux xattr is set on MDT"
166
167 test_3() {
168         local filename=$DIR/$tdir/df3
169         local level=$(id -Z | cut -d':' -f4-)
170         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t \
171                         -l $level"
172
173         mkdir -p $DIR/$tdir
174         chmod 777 $DIR/$tdir
175
176         # "access" Lustre
177         echo "As unconfined_u: touch $filename"
178         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename ||
179                 error "can't touch $filename"
180         echo "As unconfined_u: rm -f $filename"
181         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx rm -f $filename ||
182                 error "can't remove $filename"
183
184         return 0
185 }
186 run_test 3 "access with unconfined user"
187
188 test_4() {
189         local filename=$DIR/$tdir/df4
190         local guestctx="-u guest_u -r guest_r -t guest_t -l s0"
191         local usrctx="-u user_u -r user_r -t user_t -l s0"
192
193         sesearch --role_allow | grep -q "allow unconfined_r user_r"
194         if [ $? -ne 0 ]; then
195             skip "SELinux policy module must allow transition from \
196                    unconfined_r to user_r for this test." && exit 0
197         fi
198         sesearch --role_allow | grep -q "allow unconfined_r guest_r"
199         if [ $? -ne 0 ]; then
200             skip "SELinux policy module must allow transition from \
201                    unconfined_r to guest_r for this test." && exit 0
202         fi
203
204         mkdir -p $DIR/$tdir
205         chmod 777 $DIR/$tdir
206
207         # "access" Lustre
208         echo "As guest_u: touch $filename"
209         $RUNAS_CMD -u $RUNAS_ID runcon $guestctx touch $filename &&
210                 error "touch $filename should have failed"
211
212         # "access" Lustre
213         echo "As user_u: touch $filename"
214         $RUNAS_CMD -u $RUNAS_ID runcon $usrctx touch $filename ||
215                 error "can't touch $filename"
216         echo "As user_u: rm -f $filename"
217         $RUNAS_CMD -u $RUNAS_ID runcon $usrctx rm -f $filename ||
218                 error "can't remove $filename"
219
220         return 0
221 }
222 run_test 4 "access with specific SELinux user"
223
224 test_5() {
225         local filename=$DIR/df5
226         local newsecctx="nfs_t"
227
228         # create file
229         touch $filename || error "cannot touch $filename"
230
231         # change sec context
232         chcon -t $newsecctx $filename
233         ls -lZ $filename
234
235         # purge client's cache
236         sync ; echo 3 > /proc/sys/vm/drop_caches
237
238         # get sec context
239         ls -lZ $filename
240         local secctxseen=$(get_sel_ctx $filename | cut -d: -f3)
241
242         [ "$newsecctx" == "$secctxseen" ] ||
243                 error "sec context seen from 1st mount point is not correct"
244
245         return 0
246 }
247 run_test 5 "security context retrieval from MDT xattr"
248
249 test_10() {
250         local filename1=$DIR/df10
251         local filename2=$DIR2/df10
252         local newsecctx="nfs_t"
253
254         # create file from 1st mount point
255         touch $filename1 || error "cannot touch $filename1"
256         ls -lZ $filename1
257
258         # change sec context from 2nd mount point
259         chcon -t $newsecctx $filename2
260         ls -lZ $filename2
261
262         # get sec context from 1st mount point
263         ls -lZ $filename1
264         local secctxseen=$(get_sel_ctx $filename1 | cut -d: -f3)
265
266         [ "$newsecctx" == "$secctxseen" ] ||
267                 error_ignore LU-6784 \
268                     "sec context seen from 1st mount point is not correct"
269
270         return 0
271 }
272 run_test 10 "[consistency] concurrent security context change"
273
274 test_20a() {
275         local filename1=$DIR/$tdir/df20a
276         local filename2=$DIR2/$tdir/df20a
277         local req_delay=20
278         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
279
280         mkdir -p $DIR/$tdir
281         chmod 777 $DIR/$tdir
282
283         # sleep some time in ll_create_nd()
284         #define OBD_FAIL_LLITE_CREATE_FILE_PAUSE   0x1409
285         do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x1409"
286
287         # create file on first mount point
288         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename1 &
289         local touchpid=$!
290         sleep 5
291
292         if [[ -z "$(ps h -o comm -p $touchpid)" ]]; then
293                 error "touch failed to sleep, pid=$touchpid"
294         fi
295
296         # get sec info on second mount point
297         if [ -e "$filename2" ]; then
298                 secinfo2=$(get_sel_ctx $filename2)
299         fi
300
301         # get sec info on first mount point
302         wait $touchpid
303         secinfo1=$(get_sel_ctx $filename1)
304
305         # compare sec contexts
306         [ -z "$secinfo2" -o "$secinfo1" == "$secinfo2" ] ||
307                 error "sec context seen from 2nd mount point is not correct"
308
309         return 0
310 }
311 run_test 20a "[atomicity] concurrent access from another client (file)"
312
313 test_20b() {
314         local dirname1=$DIR/$tdir/dd20b
315         local dirname2=$DIR2/$tdir/dd20b
316         local req_delay=20
317         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
318
319         mkdir -p $DIR/$tdir
320         chmod 777 $DIR/$tdir
321
322         # sleep some time in ll_create_nd()
323         #define OBD_FAIL_LLITE_NEWNODE_PAUSE     0x140a
324         do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x140a"
325
326         # create file on first mount point
327         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx mkdir $dirname1 &
328         local mkdirpid=$!
329         sleep 5
330
331         if [[ -z "$(ps h -o comm -p $mkdirpid)" ]]; then
332                 error "mkdir failed to sleep, pid=$mkdirpid"
333         fi
334
335         # get sec info on second mount point
336         if [ -e "$dirname2" ]; then
337                 secinfo2=$(ls -ldZ $dirname2 | awk '{print $4}')
338         else
339                 secinfo2=""
340         fi
341
342         # get sec info on first mount point
343         wait $mkdirpid
344         secinfo1=$(ls -ldZ $dirname1 | awk '{print $4}')
345
346         # compare sec contexts
347         [ -z "$secinfo2" -o "$secinfo1" == "$secinfo2" ] ||
348                 error "sec context seen from 2nd mount point is not correct"
349
350         return 0
351 }
352 run_test 20b "[atomicity] concurrent access from another client (dir)"
353
354 test_20c() {
355         local dirname1=$DIR/dd20c
356         local dirname2=$DIR2/dd20c
357         local req_delay=20
358
359         # sleep some time in ll_create_nd()
360         #define OBD_FAIL_LLITE_SETDIRSTRIPE_PAUSE     0x140b
361         do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x140b"
362
363         # create file on first mount point
364         $LFS mkdir -c0 -i0 $dirname1 &
365         local mkdirpid=$!
366         sleep 5
367
368         if [[ -z "$(ps h -o comm -p $mkdirpid)" ]]; then
369                 error "lfs mkdir failed to sleep, pid=$mkdirpid"
370         fi
371
372         # get sec info on second mount point
373         if [ -e "$dirname2" ]; then
374                 secinfo2=$(ls -ldZ $dirname2 | awk '{print $4}')
375         else
376                 secinfo2=""
377         fi
378
379         # get sec info on first mount point
380         wait $mkdirpid
381         secinfo1=$(ls -ldZ $dirname1 | awk '{print $4}')
382
383         # compare sec contexts
384         [ -z "$secinfo2" -o "$secinfo1" == "$secinfo2" ] ||
385                 error "sec context seen from 2nd mount point is not correct"
386
387         return 0
388 }
389 run_test 20c "[atomicity] concurrent access from another client (dir via lfs)"
390
391 cleanup_20d() {
392         umount_client $MOUNT || error "umount $MOUNT failed"
393         mountcli
394 }
395
396 trace_cmd() {
397         local cmd="$@"
398         local xattr_prefix=$(grep -E \
399                 "#define[[:space:]]+XATTR_SECURITY_PREFIX[[:space:]]+" \
400                 /usr/include/linux/xattr.h 2>/dev/null |
401                 awk '{print $3}' | sed s+\"++g)
402         local xattr_suffix=$(grep -E \
403                 "#define[[:space:]]+XATTR_SELINUX_SUFFIX[[:space:]]+" \
404                 /usr/include/linux/xattr.h 2>/dev/null |
405                 awk '{print $3}' | sed s+\"++g)
406         local xattr_name=${xattr_prefix}${xattr_suffix}
407
408         [ -z "$xattr_name" ] && xattr_name="security.selinux"
409
410         # umount client
411         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
412                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
413         fi
414         if $(grep -q $MOUNT' ' /proc/mounts); then
415                 umount_client $MOUNT || error "umount $MOUNT failed"
416         fi
417         lustre_rmmod
418         # remount client
419         mount_client $MOUNT ${MOUNT_OPTS} || error "mount client failed"
420
421         $LCTL set_param debug=+info
422         $LCTL clear
423
424         echo $cmd
425         eval $cmd
426
427         $LCTL dk | grep "get xattr '${xattr_name}'"
428         [ $? -eq 0 ] && error "get xattr event was triggered" || true
429 }
430
431 test_20d() {
432         if [ "$MDS1_VERSION" -lt $(version_code 2.12.50) ] ||
433            [ "$CLIENT_VERSION" -lt $(version_code 2.12.50) ]; then
434                 skip "Need version >= 2.12.50"
435         fi
436         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
437
438         stack_trap cleanup_20d EXIT
439
440         local dirname=$DIR/$tdir/subdir
441
442         mkdir -p $DIR/$tdir
443         mkdir $dirname
444
445         trace_cmd stat $dirname
446         trace_cmd touch $dirname/f1
447         trace_cmd stat $dirname/f1
448         trace_cmd cat $dirname/f1
449         dd if=/dev/zero of=$dirname/f1 bs=1M count=10
450         trace_cmd /usr/bin/truncate -s 10240 $dirname/f1
451         trace_cmd lfs setstripe -E -1 -S 4M $dirname/f2
452         trace_cmd lfs migrate -E -1 -S 256K $dirname/f2
453         trace_cmd lfs setdirstripe -i 1 $dirname/d2
454         trace_cmd lfs migrate -m 0 $dirname/d2
455
456         lfs setdirstripe -i 1 -c 1 $dirname/d3
457         dirname=$dirname/d3/subdir
458         mkdir $dirname
459
460         trace_cmd stat $dirname
461         trace_cmd touch $dirname/f1
462         trace_cmd stat $dirname/f1
463         trace_cmd cat $dirname/f1
464         dd if=/dev/zero of=$dirname/f1 bs=1M count=10
465         trace_cmd /usr/bin/truncate -s 10240 $dirname/f1
466         trace_cmd lfs setstripe -E -1 -S 4M $dirname/f2
467         trace_cmd lfs migrate -E -1 -S 256K $dirname/f2
468 }
469 run_test 20d "[atomicity] avoid getxattr for security context"
470
471 check_nodemap() {
472         local nm=$1
473         local key=$2
474         local val=$3
475         local facets=""
476         local i
477
478         if [ "$nm" == "active" ]; then
479                 proc_param="active"
480         else
481                 proc_param="$nm.$key"
482         fi
483         # check all MDS nodes, in reverse order to privilege remote ones first
484         for i in $(seq $MDSCOUNT); do
485                 facets="mds$i $facets"
486         done
487         for facet in $facets; do
488                 is_sync=false
489                 for i in {1..20}; do
490                         out=$(do_facet $facet $LCTL get_param -n \
491                                    nodemap.$proc_param 2>/dev/null)
492                         echo "On $facet, ${proc_param} = $out"
493                         [ "$val" == "$out" ] && is_sync=true && break
494                         sleep 1
495                 done
496                 if ! $is_sync; then
497                         error "$proc_param not updated on $facet after 20 secs"
498                 fi
499         done
500 }
501
502 create_nodemap() {
503         local nm=$1
504         local sepol
505         local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
506         local client_nid=$(h2nettype $client_ip)
507
508         do_facet mgs $LCTL nodemap_activate 1
509
510         do_facet mgs $LCTL nodemap_add $nm
511         do_facet mgs $LCTL nodemap_add_range \
512                         --name $nm --range $client_nid
513         do_facet mgs $LCTL nodemap_modify --name $nm \
514                         --property admin --value 1
515         do_facet mgs $LCTL nodemap_modify --name $nm \
516                         --property trusted --value 1
517
518         check_nodemap $nm admin_nodemap 1
519         check_nodemap $nm trusted_nodemap 1
520
521         sleep 10
522         sepol=$(l_getsepol | cut -d':' -f2- | xargs)
523         do_facet mgs $LCTL set_param -P nodemap.$nm.sepol="$sepol"
524
525         check_nodemap $nm sepol $sepol
526 }
527
528 remove_nodemap() {
529         local nm=$1
530
531         do_facet mgs $LCTL nodemap_del $nm
532
533         wait_update_facet --verbose mds1 \
534                 "$LCTL get_param nodemap.$nm.id 2>/dev/null | \
535                 grep -c $nm || true" 0 30 ||
536                 error "nodemap $nm could not be removed"
537
538         do_facet mgs $LCTL nodemap_activate 0
539
540         check_nodemap active x  0
541 }
542
543 test_21a() {
544         [ "$MDS1_VERSION" -lt $(version_code 2.11.56) ] &&
545                 skip "Need MDS >= 2.11.56"
546
547         local sepol
548
549         # umount client
550         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
551                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
552         fi
553         if $(grep -q $MOUNT' ' /proc/mounts); then
554                 umount_client $MOUNT || error "umount $MOUNT failed"
555         fi
556
557         # create nodemap entry with sepol
558         create_nodemap c0
559
560         if $GSS_SK; then
561                 # update mount option with skpath
562                 MOUNT_OPTS=$(add_sk_mntflag $MOUNT_OPTS)
563                 export SK_UNIQUE_NM=true
564
565                 # load specific key on servers
566                 do_nodes $(comma_list $(all_server_nodes)) "lgss_sk -t server \
567                                                     -l $SK_PATH/nodemap/c0.key"
568
569                 # set perms for per-nodemap keys else permission denied
570                 do_nodes $(comma_list $(all_server_nodes)) \
571                  "keyctl show | grep lustre | cut -c1-11 |
572                                 sed -e 's/ //g;' |
573                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
574
575         fi
576
577         # mount client without sending sepol
578         mount_client $MOUNT $MOUNT_OPTS &&
579                 error "client mount without sending sepol should be refused"
580
581         # mount client with sepol
582         echo -1 > /sys/module/ptlrpc/parameters/send_sepol
583         mount_client $MOUNT $MOUNT_OPTS ||
584                 error "client mount with sepol failed"
585
586         # umount client
587         umount_client $MOUNT || error "umount $MOUNT failed"
588
589         # store wrong sepol in nodemap
590         sepol="0:policy:0:0000000000000000000000000000000000000000000000000000000000000000"
591         do_facet mgs $LCTL set_param -P nodemap.c0.sepol="$sepol"
592         check_nodemap c0 sepol $sepol
593
594         # mount client with sepol
595         mount_client $MOUNT $MOUNT_OPTS &&
596                 error "client mount without matching sepol should be refused"
597
598         # remove nodemap
599         remove_nodemap c0
600
601         if $GSS_SK; then
602                 export SK_UNIQUE_NM=false
603         fi
604
605         # remount client normally
606         echo 0 > /sys/module/ptlrpc/parameters/send_sepol
607         mountcli || error "normal client mount failed"
608 }
609 run_test 21a "Send sepol at connect"
610
611 test_21b() {
612         [ "$MDS1_VERSION" -lt $(version_code 2.11.56) ] &&
613                 skip "Need MDS >= 2.11.56"
614
615         local sepol
616
617         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
618         echo test > $DIR/$tdir/toopen ||
619                 error "failed to write to $DIR/$tdir/toopen"
620         touch $DIR/$tdir/ftoremove ||
621                 error "failed to create $DIR/$tdir/ftoremove"
622         touch $DIR/$tdir/ftoremove2 ||
623                 error "failed to create $DIR/$tdir/ftoremove2"
624         touch $DIR/$tdir/ftoremove3 ||
625                 error "failed to create $DIR/$tdir/ftoremove3"
626         touch $DIR/$tdir/ftoremove4 ||
627                 error "failed to create $DIR/$tdir/ftoremove4"
628         mkdir $DIR/$tdir/dtoremove ||
629                 error "failed to create $DIR/$tdir/dtoremove"
630         mkdir $DIR/$tdir/dtoremove2 ||
631                 error "failed to create $DIR/$tdir/dtoremove2"
632         mkdir $DIR/$tdir/dtoremove3 ||
633                 error "failed to create $DIR/$tdir/dtoremove3"
634         mkdir $DIR/$tdir/dtoremove4 ||
635                 error "failed to create $DIR/$tdir/dtoremove4"
636         touch $DIR/$tdir/ftorename ||
637                 error "failed to create $DIR/$tdir/ftorename"
638         mkdir $DIR/$tdir/dtorename ||
639                 error "failed to create $DIR/$tdir/dtorename"
640         setfattr -n user.myattr -v myval $DIR/$tdir/toopen ||
641                 error "failed to set xattr on $DIR/$tdir/toopen"
642         echo 3 > /proc/sys/vm/drop_caches
643
644         # create nodemap entry with sepol
645         create_nodemap c0
646
647         if $GSS_SK; then
648                 export SK_UNIQUE_NM=true
649
650                 # load specific key on servers
651                 do_nodes $(comma_list $(all_server_nodes)) "lgss_sk -t server \
652                                                     -l $SK_PATH/nodemap/c0.key"
653
654                 # set perms for per-nodemap keys else permission denied
655                 do_nodes $(comma_list $(all_server_nodes)) \
656                  "keyctl show | grep lustre | cut -c1-11 |
657                                 sed -e 's/ //g;' |
658                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
659
660         fi
661
662         # metadata ops without sending sepol
663         touch $DIR/$tdir/f0 && error "touch (1)"
664         lfs setstripe -c1 $DIR/$tdir/f1 && error "lfs setstripe (1)"
665         mkdir $DIR/$tdir/d0 && error "mkdir (1)"
666         lfs setdirstripe -i0 -c1 $DIR/$tdir/d1 && error "lfs setdirstripe (1)"
667         cat $DIR/$tdir/toopen && error "cat (1)"
668         rm -f $DIR/$tdir/ftoremove && error "rm (1)"
669         rmdir $DIR/$tdir/dtoremove && error "rmdir (1)"
670         mv $DIR/$tdir/ftorename $DIR/$tdir/ftorename2 && error "mv (1)"
671         mv $DIR/$tdir/dtorename $DIR/$tdir/dtorename2 && error "mv (2)"
672         getfattr -n user.myattr $DIR/$tdir/toopen && error "getfattr (1)"
673         setfattr -n user.myattr -v myval2 $DIR/$tdir/toopen &&
674                 error "setfattr (1)"
675         chattr +i $DIR/$tdir/toopen && error "chattr (1)"
676         lsattr $DIR/$tdir/toopen && error "lsattr (1)"
677         chattr -i $DIR/$tdir/toopen && error "chattr (1)"
678         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl1 && error "symlink (1)"
679         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl1 && error "hardlink (1)"
680
681         # metadata ops with sepol
682         echo -1 > /sys/module/ptlrpc/parameters/send_sepol
683         touch $DIR/$tdir/f2 || error "touch (2)"
684         lfs setstripe -c1 $DIR/$tdir/f3 || error "lfs setstripe (2)"
685         mkdir $DIR/$tdir/d2 || error "mkdir (2)"
686         lfs setdirstripe -i0 -c1 $DIR/$tdir/d3 || error "lfs setdirstripe (2)"
687         cat $DIR/$tdir/toopen || error "cat (2)"
688         rm -f $DIR/$tdir/ftoremove || error "rm (2)"
689         rmdir $DIR/$tdir/dtoremove || error "rmdir (2)"
690         mv $DIR/$tdir/ftorename $DIR/$tdir/ftorename2 || error "mv (3)"
691         mv $DIR/$tdir/dtorename $DIR/$tdir/dtorename2 || error "mv (4)"
692         getfattr -n user.myattr $DIR/$tdir/toopen || error "getfattr (2)"
693         setfattr -n user.myattr -v myval2 $DIR/$tdir/toopen ||
694                 error "setfattr (2)"
695         chattr +i $DIR/$tdir/toopen || error "chattr (2)"
696         lsattr $DIR/$tdir/toopen || error "lsattr (2)"
697         chattr -i $DIR/$tdir/toopen || error "chattr (2)"
698         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl2 || error "symlink (2)"
699         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl2 || error "hardlink (2)"
700         echo 3 > /proc/sys/vm/drop_caches
701
702         # store wrong sepol in nodemap
703         sepol="0:policy:0:0000000000000000000000000000000000000000000000000000000000000000"
704         do_facet mgs $LCTL set_param -P nodemap.c0.sepol="$sepol"
705         check_nodemap c0 sepol $sepol
706
707         # metadata ops with sepol
708         touch $DIR/$tdir/f4 && error "touch (3)"
709         lfs setstripe -c1 $DIR/$tdir/f5 && error "lfs setstripe (3)"
710         mkdir $DIR/$tdir/d4 && error "mkdir (3)"
711         lfs setdirstripe -i0 -c1 $DIR/$tdir/d5 && error "lfs setdirstripe (3)"
712         cat $DIR/$tdir/toopen && error "cat (3)"
713         rm -f $DIR/$tdir/ftoremove2 && error "rm (3)"
714         rmdir $DIR/$tdir/dtoremove2 && error "rmdir (3)"
715         mv $DIR/$tdir/ftorename2 $DIR/$tdir/ftorename && error "mv (5)"
716         mv $DIR/$tdir/dtorename2 $DIR/$tdir/dtorename && error "mv (6)"
717         getfattr -n user.myattr $DIR/$tdir/toopen && error "getfattr (3)"
718         setfattr -n user.myattr -v myval3 $DIR/$tdir/toopen &&
719                 error "setfattr (3)"
720         chattr +i $DIR/$tdir/toopen && error "chattr (3)"
721         lsattr $DIR/$tdir/toopen && error "lsattr (3)"
722         chattr -i $DIR/$tdir/toopen && error "chattr (3)"
723         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl3 && error "symlink (3)"
724         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl3 && error "hardlink (3)"
725
726         # reset correct sepol
727         sepol=$(l_getsepol | cut -d':' -f2- | xargs)
728         do_facet mgs $LCTL set_param -P nodemap.c0.sepol="$sepol"
729         check_nodemap c0 sepol $sepol
730
731         # metadata ops with sepol every 1000 seconds only
732         echo 1000 > /sys/module/ptlrpc/parameters/send_sepol
733         local before=$(date +%s)
734         touch $DIR/$tdir/f6 || error "touch (4)"
735         lfs setstripe -c1 $DIR/$tdir/f7 || error "lfs setstripe (4)"
736         mkdir $DIR/$tdir/d6 || error "mkdir (4)"
737         lfs setdirstripe -i0 -c1 $DIR/$tdir/d7 || error "lfs setdirstripe (4)"
738         cat $DIR/$tdir/toopen || error "cat (4)"
739         rm -f $DIR/$tdir/ftoremove2 || error "rm (4)"
740         rmdir $DIR/$tdir/dtoremove2 || error "rmdir (4)"
741         mv $DIR/$tdir/ftorename2 $DIR/$tdir/ftorename || error "mv (7)"
742         mv $DIR/$tdir/dtorename2 $DIR/$tdir/dtorename || error "mv (8)"
743         getfattr -n user.myattr $DIR/$tdir/toopen || error "getfattr (4)"
744         setfattr -n user.myattr -v myval3 $DIR/$tdir/toopen ||
745                 error "setfattr (4)"
746         chattr +i $DIR/$tdir/toopen || error "chattr (4)"
747         lsattr $DIR/$tdir/toopen || error "lsattr (4)"
748         chattr -i $DIR/$tdir/toopen || error "chattr (4)"
749         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl4 || error "symlink (4)"
750         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl4 || error "hardlink (4)"
751         echo 3 > /proc/sys/vm/drop_caches
752
753         # change one SELinux boolean value
754         sebool=$(getsebool deny_ptrace | awk '{print $3}')
755         if [ "$sebool" == "off" ]; then
756                 setsebool -P deny_ptrace on
757         else
758                 setsebool -P deny_ptrace off
759         fi
760
761         # sepol should not be checked yet, so metadata ops without matching
762         # sepol should succeed
763         touch $DIR/$tdir/f8 || error "touch (5)"
764         lfs setstripe -c1 $DIR/$tdir/f9 || error "lfs setstripe (5)"
765         mkdir $DIR/$tdir/d8 || error "mkdir (5)"
766         lfs setdirstripe -i0 -c1 $DIR/$tdir/d9 || error "lfs setdirstripe (5)"
767         cat $DIR/$tdir/toopen || error "cat (5)"
768         rm -f $DIR/$tdir/ftoremove3 || error "rm (5)"
769         rmdir $DIR/$tdir/dtoremove3 || error "rmdir (5)"
770         mv $DIR/$tdir/ftorename $DIR/$tdir/ftorename2 || error "mv (9)"
771         mv $DIR/$tdir/dtorename $DIR/$tdir/dtorename2 || error "mv (10)"
772         getfattr -n user.myattr $DIR/$tdir/toopen || error "getfattr (5)"
773         setfattr -n user.myattr -v myval4 $DIR/$tdir/toopen ||
774                 error "setfattr (5)"
775         chattr +i $DIR/$tdir/toopen || error "chattr (5)"
776         lsattr $DIR/$tdir/toopen || error "lsattr (5)"
777         chattr -i $DIR/$tdir/toopen || error "chattr (5)"
778         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl5 || error "symlink (5)"
779         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl5 || error "hardlink (5)"
780         echo 3 > /proc/sys/vm/drop_caches
781
782         local after=$(date +%s)
783         # change send_sepol to a smaller, already expired, value
784         echo $((after-before-1)) > /sys/module/ptlrpc/parameters/send_sepol
785         # metadata ops without matching sepol: should fail now
786         touch $DIR/$tdir/f10 && error "touch (6)"
787         lfs setstripe -c1 $DIR/$tdir/f11 && error "lfs setstripe (6)"
788         mkdir $DIR/$tdir/d10 && error "mkdir (6)"
789         lfs setdirstripe -i0 -c1 $DIR/$tdir/d11 && error "lfs setdirstripe (6)"
790         cat $DIR/$tdir/toopen && error "cat (6)"
791         rm -f $DIR/$tdir/ftoremove4 && error "rm (6)"
792         rmdir $DIR/$tdir/dtoremove4 && error "rmdir (6)"
793         mv $DIR/$tdir/ftorename2 $DIR/$tdir/ftorename && error "mv (11)"
794         mv $DIR/$tdir/dtorename2 $DIR/$tdir/dtorename && error "mv (12)"
795         getfattr -n user.myattr $DIR/$tdir/toopen && error "getfattr (6)"
796         setfattr -n user.myattr -v myval5 $DIR/$tdir/toopen &&
797                 error "setfattr (6)"
798         chattr +i $DIR/$tdir/toopen && error "chattr (6)"
799         lsattr $DIR/$tdir/toopen && error "lsattr (6)"
800         chattr -i $DIR/$tdir/toopen && error "chattr (6)"
801         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl6 && error "symlink (6)"
802         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl6 && error "hardlink (6)"
803
804         # restore SELinux boolean value
805         if [ "$sebool" == "off" ]; then
806                 setsebool -P deny_ptrace off
807         else
808                 setsebool -P deny_ptrace on
809         fi
810
811         # remove nodemap
812         remove_nodemap c0
813         echo 0 > /sys/module/ptlrpc/parameters/send_sepol
814
815         if $GSS_SK; then
816                 export SK_UNIQUE_NM=false
817         fi
818 }
819 run_test 21b "Send sepol for metadata ops"
820
821 complete $SECONDS
822 check_and_cleanup_lustre
823 exit_status