~jkaivo/privexec

757c0bd92bd777c47e23281ad814f3e28bde3498 — Jakob Kaivo 1 year, 5 months ago c941b92 privexec
implement full precedence rules
3 files changed, 68 insertions(+), 23 deletions(-)

M check/check.c
M check/check.h
M check/parse.c
M check/check.c => check/check.c +13 -3
@@ 69,7 69,10 @@ int main(int argc, char *argv[])
		user, group, cmd);

	switch (get_permission(user, group, cmd)) {
	case AUTHENTICATE:
	case AUTH_GROUP_ALL:
	case AUTH_GROUP_CMD:
	case AUTH_USER_ALL:
	case AUTH_USER_CMD:
		syslog(LOG_INFO, "%s:%s requires authentication to run %s",
			user, group, cmd);
		if (authenticate(user) != 0) {


@@ 78,12 81,19 @@ int main(int argc, char *argv[])
			fatal(0, "bad authentication");
		}
		/* FALLTHRU */
	case AUTHORIZED:

	case PASS_GROUP_ALL:
	case PASS_GROUP_CMD:
	case PASS_USER_ALL:
	case PASS_USER_CMD:
		syslog(LOG_INFO, "%s:%s authorized to run %s",
			user, group, cmd);
		return 0;

	case DENIED:
	case DENY_GROUP_ALL:
	case DENY_GROUP_CMD:
	case DENY_USER_ALL:
	case DENY_USER_CMD:
		syslog(LOG_NOTICE,
			"%s:%s explicitly denied permission to run %s",
			user, group, cmd);

M check/check.h => check/check.h +36 -1
@@ 13,7 13,42 @@
#define PRIVEXEC_LOG_ID		"privexec"
#endif

enum permission { UNKNOWN, AUTHORIZED, AUTHENTICATE, DENIED };
enum permission_keyword {
	PERM_PASS = 0x1,
	PERM_AUTH = 0x2,
	PERM_DENY = 0x3,
};

enum permission_principal {
	PERM_GROUP = 0x100,
	PERM_USER = 0x200,
};

enum permission_command {
	PERM_ALL = 0x10,
	PERM_CMD = 0x20,
};

enum permission {
	UNKNOWN,

	PASS_GROUP_ALL = PERM_PASS | PERM_GROUP | PERM_ALL,
	AUTH_GROUP_ALL = PERM_AUTH | PERM_GROUP | PERM_ALL,
	DENY_GROUP_ALL = PERM_DENY | PERM_GROUP | PERM_ALL,

	PASS_GROUP_CMD = PERM_PASS | PERM_GROUP | PERM_CMD,
	AUTH_GROUP_CMD = PERM_AUTH | PERM_GROUP | PERM_CMD,
	DENY_GROUP_CMD = PERM_DENY | PERM_GROUP | PERM_CMD,

	PASS_USER_ALL = PERM_PASS | PERM_USER | PERM_ALL,
	AUTH_USER_ALL = PERM_AUTH | PERM_USER | PERM_ALL,
	DENY_USER_ALL = PERM_DENY | PERM_USER | PERM_ALL,

	PASS_USER_CMD = PERM_PASS | PERM_USER | PERM_CMD,
	AUTH_USER_CMD = PERM_AUTH | PERM_USER | PERM_CMD,
	DENY_USER_CMD = PERM_DENY | PERM_USER | PERM_CMD,
};


void fatal(int include_errno, char *fmt, ...);
enum permission get_permission(const char *user, const char *group, const char *cmd);

M check/parse.c => check/parse.c +19 -19
@@ 7,36 7,36 @@

static enum permission eval(const char *keyword, const char *principal, const char *cmd, const char *user, const char *group, const char *command)
{
	int pmatch = 0;
	enum permission_principal pp = 0;
	if (!strcmp(user, principal)) {
		pmatch = 1;
	}
	if (principal[0] == ':' && !strcmp(group, principal + 1)) {
		pmatch = 1;
		pp = PERM_USER;
	} else if (principal[0] == ':' && !strcmp(group, principal + 1)) {
		pp = PERM_GROUP;
	}

	int cmatch = 0;
	if (cmd == NULL || !strcmp(cmd, command)) {
		cmatch = 1;
	enum permission_command pc = 0;
	if (cmd == NULL) {
		pc = PERM_ALL;
	} else if (!strcmp(cmd, command)) {
		pc = PERM_CMD;
	}

	enum permission_keyword pk = 0;
	if (!strcmp(keyword, "authorize")) {
		if (cmatch && pmatch) {
			return AUTHORIZED;
		}
		pk = PERM_PASS;
	} else if (!strcmp(keyword, "authenticate")) {
		if (cmatch && pmatch) {
			return AUTHENTICATE;
		}
		pk = PERM_AUTH;
	} else if (!strcmp(keyword, "deny")) {
		if (cmatch && pmatch) {
			return DENIED;
		}
		pk = PERM_DENY;
	} else {
		fatal(0, "invalid keyword: %s", keyword);
	}

	return UNKNOWN;
	if (pp == 0 || pc == 0) {
		return UNKNOWN;
	}

	return pp | pc | pk;
}

enum permission get_permission(const char *user, const char *group, const char *command)


@@ 76,7 76,7 @@ enum permission get_permission(const char *user, const char *group, const char *
		}

		enum permission tmp = eval(keyword, principal, cmd, user, group, command);
		/* only increase, so deny trumps authenticate, which trumps authorize */
		/* only change if a higher precedence is found */
		if (tmp > perm) {
			perm = tmp;
		}