Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / cmd / filesync / acls.c
blobaef5dac80e6a5f49cf2b667ee725092f757700c2
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
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]
20 * CDDL HEADER END
23 * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved
25 * module:
26 * acls.c
28 * purpose:
29 * routines to manipulate access control lists, mapping between
30 * the data structures required by the filesystem ACL system calls
31 * and the representation used in our fileinfo structure.
34 #ident "%W% %E% SMI"
36 #include <stdio.h>
37 #include <stdlib.h>
39 #include "filesync.h"
40 #include "database.h"
42 #ifdef NO_ACLS
44 * Solaris 2.4 libc.so does not contain this entry point, so if we
45 * want to build a 2.4 version of filesync, we need to provide a
46 * dummy entry point that will fail when-ever it is called.
48 #define acl bogus_acl
50 static int acl(const char *name, int opcode, int count, aclent_t *acls)
52 return (-1);
54 #endif
57 * routine:
58 * get_acls
60 * purpose:
61 * to read the ACL (if any) from a file into a fileinfo structure
63 * parameters:
64 * name of file
65 * pointer to fileinfo structure
67 * returns:
68 * number of ACL entries
70 int
71 get_acls(const char *name, struct fileinfo *ip)
72 { int count;
73 int i;
74 static aclent_t acls[MAX_ACL_ENTRIES];
75 aclent_t *list;
77 count = acl(name, GETACL, MAX_ACL_ENTRIES, acls);
78 if (count <= 0)
79 return (0);
81 /* with a count of 3 or 4 there may not be any real ones */
82 if (count > 4)
83 goto gotsome;
85 /* look for anything beyond the normal unix protection */
86 for (i = 0; i < count; i++)
87 switch (acls[i].a_type) {
88 default: /* weird types are real */
89 goto gotsome;
91 case USER_OBJ:
92 case GROUP_OBJ:
93 case OTHER_OBJ:
94 case CLASS_OBJ:
95 continue; /* all file have these */
98 return (0); /* nothing interesting */
100 gotsome:
101 /* allocate an array to hold the acls */
102 list = (aclent_t *) malloc(count * sizeof (*list));
103 if (list == 0)
104 nomem("Access Control List");
106 /* copy the acls into the new list */
107 for (i = 0; i < count; i++) {
108 list[i].a_type = acls[i].a_type;
109 list[i].a_id = acls[i].a_id;
110 list[i].a_perm = acls[i].a_perm;
113 ip->f_acls = list;
114 ip->f_numacls = count;
115 return (ip->f_numacls);
119 * routine:
120 * cmp_acls
122 * purpose:
123 * determine whether or not two ACLs are the same
125 * parameters:
126 * pointer to first fileinfo
127 * pointer to second fileinfo
129 * returns:
130 * true equal
131 * false different
134 cmp_acls(struct fileinfo *f1, struct fileinfo *f2)
135 { int i;
137 if (f1->f_numacls != f2->f_numacls)
138 return (0);
140 if (f1->f_numacls == 0)
141 return (1);
143 for (i = 0; i < f1->f_numacls; i++) {
144 if (f1->f_acls[i].a_type != f2->f_acls[i].a_type)
145 return (0);
146 if (f1->f_acls[i].a_id != f2->f_acls[i].a_id)
147 return (0);
148 if (f1->f_acls[i].a_perm != f2->f_acls[i].a_perm)
149 return (0);
152 return (1);
156 * routine:
157 * set_acls
159 * purpose:
160 * to write the ACL of a file
162 * parameters:
163 * name of file
164 * fileinfo pointer (which contains an acl pointer)
166 * returns:
167 * retcode and errno
170 set_acls(const char *name, struct fileinfo *fp)
171 { int rc;
172 int nacl;
173 aclent_t acls[4], *list;
175 if (fp->f_numacls == 0) {
176 /* fabricate a standard set of bogus ACLs */
177 acls[0].a_type = USER_OBJ;
178 acls[0].a_id = fp->f_uid;
179 acls[0].a_perm = (fp->f_mode >> 6) & 7;
181 acls[1].a_type = GROUP_OBJ;
182 acls[1].a_id = fp->f_gid;
183 acls[1].a_perm = (fp->f_mode >> 3) & 7;
185 acls[2].a_type = CLASS_OBJ;
186 acls[2].a_id = 0;
187 acls[2].a_perm = (fp->f_mode >> 6) & 7;
189 acls[3].a_type = OTHER_OBJ;
190 acls[3].a_id = 0;
191 acls[3].a_perm = fp->f_mode & 7;
193 nacl = 4;
194 list = acls;
195 } else {
196 nacl = fp->f_numacls;
197 list = fp->f_acls;
200 rc = acl(name, SETACL, nacl, list);
202 /* non-negative number mean success */
203 if (rc < 0)
204 return (rc);
205 else
206 return (0);
210 * routine:
211 * show_acls
213 * purpose:
214 * to map an acl into arguments for a setfacl command
216 * paramters:
217 * number of elements in list
218 * pointer to list
220 * returns:
221 * pointer to character buffer containing arguments
223 char
224 *show_acls(int numacl, aclent_t *list)
225 { int i, j;
226 int type, perm, id;
227 char *s;
228 static char buf[ MAX_LINE ];
230 s = buf;
232 if (numacl > 0) {
233 *s++ = '-';
234 *s++ = 's';
235 *s++ = ' ';
236 } else {
237 *s++ = '-';
238 *s++ = 'd';
241 for (i = 0; i < numacl; i++) {
242 type = list[i].a_type;
243 id = list[i].a_id;
244 perm = list[i].a_perm;
246 if (i > 0)
247 *s++ = ',';
249 /* note whether this is per-file or default */
250 if (type & ACL_DEFAULT) {
251 *s++ = 'd';
252 *s++ = ':';
255 /* print out the entry type */
256 if (type & (USER_OBJ|USER)) {
257 *s++ = 'u';
258 *s++ = ':';
259 } else if (type & (GROUP_OBJ|GROUP)) {
260 *s++ = 'g';
261 *s++ = ':';
262 } else if (type & OTHER_OBJ) {
263 *s++ = 'o';
264 *s++ = ':';
265 } else if (type & CLASS_OBJ) {
266 *s++ = 'm';
267 *s++ = ':';
270 /* print out the ID for this ACL */
271 if (type & (USER_OBJ|GROUP_OBJ))
272 *s++ = ':';
273 else if (type & (USER|GROUP)) {
274 for (j = 1; id/j > 10; j *= 10);
276 while (j > 0) {
277 *s++ = '0' + (id/j);
278 id %= j*10;
279 j /= 10;
282 *s++ = ':';
285 /* print out the permissions for this ACL */
286 *s++ = (perm & 04) ? 'r' : '-';
287 *s++ = (perm & 02) ? 'w' : '-';
288 *s++ = (perm & 01) ? 'x' : '-';
291 *s = 0;
292 return (buf);