/*
 * chcon -- change security context, based on coreutils-5.97-13
 *
 * Port to busybox: KaiGai Kohei <kaigai@kaigai.gr.jp>
 *
 * Copyright (C) 2006 - 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
//config:config CHCON
//config:	bool "chcon (8.9 kb)"
//config:	default n
//config:	depends on SELINUX
//config:	help
//config:	Enable support to change the security context of file.

//applet:IF_CHCON(APPLET(chcon, BB_DIR_USR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_CHCON) += chcon.o

//usage:#define chcon_trivial_usage
//usage:       "[-chfRv] CONTEXT FILE..."
//usage:       "\n	chcon [-chfRv] [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE..."
//usage:	IF_LONG_OPTS(
//usage:       "\n	chcon [-chfRv] --reference=RFILE FILE..."
//usage:	)
//usage:
//usage:#define chcon_full_usage "\n\n"
//usage:       "Change the security context of each FILE to CONTEXT\n"
//usage:     "\n	-v	Verbose"
//usage:     "\n	-c	Report changes made"
//usage:     "\n	-h	Affect symlinks instead of their targets"
//usage:     "\n	-f	Suppress most error messages"
//usage:	IF_LONG_OPTS(
//usage:     "\n	--reference RFILE Use RFILE's group instead of using a CONTEXT value"
//usage:	)
//usage:     "\n	-u USER	Set user/role/type/range in the target security context"
//usage:     "\n	-r ROLE"
//usage:     "\n	-t TYPE"
//usage:     "\n	-l RANGE"
//usage:     "\n	-R	Recurse"

#include <selinux/context.h>

#include "libbb.h"

#define OPT_RECURSIVE		(1<<0)	/* 'R' */
#define OPT_CHANHES		(1<<1)	/* 'c' */
#define OPT_NODEREFERENCE	(1<<2)	/* 'h' */
#define OPT_QUIET		(1<<3)	/* 'f' */
#define OPT_USER		(1<<4)	/* 'u' */
#define OPT_ROLE		(1<<5)	/* 'r' */
#define OPT_TYPE		(1<<6)	/* 't' */
#define OPT_RANGE		(1<<7)	/* 'l' */
#define OPT_VERBOSE		(1<<8)	/* 'v' */
#define OPT_REFERENCE		((1<<9) * ENABLE_LONG_OPTS)
#define OPT_COMPONENT_SPECIFIED	(OPT_USER | OPT_ROLE | OPT_TYPE | OPT_RANGE)

static char *user = NULL;
static char *role = NULL;
static char *type = NULL;
static char *range = NULL;
static char *specified_context = NULL;

static int FAST_FUNC change_filedir_context(struct recursive_state *state UNUSED_PARAM,
		const char *fname,
		struct stat *stbuf UNUSED_PARAM)
{
	context_t context = NULL;
	security_context_t file_context = NULL;
	security_context_t context_string;
	int rc = FALSE;
	int status = 0;

	if (option_mask32 & OPT_NODEREFERENCE) {
		status = lgetfilecon(fname, &file_context);
	} else {
		status = getfilecon(fname, &file_context);
	}
	if (status < 0 && errno != ENODATA) {
		if ((option_mask32 & OPT_QUIET) == 0)
			bb_error_msg("can't obtain security context: %s", fname);
		goto skip;
	}

	if (file_context == NULL && specified_context == NULL) {
		bb_error_msg("can't apply partial context to unlabeled file %s", fname);
		goto skip;
	}

	if (specified_context == NULL) {
		context = set_security_context_component(file_context,
							user, role, type, range);
		if (!context) {
			bb_error_msg("can't compute security context from %s", file_context);
			goto skip;
		}
	} else {
		context = context_new(specified_context);
		if (!context) {
			bb_error_msg("invalid context: %s", specified_context);
			goto skip;
		}
	}

	context_string = context_str(context);
	if (!context_string) {
		bb_simple_error_msg("can't obtain security context in text expression");
		goto skip;
	}

	if (file_context == NULL || strcmp(context_string, file_context) != 0) {
		int fail;

		if (option_mask32 & OPT_NODEREFERENCE) {
			fail = lsetfilecon(fname, context_string);
		} else {
			fail = setfilecon(fname, context_string);
		}
		if ((option_mask32 & OPT_VERBOSE) || ((option_mask32 & OPT_CHANHES) && !fail)) {
			printf(!fail
				? "context of %s changed to %s\n"
				: "can't change context of %s to %s\n",
				fname, context_string);
		}
		if (!fail) {
			rc = TRUE;
		} else if ((option_mask32 & OPT_QUIET) == 0) {
			bb_error_msg("can't change context of %s to %s",
					fname, context_string);
		}
	} else {
		if (option_mask32 & OPT_VERBOSE) {
			printf("context of %s retained as %s\n", fname, context_string);
		}
		rc = TRUE;
	}
skip:
	context_free(context);
	freecon(file_context);

	return rc;
}

#if ENABLE_LONG_OPTS
static const char chcon_longopts[] ALIGN1 =
	"recursive\0"      No_argument       "R"
	"changes\0"        No_argument       "c"
	"no-dereference\0" No_argument       "h"
	"silent\0"         No_argument       "f"
	"quiet\0"          No_argument       "f"
	"user\0"           Required_argument "u"
	"role\0"           Required_argument "r"
	"type\0"           Required_argument "t"
	"range\0"          Required_argument "l"
	"verbose\0"        No_argument       "v"
	"reference\0"      Required_argument "\xff" /* no short option */
	;
#endif

int chcon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int chcon_main(int argc UNUSED_PARAM, char **argv)
{
	char *reference_file;
	char *fname;
	int i, errors = 0;

	getopt32long(argv, "^"
		"Rchfu:r:t:l:v"
		"\0"
		"-1" /* at least 1 arg */
		":?" /* error if exclusivity constraints are violated */
#if ENABLE_LONG_OPTS
		":\xff--urtl:u--\xff:r--\xff:t--\xff:l--\xff"
#endif
		":f--v:v--f"  /* 'verbose' and 'quiet' are exclusive */
		, chcon_longopts,
		&user, &role, &type, &range, &reference_file
	);
	argv += optind;

#if ENABLE_LONG_OPTS
	if (option_mask32 & OPT_REFERENCE) {
		/* FIXME: lgetfilecon() should be used when '-h' is specified.
		 * But current implementation follows the original one. */
		if (getfilecon(reference_file, &specified_context) < 0)
			bb_perror_msg_and_die("getfilecon('%s') failed", reference_file);
	} else
#endif
	if ((option_mask32 & OPT_COMPONENT_SPECIFIED) == 0) {
		specified_context = *argv++;
		/* specified_context is never NULL -
		 * "-1" in opt_complementary prevents this. */
		if (!argv[0])
			bb_simple_error_msg_and_die("too few arguments");
	}

	for (i = 0; (fname = argv[i]) != NULL; i++) {
		int fname_len = strlen(fname);
		while (fname_len > 1 && fname[fname_len - 1] == '/')
			fname_len--;
		fname[fname_len] = '\0';

		if (recursive_action(fname,
					((option_mask32 & OPT_RECURSIVE) ? ACTION_RECURSE : 0),
					change_filedir_context,
					change_filedir_context,
					NULL) != TRUE)
			errors = 1;
	}
	return errors;
}
