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