示例#1
0
void
print_test(
	FILE *file,
	const char *path_p,
	const struct stat *st,
	const acl_t acl,
	const acl_t default_acl)
{
	char *acl_text, *default_acl_text;

	acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
	default_acl_text =
		acl_to_any_text(default_acl, "d:", ',', TEXT_ABBREVIATE);
	fprintf(file, "%s: %s,%s\n", path_p,
		acl_text ? acl_text : "*",
		default_acl_text ? default_acl_text : "*");
	acl_free(acl_text);
	acl_free(default_acl_text);
}
示例#2
0
/*
 *    lists the acl for a file/dir in short text form
 *    return 0 on failure
 *    return 1 on success
 */
static int
list_acl(char *file)
{
	acl_t acl = NULL;
	acl_t dacl = NULL;
	char *acl_text, *dacl_text = NULL;

	if ((acl = acl_get_file(file, ACL_TYPE_ACCESS)) == NULL) {
		fprintf(stderr, _("%s: cannot get access ACL on '%s': %s\n"),
			program, file, strerror(errno));
		return 0;
	}
	if ((dacl = acl_get_file(file, ACL_TYPE_DEFAULT)) == NULL &&
	    (errno != EACCES)) {	/* EACCES given if not a directory */
		fprintf(stderr, _("%s: cannot get default ACL on '%s': %s\n"),
			program, file, strerror(errno));
		return 0;
	}
	acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
	if (acl_text == NULL) {
		fprintf(stderr, _("%s: cannot get access ACL text on "
			"'%s': %s\n"), program, file, strerror(errno));
		return 0;
	}
	if (acl_entries(dacl) > 0) {
		dacl_text = acl_to_any_text(dacl, NULL, ',', TEXT_ABBREVIATE);
		if (dacl_text == NULL) {
			fprintf(stderr, _("%s: cannot get default ACL text on "
				"'%s': %s\n"), program, file, strerror(errno));
			return 0;
		}
	}
	if (dacl_text) {
		printf("%s [%s/%s]\n", file, acl_text, dacl_text);
		acl_free(dacl_text);
	} else
		printf("%s [%s]\n", file, acl_text);
	acl_free(acl_text);
	acl_free(acl);
	acl_free(dacl);
	return 1;
}
示例#3
0
文件: acl_get.c 项目: Andiry/xfstests
int
main(int argc, char **argv)
{
	int c;
        char *file;
	char *acl_text;
	int getaccess = 0;
	int getdefault = 0;
	int usefd = 0;
	int fd = -1;
	acl_t acl;

        prog = basename(argv[0]);

	while ((c = getopt(argc, argv, "adf")) != -1) {
		switch (c) {
		case 'a':
			getaccess = 1;
			break;
		case 'd':
			getdefault = 1;
			break;
		case 'f':
			usefd = 1;
			break;
		case '?':
                        usage();
			return 1;
		}
	}

	if (getdefault && usefd) {
	    fprintf(stderr, "%s: -f and -d are not compatible\n", prog);
	    return 1;
	}

        /* need path */
        if (optind == argc) {
            usage();
            exit(1);
        }
	else {
	    file = argv[optind];
	} 

	if (usefd) {
	    fd = open(file, O_RDONLY);
	    if (fd < 0) {
		fprintf (stderr, "%s: error opening \"%s\": %s\n",
			     prog, file, strerror(errno));
	 	usage(); 
		return 1;

	    }	
	}

        if (getaccess) {
	    if (usefd) { 
		acl = acl_get_fd(fd);
	    }
	    else {
		acl = acl_get_file(file, ACL_TYPE_ACCESS);
	    }
	    if (acl == NULL) {
		fprintf(stderr, "%s: error getting access ACL on \"%s\": %s\n",
			     prog, file, strerror(errno));
		return 0;
	    }
	    acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
	    if (acl_text == NULL) {
	    	fprintf(stderr, "%s: cannot get access ACL text on '%s': %s\n",
			prog, file, strerror(errno));
	    	return 0;
	    }
	    printf("%s: access %s", file, acl_text);
	    acl_free(acl_text);
	    acl_free(acl);
	}

        if (getdefault) {
	    acl = acl_get_file(file, ACL_TYPE_DEFAULT);
	    if (acl == NULL) {
		fprintf(stderr, "%s: error getting default ACL on \"%s\": %s\n",
			     prog, file, strerror(errno));
		return 0;
	    }
	    acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
	    if (acl_text == NULL) {
	    	fprintf(stderr, "%s: cannot get default ACL text on '%s': %s\n",
			prog, file, strerror(errno));
	    	return 0;
	    }
	    printf("%s: default %s", file, acl_text);
	    acl_free(acl_text);
	    acl_free(acl);
	}

	return 0;
}
示例#4
0
int do_print(const char *path_p, const struct stat *st, int walk_flags, void *unused)
{
	const char *default_prefix = NULL;
	acl_t acl = NULL, default_acl = NULL;
	int error = 0;

	if (walk_flags & WALK_TREE_FAILED) {
		fprintf(stderr, "%s: %s: %s\n", progname, xquote(path_p, "\n\r"),
			strerror(errno));
		return 1;
	}

	/*
	 * Symlinks can never have ACLs, so when doing a physical walk, we
	 * skip symlinks altogether, and when doing a half-logical walk, we
	 * skip all non-toplevel symlinks. 
	 */
	if ((walk_flags & WALK_TREE_SYMLINK) &&
	    ((walk_flags & WALK_TREE_PHYSICAL) ||
	     !(walk_flags & (WALK_TREE_TOPLEVEL | WALK_TREE_LOGICAL))))
		return 0;

	if (opt_print_acl) {
		acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
		if (acl == NULL && (errno == ENOSYS || errno == ENOTSUP))
			acl = acl_get_file_mode(path_p);
		if (acl == NULL)
			goto fail;
	}

	if (opt_print_default_acl && S_ISDIR(st->st_mode)) {
		default_acl = acl_get_file(path_p, ACL_TYPE_DEFAULT);
		if (default_acl == NULL) {
			if (errno != ENOSYS && errno != ENOTSUP)
				goto fail;
		} else if (acl_entries(default_acl) == 0) {
			acl_free(default_acl);
			default_acl = NULL;
		}
	}

	if (opt_skip_base &&
	    (!acl || acl_equiv_mode(acl, NULL) == 0) && !default_acl)
		return 0;

	if (opt_print_acl && opt_print_default_acl)
		default_prefix = "default:";

	if (opt_strip_leading_slash) {
		if (*path_p == '/') {
			if (!absolute_warning) {
				fprintf(stderr, _("%s: Removing leading "
					"'/' from absolute path names\n"),
				        progname);
				absolute_warning = 1;
			}
			while (*path_p == '/')
				path_p++;
		} else if (*path_p == '.' && *(path_p+1) == '/')
			while (*++path_p == '/')
				/* nothing */ ;
		if (*path_p == '\0')
			path_p = ".";
	}

	if (opt_tabular)  {
		if (do_show(stdout, path_p, st, acl, default_acl) != 0)
			goto fail;
	} else {
		if (opt_comments) {
			printf("# file: %s\n", xquote(path_p, "\n\r"));
			printf("# owner: %s\n",
			       xquote(user_name(st->st_uid, opt_numeric), " \t\n\r"));
			printf("# group: %s\n",
			       xquote(group_name(st->st_gid, opt_numeric), " \t\n\r"));
			if ((st->st_mode & (S_ISVTX | S_ISUID | S_ISGID)) && !posixly_correct)
				printf("# flags: %s\n", flagstr(st->st_mode));
		}
		if (acl != NULL) {
			char *acl_text = acl_to_any_text(acl, NULL, '\n',
							 print_options);
			if (!acl_text)
				goto fail;
			if (puts(acl_text) < 0) {
				acl_free(acl_text);
				goto fail;
			}
			acl_free(acl_text);
		}
		if (default_acl != NULL) {
			char *acl_text = acl_to_any_text(default_acl, 
							 default_prefix, '\n',
							 print_options);
			if (!acl_text)
				goto fail;
			if (puts(acl_text) < 0) {
				acl_free(acl_text);
				goto fail;
			}
			acl_free(acl_text);
		}
	}
	if (acl || default_acl || opt_comments)
		printf("\n");

cleanup:
	if (acl)
		acl_free(acl);
	if (default_acl)
		acl_free(default_acl);
	return error;

fail:
	fprintf(stderr, "%s: %s: %s\n", progname, xquote(path_p, "\n\r"),
		strerror(errno));
	error = -1;
	goto cleanup;
}
示例#5
0
int
do_set(
	const char *path_p,
	const struct stat *st,
	const seq_t seq)
{
	acl_t old_acl = NULL, old_default_acl = NULL;
	acl_t acl = NULL, default_acl = NULL;
	acl_t *xacl, *old_xacl;
	acl_entry_t ent;
	cmd_t cmd;
	int which_entry;
	int errors = 0, error;
	char *acl_text;
	int acl_modified = 0, default_acl_modified = 0;
	int acl_mask_provided = 0, default_acl_mask_provided = 0;

	/* Execute the commands in seq (read ACLs on demand) */
	error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd);
	if (error == 0)
		return 0;
	while (error == 1) {
		if (cmd->c_type == ACL_TYPE_ACCESS) {
			xacl = &acl;
			old_xacl = &old_acl;
			acl_modified = 1;
			if (cmd->c_tag == ACL_MASK)
				acl_mask_provided = 1;
		} else {
			xacl = &default_acl;
			old_xacl = &old_default_acl;
			default_acl_modified = 1;
			if (cmd->c_tag == ACL_MASK)
				default_acl_mask_provided = 1;
		}

		RETRIEVE_ACL(cmd->c_type);

		/* Check for `X', and replace with `x' as appropriate. */
		if (cmd->c_perm & CMD_PERM_COND_EXECUTE) {
			cmd->c_perm &= ~CMD_PERM_COND_EXECUTE;
			if (S_ISDIR(st->st_mode) || has_execute_perms(*xacl))
				cmd->c_perm |= CMD_PERM_EXECUTE;
		}

		switch(cmd->c_cmd) {
			case CMD_ENTRY_REPLACE:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (!ent) {
					if (acl_create_entry(xacl, &ent) != 0)
						goto fail;
					acl_set_tag_type(ent, cmd->c_tag);
					if (cmd->c_id != ACL_UNDEFINED_ID)
						acl_set_qualifier(ent,
								  &cmd->c_id);
				}
				set_perm(ent, cmd->c_perm, ~cmd->c_perm);
				break;

			case CMD_ENTRY_ADD:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (ent)
					set_perm(ent, cmd->c_perm, 0);
				break;

			case CMD_ENTRY_SUBTRACT:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (ent)
					set_perm(ent, 0, cmd->c_perm);
				break;

			case CMD_REMOVE_ENTRY:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (ent)
					acl_delete_entry(*xacl, ent);
				else
					/* ignore */;
				break;

			case CMD_REMOVE_EXTENDED_ACL:
				remove_extended_entries(acl);
				break;

			case CMD_REMOVE_ACL:
				acl_free(*xacl);
				*xacl = acl_init(5);
				if (!*xacl)
					goto fail;
				break;

			default:
				errno = EINVAL;
				goto fail;
		}

		error = seq_get_cmd(seq, SEQ_NEXT_CMD, &cmd);
	}

	if (error < 0)
		goto fail;

	/* Try to fill in missing entries */
	if (default_acl && acl_entries(default_acl) != 0) {
		xacl = &acl;
		old_xacl = &old_acl;
	
		if (!find_entry(default_acl, ACL_USER_OBJ, ACL_UNDEFINED_ID)) {
			if (!acl)
				RETRIEVE_ACL(ACL_TYPE_ACCESS);
			clone_entry(acl, ACL_USER_OBJ,
			            &default_acl, ACL_USER_OBJ);
		}
		if (!find_entry(default_acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) {
			if (!acl)
				RETRIEVE_ACL(ACL_TYPE_ACCESS);
			clone_entry(acl, ACL_GROUP_OBJ,
			            &default_acl, ACL_GROUP_OBJ);
		}
		if (!find_entry(default_acl, ACL_OTHER, ACL_UNDEFINED_ID)) {
			if (!acl)
				RETRIEVE_ACL(ACL_TYPE_ACCESS);
			clone_entry(acl, ACL_OTHER,
			            &default_acl, ACL_OTHER);
		}
	}

	/* update mask entries and check if ACLs are valid */
	if (acl && acl_modified) {
		if (acl_equiv_mode(acl, NULL) != 0) {
			if (!acl_mask_provided &&
			    !find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID))
				clone_entry(acl, ACL_GROUP_OBJ,
				            &acl, ACL_MASK);
			if (opt_recalculate != -1 &&
			    (!acl_mask_provided || opt_recalculate == 1))
				acl_calc_mask(&acl);
		}

		error = acl_check(acl, &which_entry);
		if (error < 0)
			goto fail;
		if (error > 0) {
			acl_text = acl_to_any_text(acl, NULL, ',', 0);
			fprintf(stderr, gettext("%s: %s: Malformed access ACL "
				"`%s': %s at entry %d\n"), progname, path_p,
				acl_text, acl_error(error), which_entry+1);
			acl_free(acl_text);
			errors++;
			goto cleanup;
		}
	}

	if (default_acl && acl_entries(default_acl) != 0 &&
	    default_acl_modified) {
		if (acl_equiv_mode(default_acl, NULL) != 0) {
			if (!default_acl_mask_provided &&
			    !find_entry(default_acl,ACL_MASK,ACL_UNDEFINED_ID))
				clone_entry(default_acl, ACL_GROUP_OBJ,
				            &default_acl, ACL_MASK);
			if (opt_recalculate != -1 &&
			    (!default_acl_mask_provided ||
			     opt_recalculate == 1))
				acl_calc_mask(&default_acl);
		}

		error = acl_check(default_acl, &which_entry);
		if (error < 0)
			goto fail;
		if (error > 0) {
			acl_text = acl_to_any_text(default_acl, NULL, ',', 0);
			fprintf(stderr, gettext("%s: %s: Malformed default ACL "
			                  "`%s': %s at entry %d\n"),
				progname, path_p, acl_text,
				acl_error(error), which_entry+1);
			acl_free(acl_text);
			errors++;
			goto cleanup;
		}
	}

	/* Only directores can have default ACLs */
	if (default_acl && !S_ISDIR(st->st_mode) && opt_recursive) {
		/* In recursive mode, ignore default ACLs for files */
		acl_free(default_acl);
		default_acl = NULL;
	}

	/* check which ACLs have changed */
	if (acl && old_acl && acl_cmp(old_acl, acl) == 0) {
		acl_free(acl);
		acl = NULL;
	}
	if ((default_acl && old_default_acl &&
	    acl_cmp(old_default_acl, default_acl) == 0)) {
		acl_free(default_acl);
		default_acl = NULL;
	}

	/* update the file system */
	if (opt_test) {
		print_test(stdout, path_p, st,
		           acl, default_acl);
		goto cleanup;
	}
	if (acl) {
		if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) != 0) {
			if (errno == ENOSYS || errno == ENOTSUP) {
				int saved_errno = errno;
				mode_t mode;

				if (acl_equiv_mode(acl, &mode) != 0) {
					errno = saved_errno;
					goto fail;
				} else if (chmod(path_p, mode) != 0)
					goto fail;
			} else
				goto fail;
		}
	}
	if (default_acl) {
		if (S_ISDIR(st->st_mode)) {
			if (acl_entries(default_acl) == 0) {
				if (acl_delete_def_file(path_p) != 0 &&
				    errno != ENOSYS && errno != ENOTSUP)
					goto fail;
			} else {
				if (acl_set_file(path_p, ACL_TYPE_DEFAULT,
						 default_acl) != 0)
					goto fail;
			}
		} else {
			if (acl_entries(default_acl) != 0) {
				fprintf(stderr, gettext(
						"%s: %s: Only directories "
						"can have default ACLs\n"),
					progname, path_p);
				errors++;
				goto cleanup;
			}
		}
	}

	error = 0;

cleanup:
	if (acl)
		acl_free(acl);
	if (old_acl)
		acl_free(old_acl);
	if (default_acl)
		acl_free(default_acl);
	if (old_default_acl)
		acl_free(old_default_acl);
	return errors;
	
fail:
	fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno));
	errors++;
	goto cleanup;
}