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

	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);

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

	/* 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[0];
	}

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

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