static int do_set_acl(struct asfd *asfd, const char *path, const char *acltext, int acltype, struct cntr *cntr) { acl_t acl; int ret=-1; if(!(acl=acl_from_text(acltext))) { logp("acl_from_text error on %s (%s): %s\n", path, acltext, strerror(errno)); logw(asfd, cntr, "acl_from_text error on %s (%s): %s\n", path, acltext, strerror(errno)); goto end; } if(acl_valid(acl)) { logp("acl_valid error on %s: %s", path, strerror(errno)); logw(asfd, cntr, "acl_valid error on %s: %s\n", path, strerror(errno)); goto end; } if(acl_set_file(path, acltype, acl)) { logp("acl set error on %s: %s", path, strerror(errno)); logw(asfd, cntr, "acl set error on %s: %s\n", path, strerror(errno)); goto end; } ret=0; end: if(acl) acl_free(acl); return ret; }
int fpm_unix_set_socket_premissions(struct fpm_worker_pool_s *wp, const char *path) /* {{{ */ { #ifdef HAVE_FPM_ACL if (wp->socket_acl) { acl_t aclfile, aclconf; acl_entry_t entryfile, entryconf; int i; /* Read the socket ACL */ aclconf = wp->socket_acl; aclfile = acl_get_file (path, ACL_TYPE_ACCESS); if (!aclfile) { zlog(ZLOG_SYSERROR, "[pool %s] failed to read the ACL of the socket '%s'", wp->config->name, path); return -1; } /* Copy the new ACL entry from config */ for (i=ACL_FIRST_ENTRY ; acl_get_entry(aclconf, i, &entryconf) ; i=ACL_NEXT_ENTRY) { if (0 > acl_create_entry (&aclfile, &entryfile) || 0 > acl_copy_entry(entryfile, entryconf)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to add entry to the ACL of the socket '%s'", wp->config->name, path); acl_free(aclfile); return -1; } } /* Write the socket ACL */ if (0 > acl_calc_mask (&aclfile) || 0 > acl_valid (aclfile) || 0 > acl_set_file (path, ACL_TYPE_ACCESS, aclfile)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to write the ACL of the socket '%s'", wp->config->name, path); acl_free(aclfile); return -1; } else { zlog(ZLOG_DEBUG, "[pool %s] ACL of the socket '%s' is set", wp->config->name, path); } acl_free(aclfile); return 0; } /* When listen.users and listen.groups not configured, continue with standard right */ #endif if (wp->socket_uid != -1 || wp->socket_gid != -1) { if (0 > chown(path, wp->socket_uid, wp->socket_gid)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to chown() the socket '%s'", wp->config->name, wp->config->listen_address); return -1; } } return 0; }
int main(int argc, char *argv[]) { acl_t acl; int n, ret = 0; progname = basename(argv[0]); if (argc < 3) { printf("%s -- set access control list of files\n" "Usage: %s acl file ...\n", progname, progname); return 1; } acl = acl_from_text(argv[1]); if (!acl) { fprintf(stderr, "%s: `%s': %s\n", progname, argv[1], strerror(errno)); return 1; } if (acl_valid(acl) != 0) { fprintf(stderr, "%s: `%s': invalid/incomplete acl\n", progname, argv[1]); acl_free(acl); return 1; } for (n = 2; n < argc; n++) { if (acl_set_file(argv[n], ACL_TYPE_ACCESS, acl) != 0) { fprintf(stderr, "%s: setting acl of %s: %s\n", progname, argv[n], strerror(errno)); ret = 1; } } acl_free(acl); return ret; }
/*! * Remove any ACL_USER, ACL_GROUP, ACL_MASK or ACL_TYPE_DEFAULT ACEs from an object * * @param name (r) filesystem object name * * @returns AFP error code, AFP_OK (= 0) on success, AFPERR_MISC on error */ int remove_acl_vfs(const char *name) { EC_INIT; struct stat st; acl_t acl = NULL; acl_entry_t e; acl_tag_t tag; int entry_id = ACL_FIRST_ENTRY; /* Remove default ACL if it's a dir */ EC_ZERO_ERR(stat(name, &st), AFPERR_MISC); if (S_ISDIR(st.st_mode)) { EC_NULL_LOG_ERR(acl = acl_init(0), AFPERR_MISC); EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_DEFAULT, acl), AFPERR_MISC); EC_ZERO_LOG_ERR(acl_free(acl), AFPERR_MISC); acl = NULL; } /* Now get ACL and remove ACL_MASK, ACL_USER or ACL_GROUP entries, then re-set * the ACL again. acl_calc_mask() must not be called because there is no need * for an ACL_MASK entry in a basic ACL. */ EC_NULL_LOG_ERR(acl = acl_get_file(name, ACL_TYPE_ACCESS), AFPERR_MISC); for ( ; acl_get_entry(acl, entry_id, &e) == 1; entry_id = ACL_NEXT_ENTRY) { EC_ZERO_LOG_ERR(acl_get_tag_type(e, &tag), AFPERR_MISC); if (tag == ACL_USER || tag == ACL_GROUP || tag == ACL_MASK) EC_ZERO_LOG_ERR(acl_delete_entry(acl, e), AFPERR_MISC); } EC_ZERO_LOG_ERR(acl_valid(acl), AFPERR_MISC); EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_ACCESS, acl), AFPERR_MISC); EC_CLEANUP: if (errno == ENOENT) EC_STATUS(0); if (acl) acl_free(acl); EC_EXIT; }
static int do_set_acl(struct asfd *asfd, const char *path, const char *acltext, size_t alen, int acltype, struct cntr *cntr) { acl_t acl; int ret=-1; if(!(acl=acl_from_text(acltext))) { logp("acl_from_text error on %s (%s): %s\n", path, acltext, strerror(errno)); logw(asfd, cntr, "acl_from_text error on %s (%s): %s\n", path, acltext, strerror(errno)); goto end; } //#ifndef HAVE_FREEBSD_OS // Bacula says that acl_valid fails on valid input // on freebsd. It works OK for me on FreeBSD 8.2. if(acl_valid(acl)) { logp("acl_valid error on %s: %s", path, strerror(errno)); logw(asfd, cntr, "acl_valid error on %s: %s\n", path, strerror(errno)); goto end; } //#endif if(acl_set_file(path, acltype, acl)) { logp("acl set error on %s: %s", path, strerror(errno)); logw(asfd, cntr, "acl set error on %s: %s\n", path, strerror(errno)); goto end; } ret=0; end: if(acl) acl_free(acl); return ret; }
/* * acl_from_text -- Convert a string into an ACL. * Postpone most validity checking until the end and call acl_valid() to do * that. */ acl_t acl_from_text(const char *buf_p) { acl_t acl; char *mybuf_p, *line, *cur, *notcomment, *comment, *entry; int error; /* Local copy we can mess up. */ mybuf_p = strdup(buf_p); if (mybuf_p == NULL) return(NULL); acl = acl_init(3); /* XXX: WTF, 3? */ if (acl == NULL) { free(mybuf_p); return(NULL); } /* Outer loop: delimit at \n boundaries. */ cur = mybuf_p; while ((line = strsep(&cur, "\n"))) { /* Now split the line on the first # to strip out comments. */ comment = line; notcomment = strsep(&comment, "#"); /* Inner loop: delimit at ',' boundaries. */ while ((entry = strsep(¬comment, ","))) { /* Skip empty lines. */ if (strlen(string_skip_whitespace(entry)) == 0) continue; if (_acl_brand(acl) == ACL_BRAND_UNKNOWN) { if (_text_is_nfs4_entry(entry)) _acl_brand_as(acl, ACL_BRAND_NFS4); else _acl_brand_as(acl, ACL_BRAND_POSIX); } switch (_acl_brand(acl)) { case ACL_BRAND_NFS4: error = _nfs4_acl_entry_from_text(acl, entry); break; case ACL_BRAND_POSIX: error = _posix1e_acl_entry_from_text(acl, entry); break; default: error = EINVAL; break; } if (error) goto error_label; } } #if 0 /* XXX Should we only return ACLs valid according to acl_valid? */ /* Verify validity of the ACL we read in. */ if (acl_valid(acl) == -1) { errno = EINVAL; goto error_label; } #endif free(mybuf_p); return(acl); error_label: acl_free(acl); free(mybuf_p); return(NULL); }
void cupsdAddCert(int pid, /* I - Process ID */ const char *username, /* I - Username */ int type) /* I - AuthType for username */ { int i; /* Looping var */ cupsd_cert_t *cert; /* Current certificate */ int fd; /* Certificate file */ char filename[1024]; /* Certificate filename */ static const char hex[] = "0123456789ABCDEF"; /* Hex constants... */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: Adding certificate for PID %d", pid); /* * Allocate memory for the certificate... */ if ((cert = calloc(sizeof(cupsd_cert_t), 1)) == NULL) return; /* * Fill in the certificate information... */ cert->pid = pid; cert->type = type; strlcpy(cert->username, username, sizeof(cert->username)); for (i = 0; i < 32; i ++) cert->certificate[i] = hex[CUPS_RAND() & 15]; /* * Save the certificate to a file readable only by the User and Group * (or root and SystemGroup for PID == 0)... */ snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid); unlink(filename); if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create certificate file %s - %s", filename, strerror(errno)); free(cert); return; } if (pid == 0) { #ifdef HAVE_ACL_INIT acl_t acl; /* ACL information */ acl_entry_t entry; /* ACL entry */ acl_permset_t permset; /* Permissions */ # ifdef HAVE_MBR_UID_TO_UUID uuid_t group; /* Group ID */ # endif /* HAVE_MBR_UID_TO_UUID */ static int acls_not_supported = 0; /* Only warn once */ #endif /* HAVE_ACL_INIT */ /* * Root certificate... */ fchmod(fd, 0440); fchown(fd, RunUser, SystemGroupIDs[0]); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d", NumSystemGroups); #ifdef HAVE_ACL_INIT if (NumSystemGroups > 1) { /* * Set POSIX ACLs for the root certificate so that all system * groups can access it... */ int j; /* Looping var */ # ifdef HAVE_MBR_UID_TO_UUID /* * On MacOS X, ACLs use UUIDs instead of GIDs... */ acl = acl_init(NumSystemGroups - 1); for (i = 1; i < NumSystemGroups; i ++) { /* * Add each group ID to the ACL... */ for (j = 0; j < i; j ++) if (SystemGroupIDs[j] == SystemGroupIDs[i]) break; if (j < i) continue; /* Skip duplicate groups */ acl_create_entry(&acl, &entry); acl_get_permset(entry, &permset); acl_add_perm(permset, ACL_READ_DATA); acl_set_tag_type(entry, ACL_EXTENDED_ALLOW); mbr_gid_to_uuid((gid_t)SystemGroupIDs[i], group); acl_set_qualifier(entry, &group); acl_set_permset(entry, permset); } # else /* * POSIX ACLs need permissions for owner, group, other, and mask * in addition to the rest of the system groups... */ acl = acl_init(NumSystemGroups + 3); /* Owner */ acl_create_entry(&acl, &entry); acl_get_permset(entry, &permset); acl_add_perm(permset, ACL_READ); acl_set_tag_type(entry, ACL_USER_OBJ); acl_set_permset(entry, permset); /* Group */ acl_create_entry(&acl, &entry); acl_get_permset(entry, &permset); acl_add_perm(permset, ACL_READ); acl_set_tag_type(entry, ACL_GROUP_OBJ); acl_set_permset(entry, permset); /* Others */ acl_create_entry(&acl, &entry); acl_get_permset(entry, &permset); acl_add_perm(permset, 0); acl_set_tag_type(entry, ACL_OTHER); acl_set_permset(entry, permset); /* Mask */ acl_create_entry(&acl, &entry); acl_get_permset(entry, &permset); acl_add_perm(permset, ACL_READ); acl_set_tag_type(entry, ACL_MASK); acl_set_permset(entry, permset); for (i = 1; i < NumSystemGroups; i ++) { /* * Add each group ID to the ACL... */ for (j = 0; j < i; j ++) if (SystemGroupIDs[j] == SystemGroupIDs[i]) break; if (j < i) continue; /* Skip duplicate groups */ acl_create_entry(&acl, &entry); acl_get_permset(entry, &permset); acl_add_perm(permset, ACL_READ); acl_set_tag_type(entry, ACL_GROUP); acl_set_qualifier(entry, SystemGroupIDs + i); acl_set_permset(entry, permset); } if (acl_valid(acl)) { char *text, *textptr; /* Temporary string */ cupsdLogMessage(CUPSD_LOG_ERROR, "ACL did not validate: %s", strerror(errno)); text = acl_to_text(acl, NULL); for (textptr = strchr(text, '\n'); textptr; textptr = strchr(textptr + 1, '\n')) *textptr = ','; cupsdLogMessage(CUPSD_LOG_ERROR, "ACL: %s", text); acl_free(text); } # endif /* HAVE_MBR_UID_TO_UUID */ if (acl_set_fd(fd, acl)) { if (errno != EOPNOTSUPP || !acls_not_supported) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set ACLs on root certificate \"%s\" - %s", filename, strerror(errno)); if (errno == EOPNOTSUPP) acls_not_supported = 1; } acl_free(acl); } #endif /* HAVE_ACL_INIT */ RootCertTime = time(NULL); } else { /* * CGI certificate... */ fchmod(fd, 0400); fchown(fd, User, Group); } DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username, cert->certificate)); write(fd, cert->certificate, strlen(cert->certificate)); close(fd); /* * Insert the certificate at the front of the list... */ cert->next = Certs; Certs = cert; }
int main(int argc, char *argv[]) { Boolean recalcMask, useDefaultACL; Boolean modifyACL, removeACL, removeDefaultACL, checkValidity; int optCnt, j, opt, numEntries, en; acl_type_t type; char *aclSpec; acl_t acl; acl_entry_t entry; struct AccessControlEntry aclist[MAX_ENTRIES]; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageError(argv[0], NULL, FALSE); /* Parse command-line options */ recalcMask = TRUE; useDefaultACL = FALSE; modifyACL = FALSE; removeACL = FALSE; checkValidity = FALSE; removeDefaultACL = FALSE; optCnt = 0; while ((opt = getopt(argc, argv, "m:x:kdnV:")) != -1) { switch (opt) { case 'm': modifyACL = TRUE; aclSpec = optarg; optCnt++; break; case 'x': removeACL = TRUE; aclSpec = optarg; optCnt++; break; case 'k': removeDefaultACL = TRUE; optCnt++; break; case 'V': checkValidity = TRUE; aclSpec = optarg; optCnt++; break; case 'd': useDefaultACL = TRUE; break; case 'n': recalcMask = FALSE; break; default: usageError(argv[0], "Bad option\n", TRUE); break; } } if (optCnt != 1) usageError(argv[0], "Specify exactly one of -m, -x, -k, or -V\n", TRUE); if (checkValidity && useDefaultACL) usageError(argv[0], "Can't specify -d with -V\n", TRUE); if (checkValidity) { if (parseACL(aclSpec, aclist, TRUE) == -1) { fatal("Bad ACL entry specification"); } else { printf("ACL is valid\n"); exit(EXIT_SUCCESS); } } if (modifyACL || removeACL) { numEntries = parseACL(aclSpec, aclist, modifyACL); if (numEntries == -1) usageError(argv[0], "Bad ACL specification\n", TRUE); } type = useDefaultACL ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS; /* Perform the operation on each file argument */ for (j = optind; j < argc; j++) { if (removeDefaultACL) { if (acl_delete_def_file(argv[j]) == -1) errExit("acl_delete_def_file: %s", argv[j]); } else if (modifyACL || removeACL) { acl = acl_get_file(argv[j], type); if (acl == NULL) errExit("acl_get_file"); /* Apply each of the entries in 'aclist' to the current file */ for (en = 0; en < numEntries; en++) { entry = findEntry(acl, aclist[en].tag, aclist[en].qual); if (removeACL) { if (entry != NULL) if (acl_delete_entry(acl, entry) == -1) errExit("acl_delete_entry"); } else { /* modifyACL */ if (entry == NULL) { /* Entry didn't exist in ACL -- create a new entry with required tag and qualifier */ if (acl_create_entry(&acl, &entry) == -1) errExit("acl_create_entry"); if (acl_set_tag_type(entry, aclist[en].tag) == -1) errExit("acl_set_tag_type"); if (aclist[en].tag == ACL_USER || aclist[en].tag == ACL_GROUP) if (acl_set_qualifier(entry, &aclist[en].qual) == -1) errExit("acl_set_qualifier"); } setPerms(entry, aclist[en].perms); } /* Recalculate the mask entry if requested */ if (recalcMask) if (acl_calc_mask(&acl) == -1) errExit("acl_calc_mask"); /* Update the file ACL */ if (acl_valid(acl) == -1) errExit("acl_valid"); if (acl_set_file(argv[j], type, acl) == -1) errExit("acl_set_file"); } if (acl_free(acl) == -1) errExit("acl_free"); } else { fatal("Bad logic!"); } } exit(EXIT_SUCCESS); }
static acl_t smb_acl_to_posix(const struct smb_acl_t *acl) { acl_t result; int i; result = acl_init(acl->count); if (result == NULL) { DEBUG(10, ("acl_init failed\n")); return NULL; } for (i=0; i<acl->count; i++) { const struct smb_acl_entry *entry = &acl->acl[i]; acl_entry_t e; acl_tag_t tag; if (acl_create_entry(&result, &e) != 0) { DEBUG(1, ("acl_create_entry failed: %s\n", strerror(errno))); goto fail; } switch (entry->a_type) { case SMB_ACL_USER: tag = ACL_USER; break; case SMB_ACL_USER_OBJ: tag = ACL_USER_OBJ; break; case SMB_ACL_GROUP: tag = ACL_GROUP; break; case SMB_ACL_GROUP_OBJ: tag = ACL_GROUP_OBJ; break; case SMB_ACL_OTHER: tag = ACL_OTHER; break; case SMB_ACL_MASK: tag = ACL_MASK; break; default: DEBUG(1, ("Unknown tag value %d\n", entry->a_type)); goto fail; } if (acl_set_tag_type(e, tag) != 0) { DEBUG(10, ("acl_set_tag_type(%d) failed: %s\n", tag, strerror(errno))); goto fail; } switch (entry->a_type) { case SMB_ACL_USER: if (acl_set_qualifier(e, &entry->uid) != 0) { DEBUG(1, ("acl_set_qualifiier failed: %s\n", strerror(errno))); goto fail; } break; case SMB_ACL_GROUP: if (acl_set_qualifier(e, &entry->gid) != 0) { DEBUG(1, ("acl_set_qualifiier failed: %s\n", strerror(errno))); goto fail; } break; default: /* Shut up, compiler! :-) */ break; } if (smb_acl_set_mode(e, entry->a_perm) != 0) { goto fail; } } if (acl_valid(result) != 0) { DEBUG(0, ("smb_acl_to_posix: ACL is invalid for set (%s)\n", strerror(errno))); goto fail; } return result; fail: if (result != NULL) { acl_free(result); } return NULL; }
void dump_acl(const acl_t acl) { DEBUG("acl valid: %d\n", acl_valid(acl) == 0 ? 1 : 0); walk_acl(acl, dump_acl_callback, NULL); }
/* * acl_calc_mask() (23.4.2): calculate and set the permissions * associated with the ACL_MASK ACL entry. If the ACL already * contains an ACL_MASK entry, its permissions shall be * overwritten; if not, one shall be added. */ int acl_calc_mask(acl_t *acl_p) { struct acl *acl_int, *acl_int_new; acl_t acl_new; int i, mask_mode, mask_num; /* * (23.4.2.4) requires acl_p to point to a pointer to a valid ACL. * Since one of the primary reasons to use this function would be * to calculate the appropriate mask to obtain a valid ACL, we only * perform sanity checks here and validate the ACL prior to * returning. */ if (acl_p == NULL || *acl_p == NULL) { errno = EINVAL; return (-1); } if (!_acl_brand_may_be(*acl_p, ACL_BRAND_POSIX)) { errno = EINVAL; return (-1); } _acl_brand_as(*acl_p, ACL_BRAND_POSIX); acl_int = &(*acl_p)->ats_acl; if ((acl_int->acl_cnt < 3) || (acl_int->acl_cnt > ACL_MAX_ENTRIES)) { errno = EINVAL; return (-1); } acl_new = acl_dup(*acl_p); if (acl_new == NULL) return (-1); acl_int_new = &acl_new->ats_acl; mask_mode = 0; mask_num = -1; /* gather permissions and find a mask entry */ for (i = 0; i < acl_int_new->acl_cnt; i++) { switch(acl_int_new->acl_entry[i].ae_tag) { case ACL_USER: case ACL_GROUP: case ACL_GROUP_OBJ: mask_mode |= acl_int_new->acl_entry[i].ae_perm & ACL_PERM_BITS; break; case ACL_MASK: mask_num = i; break; } } /* if a mask entry already exists, overwrite the perms */ if (mask_num != -1) acl_int_new->acl_entry[mask_num].ae_perm = mask_mode; else { /* if no mask exists, check acl_cnt... */ if (acl_int_new->acl_cnt == ACL_MAX_ENTRIES) { errno = ENOMEM; acl_free(acl_new); return (-1); } /* ...and add the mask entry */ acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_tag = ACL_MASK; acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_id = ACL_UNDEFINED_ID; acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_perm = mask_mode; acl_int_new->acl_cnt++; } if (acl_valid(acl_new) == -1) { errno = EINVAL; acl_free(acl_new); return (-1); } **acl_p = *acl_new; acl_free(acl_new); return (0); }