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;
	}
}
Exemple #3
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);
}