int chirp_acl_check_dir(const char *dirname, const char *subject, int flags) { int myflags = 0; int paflags = 0; if(cfs->do_acl_check() == 0) return 1; /* If flags is CHIRP_ACL_DELETE, then check if we have delete permissions in the *containing directory*. */ if (flags & CHIRP_ACL_DELETE) { char dir[CHIRP_PATH_MAX]; path_dirname(dirname, dir); if(!do_chirp_acl_get(dir, subject, &paflags)) { /* Applications are very sensitive to this error condition. A * missing ACL file indicates permission denied, but a missing * directory entirely indicates no such entry. */ if(cfs_isdir(dirname)) { errno = EACCES; } else { errno = ENOENT; } return 0; } } /* other flags require checking the actual directory... */ if ((flags & ~CHIRP_ACL_DELETE)) { if(!do_chirp_acl_get(dirname, subject, &myflags)) { /* Applications are very sensitive to this error condition. A * missing ACL file indicates permission denied, but a missing * directory entirely indicates no such entry. */ if(cfs_isdir(dirname)) { errno = EACCES; } else { errno = ENOENT; } return 0; } } myflags |= (paflags & CHIRP_ACL_DELETE); /* The superuser can implicitly list and admin */ if(strcmp(subject, chirp_super_user) == 0) { myflags |= CHIRP_ACL_LIST | CHIRP_ACL_ADMIN; } if((flags & myflags) == flags) { return 1; } else { errno = EACCES; return 0; } }
int chirp_acl_check_dir(const char *dirname, const char *subject, int flags) { int myflags; if(cfs->do_acl_check() == 0) return 1; if(!do_chirp_acl_get(dirname, subject, &myflags)) { /* Applications are very sensitive to this error condition. A missing ACL file indicates permission denied, but a missing directory entirely indicates no such entry. */ if(cfs_isdir(dirname)) { errno = EACCES; } else { errno = ENOENT; } return 0; } /* The superuser can implicitly list and admin */ if(chirp_super_user && !strcmp(subject, chirp_super_user)) { myflags |= CHIRP_ACL_LIST | CHIRP_ACL_ADMIN; } if((flags & myflags) == flags) { return 1; } else { errno = EACCES; return 0; } }
int chirp_acl_init_reserve(const char *path, const char *subject) { char dirname[CHIRP_PATH_MAX]; char aclpath[CHIRP_PATH_MAX]; CHIRP_FILE *file; int newflags = 0; int aclflags; if(!cfs->do_acl_check()) return 1; path_dirname(path, dirname); if(!do_chirp_acl_get(dirname, subject, &aclflags)) return 0; if(aclflags & CHIRP_ACL_RESERVE_READ) newflags |= CHIRP_ACL_READ; if(aclflags & CHIRP_ACL_RESERVE_WRITE) newflags |= CHIRP_ACL_WRITE; if(aclflags & CHIRP_ACL_RESERVE_LIST) newflags |= CHIRP_ACL_LIST; if(aclflags & CHIRP_ACL_RESERVE_DELETE) newflags |= CHIRP_ACL_DELETE; if(aclflags & CHIRP_ACL_RESERVE_PUT) newflags |= CHIRP_ACL_PUT; if(aclflags & CHIRP_ACL_RESERVE_RESERVE) newflags |= CHIRP_ACL_RESERVE; if(aclflags & CHIRP_ACL_RESERVE_ADMIN) newflags |= CHIRP_ACL_ADMIN; if(aclflags & CHIRP_ACL_RESERVE_EXECUTE) newflags |= CHIRP_ACL_EXECUTE; /* compatibility note: If no sub-rights are associated with the v right, then give all of the ordinary subrights. */ if(newflags == 0) newflags = CHIRP_ACL_READ | CHIRP_ACL_WRITE | CHIRP_ACL_LIST | CHIRP_ACL_DELETE | CHIRP_ACL_ADMIN; sprintf(aclpath, "%s/%s", path, CHIRP_ACL_BASE_NAME); file = cfs_fopen(aclpath, "w"); if(file) { cfs_fprintf(file, "%s %s\n", subject, chirp_acl_flags_to_text(newflags)); cfs_fclose(file); return 1; } else { return 0; } }
int chirp_acl_check_dir(const char *dirname, const char *subject, int flags) { int myflags; if(cfs->do_acl_check()==0) return 1; if(!do_chirp_acl_get(dirname, subject, &myflags)) { errno = EACCES; return 0; } /* The superuser can implicitly list and admin */ if(chirp_super_user && !strcmp(subject, chirp_super_user)) { myflags |= CHIRP_ACL_LIST | CHIRP_ACL_ADMIN; } if((flags & myflags) == flags) { return 1; } else { errno = EACCES; return 0; } }
static int do_chirp_acl_get(const char *dirname, const char *subject, int *totalflags) { CHIRP_FILE *aclfile; char aclsubject[CHIRP_LINE_MAX]; int aclflags; errno = 0; *totalflags = 0; /* if the subject is a ticket, then we need the rights we have for the * directory along with the rights of the subject in that directory */ const char *digest; if(chirp_ticket_isticketsubject(subject, &digest)) { /* open the ticket file, read the public key */ char ticket_filename[CHIRP_PATH_MAX]; struct chirp_ticket ct; chirp_ticket_filename(ticket_filename, subject, NULL); if(!ticket_read(ticket_filename, &ct)) return 0; if(!do_chirp_acl_get(dirname, ct.subject, totalflags)) { chirp_ticket_free(&ct); return 0; } size_t i; size_t longest = 0; int mask = 0; for(i = 0; i < ct.nrights; i++) { char where[CHIRP_PATH_MAX]; path_collapse(ct.rights[i].directory, where, 1); if(strncmp(dirname, where, strlen(where)) == 0) { if(strlen(where) > longest) { longest = strlen(where); mask = chirp_acl_text_to_flags(ct.rights[i].acl); } } } *totalflags &= mask; } else { aclfile = chirp_acl_open(dirname); if(aclfile) { while(chirp_acl_read(aclfile, aclsubject, &aclflags)) { if(string_match(aclsubject, subject)) { *totalflags |= aclflags; } else if(!strncmp(aclsubject, "group:", 6)) { if(chirp_group_lookup(aclsubject, subject)) { *totalflags |= aclflags; } } } chirp_acl_close(aclfile); } else { return 0; } } if(read_only_mode) { *totalflags &= CHIRP_ACL_READ | CHIRP_ACL_LIST; } return 1; }