diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/filesync/acls.c | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/filesync/acls.c')
| -rw-r--r-- | usr/src/cmd/filesync/acls.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/usr/src/cmd/filesync/acls.c b/usr/src/cmd/filesync/acls.c new file mode 100644 index 0000000000..aef5dac80e --- /dev/null +++ b/usr/src/cmd/filesync/acls.c @@ -0,0 +1,293 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved + * + * module: + * acls.c + * + * purpose: + * routines to manipulate access control lists, mapping between + * the data structures required by the filesystem ACL system calls + * and the representation used in our fileinfo structure. + * + */ +#ident "%W% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> + +#include "filesync.h" +#include "database.h" + +#ifdef NO_ACLS +/* + * Solaris 2.4 libc.so does not contain this entry point, so if we + * want to build a 2.4 version of filesync, we need to provide a + * dummy entry point that will fail when-ever it is called. + */ +#define acl bogus_acl + +static int acl(const char *name, int opcode, int count, aclent_t *acls) +{ + return (-1); +} +#endif + +/* + * routine: + * get_acls + * + * purpose: + * to read the ACL (if any) from a file into a fileinfo structure + * + * parameters: + * name of file + * pointer to fileinfo structure + * + * returns: + * number of ACL entries + */ +int +get_acls(const char *name, struct fileinfo *ip) +{ int count; + int i; + static aclent_t acls[MAX_ACL_ENTRIES]; + aclent_t *list; + + count = acl(name, GETACL, MAX_ACL_ENTRIES, acls); + if (count <= 0) + return (0); + + /* with a count of 3 or 4 there may not be any real ones */ + if (count > 4) + goto gotsome; + + /* look for anything beyond the normal unix protection */ + for (i = 0; i < count; i++) + switch (acls[i].a_type) { + default: /* weird types are real */ + goto gotsome; + + case USER_OBJ: + case GROUP_OBJ: + case OTHER_OBJ: + case CLASS_OBJ: + continue; /* all file have these */ + } + + return (0); /* nothing interesting */ + +gotsome: + /* allocate an array to hold the acls */ + list = (aclent_t *) malloc(count * sizeof (*list)); + if (list == 0) + nomem("Access Control List"); + + /* copy the acls into the new list */ + for (i = 0; i < count; i++) { + list[i].a_type = acls[i].a_type; + list[i].a_id = acls[i].a_id; + list[i].a_perm = acls[i].a_perm; + } + + ip->f_acls = list; + ip->f_numacls = count; + return (ip->f_numacls); +} + +/* + * routine: + * cmp_acls + * + * purpose: + * determine whether or not two ACLs are the same + * + * parameters: + * pointer to first fileinfo + * pointer to second fileinfo + * + * returns: + * true equal + * false different + */ +int +cmp_acls(struct fileinfo *f1, struct fileinfo *f2) +{ int i; + + if (f1->f_numacls != f2->f_numacls) + return (0); + + if (f1->f_numacls == 0) + return (1); + + for (i = 0; i < f1->f_numacls; i++) { + if (f1->f_acls[i].a_type != f2->f_acls[i].a_type) + return (0); + if (f1->f_acls[i].a_id != f2->f_acls[i].a_id) + return (0); + if (f1->f_acls[i].a_perm != f2->f_acls[i].a_perm) + return (0); + } + + return (1); +} + +/* + * routine: + * set_acls + * + * purpose: + * to write the ACL of a file + * + * parameters: + * name of file + * fileinfo pointer (which contains an acl pointer) + * + * returns: + * retcode and errno + */ +int +set_acls(const char *name, struct fileinfo *fp) +{ int rc; + int nacl; + aclent_t acls[4], *list; + + if (fp->f_numacls == 0) { + /* fabricate a standard set of bogus ACLs */ + acls[0].a_type = USER_OBJ; + acls[0].a_id = fp->f_uid; + acls[0].a_perm = (fp->f_mode >> 6) & 7; + + acls[1].a_type = GROUP_OBJ; + acls[1].a_id = fp->f_gid; + acls[1].a_perm = (fp->f_mode >> 3) & 7; + + acls[2].a_type = CLASS_OBJ; + acls[2].a_id = 0; + acls[2].a_perm = (fp->f_mode >> 6) & 7; + + acls[3].a_type = OTHER_OBJ; + acls[3].a_id = 0; + acls[3].a_perm = fp->f_mode & 7; + + nacl = 4; + list = acls; + } else { + nacl = fp->f_numacls; + list = fp->f_acls; + } + + rc = acl(name, SETACL, nacl, list); + + /* non-negative number mean success */ + if (rc < 0) + return (rc); + else + return (0); +} + +/* + * routine: + * show_acls + * + * purpose: + * to map an acl into arguments for a setfacl command + * + * paramters: + * number of elements in list + * pointer to list + * + * returns: + * pointer to character buffer containing arguments + */ +char +*show_acls(int numacl, aclent_t *list) +{ int i, j; + int type, perm, id; + char *s; + static char buf[ MAX_LINE ]; + + s = buf; + + if (numacl > 0) { + *s++ = '-'; + *s++ = 's'; + *s++ = ' '; + } else { + *s++ = '-'; + *s++ = 'd'; + } + + for (i = 0; i < numacl; i++) { + type = list[i].a_type; + id = list[i].a_id; + perm = list[i].a_perm; + + if (i > 0) + *s++ = ','; + + /* note whether this is per-file or default */ + if (type & ACL_DEFAULT) { + *s++ = 'd'; + *s++ = ':'; + } + + /* print out the entry type */ + if (type & (USER_OBJ|USER)) { + *s++ = 'u'; + *s++ = ':'; + } else if (type & (GROUP_OBJ|GROUP)) { + *s++ = 'g'; + *s++ = ':'; + } else if (type & OTHER_OBJ) { + *s++ = 'o'; + *s++ = ':'; + } else if (type & CLASS_OBJ) { + *s++ = 'm'; + *s++ = ':'; + } + + /* print out the ID for this ACL */ + if (type & (USER_OBJ|GROUP_OBJ)) + *s++ = ':'; + else if (type & (USER|GROUP)) { + for (j = 1; id/j > 10; j *= 10); + + while (j > 0) { + *s++ = '0' + (id/j); + id %= j*10; + j /= 10; + } + + *s++ = ':'; + } + + /* print out the permissions for this ACL */ + *s++ = (perm & 04) ? 'r' : '-'; + *s++ = (perm & 02) ? 'w' : '-'; + *s++ = (perm & 01) ? 'x' : '-'; + } + + *s = 0; + return (buf); +} |
