/* vi: set sw=4 ts=4: */
/*
 * addgroup - add groups to /etc/group and /etc/gshadow
 *
 * Copyright (C) 1999 by Lineo, inc. and John Beppu
 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 *
 */
//config:config ADDGROUP
//config:	bool "addgroup"
//config:	default y
//config:	help
//config:	  Utility for creating a new group account.
//config:
//config:config FEATURE_ADDGROUP_LONG_OPTIONS
//config:	bool "Enable long options"
//config:	default y
//config:	depends on ADDGROUP && LONG_OPTS
//config:	help
//config:	  Support long options for the addgroup applet.
//config:
//config:config FEATURE_ADDUSER_TO_GROUP
//config:	bool "Support for adding users to groups"
//config:	default y
//config:	depends on ADDGROUP
//config:	help
//config:	  If  called  with two non-option arguments,
//config:	  addgroup will add an existing user to an
//config:	  existing group.

//applet:IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_ADDGROUP) += addgroup.o

//usage:#define addgroup_trivial_usage
//usage:       "[-g GID] [-S] " IF_FEATURE_ADDUSER_TO_GROUP("[USER] ") "GROUP"
//usage:#define addgroup_full_usage "\n\n"
//usage:       "Add a group" IF_FEATURE_ADDUSER_TO_GROUP(" or add a user to a group") "\n"
//usage:     "\n	-g GID	Group id"
//usage:     "\n	-S	Create a system group"

#include "libbb.h"

#if CONFIG_LAST_SYSTEM_ID < CONFIG_FIRST_SYSTEM_ID
#error Bad LAST_SYSTEM_ID or FIRST_SYSTEM_ID in .config
#endif
#if CONFIG_LAST_ID < CONFIG_LAST_SYSTEM_ID
#error Bad LAST_ID or LAST_SYSTEM_ID in .config
#endif

#define OPT_GID                       (1 << 0)
#define OPT_SYSTEM_ACCOUNT            (1 << 1)

static void xgroup_study(struct group *g)
{
	unsigned max = CONFIG_LAST_ID;

	/* Make sure gr_name is unused */
	if (getgrnam(g->gr_name)) {
		bb_error_msg_and_die("%s '%s' in use", "group", g->gr_name);
		/* these format strings are reused in adduser and addgroup */
	}

	/* if a specific gid is requested, the --system switch and */
	/* min and max values are overridden, and the range of valid */
	/* gid values is set to [0, INT_MAX] */
	if (!(option_mask32 & OPT_GID)) {
		if (option_mask32 & OPT_SYSTEM_ACCOUNT) {
			g->gr_gid = CONFIG_FIRST_SYSTEM_ID;
			max = CONFIG_LAST_SYSTEM_ID;
		} else {
			g->gr_gid = CONFIG_LAST_SYSTEM_ID + 1;
		}
	}
	/* Check if the desired gid is free
	 * or find the first free one */
	while (1) {
		if (!getgrgid(g->gr_gid)) {
			return; /* found free group: return */
		}
		if (option_mask32 & OPT_GID) {
			/* -g N, cannot pick gid other than N: error */
			bb_error_msg_and_die("%s '%s' in use", "gid", itoa(g->gr_gid));
			/* this format strings is reused in adduser and addgroup */
		}
		if (g->gr_gid == max) {
			/* overflowed: error */
			bb_error_msg_and_die("no %cids left", 'g');
			/* this format string is reused in adduser and addgroup */
		}
		g->gr_gid++;
	}
}

/* append a new user to the passwd file */
static void new_group(char *group, gid_t gid)
{
	struct group gr;
	char *p;

	/* make sure gid and group haven't already been allocated */
	gr.gr_gid = gid;
	gr.gr_name = group;
	xgroup_study(&gr);

	/* add entry to group */
	p = xasprintf("x:%u:", (unsigned) gr.gr_gid);
	if (update_passwd(bb_path_group_file, group, p, NULL) < 0)
		exit(EXIT_FAILURE);
	if (ENABLE_FEATURE_CLEAN_UP)
		free(p);
#if ENABLE_FEATURE_SHADOWPASSWDS
	/* /etc/gshadow fields:
	 * 1. Group name.
	 * 2. Encrypted password.
	 *    If set, non-members of the group can join the group
	 *    by typing the password for that group using the newgrp command.
	 *    If the value is of this field ! then no user is allowed
	 *    to access the group using the newgrp command. A value of !!
	 *    is treated the same as a value of ! only it indicates
	 *    that a password has never been set before. If the value is null,
	 *    only group members can log into the group.
	 * 3. Group administrators (comma delimited list).
	 *    Group members listed here can add or remove group members
	 *    using the gpasswd command.
	 * 4. Group members (comma delimited list).
	 */
	/* Ignore errors: if file is missing we assume admin doesn't want it */
	update_passwd(bb_path_gshadow_file, group, "!::", NULL);
#endif
}

#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
static const char addgroup_longopts[] ALIGN1 =
		"gid\0"                 Required_argument "g"
		"system\0"              No_argument       "S"
		;
#endif

/*
 * addgroup will take a login_name as its first parameter.
 *
 * gid can be customized via command-line parameters.
 * If called with two non-option arguments, addgroup
 * will add an existing user to an existing group.
 */
int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int addgroup_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opts;
	const char *gid = "0";

	/* need to be root */
	if (geteuid()) {
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
	}
#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
	applet_long_options = addgroup_longopts;
#endif
	/* Syntax:
	 *  addgroup group
	 *  addgroup -g num group
	 *  addgroup user group
	 * Check for min, max and missing args */
	opt_complementary = "-1:?2";
	opts = getopt32(argv, "g:S", &gid);
	/* move past the commandline options */
	argv += optind;
	//argc -= optind;

#if ENABLE_FEATURE_ADDUSER_TO_GROUP
	if (argv[1]) {
		struct group *gr;

		if (opts & OPT_GID) {
			/* -g was there, but "addgroup -g num user group"
			 * is a no-no */
			bb_show_usage();
		}

		/* check if group and user exist */
		xuname2uid(argv[0]); /* unknown user: exit */
		gr = xgetgrnam(argv[1]); /* unknown group: exit */
		/* check if user is already in this group */
		for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) {
			if (strcmp(argv[0], *(gr->gr_mem)) == 0) {
				/* user is already in group: do nothing */
				return EXIT_SUCCESS;
			}
		}
		if (update_passwd(bb_path_group_file, argv[1], NULL, argv[0]) < 0) {
			return EXIT_FAILURE;
		}
# if ENABLE_FEATURE_SHADOWPASSWDS
		update_passwd(bb_path_gshadow_file, argv[1], NULL, argv[0]);
# endif
	} else
#endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */
	{
		die_if_bad_username(argv[0]);
		new_group(argv[0], xatou_range(gid, 0, CONFIG_LAST_ID));
	}
	/* Reached only on success */
	return EXIT_SUCCESS;
}
