CHIRP_FILE *chirp_acl_open(const char *dirname) { char aclname[CHIRP_PATH_MAX]; CHIRP_FILE *file; make_acl_name(dirname, 0, aclname); file = cfs_fopen(aclname, "r"); if(!file && default_acl) file = cfs_fopen(default_acl, "r"); return file; }
int chirp_acl_init_copy(const char *path) { char oldpath[CHIRP_LINE_MAX]; char newpath[CHIRP_LINE_MAX]; char subject[CHIRP_LINE_MAX]; CHIRP_FILE *oldfile; CHIRP_FILE *newfile; int result = 0; int flags; if(!cfs->do_acl_check()) return 1; sprintf(oldpath, "%s/..", path); sprintf(newpath, "%s/%s", path, CHIRP_ACL_BASE_NAME); oldfile = chirp_acl_open(oldpath); if(oldfile) { newfile = cfs_fopen(newpath, "w"); if(newfile) { while(chirp_acl_read(oldfile, subject, &flags)) { cfs_fprintf(newfile, "%s %s\n", subject, chirp_acl_flags_to_text(flags)); } cfs_fclose(newfile); result = 1; } chirp_acl_close(oldfile); } return result; }
int chirp_acl_init_root(const char *path) { char aclpath[CHIRP_PATH_MAX]; char username[USERNAME_MAX]; CHIRP_FILE *file; if(!cfs->do_acl_check()) return 1; file = chirp_acl_open(path); if(file) { chirp_acl_close(file); return 1; } username_get(username); sprintf(aclpath, "%s/%s", path, CHIRP_ACL_BASE_NAME); file = cfs_fopen(aclpath, "w"); if(file) { cfs_fprintf(file, "unix:%s %s\n", username, chirp_acl_flags_to_text(CHIRP_ACL_READ | CHIRP_ACL_WRITE | CHIRP_ACL_DELETE | CHIRP_ACL_LIST | CHIRP_ACL_ADMIN)); cfs_fclose(file); return 1; } else { return 0; } }
CHIRP_FILE *chirp_acl_open( const char *dirname ) { char dirpath[CHIRP_PATH_MAX]; strcpy(dirpath,dirname); while(1) { char aclpath[CHIRP_PATH_MAX]; CHIRP_FILE *file; // Open the file and return if found snprintf(aclpath,sizeof(aclpath),"%s/%s",dirpath,CHIRP_ACL_BASE_NAME); file = cfs_fopen(aclpath, "r"); if(file) return file; // Stop if acl inheriting not turned on if(!acl_inherit_default_mode) break; // Stop if already at the root. if(!strcmp(dirpath,"/")) break; // Look for the previous directory element. char *slash = strrchr(dirpath,'/'); // If not found, replace with the root. if(slash==dirpath || slash==0) { strcpy(dirpath,"/"); } else { *slash = 0; } } return strlen(default_acl) ? cfs_fopen_local(default_acl, "r") : NULL; }
static int get_directory_owner(const char *path, char *owner) { char aclpath[CHIRP_PATH_MAX]; char tmp[CHIRP_LINE_MAX]; char *r; CHIRP_FILE *file; int result; sprintf(aclpath, "%s/.__acl", path); file = cfs_fopen(aclpath, "r"); if(!file) return -1; r = cfs_fgets(tmp, sizeof(tmp), file); if(!r) return -1; result = sscanf(tmp, "%[^ \t\n]", owner); cfs_fclose(file); if(result == 1) { return 0; } else { return -1; } }
int chirp_acl_ticket_create(const char *subject, const char *newsubject, const char *ticket, const char *duration) { time_t now; /*, delta; */ time_t offset = (time_t) strtoul(duration, NULL, 10); const char *digest; char ticket_subject[CHIRP_PATH_MAX]; char ticket_filename[CHIRP_PATH_MAX]; char expiration[128]; now = time(NULL); now = mktime(gmtime(&now)); /* convert to UTC */ sprintf(expiration, "%lu", (unsigned long) (now + offset)); /* Note about tickets making tickets: * A ticket created by a ticket authenticated user has the same effective * subject (see the ticket_register RPC in chirp_server.c). Also, the * expiration time is less than or equal to the expiration time of the * ticket used to authenticate. */ if(chirp_ticket_isticketsubject(subject, &digest)) { struct chirp_ticket ct; chirp_ticket_filename(ticket_filename, subject, NULL); if(!ticket_read(ticket_filename, &ct)) return -1; if(ct.expiration < now + offset) { sprintf(expiration, "%lu", (unsigned long) ct.expiration); } chirp_ticket_free(&ct); } if(!cfs_isdir("/")) { errno = ENOTDIR; return -1; } chirp_ticket_name(ticket, ticket_subject, ticket_filename); CHIRP_FILE *f = cfs_fopen(ticket_filename, "w"); if(!f) { errno = EACCES; return -1; } cfs_fprintf(f, "subject \"%s\"\n", newsubject); cfs_fprintf(f, "expiration \"%s\"\n", expiration); cfs_fprintf(f, "ticket \"%s\"\n", ticket); cfs_fprintf(f, "rights \"/\" \"n\"\n"); cfs_fflush(f); int result = cfs_ferror(f); if(result) { errno = EACCES; return -1; } cfs_fclose(f); 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; } }
static int ticket_write(const char *ticket_filename, struct chirp_ticket *ct) { CHIRP_FILE *tf = cfs_fopen(ticket_filename, "w"); if(!tf) return 0; char *str = chirp_ticket_tostring(ct); cfs_fprintf(tf, "%s", str); free(str); int result = cfs_ferror(tf); cfs_fclose(tf); if(result) { errno = EACCES; return -1; } return 0; }
static int ticket_read(char *ticket_filename, struct chirp_ticket *ct) { CHIRP_FILE *tf = cfs_fopen(ticket_filename, "r"); if(!tf) return 0; char *b; size_t l; if(!cfs_freadall(tf, &b, &l)) { cfs_fclose(tf); return 0; } cfs_fclose(tf); int result = chirp_ticket_read(b, ct); free(b); return result; }
static int ticket_read(char *ticket_filename, struct chirp_ticket *ct) { buffer_t B; CHIRP_FILE *tf = cfs_fopen(ticket_filename, "r"); if(!tf) return 0; buffer_init(&B); buffer_abortonfailure(&B, 1); if(!cfs_freadall(tf, &B)) { cfs_fclose(tf); return 0; } cfs_fclose(tf); int result = chirp_ticket_read(buffer_tostring(&B, NULL), ct); buffer_free(&B); return result; }
int chirp_acl_set(const char *dirname, const char *subject, int flags, int reset_acl) { char aclname[CHIRP_PATH_MAX]; char newaclname[CHIRP_PATH_MAX]; char aclsubject[CHIRP_LINE_MAX]; int aclflags; CHIRP_FILE *aclfile, *newaclfile; int result; int replaced_acl_entry = 0; if(!cfs_isdir(dirname)) { errno = ENOTDIR; return -1; } sprintf(aclname, "%s/%s", dirname, CHIRP_ACL_BASE_NAME); sprintf(newaclname, "%s/%s.%d", dirname, CHIRP_ACL_BASE_NAME, (int) getpid()); if(reset_acl) { aclfile = cfs_fopen_local("/dev/null", "r"); } else { aclfile = chirp_acl_open(dirname); /* If the acl never existed, then we can simply create it. */ if(!aclfile && errno == ENOENT) { aclfile = cfs_fopen_local("/dev/null", "r"); /* use local... */ } } if(!aclfile) { errno = EACCES; return -1; } replaced_acl_entry = 0; newaclfile = cfs_fopen(newaclname, "w"); if(!newaclfile) { cfs_fclose(aclfile); errno = EACCES; return -1; } while(chirp_acl_read(aclfile, aclsubject, &aclflags)) { if(!strcmp(subject, aclsubject)) { aclflags = flags; replaced_acl_entry = 1; } if(aclflags != 0) { cfs_fprintf(newaclfile, "%s %s\n", aclsubject, chirp_acl_flags_to_text(aclflags)); } } cfs_fclose(aclfile); if(!replaced_acl_entry) { cfs_fprintf(newaclfile, "%s %s\n", subject, chirp_acl_flags_to_text(flags)); } /* Need to force a write in order to get response from ferror */ cfs_fflush(newaclfile); result = cfs_ferror(newaclfile); cfs_fclose(newaclfile); if(result) { errno = EACCES; result = -1; } else { result = cfs->rename(newaclname, aclname); if(result < 0) { cfs->unlink(newaclname); errno = EACCES; result = -1; } } return result; }