示例#1
0
文件: bb_pwd.c 项目: nawawi/busybox
long FAST_FUNC xgroup2gid(const char *name)
{
	struct group *mygroup;

	mygroup = xgetgrnam(name);
	return mygroup->gr_gid;
}
int addgroup_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opts;
	unsigned 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:g+";
	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))) {
				/* 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], gid);

	}
	/* Reached only on success */
	return EXIT_SUCCESS;
}
void groupdel_main(void)
{
  struct group *grp = xgetgrnam(toys.optargs[toys.optc-1]);
  char *entry = 0;

  // delete user from group
  if (toys.optc == 2) {
    int i, len = 0, found = 0;
    char *s;

    xgetpwnam(*toys.optargs);
    if (grp->gr_mem) for (i = 0; grp->gr_mem[i]; i++) {
      if (!found && !strcmp(*toys.optargs, grp->gr_mem[i])) found++;
      else len += strlen(grp->gr_mem[i]) + 1;
    }
    if (!found)
      error_exit("user '%s' not in group '%s'", *toys.optargs, toys.optargs[1]);

    entry = s = xmalloc(len);
    for (i = 0; grp->gr_mem[i]; ) {
      if (i) *(s++) = ',';
      s = stpcpy(s, grp->gr_mem[i]);
    }

  // delete group
  } else {
    struct passwd *pw;

    for (endpwent(); (pw = getpwent());)
      if (pw->pw_gid == grp->gr_gid) break;

    if (pw) error_exit("can't remove primary group of user '%s'", pw->pw_name);
    if (CFG_TOYBOX_FREE) endpwent();
  }

  update_password("/etc/group", grp->gr_name, entry);
  update_password("/etc/gshadow", grp->gr_name, entry);
  if (CFG_TOYBOX_FREE) free(entry);
}
示例#4
0
int deluser_main(int argc, char **argv)
{
	/* User or group name */
	char *name;
	/* Username (non-NULL only in "delgroup USER GROUP" case) */
	char *member;
	/* Name of passwd or group file */
	const char *pfile;
	/* Name of shadow or gshadow file */
	const char *sfile;
	/* Are we deluser or delgroup? */
	int do_deluser = (ENABLE_DELUSER && (!ENABLE_DELGROUP || applet_name[3] == 'u'));

	if (geteuid() != 0)
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);

	name = argv[1];
	member = NULL;

	switch (argc) {
	case 3:
		if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || do_deluser)
			break;
		/* It's "delgroup USER GROUP" */
		member = name;
		name = argv[2];
		/* Fallthrough */

	case 2:
		if (do_deluser) {
			/* "deluser USER" */
			xgetpwnam(name); /* bail out if USER is wrong */
			pfile = bb_path_passwd_file;
			if (ENABLE_FEATURE_SHADOWPASSWDS)
				sfile = bb_path_shadow_file;
		} else {
			struct group *gr;
 do_delgroup:
			/* "delgroup GROUP" or "delgroup USER GROUP" */
			if (do_deluser < 0) { /* delgroup after deluser? */
				gr = getgrnam(name);
				if (!gr)
					return EXIT_SUCCESS;
			} else {
				gr = xgetgrnam(name); /* bail out if GROUP is wrong */
			}
			if (!member) {
				/* "delgroup GROUP" */
				struct passwd *pw;
				struct passwd pwent;
				/* Check if the group is in use */
#define passwd_buf bb_common_bufsiz1
				while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) {
					if (pwent.pw_gid == gr->gr_gid)
						bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name);
				}
				//endpwent();
			}
			pfile = bb_path_group_file;
			if (ENABLE_FEATURE_SHADOWPASSWDS)
				sfile = bb_path_gshadow_file;
		}

		/* Modify pfile, then sfile */
		do {
			if (update_passwd(pfile, name, NULL, member) == -1)
				return EXIT_FAILURE;
			if (ENABLE_FEATURE_SHADOWPASSWDS) {
				pfile = sfile;
				sfile = NULL;
			}
		} while (ENABLE_FEATURE_SHADOWPASSWDS && pfile);

		if (ENABLE_DELGROUP && do_deluser > 0) {
			/* "deluser USER" also should try to delete
			 * same-named group. IOW: do "delgroup USER"
			 */
// On debian deluser is a perl script that calls userdel.
// From man userdel:
//  If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will
//  delete the group with the same name as the user.
			do_deluser = -1;
			goto do_delgroup;
		}
		return EXIT_SUCCESS;
	}
	/* Reached only if number of command line args is wrong */
	bb_show_usage();
}
示例#5
0
/*
 * update_groups - delete user from secondary group set
 *
 *	update_groups() takes the user name that was given and searches
 *	the group files for membership in any group.
 *
 *	we also check to see if they have any groups they own (the same
 *	name is their user name) and delete them too (only if USERGROUPS_ENAB
 *	is enabled).
 */
static void update_groups (void)
{
	const struct group *grp;
	struct group *ngrp;
	struct passwd *pwd;

#ifdef	SHADOWGRP
	bool deleted_user_group = false;
	const struct sgrp *sgrp;
	struct sgrp *nsgrp;
#endif				/* SHADOWGRP */

	/*
	 * Scan through the entire group file looking for the groups that
	 * the user is a member of.
	 */
	for (gr_rewind (), grp = gr_next (); NULL != grp; grp = gr_next ()) {

		/*
		 * See if the user specified this group as one of their
		 * concurrent groups.
		 */
		if (!is_on_list (grp->gr_mem, user_name)) {
			continue;
		}

		/* 
		 * Delete the username from the list of group members and
		 * update the group entry to reflect the change.
		 */
		ngrp = __gr_dup (grp);
		if (NULL == ngrp) {
			fprintf (stderr,
			         _("%s: Out of memory. Cannot update %s.\n"),
			         Prog, gr_dbname ());
			exit (13);	/* XXX */
		}
		ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
		if (gr_update (ngrp) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, gr_dbname (), ngrp->gr_name);
			exit (E_GRP_UPDATE);
		}

		/*
		 * Update the DBM group file with the new entry as well.
		 */
#ifdef WITH_AUDIT
		audit_logger (AUDIT_DEL_USER, Prog,
		              "deleting user from group",
		              user_name, (unsigned int) user_id,
		              SHADOW_AUDIT_SUCCESS);
#endif
		SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n",
			 user_name, ngrp->gr_name));
	}

	/*
	 * we've removed their name from all the groups above, so
	 * now if they have a group with the same name as their
	 * user name, with no members, we delete it.
	 * FIXME: below, the check for grp->gr_mem[0] is not sufficient.
	 *        We should retrieve the group with gr_locate and check
	 *        that gr_mem is empty.
	 */
	grp = xgetgrnam (user_name);
	if (   (NULL != grp)
	    && getdef_bool ("USERGROUPS_ENAB")
	    && (   (NULL == grp->gr_mem[0])
	        || (   (NULL == grp->gr_mem[1])
	            && (strcmp (grp->gr_mem[0], user_name) == 0)))) {

		pwd = NULL;
		if (!fflg) {
			/*
			 * Scan the passwd file to check if this group is still
			 * used as a primary group.
			 */
			setpwent ();
			while ((pwd = getpwent ()) != NULL) {
				if (strcmp (pwd->pw_name, user_name) == 0) {
					continue;
				}
				if (pwd->pw_gid == grp->gr_gid) {
					fprintf (stderr,
					         _("%s: group %s is the primary group of another user and is not removed.\n"),
					         Prog, grp->gr_name);
					break;
				}
			}
			endpwent ();
		}

		if (NULL == pwd) {
			/*
			 * We can remove this group, it is not the primary
			 * group of any remaining user.
			 */
			if (gr_remove (grp->gr_name) == 0) {
				fprintf (stderr,
				         _("%s: cannot remove entry '%s' from %s\n"),
				         Prog, grp->gr_name, gr_dbname ());
				fail_exit (E_GRP_UPDATE);
			}

#ifdef SHADOWGRP
			deleted_user_group = true;
#endif

#ifdef WITH_AUDIT
			audit_logger (AUDIT_DEL_GROUP, Prog,
			              "deleting group",
			              grp->gr_name, AUDIT_NO_ID,
			              SHADOW_AUDIT_SUCCESS);
#endif
			SYSLOG ((LOG_INFO,
				 "removed group '%s' owned by '%s'\n",
				 grp->gr_name, user_name));
		}
	}
#ifdef	SHADOWGRP
	if (!is_shadow_grp) {
		return;
	}

	/*
	 * Scan through the entire shadow group file looking for the groups
	 * that the user is a member of. Both the administrative list and
	 * the ordinary membership list is checked.
	 */
	for (sgr_rewind (), sgrp = sgr_next ();
	     NULL != sgrp;
	     sgrp = sgr_next ()) {
		bool was_member, was_admin;

		/*
		 * See if the user specified this group as one of their
		 * concurrent groups.
		 */
		was_member = is_on_list (sgrp->sg_mem, user_name);
		was_admin = is_on_list (sgrp->sg_adm, user_name);

		if (!was_member && !was_admin) {
			continue;
		}

		nsgrp = __sgr_dup (sgrp);
		if (NULL == nsgrp) {
			fprintf (stderr,
			         _("%s: Out of memory. Cannot update %s.\n"),
			         Prog, sgr_dbname ());
			exit (13);	/* XXX */
		}

		if (was_member) {
			nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
		}

		if (was_admin) {
			nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
		}

		if (sgr_update (nsgrp) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, sgr_dbname (), nsgrp->sg_name);
			exit (E_GRP_UPDATE);
		}
#ifdef WITH_AUDIT
		audit_logger (AUDIT_DEL_USER, Prog,
		              "deleting user from shadow group",
		              user_name, (unsigned int) user_id,
		              SHADOW_AUDIT_SUCCESS);
#endif
		SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n",
			 user_name, nsgrp->sg_name));
	}

	if (   deleted_user_group
	    && (sgr_locate (user_name) != NULL)) {
		if (sgr_remove (user_name) == 0) {
			fprintf (stderr,
			         _("%s: cannot remove entry '%s' from %s\n"),
			         Prog, user_name, sgr_dbname ());
			fail_exit (E_GRP_UPDATE);
		}
	}
#endif				/* SHADOWGRP */
}