/*
 * 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 FILEs 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;
}
