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 cfs_fclose(CHIRP_FILE * file) { if(file->type == LOCAL) return fclose(file->f.lfile); if(cfs_fflush(file) != 0) return EOF; buffer_free(&file->f.cfile.B); cfs->close(file->f.cfile.fd); free(file); return 0; }
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; }