4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * This is the smbfs/chacl command.
29 * (just for testing - not installed)
31 * Works like chmod(1), but only supporting A=... forms.
32 * i.e. chacl A=everyone@:full_set:fd:allow /mnt/foo
34 * Some more test cases:
35 * /usr/lib/fs/smbfs/chacl -v
36 * A=user:2147483649:rwxpdDaARWcCos::allow,
37 * user:2147483653:raRcs::allow,
38 * everyone@:raRcs::allow
41 #include <sys/types.h>
42 #include <sys/errno.h>
45 #include <sys/acl_impl.h>
54 #include <netsmb/smbfs_acl.h>
59 void chacl(char *, uint32_t, uid_t
, gid_t
, acl_t
*);
61 static const char Usage
[] =
62 "Usage: %s [-v] [-u UID] [-g GID] A=ACL... file ...\n"
63 "\twhere A=ACL is like chmod(1)\n";
68 fprintf(stderr
, Usage
, progname
);
73 main(int argc
, char **argv
)
75 uid_t uid
= (uid_t
)-1;
76 gid_t gid
= (gid_t
)-1;
85 while ((c
= getopt(argc
, argv
, "vu:g:")) != -1) {
91 tl
= strtoul(optarg
, NULL
, 10);
97 tl
= strtoul(optarg
, NULL
, 10);
103 fprintf(stderr
, "%s: option %c requires arg\n",
110 fprintf(stderr
, "%s: bad option: %c\n",
117 if (optind
+ 1 > argc
)
119 acl_arg
= argv
[optind
++];
122 * Ask libsec to parse the ACL arg.
124 if (strncmp(acl_arg
, "A=", 2) != 0)
126 error
= acl_parse(acl_arg
+ 2, &acl
);
128 fprintf(stderr
, "%s: can not parse ACL: %s\n",
132 if (acl
->acl_type
!= ACE_T
) {
133 fprintf(stderr
, "%s: ACL not ACE_T type: %s\n",
139 * Which parts of the SD are being modified?
143 selector
|= DACL_SECURITY_INFORMATION
;
144 if (uid
!= (uid_t
)-1)
145 selector
|= OWNER_SECURITY_INFORMATION
;
146 if (gid
!= (gid_t
)-1)
147 selector
|= GROUP_SECURITY_INFORMATION
;
151 for (; optind
< argc
; optind
++)
152 chacl(argv
[optind
], selector
, uid
, gid
, acl
);
160 chacl(char *file
, uint32_t selector
, uid_t uid
, gid_t gid
, acl_t
*acl
)
163 struct i_ntsd
*sd
= NULL
;
167 * OK, try setting the ACL (via ioctl). Open
168 * read-only because we're NOT writing data.
169 * The driver will re-open with the necessary
170 * access rights to set the ACL.
172 fd
= open(file
, O_RDONLY
, 0);
178 if (uid
== (uid_t
)-1 || gid
== (gid_t
)-1) {
180 * If not setting owner or group, we need the
181 * current owner and group for translating
182 * references via owner@ or group@ ACEs.
184 if (fstat(fd
, &st
) != 0) {
188 if (uid
== (uid_t
)-1)
190 if (gid
== (gid_t
)-1)
195 * Convert the ZFS ACL to an NT SD.
197 error
= smbfs_acl_zfs2sd(acl
, uid
, gid
, selector
, &sd
);
199 fprintf(stderr
, "%s: failed to convert ACL\n", progname
);
206 * Print the SD in ZFS form.
208 printf("Solaris security data:\n");
209 if (uid
== (uid_t
)-1)
210 printf("owner: -1\n");
212 printf("owner: %u\n", uid
);
213 if (gid
== (gid_t
)-1)
214 printf("group: -1\n");
216 printf("group: %u\n", gid
);
217 acl_printacl(acl
, 80, 1);
221 * Print the SD in Windows form.
223 printf("CIFS security data:\n");
224 smbfs_acl_print_sd(stdout
, sd
);
228 error
= smbfs_acl_setsd(fd
, selector
, sd
);
232 fprintf(stderr
, "%s: ACL set failed, %s\n",
233 file
, strerror(error
));
237 smbfs_acl_free_sd(sd
);