/* vi: set sw=4 ts=4: */
/*
 * adduser - add users to /etc/passwd and /etc/shadow
 *
 * Copyright (C) 1999 by Lineo, inc. and John Beppu
 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 */

#include "busybox.h"

#define DONT_SET_PASS			(1 << 4)
#define DONT_MAKE_HOME			(1 << 6)


/* remix */
/* EDR recoded such that the uid may be passed in *p */
static int passwd_study(const char *filename, struct passwd *p)
{
	struct passwd *pw;
	FILE *passwd;

	const int min = 500;
	const int max = 65000;

	passwd = xfopen(filename, "r");

	/* EDR if uid is out of bounds, set to min */
	if ((p->pw_uid > max) || (p->pw_uid < min))
		p->pw_uid = min;

	/* stuff to do:
	 * make sure login isn't taken;
	 * find free uid and gid;
	 */
	while ((pw = fgetpwent(passwd))) {
		if (strcmp(pw->pw_name, p->pw_name) == 0) {
			/* return 0; */
			return 1;
		}
		if ((pw->pw_uid >= p->pw_uid) && (pw->pw_uid < max)
			&& (pw->pw_uid >= min)) {
			p->pw_uid = pw->pw_uid + 1;
		}
	}

	if (p->pw_gid == 0) {
		/* EDR check for an already existing gid */
		while (getgrgid(p->pw_uid) != NULL)
			p->pw_uid++;

		/* EDR also check for an existing group definition */
		if (getgrnam(p->pw_name) != NULL)
			return 3;

		/* EDR create new gid always = uid */
		p->pw_gid = p->pw_uid;
	}

	/* EDR bounds check */
	if ((p->pw_uid > max) || (p->pw_uid < min))
		return 2;

	/* return 1; */
	return 0;
}

static void addgroup_wrapper(struct passwd *p)
{
	char *cmd;

	cmd = xasprintf("addgroup -g %d \"%s\"", p->pw_gid, p->pw_name);
	system(cmd);
	free(cmd);
}

static void passwd_wrapper(const char *login) ATTRIBUTE_NORETURN;

static void passwd_wrapper(const char *login)
{
	static const char prog[] = "passwd";
	execlp(prog, prog, login, NULL);
	bb_error_msg_and_die("failed to execute '%s', you must set the password for '%s' manually", prog, login);
}

/* putpwent(3) remix */
static int adduser(struct passwd *p, unsigned long flags)
{
	FILE *file;
	int addgroup = !p->pw_gid;

	/* make sure everything is kosher and setup uid && gid */
	file = xfopen(bb_path_passwd_file, "a");
	fseek(file, 0, SEEK_END);

	switch (passwd_study(bb_path_passwd_file, p)) {
		case 1:
			bb_error_msg_and_die("%s: login already in use", p->pw_name);
		case 2:
			bb_error_msg_and_die("illegal uid or no uids left");
		case 3:
			bb_error_msg_and_die("%s: group name already in use", p->pw_name);
 	}

	/* add to passwd */
	if (putpwent(p, file) == -1) {
		bb_perror_nomsg_and_die();
	}
	fclose(file);

#if ENABLE_FEATURE_SHADOWPASSWDS
	/* add to shadow if necessary */
	file = xfopen(bb_path_shadow_file, "a");
	fseek(file, 0, SEEK_END);
	fprintf(file, "%s:!:%ld:%d:%d:%d:::\n",
			p->pw_name,             /* username */
			time(NULL) / 86400,     /* sp->sp_lstchg */
			0,                      /* sp->sp_min */
			99999,                  /* sp->sp_max */
			7);                     /* sp->sp_warn */
	fclose(file);
#endif

	/* add to group */
	/* addgroup should be responsible for dealing w/ gshadow */
	/* if using a pre-existing group, don't create one */
	if (addgroup) addgroup_wrapper(p);

	/* Clear the umask for this process so it doesn't
	 * * screw up the permissions on the mkdir and chown. */
	umask(0);
	if (!(flags & DONT_MAKE_HOME)) {
		/* Set the owner and group so it is owned by the new user,
		   then fix up the permissions to 2755. Can't do it before
		   since chown will clear the setgid bit */
		if (mkdir(p->pw_dir, 0755)
		|| chown(p->pw_dir, p->pw_uid, p->pw_gid)
		|| chmod(p->pw_dir, 02755)) {
			bb_perror_msg("%s", p->pw_dir);
		}
	}

	if (!(flags & DONT_SET_PASS)) {
		/* interactively set passwd */
		passwd_wrapper(p->pw_name);
	}

	return 0;
}

/*
 * adduser will take a login_name as its first parameter.
 *
 * home
 * shell
 * gecos
 *
 * can be customized via command-line parameters.
 */
int adduser_main(int argc, char **argv)
{
	struct passwd pw;
	const char *usegroup = NULL;
	unsigned long flags;

	/* got root? */
	if (geteuid()) {
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
	}

	pw.pw_gecos = "Linux User,,,";
	pw.pw_shell = (char *)DEFAULT_SHELL;
	pw.pw_dir = NULL;

	/* check for min, max and missing args and exit on error */
	opt_complementary = "-1:?1:?";
	flags = getopt32(argc, argv, "h:g:s:G:DSH", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup);

	/* create string for $HOME if not specified already */
	if (!pw.pw_dir) {
		snprintf(bb_common_bufsiz1, BUFSIZ, "/home/%s", argv[optind]);
		pw.pw_dir = bb_common_bufsiz1;
	}

	/* create a passwd struct */
	pw.pw_name = argv[optind];
	pw.pw_passwd = "x";
	pw.pw_uid = 0;
	pw.pw_gid = usegroup ? xgroup2gid(usegroup) : 0; /* exits on failure */

	/* grand finale */
	return adduser(&pw, flags);
}
