#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <ctype.h>
#include <errno.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include "selinux_internal.h"

/* Process line from seusers.conf and split into its fields.
   Returns 0 on success, -1 on comments, and -2 on error. */
static int process_seusers(const char *buffer,
			   char **luserp,
			   char **seuserp, char **levelp, int mls_enabled)
{
	char *newbuf = strdup(buffer);
	char *luser = NULL, *seuser = NULL, *level = NULL;
	char *start, *end;
	int mls_found = 1;

	if (!newbuf)
		goto err;

	start = newbuf;
	while (isspace(*start))
		start++;
	if (*start == '#' || *start == 0) {
		free(newbuf);
		return -1;	/* Comment or empty line, skip over */
	}
	end = strchr(start, ':');
	if (!end)
		goto err;
	*end = 0;

	luser = strdup(start);
	if (!luser)
		goto err;

	start = end + 1;
	end = strchr(start, ':');
	if (!end) {
		mls_found = 0;

		end = start;
		while (*end && !isspace(*end))
			end++;
	}
	*end = 0;

	seuser = strdup(start);
	if (!seuser)
		goto err;

	if (!strcmp(seuser, ""))
		goto err;

	/* Skip MLS if disabled, or missing. */
	if (!mls_enabled || !mls_found)
		goto out;

	start = ++end;
	while (*end && !isspace(*end))
		end++;
	*end = 0;

	level = strdup(start);
	if (!level)
		goto err;

	if (!strcmp(level, ""))
		goto err;

      out:
	free(newbuf);
	*luserp = luser;
	*seuserp = seuser;
	*levelp = level;
	return 0;
      err:
	free(newbuf);
	free(luser);
	free(seuser);
	free(level);
	return -2;		/* error */
}

int require_seusers hidden = 0;

#include <pwd.h>
#include <grp.h>

static gid_t get_default_gid(const char *name) {
	struct passwd pwstorage, *pwent = NULL;
	gid_t gid = -1;
	/* Allocate space for the getpwnam_r buffer */
	long rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
	if (rbuflen <= 0) return -1;
	char *rbuf = malloc(rbuflen);
	if (rbuf == NULL) return -1;

	int retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent);
	if (retval == 0 && pwent) {
		gid = pwent->pw_gid;
	}
	free(rbuf);
	return gid;
}

static int check_group(const char *group, const char *name, const gid_t gid) {
	int match = 0;
	int i, ng = 0;
	gid_t *groups = NULL;
	struct group gbuf, *grent = NULL;

	long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
	if (rbuflen <= 0)
		return 0;
	char *rbuf;

	while(1) {
		rbuf = malloc(rbuflen);
		if (rbuf == NULL)
			return 0;
		int retval = getgrnam_r(group, &gbuf, rbuf, 
				rbuflen, &grent);
		if ( retval == ERANGE )
		{
			free(rbuf);
			rbuflen = rbuflen * 2;
		} else if ( retval != 0 || grent == NULL )
		{
			goto done;
		} else
		{
			break;
		}
	}

	if (getgrouplist(name, gid, NULL, &ng) < 0) {
		if (ng == 0)
			goto done;
		groups = calloc(ng, sizeof(*groups));
		if (!groups)
			goto done;
		if (getgrouplist(name, gid, groups, &ng) < 0)
			goto done;
	} else {
		/* WTF?  ng was 0 and we didn't fail? Are we in 0 groups? */
		goto done;
	}

	for (i = 0; i < ng; i++) {
		if (grent->gr_gid == groups[i]) {
			match = 1;
			goto done;
		}
	}

 done:
	free(groups);
	free(rbuf);
	return match;
}

int getseuserbyname(const char *name, char **r_seuser, char **r_level)
{
	FILE *cfg = NULL;
	size_t size = 0;
	char *buffer = NULL;
	int rc;
	unsigned long lineno = 0;
	int mls_enabled = is_selinux_mls_enabled();

	char *username = NULL;
	char *seuser = NULL;
	char *level = NULL;
	char *groupseuser = NULL;
	char *grouplevel = NULL;
	char *defaultseuser = NULL;
	char *defaultlevel = NULL;

	gid_t gid = get_default_gid(name);

	cfg = fopen(selinux_usersconf_path(), "r");
	if (!cfg)
		goto nomatch;

	__fsetlocking(cfg, FSETLOCKING_BYCALLER);
	while (getline(&buffer, &size, cfg) > 0) {
		++lineno;
		rc = process_seusers(buffer, &username, &seuser, &level,
				     mls_enabled);
		if (rc == -1)
			continue;	/* comment, skip */
		if (rc == -2) {
			fprintf(stderr, "%s:  error on line %lu, skipping...\n",
				selinux_usersconf_path(), lineno);
			continue;
		}

		if (!strcmp(username, name))
			break;

		if (username[0] == '%' && 
		    !groupseuser && 
		    check_group(&username[1], name, gid)) {
				groupseuser = seuser;
				grouplevel = level;
		} else {
			if (!defaultseuser && 
			    !strcmp(username, "__default__")) {
				defaultseuser = seuser;
				defaultlevel = level;
			} else {
				free(seuser);
				free(level);
			}
		}
		free(username);
		username = NULL;
		seuser = NULL;
	}

	free(buffer);
	fclose(cfg);

	if (seuser) {
		free(username);
		free(defaultseuser);
		free(defaultlevel);
		free(groupseuser);
		free(grouplevel);
		*r_seuser = seuser;
		*r_level = level;
		return 0;
	}

	if (groupseuser) {
		free(defaultseuser);
		free(defaultlevel);
		*r_seuser = groupseuser;
		*r_level = grouplevel;
		return 0;
	}

	if (defaultseuser) {
		*r_seuser = defaultseuser;
		*r_level = defaultlevel;
		return 0;
	}

      nomatch:
	if (require_seusers)
		return -1;

	/* Fall back to the Linux username and no level. */
	*r_seuser = strdup(name);
	if (!(*r_seuser))
		return -1;
	*r_level = NULL;
	return 0;
}

int getseuser(const char *username, const char *service, 
	      char **r_seuser, char **r_level) {
	int ret = -1;
	int len = 0;
	char *seuser = NULL;
	char *level = NULL;
	char *buffer = NULL;
	size_t size = 0;
	char *rec = NULL;
	char *path=NULL;
	FILE *fp = NULL;
	if (asprintf(&path,"%s/logins/%s", selinux_policy_root(), username) <  0)
		goto err;
	fp = fopen(path, "r");
	free(path);
	if (fp == NULL) goto err;
	__fsetlocking(fp, FSETLOCKING_BYCALLER);
	while (getline(&buffer, &size, fp) > 0) {
		if (strncmp(buffer, "*:", 2) == 0) {
			free(rec);
			rec = strdup(buffer);
			continue;
		}
		if (!service)
			continue;
		len = strlen(service);
		if ((strncmp(buffer, service, len) == 0) &&
		    (buffer[len] == ':')) {
			free(rec);
			rec = strdup(buffer);
			break;
		}
	}

	if (! rec)  goto err;
	seuser = strchr(rec, ':');
	if (! seuser) goto err;

	seuser++;
	level = strchr(seuser, ':');
	if (! level) goto err;
	*level = 0;
	level++;
	*r_seuser = strdup(seuser);
	if (! *r_seuser) goto err;

	len = strlen(level);
	if (len && level[len-1] == '\n')
		level[len-1] = 0;

	*r_level = strdup(level);
	if (! *r_level) {
		free(*r_seuser);
		goto err;
	}
	ret = 0;

	err:
	free(buffer);
	if (fp) fclose(fp);
	free(rec);

	return (ret ? getseuserbyname(username, r_seuser, r_level) : ret);
}
