static int smb_acl_set_mode(acl_entry_t entry, SMB_ACL_PERM_T perm) { int ret; acl_permset_t permset; if ((ret = acl_get_permset(entry, &permset)) != 0) { return ret; } if ((ret = acl_clear_perms(permset)) != 0) { return ret; } if ((perm & SMB_ACL_READ) && ((ret = acl_add_perm(permset, ACL_READ)) != 0)) { return ret; } if ((perm & SMB_ACL_WRITE) && ((ret = acl_add_perm(permset, ACL_WRITE)) != 0)) { return ret; } if ((perm & SMB_ACL_EXECUTE) && ((ret = acl_add_perm(permset, ACL_EXECUTE)) != 0)) { return ret; } return acl_set_permset(entry, permset); }
/* Remove all perms specified in modifier from rentry*/ int subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier, int* valid_perms) { acl_permset_t rperms, mperms; acl_flagset_t rflags, mflags; if (valid_perms) *valid_perms = 0; int i; if ((acl_get_permset(rentry, &rperms) != 0) || (acl_get_flagset_np(rentry, &rflags) != 0) || (acl_get_permset(modifier, &mperms) != 0) || (acl_get_flagset_np(modifier, &mflags) != 0)) { // err(1, "error computing ACL modification"); fprintf(stderr, "chmod: error computing ACL modification: %s\n", strerror(errno)); pthread_exit(NULL); } for (i = 0; acl_perms[i].name != NULL; i++) { if (acl_get_perm_np(mperms, acl_perms[i].perm)) acl_delete_perm(rperms, acl_perms[i].perm); else if (valid_perms && acl_get_perm_np(rperms, acl_perms[i].perm)) (*valid_perms)++; } for (i = 0; acl_flags[i].name != NULL; i++) { if (acl_get_flag_np(mflags, acl_flags[i].flag)) acl_delete_flag_np(rflags, acl_flags[i].flag); } acl_set_permset(rentry, rperms); acl_set_flagset_np(rentry, rflags); return 0; }
/* Add the perms specified in modifier to rentry */ static int merge_entry_perms(acl_entry_t rentry, acl_entry_t modifier) { acl_permset_t rperms, mperms; acl_flagset_t rflags, mflags; int i; if ((acl_get_permset(rentry, &rperms) != 0) || (acl_get_flagset_np(rentry, &rflags) != 0) || (acl_get_permset(modifier, &mperms) != 0) || (acl_get_flagset_np(modifier, &mflags) != 0)) { // err(1, "error computing ACL modification"); fprintf(stderr, "chmod: error computing ACL modification: %s\n", strerror(errno)); pthread_exit(NULL); } for (i = 0; acl_perms[i].name != NULL; i++) { if (acl_get_perm_np(mperms, acl_perms[i].perm)) acl_add_perm(rperms, acl_perms[i].perm); } for (i = 0; acl_flags[i].name != NULL; i++) { if (acl_get_flag_np(mflags, acl_flags[i].flag)) acl_add_flag_np(rflags, acl_flags[i].flag); } acl_set_permset(rentry, rperms); acl_set_flagset_np(rentry, rflags); return 0; }
/* Add the perms specified in modifier to rentry */ static int merge_entry_perms(acl_entry_t rentry, acl_entry_t modifier) { acl_permset_t rperms, mperms; acl_flagset_t rflags, mflags; int i; if ((acl_get_permset(rentry, &rperms) != 0) || (acl_get_flagset_np(rentry, &rflags) != 0) || (acl_get_permset(modifier, &mperms) != 0) || (acl_get_flagset_np(modifier, &mflags) != 0)) err(1, "error computing ACL modification"); for (i = 0; acl_perms[i].name != NULL; i++) { if (acl_get_perm_np(mperms, acl_perms[i].perm)) acl_add_perm(rperms, acl_perms[i].perm); } for (i = 0; acl_flags[i].name != NULL; i++) { if (acl_get_flag_np(mflags, acl_flags[i].flag)) acl_add_flag_np(rflags, acl_flags[i].flag); } acl_set_permset(rentry, rperms); acl_set_flagset_np(rentry, rflags); return 0; }
static int merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new, int acl_brand) { acl_permset_t permset; acl_entry_type_t entry_type; acl_flagset_t flagset; int have_entry; uid_t *id, *id_new; have_entry = 0; id = acl_get_qualifier(*entry); if (id == NULL) err(1, "acl_get_qualifier() failed"); id_new = acl_get_qualifier(*entry_new); if (id_new == NULL) err(1, "acl_get_qualifier() failed"); if (*id == *id_new) { /* any other matches */ if (acl_get_permset(*entry, &permset) == -1) err(1, "acl_get_permset() failed"); if (acl_set_permset(*entry_new, permset) == -1) err(1, "acl_set_permset() failed"); if (acl_brand == ACL_BRAND_NFS4) { if (acl_get_entry_type_np(*entry, &entry_type)) err(1, "acl_get_entry_type_np() failed"); if (acl_set_entry_type_np(*entry_new, entry_type)) err(1, "acl_set_entry_type_np() failed"); if (acl_get_flagset_np(*entry, &flagset)) err(1, "acl_get_flagset_np() failed"); if (acl_set_flagset_np(*entry_new, flagset)) err(1, "acl_set_flagset_np() failed"); } have_entry = 1; } acl_free(id); acl_free(id_new); return (have_entry); }
/** * update a perm_set_t in entry to the one in aclentry * entry: acl entry to change from in-memory * acl_entry: where to retrieve new perms from * returns status **/ static _BOOL acl_update_perm(acl_entry_t *entry,acl_entry_in *entry_in){ if(entry_in == NULL) return; acl_permset_t perm_set; if(acl_get_permset(*entry,&perm_set)!=ACL_OK) return FALSE; if(((entry_in->permset.nibble&READ) ? acl_add_perm(perm_set,ACL_READ) : acl_delete_perm(perm_set,ACL_READ))!=ACL_OK) return FALSE; if(((entry_in->permset.nibble&WRITE)? acl_add_perm(perm_set,ACL_WRITE) : acl_delete_perm(perm_set,ACL_WRITE))!=ACL_OK) return FALSE; if(((entry_in->permset.nibble&EXEC) ? acl_add_perm(perm_set,ACL_EXECUTE): acl_delete_perm(perm_set,ACL_EXECUTE))!=ACL_OK) return FALSE; if(acl_set_permset(*entry,perm_set)!=ACL_OK) return FALSE; return TRUE; }
/* merge two acl entries together */ static int merge_acl_entries(acl_entry_t *entry1, acl_entry_t *entry2) { acl_permset_t permset; acl_entry_type_t entry_type; acl_flagset_t flagset; if (acl_get_permset(*entry1, &permset) < 0) err(EX_OSERR, "acl_get_permset() failed"); if (acl_set_permset(*entry2, permset) < 0) err(EX_OSERR, "acl_set_permset() failed"); if (acl_get_entry_type_np(*entry1, &entry_type) < 0) err(EX_OSERR, "acl_get_entry_type_np() failed"); if (acl_set_entry_type_np(*entry2, entry_type) < 0) err(EX_OSERR, "acl_set_entry_type_np() failed"); if (acl_get_flagset_np(*entry1, &flagset) < 0) err(EX_OSERR, "acl_get_flagset_np() failed"); if (acl_set_flagset_np(*entry2, flagset) < 0) err(EX_OSERR, "acl_set_flagset_np() failed"); return (0); }
static void setPerms(acl_entry_t entry, int perms) { acl_permset_t permset; if (acl_get_permset(entry, &permset) == -1) errExit("acl_get_permset"); if (acl_clear_perms(permset) == -1) errExit("acl_clear_perms"); if (perms & ACL_READ) if (acl_add_perm(permset, ACL_READ) == -1) errExit("acl_add_perm"); if (perms & ACL_WRITE) if (acl_add_perm(permset, ACL_WRITE) == -1) errExit("acl_add_perm"); if (perms & ACL_EXECUTE) if (acl_add_perm(permset, ACL_EXECUTE) == -1) errExit("acl_add_perm"); if (acl_set_permset(entry, permset) == -1) errExit("acl_set_permset"); }
acl_t pfl_acl_from_xattr(const void *buf, size_t size) { int i, entries; const struct acl_ea_header *h = buf; const struct acl_ea_entry *xe = PSC_AGP(h + 1, 0); unsigned int xperms; acl_permset_t permset; acl_entry_t e; acl_tag_t tag; acl_t a; if (size < sizeof(*h)) { errno = EINVAL; return (NULL); } if (le32toh(h->version) != ACL_EA_VERSION) { errno = EINVAL; return (NULL); } size -= sizeof(*h); if (size % sizeof(*xe)) { errno = EINVAL; return (NULL); } entries = size / sizeof(*xe); a = acl_init(entries); if (a == NULL) return (NULL); for (i = 0; i < entries; i++, xe++) { acl_create_entry(&a, &e); if (acl_get_permset(e, &permset) == -1) psclog_error("get_permset"); acl_clear_perms(permset); xperms = le16toh(xe->perm); if (xperms & ACL_READ) acl_add_perm(permset, ACL_READ); if (xperms & ACL_WRITE) acl_add_perm(permset, ACL_WRITE); if (xperms & ACL_EXECUTE) acl_add_perm(permset, ACL_EXECUTE); if (acl_set_permset(e, permset) == -1) psclog_error("set_permset"); acl_set_tag_type(e, tag = le16toh(xe->tag)); switch (tag) { case ACL_USER: { uid_t uid = le32toh(xe->id); acl_set_qualifier(e, &uid); break; } case ACL_GROUP: { gid_t gid = le32toh(xe->id); acl_set_qualifier(e, &gid); break; } } } return (a); }
static acl_t _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask) { acl_t acl_new, acl_old; acl_entry_t entry, entry_new; acl_permset_t perm; acl_tag_t tag; int entry_id, have_mask_entry; assert(_acl_brand(aclp) == ACL_BRAND_POSIX); acl_old = acl_dup(aclp); if (acl_old == NULL) return (NULL); assert(_acl_brand(acl_old) == ACL_BRAND_POSIX); have_mask_entry = 0; acl_new = acl_init(ACL_MAX_ENTRIES); if (acl_new == NULL) return (NULL); tag = ACL_UNDEFINED_TAG; /* only save the default user/group/other entries */ entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(acl_old, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; assert(_entry_brand(entry) == ACL_BRAND_POSIX); if (acl_get_tag_type(entry, &tag) == -1) return (NULL); switch(tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_OTHER: if (acl_get_tag_type(entry, &tag) == -1) return (NULL); if (acl_get_permset(entry, &perm) == -1) return (NULL); if (acl_create_entry(&acl_new, &entry_new) == -1) return (NULL); if (acl_set_tag_type(entry_new, tag) == -1) return (NULL); if (acl_set_permset(entry_new, perm) == -1) return (NULL); if (acl_copy_entry(entry_new, entry) == -1) return (NULL); assert(_entry_brand(entry_new) == ACL_BRAND_POSIX); break; case ACL_MASK: have_mask_entry = 1; break; default: break; } } assert(_acl_brand(acl_new) == ACL_BRAND_POSIX); if (have_mask_entry && recalculate_mask) { if (acl_calc_mask(&acl_new) == -1) return (NULL); } return (acl_new); }
/* * merge an ACL into existing file's ACL */ int merge_acl(acl_t acl, acl_t *prev_acl, const char *filename) { acl_entry_t entry, entry_new; acl_permset_t permset; acl_t acl_new; acl_tag_t tag, tag_new; acl_entry_type_t entry_type, entry_type_new; acl_flagset_t flagset; int entry_id, entry_id_new, have_entry, had_entry, entry_number = 0; int acl_brand, prev_acl_brand; acl_get_brand_np(acl, &acl_brand); acl_get_brand_np(*prev_acl, &prev_acl_brand); if (branding_mismatch(acl_brand, prev_acl_brand)) { warnx("%s: branding mismatch; existing ACL is %s, " "entry to be merged is %s", filename, brand_name(prev_acl_brand), brand_name(acl_brand)); return (-1); } acl_new = acl_dup(*prev_acl); if (acl_new == NULL) err(1, "%s: acl_dup() failed", filename); entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(acl, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; have_entry = 0; had_entry = 0; /* keep track of existing ACL_MASK entries */ if (acl_get_tag_type(entry, &tag) == -1) err(1, "%s: acl_get_tag_type() failed - " "invalid ACL entry", filename); if (tag == ACL_MASK) have_mask = 1; /* check against the existing ACL entries */ entry_id_new = ACL_FIRST_ENTRY; while (acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) { entry_id_new = ACL_NEXT_ENTRY; if (acl_get_tag_type(entry, &tag) == -1) err(1, "%s: acl_get_tag_type() failed", filename); if (acl_get_tag_type(entry_new, &tag_new) == -1) err(1, "%s: acl_get_tag_type() failed", filename); if (tag != tag_new) continue; /* * For NFSv4, in addition to "tag" and "id" we also * compare "entry_type". */ if (acl_brand == ACL_BRAND_NFS4) { if (acl_get_entry_type_np(entry, &entry_type)) err(1, "%s: acl_get_entry_type_np() " "failed", filename); if (acl_get_entry_type_np(entry_new, &entry_type_new)) err(1, "%s: acl_get_entry_type_np() " "failed", filename); if (entry_type != entry_type_new) continue; } switch(tag) { case ACL_USER: case ACL_GROUP: have_entry = merge_user_group(&entry, &entry_new, acl_brand); if (have_entry == 0) break; /* FALLTHROUGH */ case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_OTHER: case ACL_MASK: case ACL_EVERYONE: if (acl_get_permset(entry, &permset) == -1) err(1, "%s: acl_get_permset() failed", filename); if (acl_set_permset(entry_new, permset) == -1) err(1, "%s: acl_set_permset() failed", filename); if (acl_brand == ACL_BRAND_NFS4) { if (acl_get_entry_type_np(entry, &entry_type)) err(1, "%s: acl_get_entry_type_np() failed", filename); if (acl_set_entry_type_np(entry_new, entry_type)) err(1, "%s: acl_set_entry_type_np() failed", filename); if (acl_get_flagset_np(entry, &flagset)) err(1, "%s: acl_get_flagset_np() failed", filename); if (acl_set_flagset_np(entry_new, flagset)) err(1, "%s: acl_set_flagset_np() failed", filename); } had_entry = have_entry = 1; break; default: /* should never be here */ errx(1, "%s: invalid tag type: %i", filename, tag); break; } } /* if this entry has not been found, it must be new */ if (had_entry == 0) { /* * NFSv4 ACL entries must be prepended to the ACL. * Appending them at the end makes no sense, since * in most cases they wouldn't even get evaluated. */ if (acl_brand == ACL_BRAND_NFS4) { if (acl_create_entry_np(&acl_new, &entry_new, entry_number) == -1) { warn("%s: acl_create_entry_np() failed", filename); acl_free(acl_new); return (-1); } /* * Without this increment, adding several * entries at once, for example * "setfacl -m user:1:r:allow,user:2:r:allow", * would make them appear in reverse order. */ entry_number++; } else { if (acl_create_entry(&acl_new, &entry_new) == -1) { warn("%s: acl_create_entry() failed", filename); acl_free(acl_new); return (-1); } } if (acl_copy_entry(entry_new, entry) == -1) err(1, "%s: acl_copy_entry() failed", filename); } } acl_free(*prev_acl); *prev_acl = acl_new; return (0); }
/* * remove extended entries */ void remove_ext(acl_t *prev_acl) { acl_t acl_new, acl_old; acl_entry_t entry, entry_new; acl_permset_t perm; acl_tag_t tag; int entry_id, have_mask_entry; if (acl_type == ACL_TYPE_ACCESS) acl_old = acl_dup(prev_acl[ACCESS_ACL]); else acl_old = acl_dup(prev_acl[DEFAULT_ACL]); if (acl_old == NULL) err(1, "acl_dup() failed"); have_mask_entry = 0; acl_new = acl_init(ACL_MAX_ENTRIES); if (acl_new == NULL) err(1, "acl_init() failed"); tag = ACL_UNDEFINED_TAG; /* only save the default user/group/other entries */ entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(acl_old, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; if (acl_get_tag_type(entry, &tag) == -1) err(1, "acl_get_tag_type() failed"); switch(tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_OTHER: if (acl_get_tag_type(entry, &tag) == -1) err(1, "acl_get_tag_type() failed"); if (acl_get_permset(entry, &perm) == -1) err(1, "acl_get_permset() failed"); if (acl_create_entry(&acl_new, &entry_new) == -1) err(1, "acl_create_entry() failed"); if (acl_set_tag_type(entry_new, tag) == -1) err(1, "acl_set_tag_type() failed"); if (acl_set_permset(entry_new, perm) == -1) err(1, "acl_get_permset() failed"); if (acl_copy_entry(entry_new, entry) == -1) err(1, "acl_copy_entry() failed"); break; case ACL_MASK: have_mask_entry = 1; break; default: break; } } if (have_mask_entry && n_flag == 0) { if (acl_calc_mask(&acl_new) == -1) err(1, "acl_calc_mask() failed"); } else { have_mask = 1; } if (acl_type == ACL_TYPE_ACCESS) { acl_free(prev_acl[ACCESS_ACL]); prev_acl[ACCESS_ACL] = acl_new; } else { acl_free(prev_acl[DEFAULT_ACL]); prev_acl[DEFAULT_ACL] = acl_new; } }
static int acl_from_text_callback(acl_tag_t tag, int perms, const char *name, size_t name_len, void *params_casted) { DEBUG("acl_from_text: tag: %d, name: %s, name_len: %lu\n", tag, name, (long unsigned)name_len); struct acl_from_text_params *params = (struct acl_from_text_params *)(params_casted); if (params->acl != NULL) { resolve resolve_func = params->custom_resolve; void *resolve_data = params->custom_resolve_data; uint32_t id = ((name == NULL || name_len == 0) ? ACL_UNDEFINED_ID : resolve_func(tag, name, name_len, resolve_data)); switch (tag) { case ACL_USER: case ACL_GROUP: if (id == ACL_UNDEFINED_ID) { return -ENOENT; } break; } acl_entry_t entry = NULL; errno = 0; if (acl_create_entry(params->acl, &entry) != 0) { DEBUG("%d\n", 1); return -errno; } errno = 0; if (acl_set_tag_type(entry, tag) != 0) { DEBUG("%d\n", 2); return -errno; } acl_permset_t permset = NULL; errno = 0; if (acl_get_permset(entry, &permset) != 0) { return -errno; } if ((perms & ACL_READ) != 0) { errno = 0; if (acl_add_perm(permset, ACL_READ) != 0) { return -errno; } } if ((perms & ACL_WRITE) != 0) { errno = 0; if (acl_add_perm(permset, ACL_WRITE) != 0) { return -errno; } } if ((perms & ACL_EXECUTE) != 0) { errno = 0; if (acl_add_perm(permset, ACL_EXECUTE) != 0) { return -errno; } } errno = 0; if (acl_set_permset(entry, permset) != 0) { return -errno; } switch (tag) { case ACL_USER: { uid_t uid = (uid_t)(id); errno = 0; if (acl_set_qualifier(entry, (void *)&uid) != 0) { DEBUG("%d\n", 4); return -errno; } } case ACL_GROUP: { gid_t gid = (gid_t)(id); errno = 0; if (acl_set_qualifier(entry, (void *)&gid) != 0) { DEBUG("%d\n", 5); return -errno; } } break; } } ++params->count; return 0; }
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; }
/* * return an ACL corresponding to the permissions * contained in struct stat */ static acl_t acl_from_stat(struct stat sb) { acl_t acl; acl_entry_t entry; acl_permset_t perms; /* create the ACL */ acl = acl_init(3); if (!acl) return NULL; /* First entry: ACL_USER_OBJ */ if (acl_create_entry(&acl, &entry) == -1) return NULL; if (acl_set_tag_type(entry, ACL_USER_OBJ) == -1) return NULL; if (acl_get_permset(entry, &perms) == -1) return NULL; if (acl_clear_perms(perms) == -1) return NULL; /* calculate user mode */ if (sb.st_mode & S_IRUSR) if (acl_add_perm(perms, ACL_READ) == -1) return NULL; if (sb.st_mode & S_IWUSR) if (acl_add_perm(perms, ACL_WRITE) == -1) return NULL; if (sb.st_mode & S_IXUSR) if (acl_add_perm(perms, ACL_EXECUTE) == -1) return NULL; if (acl_set_permset(entry, perms) == -1) return NULL; /* Second entry: ACL_GROUP_OBJ */ if (acl_create_entry(&acl, &entry) == -1) return NULL; if (acl_set_tag_type(entry, ACL_GROUP_OBJ) == -1) return NULL; if (acl_get_permset(entry, &perms) == -1) return NULL; if (acl_clear_perms(perms) == -1) return NULL; /* calculate group mode */ if (sb.st_mode & S_IRGRP) if (acl_add_perm(perms, ACL_READ) == -1) return NULL; if (sb.st_mode & S_IWGRP) if (acl_add_perm(perms, ACL_WRITE) == -1) return NULL; if (sb.st_mode & S_IXGRP) if (acl_add_perm(perms, ACL_EXECUTE) == -1) return NULL; if (acl_set_permset(entry, perms) == -1) return NULL; /* Third entry: ACL_OTHER */ if (acl_create_entry(&acl, &entry) == -1) return NULL; if (acl_set_tag_type(entry, ACL_OTHER) == -1) return NULL; if (acl_get_permset(entry, &perms) == -1) return NULL; if (acl_clear_perms(perms) == -1) return NULL; /* calculate other mode */ if (sb.st_mode & S_IROTH) if (acl_add_perm(perms, ACL_READ) == -1) return NULL; if (sb.st_mode & S_IWOTH) if (acl_add_perm(perms, ACL_WRITE) == -1) return NULL; if (sb.st_mode & S_IXOTH) if (acl_add_perm(perms, ACL_EXECUTE) == -1) return NULL; if (acl_set_permset(entry, perms) == -1) return NULL; return(acl); }
int acl_readonly_example(uuid_t *uuid) { int fd; acl_t acl; acl_entry_t ace; acl_permset_t perms; filesec_t fsec; /* initialize our ACL */ if (NULL == (acl = acl_init(32))) err(1, "acl_init()"); /* * create an ACE * * acl_create_entry_np() has a position capability via the * 'entry_index' argument (ACL_FIRST_ENTRY or ACL_LAST_ENTRY) */ if (0 != acl_create_entry(&acl, &ace)) err(1, "acl_create_entry()"); /* allow or deny */ if (0 != acl_set_tag_type(ace, ACL_EXTENDED_ALLOW)) err(1, "acl_set_tag_type()"); /* associate this with our uuid */ if (0 != acl_set_qualifier(ace, uuid)) err(1, "acl_set_qualifier()"); /* grant "read only" permissions */ if (0 != acl_get_permset(ace, &perms)) err(1, "acl_get_permset()"); if (0 != acl_clear_perms(perms)) err(1, "acl_clear_perms()"); if (0 != acl_add_perm(perms, ROPERMS)) err(1, "acl_add_perm()"); if (0 != acl_set_permset(ace, perms)) err(1, "acl_set_permset()"); /* create a file security object */ fsec = filesec_init(); /* add the ACL to the security descriptor */ filesec_set_property(fsec, FILESEC_ACL, &acl); acl_free(acl); /* turn off all other permissions on the file */ filesec_set_property(fsec, FILESEC_MODE, 0); /* create a file using our ACL */ fd = openx_np("foo", O_CREAT|O_EXCL|O_RDWR, fsec); /* clean up */ filesec_free(fsec); if (-1 != fd ) close(fd); return(fd); }
/* Convert an acl entry in string form to an acl_entry_t */ int parse_entry(char *entrybuf, acl_entry_t newent) { char *tok; char *pebuf; uuid_t *entryg; acl_tag_t tag; acl_permset_t perms; acl_flagset_t flags; unsigned permcount = 0; unsigned pindex = 0; char *delimiter = " "; int nametype = NAME_EITHER; acl_get_permset(newent, &perms); acl_get_flagset_np(newent, &flags); pebuf = entrybuf; if (0 == strncmp(entrybuf, "user:"******"group:", 6)) { nametype = NAME_GROUP; pebuf += 6; } if (strchr(pebuf, ':')) /* User/Group names can have spaces */ delimiter = ":"; tok = strsep(&pebuf, delimiter); if ((tok == NULL) || *tok == '\0') { // errx(1, "Invalid entry format -- expected user or group name"); fprintf(stderr, "chmod: Invalid entry format -- expected user or group name\n"); pthread_exit(NULL); } /* parse the name into a qualifier */ entryg = name_to_uuid(tok, nametype); tok = strsep(&pebuf, ": "); /* Stick with delimiter? */ if ((tok == NULL) || *tok == '\0') { // errx(1, "Invalid entry format -- expected allow or deny"); fprintf(stderr, "chmod: Invalid entry format -- expected allow or deny\n"); pthread_exit(NULL); } /* is the verb 'allow' or 'deny'? */ if (!strcmp(tok, "allow")) { tag = ACL_EXTENDED_ALLOW; } else if (!strcmp(tok, "deny")) { tag = ACL_EXTENDED_DENY; } else { // errx(1, "Unknown tag type '%s'", tok); fprintf(stderr, "chmod: Unknown tag type '%s'\n", tok); pthread_exit(NULL); } /* parse permissions */ for (; (tok = strsep(&pebuf, ",")) != NULL;) { if (*tok != '\0') { /* is it a permission? */ for (pindex = 0; acl_perms[pindex].name != NULL; pindex++) { if (!strcmp(acl_perms[pindex].name, tok)) { /* got one */ acl_add_perm(perms, acl_perms[pindex].perm); permcount++; goto found; } } /* is it a flag? */ for (pindex = 0; acl_flags[pindex].name != NULL; pindex++) { if (!strcmp(acl_flags[pindex].name, tok)) { /* got one */ acl_add_flag_np(flags, acl_flags[pindex].flag); permcount++; goto found; } } // errx(1,"Invalid permission type '%s'", tok); fprintf(stderr,"chmod: Invalid permission type '%s'\n", tok); pthread_exit(NULL); found: continue; } } if (0 == permcount) { // errx(1, "No permissions specified"); fprintf(stderr, "chmod: No permissions specified\n"); pthread_exit(NULL); } acl_set_tag_type(newent, tag); acl_set_qualifier(newent, entryg); acl_set_permset(newent, perms); acl_set_flagset_np(newent, flags); free(entryg); entryg = NULL; return(0); }