1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or https://opensource.org/licenses/CDDL-1.0.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib
24
25#
26#
27# DESCRIPTION:
28#       Test idmapped mount in a user namespace
29#
30# STRATEGY:
31#	1. Create a zoned dataset
32#	2. Create a user namespace and designate the dataset to the zone
33#	3. In the zone, mount the dataset to "idmap_test"
34#	4. In the zone, idmap mount the dataset mountpoint to "idmap_dest"
35#	5. Do some file operations in the idmapped mountpoint "idmap_dest"
36#	6. Check the owner of files/folder in the mount point "idmap_test"
37#	7. unmount the mountpoints in the zone
38#	8. Remount the dataset in global zone to "idmap_test"
39#	9. Check the owenr of filers/folder in the mountpoint "idmap_test"
40#
41
42verify_runnable "global"
43
44export WORKDIR=$TESTDIR/idmap_test
45export IDMAPDIR=$TESTDIR/idmap_dest
46
47function cleanup
48{
49	if [[ -v unshared_pid ]]; then
50		zfs unzone /proc/$unshared_pid/ns/user "$TESTPOOL/userns"
51		kill -TERM ${unshared_pid}
52	fi
53	if mountpoint $WORKDIR; then
54		log_must umount $WORKDIR
55	fi
56	log_must rm -rf $WORKDIR
57}
58
59log_onexit cleanup
60
61if ! idmap_util -c $TESTDIR; then
62	log_unsupported "Idmap mount not supported."
63fi
64
65unshare -Urm echo test
66if [ "$?" -ne "0" ]; then
67	log_unsupported "Failed to create user namespace"
68fi
69
70log_must zfs create -o zoned=off -o mountpoint=$WORKDIR "$TESTPOOL/userns"
71
72# "root" user and group in the user ns
73log_must chown 1000000:1000000 $WORKDIR
74log_must zfs set zoned=on "$TESTPOOL/userns"
75
76log_must mkdir -p $IDMAPDIR
77
78unshare -Um /usr/bin/sleep 2h &
79unshared_pid=$!
80if [ "$?" -ne "0" ]; then
81	log_unsupported "Failed to create user namespace"
82fi
83# wait for userns to be ready
84sleep 1
85echo "0 1000000 1000000" > /proc/$unshared_pid/uid_map
86if [ "$?" -ne "0" ]; then
87	log_unsupported "Failed to write to uid_map"
88fi
89echo "0 1000000 1000000" > /proc/$unshared_pid/gid_map
90if [ "$?" -ne "0" ]; then
91	log_unsupported "Failed to write to gid_map"
92fi
93
94NSENTER="nsenter -t $unshared_pid --all -S 0 -G 0"
95
96log_must zfs zone /proc/$unshared_pid/ns/user "$TESTPOOL/userns"
97log_must $NSENTER zfs mount "$TESTPOOL/userns"
98log_must $NSENTER chmod 777 $WORKDIR
99
100$NSENTER idmap_util -c $WORKDIR
101if [ "$?" -ne "0" ]; then
102	log_unsupported "Idmapped mount not supported in a user namespace"
103fi
104
105log_must $NSENTER idmap_util -m b:0:10000:100000 $WORKDIR $IDMAPDIR
106log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups touch $IDMAPDIR/file
107log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups mkdir $IDMAPDIR/folder
108log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups ln -s file $IDMAPDIR/file-soft
109log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups ln $IDMAPDIR/file $IDMAPDIR/file-hard
110
111log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups cp -p $IDMAPDIR/file $IDMAPDIR/folder/file-p
112log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups cp $IDMAPDIR/file $IDMAPDIR/folder/file
113
114log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/file)"
115log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/folder)"
116log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/file-soft)"
117log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/file-hard)"
118log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/folder/file-p)"
119log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/folder/file)"
120
121log_must $NSENTER umount $IDMAPDIR
122log_must $NSENTER umount $WORKDIR
123
124log_must zfs unzone /proc/$unshared_pid/ns/user "$TESTPOOL/userns"
125log_must kill -TERM $unshared_pid
126unset unshared_pid
127log_must zfs set zoned=off "$TESTPOOL/userns"
128log_must zfs mount "$TESTPOOL/userns"
129
130log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/file)"
131log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/folder)"
132log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/file-soft)"
133log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/file-hard)"
134log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/folder/file-p)"
135log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/folder/file)"
136
137log_pass "Testing idmapped mount in a user ns is successful."
138
139