summaryrefslogtreecommitdiff
path: root/usr/src/cmd/filesync/acls.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/filesync/acls.c
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/filesync/acls.c')
-rw-r--r--usr/src/cmd/filesync/acls.c293
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);
+}