Beispiel #1
0
int
restore(
	FILE *file,
	const char *filename)
{
	char *path_p;
	struct stat stat;
	uid_t uid;
	gid_t gid;
	seq_t seq = NULL;
	int line = 0, backup_line;
	int error, status = 0;

	memset(&stat, 0, sizeof(stat));

	for(;;) {
		backup_line = line;
		error = read_acl_comments(file, &line, &path_p, &uid, &gid);
		if (error < 0)
			goto fail;
		if (error == 0)
			return 0;

		if (path_p == NULL) {
			if (filename) {
				fprintf(stderr, _("%s: %s: No filename found "
						  "in line %d, aborting\n"),
					progname, xquote(filename),
					backup_line);
			} else {
				fprintf(stderr, _("%s: No filename found in "
						 "line %d of standard input, "
						 "aborting\n"),
					progname, backup_line);
			}
			goto getout;
		}

		if (!(seq = seq_init()))
			goto fail;
		if (seq_append_cmd(seq, CMD_REMOVE_ACL, ACL_TYPE_ACCESS) ||
		    seq_append_cmd(seq, CMD_REMOVE_ACL, ACL_TYPE_DEFAULT))
			goto fail;

		error = read_acl_seq(file, seq, CMD_ENTRY_REPLACE,
		                     SEQ_PARSE_WITH_PERM |
				     SEQ_PARSE_NO_RELATIVE |
				     SEQ_PARSE_DEFAULT |
				     SEQ_PARSE_MULTI,
				     &line, NULL);
		if (error != 0) {
			fprintf(stderr, _("%s: %s: %s in line %d\n"),
			        progname, xquote(filename), strerror(errno),
				line);
			goto getout;
		}

		error = lstat(path_p, &stat);
		if (opt_test && error != 0) {
			fprintf(stderr, "%s: %s: %s\n", progname,
				xquote(path_p), strerror(errno));
			status = 1;
		}
		stat.st_uid = uid;
		stat.st_gid = gid;

		error = do_set(path_p, &stat, seq);
		if (error != 0) {
			status = 1;
			goto resume;
		}

		if (!opt_test &&
		    (uid != ACL_UNDEFINED_ID || gid != ACL_UNDEFINED_ID)) {
			if (chown(path_p, uid, gid) != 0) {
				fprintf(stderr, _("%s: %s: Cannot change "
					          "owner/group: %s\n"),
					progname, xquote(path_p),
					strerror(errno));
				status = 1;
			}
		}
resume:
		if (path_p) {
			free(path_p);
			path_p = NULL;
		}
		if (seq) {
			seq_free(seq);
			seq = NULL;
		}
	}

getout:
	if (path_p) {
		free(path_p);
		path_p = NULL;
	}
	if (seq) {
		seq_free(seq);
		seq = NULL;
	}
	return status;

fail:
	fprintf(stderr, "%s: %s: %s\n", progname, xquote(filename),
		strerror(errno));
	status = 1;
	goto getout;
}
Beispiel #2
0
int
restore(
	FILE *file,
	const char *filename)
{
	char *path_p;
	struct stat st;
	uid_t uid;
	gid_t gid;
	mode_t mask, flags;
	struct do_set_args args = { };
	int line = 0, backup_line;
	int error, status = 0;
	int chmod_required = 0;

	memset(&st, 0, sizeof(st));

	for(;;) {
		backup_line = line;
		error = read_acl_comments(file, &line, &path_p, &uid, &gid,
					  &flags);
		if (error < 0) {
			error = -error;
			goto fail;
		}
		if (error == 0)
			return status;

		if (path_p == NULL) {
			if (filename) {
				fprintf(stderr, _("%s: %s: No filename found "
						  "in line %d, aborting\n"),
					progname, xquote(filename, "\n\r"),
					backup_line);
			} else {
				fprintf(stderr, _("%s: No filename found in "
						 "line %d of standard input, "
						 "aborting\n"),
					progname, backup_line);
			}
			status = 1;
			goto getout;
		}

		if (!(args.seq = seq_init()))
			goto fail_errno;
		if (seq_append_cmd(args.seq, CMD_REMOVE_ACL, ACL_TYPE_ACCESS) ||
		    seq_append_cmd(args.seq, CMD_REMOVE_ACL, ACL_TYPE_DEFAULT))
			goto fail_errno;

		error = read_acl_seq(file, args.seq, CMD_ENTRY_REPLACE,
		                     SEQ_PARSE_WITH_PERM |
				     SEQ_PARSE_DEFAULT |
				     SEQ_PARSE_MULTI,
				     &line, NULL);
		if (error != 0) {
			fprintf(stderr, _("%s: %s: %s in line %d\n"),
			        progname, xquote(filename, "\n\r"), strerror(errno),
				line);
			status = 1;
			goto getout;
		}

		error = stat(path_p, &st);
		if (opt_test && error != 0) {
			fprintf(stderr, "%s: %s: %s\n", progname,
				xquote(path_p, "\n\r"), strerror(errno));
			status = 1;
		}

		args.mode = 0;
		error = do_set(path_p, &st, 0, &args);
		if (error != 0) {
			status = 1;
			goto resume;
		}

		if (uid != ACL_UNDEFINED_ID && uid != st.st_uid)
			st.st_uid = uid;
		else
			st.st_uid = -1;
		if (gid != ACL_UNDEFINED_ID && gid != st.st_gid)
			st.st_gid = gid;
		else
			st.st_gid = -1;
		if (!opt_test &&
		    (st.st_uid != -1 || st.st_gid != -1)) {
			if (chown(path_p, st.st_uid, st.st_gid) != 0) {
				fprintf(stderr, _("%s: %s: Cannot change "
					          "owner/group: %s\n"),
					progname, xquote(path_p, "\n\r"),
					strerror(errno));
				status = 1;
			}

			/* chown() clears setuid/setgid so force a chmod if
			 * S_ISUID/S_ISGID was expected */
			if ((st.st_mode & flags) & (S_ISUID | S_ISGID))
				chmod_required = 1;
		}

		mask = S_ISUID | S_ISGID | S_ISVTX;
		if (chmod_required || ((st.st_mode & mask) != (flags & mask))) {
			if (!args.mode)
				args.mode = st.st_mode;
			args.mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
			if (chmod(path_p, flags | args.mode) != 0) {
				fprintf(stderr, _("%s: %s: Cannot change "
					          "mode: %s\n"),
					progname, xquote(path_p, "\n\r"),
					strerror(errno));
				status = 1;
			}
		}
resume:
		if (path_p) {
			free(path_p);
			path_p = NULL;
		}
		if (args.seq) {
			seq_free(args.seq);
			args.seq = NULL;
		}
	}

getout:
	if (path_p) {
		free(path_p);
		path_p = NULL;
	}
	if (args.seq) {
		seq_free(args.seq);
		args.seq = NULL;
	}
	return status;

fail_errno:
	error = errno;
fail:
	fprintf(stderr, "%s: %s: %s\n", progname, xquote(filename, "\n\r"),
		strerror(error));
	status = 1;
	goto getout;
}