Exemple #1
0
int chirp_acl_ticket_delete(const char *subject, const char *ticket_subject)
{
	char ticket_filename[CHIRP_PATH_MAX];
	const char *digest;
	char *esubject;
	struct chirp_ticket ct;
	int status = 0;

	if(!chirp_ticket_isticketsubject(ticket_subject, &digest)) {
		errno = EINVAL;
		return -1;
	}
	if(!chirp_acl_whoami(subject, &esubject))
		return -1;

	chirp_ticket_filename(ticket_filename, ticket_subject, NULL);

	if(!ticket_read(ticket_filename, &ct)) {
		free(esubject);
		return -1;
	}

	if(strcmp(esubject, ct.subject) == 0 || strcmp(chirp_super_user, subject) == 0) {
		status = cfs->unlink(ticket_filename);
	} else {
		errno = EACCES;
		status = -1;
	}
	chirp_ticket_free(&ct);
	free(esubject);
	return status;
}
Exemple #2
0
static int ticket_translate(const char *name, char *ticket_subject)
{
	char command[PATH_MAX * 2 + 4096];
	const char *dummy;

	if(chirp_ticket_isticketsubject(name, &dummy)) {
		strcpy(ticket_subject, name);
		return 1;
	}

	char *pk = xxmalloc(65536); /* max size of public key */
	sprintf(command, "sed '/^\\s*#/d' < '%s' | openssl rsa -pubout 2> /dev/null", name);
	FILE *pkf = popen(command, "r");
	int length = fread(pk, sizeof(char), 65536, pkf);
	if(length <= 0) {
		pclose(pkf);
		return 0;
	}
	pk[length] = 0;
	pclose(pkf);

	/* load the digest */
	const char *digest = chirp_ticket_digest(pk);

	sprintf(ticket_subject, "ticket:%s", digest);
	return 1;
}
Exemple #3
0
void chirp_ticket_filename(const char *root, char *ticket_filename, const char *ticket_subject, const char *digest)
{
	if(digest == NULL) {
		assert(ticket_subject);
		int result = chirp_ticket_isticketsubject(ticket_subject, &digest);
		assert(result);
	}
	sprintf(ticket_filename, "%s/" TICKET_FILENAME_FORMAT, root, digest);
}
Exemple #4
0
int chirp_acl_ticket_modify(const char *subject, const char *ticket_subject, const char *path, int flags)
{
	char ticket_filename[CHIRP_PATH_MAX];
	const char *digest;
	char *esubject;
	struct chirp_ticket ct;
	int status = 0;

	if(!chirp_ticket_isticketsubject(ticket_subject, &digest)) {
		errno = EINVAL;
		return -1;
	}
	/* Note about tickets making tickets:
	 * We check whether the ticket has the rights associated with the mask in
	 * the next line. So, a ticket can only make a ticket with rights it
	 * already has.
	 */
	if(!chirp_acl_check_dir(path, subject, flags))
		return -1;	/* you don't have the rights for the mask */
	if(!chirp_acl_whoami(subject, &esubject))
		return -1;

	chirp_ticket_filename(ticket_filename, ticket_subject, NULL);

	if(!ticket_read(ticket_filename, &ct)) {
		free(esubject);
		return -1;
	}

	if(strcmp(esubject, ct.subject) == 0 || strcmp(chirp_super_user, subject) == 0) {
		size_t n;
		int replaced = 0;
		for(n = 0; n < ct.nrights; n++) {
			if(strcmp(ct.rights[n].directory, path) == 0) {
				free(ct.rights[n].acl);
				ct.rights[n].acl = xxstrdup(chirp_acl_flags_to_text(flags));	/* replace old acl mask */
				replaced = 1;
			}
		}
		if(!replaced) {
			char directory[CHIRP_PATH_MAX];
			assert(strlen(path));
			ct.rights = xxrealloc(ct.rights, sizeof(*ct.rights) * (++ct.nrights) + 1);
			path_collapse(path, directory, 1);
			ct.rights[ct.nrights - 1].directory = xxstrdup(directory);
			ct.rights[ct.nrights - 1].acl = xxstrdup(chirp_acl_flags_to_text(flags));
		}
		status = ticket_write(ticket_filename, &ct);
	} else {
		errno = EACCES;
		status = -1;
	}
	chirp_ticket_free(&ct);
	free(esubject);
	return status;
}
Exemple #5
0
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;
}
Exemple #6
0
int chirp_acl_ticket_get(const char *subject, const char *ticket_subject, char **ticket_esubject, char **ticket, time_t * ticket_expiration, char ***ticket_rights)
{
	char *esubject;
	if(!chirp_acl_whoami(subject, &esubject))
		return -1;

	const char *digest;
	if(!chirp_ticket_isticketsubject(ticket_subject, &digest)) {
		errno = EINVAL;
		return -1;
	}

	struct chirp_ticket ct;
	char ticket_filename[CHIRP_PATH_MAX];
	chirp_ticket_filename(ticket_filename, ticket_subject, NULL);
	if(!ticket_read(ticket_filename, &ct)) {
		free(esubject);
		errno = EINVAL;
		return -1;
	}
	if(strcmp(ct.subject, subject) == 0 || strcmp(subject, chirp_super_user) == 0) {
		*ticket_esubject = xxstrdup(ct.subject);
		*ticket = xxstrdup(ct.ticket);

		time_t now;
		time(&now);
		now = mktime(gmtime(&now));	/* convert to UTC */
		*ticket_expiration = ct.expiration - now;

		size_t n;
		*ticket_rights = (char **) xxmalloc(sizeof(char *) * 2 * (ct.nrights + 1));
		for(n = 0; n < ct.nrights; n++) {
			(*ticket_rights)[n * 2 + 0] = xxstrdup(ct.rights[n].directory);
			(*ticket_rights)[n * 2 + 1] = xxstrdup(ct.rights[n].acl);
		}
		(*ticket_rights)[n * 2 + 0] = NULL;
		(*ticket_rights)[n * 2 + 1] = NULL;

		chirp_ticket_free(&ct);
		free(esubject);
		return 0;
	} else {
		chirp_ticket_free(&ct);
		free(esubject);
		errno = EACCES;
		return -1;
	}
}
Exemple #7
0
int chirp_acl_whoami(const char *subject, char **esubject)
{
	const char *digest;
	if(chirp_ticket_isticketsubject(subject, &digest)) {
		/* open the ticket file */
		struct chirp_ticket ct;
		char ticket_filename[CHIRP_PATH_MAX];

		chirp_ticket_filename(ticket_filename, subject, NULL);
		if(!ticket_read(ticket_filename, &ct))
			return 0;
		*esubject = xxstrdup(ct.subject);
		chirp_ticket_free(&ct);
		return 1;
	} else {
		*esubject = xxstrdup(subject);
		return 1;
	}
}
Exemple #8
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;
}