int calc_acl_mask_if_needed(acl_t *acl_p) { acl_entry_t i; int r; assert(acl_p); for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i); r > 0; r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) { acl_tag_t tag; if (acl_get_tag_type(i, &tag) < 0) return -errno; if (tag == ACL_MASK) return 0; if (IN_SET(tag, ACL_USER, ACL_GROUP)) goto calc; } if (r < 0) return -errno; return 0; calc: if (acl_calc_mask(acl_p) < 0) return -errno; return 1; }
/* Iterate through an ACL, and find the canonical position for the * specified entry */ unsigned int find_canonical_position(acl_t acl, acl_entry_t modifier) { acl_entry_t entry; int mscore = 0; unsigned mpos = 0; /* Check if there's an entry with the same qualifier * and tag type; if not, find the appropriate slot * for the score. */ if (0 != acl_get_entry(acl, ACL_FIRST_ENTRY, &entry)) return 0; mscore = score_acl_entry(modifier); while (mscore < score_acl_entry(entry)) { mpos++; if (0 != acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) break; } return mpos; }
/* * deletes an access acl or directory default acl if one exists */ static int acl_delete_file(const char *path, acl_type_t type) { int error = 0; /* converts access ACL to a minimal ACL */ if (type == ACL_TYPE_ACCESS) { acl_t acl; acl_entry_t entry; acl_tag_t tag; acl = acl_get_file(path, ACL_TYPE_ACCESS); if (!acl) return -1; error = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); while (error == 1) { acl_get_tag_type(entry, &tag); switch(tag) { case ACL_USER: case ACL_GROUP: case ACL_MASK: acl_delete_entry(acl, entry); break; } error = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); } if (!error) error = acl_set_file(path, ACL_TYPE_ACCESS, acl); } else error = acl_delete_def_file(path); return(error); }
static int flush_acl(acl_t acl) { acl_entry_t i; int found; bool changed = false; assert(acl); for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); found > 0; found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { acl_tag_t tag; if (acl_get_tag_type(i, &tag) < 0) return -errno; if (tag != ACL_USER) continue; if (acl_delete_entry(acl, i) < 0) return -errno; changed = true; } if (found < 0) return -errno; return changed; }
struct name_list *get_list(const struct stat *st, acl_t acl) { struct name_list *first = NULL, *last = NULL; acl_entry_t ent; int ret = 0; if (acl != NULL) ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent); if (ret != 1) return NULL; while (ret > 0) { acl_tag_t e_type; const id_t *id_p; const char *name = ""; int len; acl_get_tag_type(ent, &e_type); switch(e_type) { case ACL_USER_OBJ: name = user_name(st->st_uid, opt_numeric); break; case ACL_USER: id_p = acl_get_qualifier(ent); if (id_p != NULL) name = user_name(*id_p, opt_numeric); break; case ACL_GROUP_OBJ: name = group_name(st->st_gid, opt_numeric); break; case ACL_GROUP: id_p = acl_get_qualifier(ent); if (id_p != NULL) name = group_name(*id_p, opt_numeric); break; } name = xquote(name, "\t\n\r"); len = strlen(name); if (last == NULL) { first = last = (struct name_list *) malloc(sizeof(struct name_list) + len + 1); } else { last->next = (struct name_list *) malloc(sizeof(struct name_list) + len + 1); last = last->next; } if (last == NULL) { free_list(first); return NULL; } last->next = NULL; strcpy(last->name, name); ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent); } return first; }
/* * Translate POSIX.1e ACL into libarchive internal structure. */ static void setup_acl_posix1e(struct archive_read_disk *a, struct archive_entry *entry, acl_t acl, int archive_entry_acl_type) { acl_tag_t acl_tag; acl_entry_t acl_entry; acl_permset_t acl_permset; int s, ae_id, ae_tag, ae_perm; const char *ae_name; s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); while (s == 1) { ae_id = -1; ae_name = NULL; acl_get_tag_type(acl_entry, &acl_tag); if (acl_tag == ACL_USER) { ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry); ae_name = archive_read_disk_uname(&a->archive, ae_id); ae_tag = ARCHIVE_ENTRY_ACL_USER; } else if (acl_tag == ACL_GROUP) { ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry); ae_name = archive_read_disk_gname(&a->archive, ae_id); ae_tag = ARCHIVE_ENTRY_ACL_GROUP; } else if (acl_tag == ACL_MASK) { ae_tag = ARCHIVE_ENTRY_ACL_MASK; } else if (acl_tag == ACL_USER_OBJ) { ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; } else if (acl_tag == ACL_GROUP_OBJ) { ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; } else if (acl_tag == ACL_OTHER) { ae_tag = ARCHIVE_ENTRY_ACL_OTHER; } else { /* Skip types that libarchive can't support. */ continue; } acl_get_permset(acl_entry, &acl_permset); ae_perm = 0; /* * acl_get_perm() is spelled differently on different * platforms; see above. */ if (ACL_GET_PERM(acl_permset, ACL_EXECUTE)) ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE; if (ACL_GET_PERM(acl_permset, ACL_READ)) ae_perm |= ARCHIVE_ENTRY_ACL_READ; if (ACL_GET_PERM(acl_permset, ACL_WRITE)) ae_perm |= ARCHIVE_ENTRY_ACL_WRITE; archive_entry_acl_add_entry(entry, archive_entry_acl_type, ae_perm, ae_tag, ae_id, ae_name); s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); } }
int search_acl_groups(char*** dst, const char* path, bool* belong) { acl_t acl; assert(path); assert(belong); acl = acl_get_file(path, ACL_TYPE_DEFAULT); if (acl) { acl_entry_t entry; int r; r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); while (r > 0) { acl_tag_t tag; gid_t *gid; char *name; r = acl_get_tag_type(entry, &tag); if (r < 0) break; if (tag != ACL_GROUP) goto next; gid = acl_get_qualifier(entry); if (!gid) break; if (in_gid(*gid) > 0) { *belong = true; break; } name = gid_to_name(*gid); if (!name) { acl_free(acl); return log_oom(); } r = strv_consume(dst, name); if (r < 0) { acl_free(acl); return log_oom(); } next: r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); } acl_free(acl); } return 0; }
static int remove_extended_entries( acl_t acl) { acl_entry_t ent, group_obj; acl_permset_t mask_permset, group_obj_permset; acl_tag_t tag; int error; /* * Removing the ACL_MASK entry from the ACL results in * increased permissions for the owning group if the * ACL_GROUP_OBJ entry contains permissions not contained * in the ACL_MASK entry. We remove these permissions from * the ACL_GROUP_OBJ entry to avoid that. * * After removing the ACL, the file owner and the owning group * therefore have the same permissions as before. */ ent = find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID); group_obj = find_entry(acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID); if (ent && group_obj) { if (!acl_get_permset(ent, &mask_permset) && !acl_get_permset(group_obj, &group_obj_permset)) { if (!acl_get_perm(mask_permset, ACL_READ)) acl_delete_perm(group_obj_permset, ACL_READ); if (!acl_get_perm(mask_permset, ACL_WRITE)) acl_delete_perm(group_obj_permset, ACL_WRITE); if (!acl_get_perm(mask_permset, ACL_EXECUTE)) acl_delete_perm(group_obj_permset, ACL_EXECUTE); } } error = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent); while (error == 1) { acl_get_tag_type(ent, &tag); switch(tag) { case ACL_USER: case ACL_GROUP: case ACL_MASK: acl_delete_entry(acl, ent); break; default: break; } error = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent); } if (error < 0) return -1; return 0; }
/* only directories can have inherit flags set */ static int remove_inherit_flags(acl_t *acl) { int entry_id; acl_entry_t acl_entry; acl_flagset_t acl_flags; entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(*acl, entry_id, &acl_entry) > 0) { entry_id = ACL_NEXT_ENTRY; if (acl_get_flagset_np(acl_entry, &acl_flags) < 0) err(EX_OSERR, "acl_get_flagset_np() failed"); acl_delete_flag_np(acl_flags, ACL_ENTRY_FILE_INHERIT); acl_delete_flag_np(acl_flags, ACL_ENTRY_DIRECTORY_INHERIT); acl_delete_flag_np(acl_flags, ACL_ENTRY_NO_PROPAGATE_INHERIT); acl_delete_flag_np(acl_flags, ACL_ENTRY_INHERIT_ONLY); if (acl_set_flagset_np(acl_entry, acl_flags) < 0) err(EX_OSERR, "acl_set_flagset_np() failed"); } return (0); }
static struct smb_acl_t *smb_acl_to_internal(acl_t acl) { struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t); int entry_id = ACL_FIRST_ENTRY; acl_entry_t e; if (result == NULL) { return NULL; } ZERO_STRUCTP(result); while (acl_get_entry(acl, entry_id, &e) == 1) { entry_id = ACL_NEXT_ENTRY; result = (struct smb_acl_t *)SMB_REALLOC( result, sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * (result->count+1))); if (result == NULL) { DEBUG(0, ("SMB_REALLOC failed\n")); errno = ENOMEM; return NULL; } if (!smb_ace_to_internal(e, &result->acl[result->count])) { SAFE_FREE(result); return NULL; } result->count += 1; } return result; }
char get_acl(char *filename) { acl_t acl; acl_entry_t dummy; ssize_t xattr; char str[10]; xattr = 0; acl = NULL; acl = acl_get_link_np(filename, ACL_TYPE_EXTENDED); if (acl && acl_get_entry(acl, ACL_FIRST_ENTRY, &dummy) == -1) { acl_free(acl); acl = NULL; } xattr = listxattr(filename, NULL, 0, XATTR_NOFOLLOW); if (xattr < 0) xattr = 0; str[1] = '\0'; if (xattr > 0) str[0] = '@'; else if (acl) str[0] = '+'; else str[0] = ' '; return (str[0]); }
static struct smb_acl_t *smb_acl_to_internal(acl_t acl, TALLOC_CTX *mem_ctx) { struct smb_acl_t *result = sys_acl_init(mem_ctx); int entry_id = ACL_FIRST_ENTRY; acl_entry_t e; if (result == NULL) { return NULL; } while (acl_get_entry(acl, entry_id, &e) == 1) { entry_id = ACL_NEXT_ENTRY; result->acl = talloc_realloc(result, result->acl, struct smb_acl_entry, result->count+1); if (result->acl == NULL) { TALLOC_FREE(result); DEBUG(0, ("talloc_realloc failed\n")); errno = ENOMEM; return NULL; } if (!smb_ace_to_internal(e, &result->acl[result->count])) { TALLOC_FREE(result); return NULL; } result->count += 1; } return result; }
QString KrVfsHandler::getACL(const QString & path, int type) { Q_UNUSED(path); Q_UNUSED(type); #ifdef HAVE_POSIX_ACL acl_t acl = 0; // do we have an acl for the file, and/or a default acl for the dir, if it is one? if ((acl = acl_get_file(path.toLocal8Bit(), type)) != 0) { bool aclExtended = false; #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS aclExtended = acl_equiv_mode(acl, 0); #else acl_entry_t entry; int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); while (ret == 1) { acl_tag_t currentTag; acl_get_tag_type(entry, ¤tTag); if (currentTag != ACL_USER_OBJ && currentTag != ACL_GROUP_OBJ && currentTag != ACL_OTHER) { aclExtended = true; break; } ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); } #endif if (!aclExtended) { acl_free(acl); acl = 0; } } if (acl == 0) return QString(); char *aclString = acl_to_text(acl, 0); QString ret = QString::fromLatin1(aclString); acl_free((void*)aclString); acl_free(acl); return ret; #else return QString(); #endif }
int acl_entries (acl_t acl) { int count = 0; if (acl != NULL) { #if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Mac OS X */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ /* acl_get_entry returns 0 when it successfully fetches an entry, and -1/EINVAL at the end. */ acl_entry_t ace; int got_one; for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace); got_one >= 0; got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) count++; # else /* Linux, FreeBSD */ /* acl_get_entry returns 1 when it successfully fetches an entry, and 0 at the end. */ acl_entry_t ace; int got_one; for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace); got_one > 0; got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) count++; if (got_one < 0) return -1; # endif #else /* IRIX, Tru64 */ # if HAVE_ACL_TO_SHORT_TEXT /* IRIX */ /* Don't use acl_get_entry: it is undocumented. */ count = acl->acl_cnt; # endif # if HAVE_ACL_FREE_TEXT /* Tru64 */ /* Don't use acl_get_entry: it takes only one argument and does not work. */ count = acl->acl_num; # endif #endif } return count; }
int getacl(const char *pathp, aclent_t *aclpbuf) { acl_t acl = NULL, default_acl = NULL; struct stat st; if (stat(pathp, &st) != 0) { return -1; } acl = acl_get_file(pathp, ACL_TYPE_ACCESS); if(acl == NULL && (errno == ENOSYS || errno == ENOTSUP)) { acl = acl_from_mode(st.st_mode); if (acl == NULL) { return -1; } } if (S_ISDIR(st.st_mode)) { default_acl = acl_get_file(pathp, ACL_TYPE_DEFAULT); if ((default_acl != NULL) && (acl_entries(default_acl) == 0)) { acl_free(default_acl); default_acl = NULL; } } acl_entry_t acl_entry; int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); int i = 0; while(ret > 0) { aclpbuf[i++] = getentry(acl_entry, st, 0); ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); } acl_free(acl); if((default_acl != NULL) && (ret != -1)) { ret = acl_get_entry(default_acl, ACL_FIRST_ENTRY, &acl_entry); while(ret > 0) { aclpbuf[i++] = getentry(acl_entry, st, ACL_DEFAULT); ret = acl_get_entry(default_acl, ACL_NEXT_ENTRY, &acl_entry); } acl_free(default_acl); } return i; }
static int acl_entries(acl_t acl) { # if defined(HAVE_ACL_GET_ENTRY) /* POSIX 1003.1e draft 17 (abandoned) compatible version. */ acl_entry_t entry; int entries = 0; int entries = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); if (entries > 0) { while (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) > 0) entries++; } return entries; # else return -1; # endif }
void acl_mask_perm_str(acl_t acl, char *str) { acl_entry_t entry; str[0] = '\0'; if (acl_get_entry(acl, ACL_FIRST_ENTRY, &entry) != 1) return; for(;;) { acl_tag_t tag; acl_get_tag_type(entry, &tag); if (tag == ACL_MASK) { acl_perm_str(entry, str); return; } if (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) != 1) return; } }
int add_acl(acl_t acl, uint entry_number, acl_t *prev_acl, const char *filename) { acl_entry_t entry, entry_new; acl_t acl_new; int entry_id, acl_brand, prev_acl_brand; acl_get_brand_np(acl, &acl_brand); acl_get_brand_np(*prev_acl, &prev_acl_brand); if (prev_acl_brand != ACL_BRAND_NFS4) { warnx("%s: the '-a' option is only applicable to NFSv4 ACLs", filename); return (-1); } if (branding_mismatch(acl_brand, ACL_BRAND_NFS4)) { warnx("%s: branding mismatch; existing ACL is NFSv4, " "entry to be added is %s", filename, 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; 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++; 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); }
static acl_entry_t findEntry(acl_t acl, acl_tag_t tag, id_t qaul) { acl_entry_t entry; acl_tag_t entryTag; uid_t *uidp; gid_t *gidp; int ent, s; for (ent = ACL_FIRST_ENTRY; ; ent = ACL_NEXT_ENTRY) { s = acl_get_entry(acl, ent, &entry); if (s == -1) errExit("acl_get_entry"); if (s == 0) return NULL; if (acl_get_tag_type(entry, &entryTag) == -1) errExit("acl_get_tag_type"); if (tag == entryTag) { if (tag == ACL_USER) { uidp = acl_get_qualifier(entry); if (uidp == NULL) errExit("acl_get_qualifier"); if (qaul == *uidp) { if (acl_free(uidp) == -1) errExit("acl_free"); return entry; } else { if (acl_free(uidp) == -1) errExit("acl_free"); } } else if (tag == ACL_GROUP) { gidp = acl_get_qualifier(entry); if (gidp == NULL) errExit("acl_get_qualifier"); if (qaul == *gidp) { if (acl_free(gidp) == -1) errExit("acl_free"); return entry; } else { if (acl_free(gidp) == -1) errExit("acl_free"); } } else { return entry; } } } }
static void compare_acls(acl_t acl, struct myacl_t *myacls) { int *marker; int entry_id = ACL_FIRST_ENTRY; int matched; int i, n; acl_entry_t acl_entry; /* Count ACL entries in myacls array and allocate an indirect array. */ for (n = 0; myacls[n].name != NULL; ++n) continue; if (n) { marker = malloc(sizeof(marker[0]) * n); if (marker == NULL) return; for (i = 0; i < n; i++) marker[i] = i; } else marker = NULL; /* * Iterate over acls in system acl object, try to match each * one with an item in the myacls array. */ while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { /* After the first time... */ entry_id = ACL_NEXT_ENTRY; /* Search for a matching entry (tag and qualifier) */ for (i = 0, matched = 0; i < n && !matched; i++) { if (acl_match(acl_entry, &myacls[marker[i]])) { /* We found a match; remove it. */ marker[i] = marker[n - 1]; n--; matched = 1; } } /* TODO: Print out more details in this case. */ failure("ACL entry on file that shouldn't be there"); assert(matched == 1); } /* Dump entries in the myacls array that weren't in the system acl. */ for (i = 0; i < n; ++i) { failure(" ACL entry missing from file: " "type=%d,permset=%d,tag=%d,qual=%d,name=``%s''\n", myacls[marker[i]].type, myacls[marker[i]].permset, myacls[marker[i]].tag, myacls[marker[i]].qual, myacls[marker[i]].name); assert(0); /* Record this as a failure. */ } free(marker); }
int has_execute_perms( acl_t acl) { acl_entry_t ent; if (acl_get_entry(acl, ACL_FIRST_ENTRY, &ent) != 1) return 0; for(;;) { acl_permset_t permset; acl_get_permset(ent, &permset); if (acl_get_perm(permset, ACL_EXECUTE) != 0) return 1; if (acl_get_entry(acl, ACL_NEXT_ENTRY, &ent) != 1) return 0; } }
/* Verify that an ACL is in canonical order. Currently, the canonical * form is: * local deny * local allow * inherited deny (parent) * inherited allow (parent) * inherited deny (grandparent) * inherited allow (grandparent) * ... */ unsigned int is_canonical(acl_t acl) { unsigned aindex; acl_entry_t entry; int score = 0, next_score = 0; /* XXX - is a zero entry ACL in canonical form? */ if (0 != acl_get_entry(acl, ACL_FIRST_ENTRY, &entry)) return 1; score = score_acl_entry(entry); for (aindex = 0; acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) == 0; aindex++) { if (score < (next_score = score_acl_entry(entry))) return 0; score = next_score; } return 1; }
static void compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end) { int *marker; int entry_id = ACL_FIRST_ENTRY; int matched; int i, n; acl_entry_t acl_entry; n = end - start; marker = malloc(sizeof(marker[0]) * (n + 1)); for (i = 0; i < n; i++) marker[i] = i + start; /* Always include the first ACE. */ if (start > 0) { marker[n] = 0; ++n; } /* * Iterate over acls in system acl object, try to match each * one with an item in the myacls array. */ while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { /* After the first time... */ entry_id = ACL_NEXT_ENTRY; /* Search for a matching entry (tag and qualifier) */ for (i = 0, matched = 0; i < n && !matched; i++) { if (acl_match(acl_entry, &myacls[marker[i]])) { /* We found a match; remove it. */ marker[i] = marker[n - 1]; n--; matched = 1; } } failure("ACL entry on file %s that shouldn't be there", filename); assert(matched == 1); } /* Dump entries in the myacls array that weren't in the system acl. */ for (i = 0; i < n; ++i) { failure(" ACL entry %d missing from %s: " "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", marker[i], filename, myacls[marker[i]].type, myacls[marker[i]].permset, myacls[marker[i]].tag, myacls[marker[i]].qual, myacls[marker[i]].name); assert(0); /* Record this as a failure. */ } free(marker); }
/* * return true if file has ACLs beyond the traditional Unix owner/group/other ACLs */ bool hasacls(File *file) { acl_type_t acl_types[] = { ACL_TYPE_ACCESS, ACL_TYPE_DEFAULT }; for (int i = 0; i < sizeof(acl_types)/sizeof(acl_types[0]); i++) { if (!isdir(file) && acl_types[i] == ACL_TYPE_DEFAULT) continue; errno = 0; acl_t acl = acl_get_file(file->path, acl_types[i]); // XXX is this valid? if (!acl) { if (errno == EOPNOTSUPP) { /* file system does not support ACLs */ return false; } errorf("Error getting ACLs for %s: %s\n", file->name, strerror(errno)); // error = 1; break; } bool extended_found = 0; //bool error = 0; for (int entry_id = ACL_FIRST_ENTRY; ; entry_id = ACL_NEXT_ENTRY) { acl_entry_t entry; errno = 0; int status = acl_get_entry(acl, entry_id, &entry); if (status == -1) { errorf("Error getting ACLs for %s: %s\n", file->name, strerror(errno)); // XXX return -1 or '?' or something //error = 1; break; } else if (status == 0) { /* no more ACL entries */ break; } acl_tag_t tag_type; status = acl_get_tag_type(entry, &tag_type); switch (tag_type) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_OTHER: break; default: extended_found = 1; break; } /* no acl_free_entry? */ if (extended_found) break; } acl_free(acl); if (extended_found) return 1; } return 0; }
/* * remove ACL entries from an ACL */ int remove_acl(acl_t acl, acl_t *prev_acl, const char *filename) { acl_entry_t entry; acl_t acl_new; acl_tag_t tag; int carried_error, entry_id, acl_brand, prev_acl_brand; carried_error = 0; 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 removed is %s", filename, brand_name(prev_acl_brand), brand_name(acl_brand)); return (-1); } carried_error = 0; acl_new = acl_dup(*prev_acl); if (acl_new == NULL) err(1, "%s: acl_dup() failed", filename); tag = ACL_UNDEFINED_TAG; /* find and delete the entry */ entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(acl, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; if (acl_get_tag_type(entry, &tag) == -1) err(1, "%s: acl_get_tag_type() failed", filename); if (tag == ACL_MASK) have_mask++; if (acl_delete_entry(acl_new, entry) == -1) { carried_error++; warnx("%s: cannot remove non-existent ACL entry", filename); } } acl_free(*prev_acl); *prev_acl = acl_new; if (carried_error) return (-1); return (0); }
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { acl_entry_t i; int r; assert(acl); assert(entry); for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); r > 0; r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { acl_tag_t tag; uid_t *u; bool b; if (acl_get_tag_type(i, &tag) < 0) return -errno; if (tag != ACL_USER) continue; u = acl_get_qualifier(i); if (!u) return -errno; b = *u == uid; acl_free(u); if (b) { *entry = i; return 1; } } if (r < 0) return -errno; return 0; }
// section of acl_is_trivial copied from bacula static int acl_is_trivial(acl_t acl) { #if defined(HAVE_LINUX_OS) \ || defined(HAVE_FREEBSD_OS) \ || defined(HAVE_OPENBSD_OS) \ || defined(HAVE_NETBSD_OS) /* * acl is trivial if it has only the following entries: * "user::", * "group::", * "other::" */ acl_entry_t ace; acl_tag_t tag; int entry_available; entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace); while(entry_available==1) { /* * Get the tag type of this acl entry. * If we fail to get the tagtype we call the acl non-trivial. */ if (acl_get_tag_type(ace, &tag) < 0) return true; /* * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ * or ACL_OTHER breaks the spell. */ if(tag!=ACL_USER_OBJ && tag!=ACL_GROUP_OBJ && tag!=ACL_OTHER) return 0; entry_available=acl_get_entry(acl, ACL_NEXT_ENTRY, &ace); } #endif return 1; }
static int ACECount(acl_t acl) { int more_aces; int count; acl_entry_t ace; count = 0; more_aces = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace); if (more_aces <= 0) { return more_aces; } while (more_aces) { more_aces = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace); count++; } return count; }
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 remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename) { acl_entry_t entry; acl_t acl_new; acl_tag_t tag; int carried_error, entry_id; uint i; carried_error = 0; acl_new = acl_dup(*prev_acl); if (acl_new == NULL) err(1, "%s: acl_dup() failed", filename); tag = ACL_UNDEFINED_TAG; /* * Find out whether we're removing the mask entry, * to behave the same as the routine above. * * XXX: Is this loop actually needed? */ entry_id = ACL_FIRST_ENTRY; i = 0; while (acl_get_entry(acl_new, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; if (i != entry_number) continue; if (acl_get_tag_type(entry, &tag) == -1) err(1, "%s: acl_get_tag_type() failed", filename); if (tag == ACL_MASK) have_mask++; } if (acl_delete_entry_np(acl_new, entry_number) == -1) { carried_error++; warn("%s: acl_delete_entry_np() failed", filename); } acl_free(*prev_acl); *prev_acl = acl_new; if (carried_error) return (-1); return (0); }