static int do_chirp_acl_check(const char *filename, const char *subject, int flags, int follow_links) { char linkname[CHIRP_PATH_MAX]; char temp[CHIRP_PATH_MAX]; char dirname[CHIRP_PATH_MAX]; if(cfs->do_acl_check()==0) return 1; /* Symbolic links require special handling. If requested, follow the link and look for rights in that directory. */ if(follow_links && flags != CHIRP_ACL_DELETE) { int length = cfs->readlink(filename, linkname, sizeof(linkname)); if(length > 0) { linkname[length] = 0; /* If the link is relative, construct a full path */ if(linkname[0] != '/') { sprintf(temp, "%s/../%s", filename, linkname); string_collapse_path(temp, linkname, 1); } /* Use the linkname now to look up the ACL */ debug(D_DEBUG, "symlink %s points to %s", filename, linkname); filename = linkname; } } /* If the file being checked is an ACL file, then it may be written with the admin flag, but never deleted. */ if(!strcmp(string_back(filename, CHIRP_ACL_BASE_LENGTH), CHIRP_ACL_BASE_NAME)) { if(flags & CHIRP_ACL_DELETE) { errno = EACCES; return 0; } if(flags & CHIRP_ACL_WRITE) { flags &= ~CHIRP_ACL_WRITE; flags |= CHIRP_ACL_ADMIN; } } /* Now get the name of the directory containing the file */ string_collapse_path(filename, temp, 1); if(!cfs_isdir(temp)) string_dirname(temp, dirname); else strcpy(dirname, temp); /* Perform the permissions check on that directory. */ return chirp_acl_check_dir(dirname, subject, flags); }
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; string_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; } }
static struct alloc_state *alloc_state_cache(const char *path) { char dirname[CHIRP_PATH_MAX]; string_dirname(path, dirname); return alloc_state_cache_exact(dirname); }