Exemple #1
0
static int update_gshadow (void)
{
	int is_member;
	int was_member;
	int was_admin;
	int changed;
	const struct sgrp *sgrp;
	struct sgrp *nsgrp;

	if (!sgr_lock ()) {
		fprintf (stderr,
			 _("%s: error locking shadow group file\n"), Prog);
		SYSLOG ((LOG_ERR, "error locking shadow group file"));
		return -1;
	}
	if (!sgr_open (O_RDWR)) {
		fprintf (stderr,
			 _("%s: error opening shadow group file\n"), Prog);
		SYSLOG ((LOG_ERR, "error opening shadow group file"));
		sgr_unlock ();
		return -1;
	}

	changed = 0;

	/*
	 * Scan through the entire shadow group file looking for the groups
	 * that the user is a member of.
	 */
	while ((sgrp = sgr_next ())) {

		/*
		 * See if the user was a member of this group
		 */
		was_member = is_on_list (sgrp->sg_mem, user_name);

		/*
		 * See if the user was an administrator of this group
		 */
		was_admin = is_on_list (sgrp->sg_adm, user_name);

		/*
		 * See if the user specified this group as one of their
		 * concurrent groups.
		 */
		is_member = Gflg
		    && is_on_list (user_groups, sgrp->sg_name);

		if (!was_member && !was_admin && !is_member)
			continue;

		nsgrp = __sgr_dup (sgrp);
		if (!nsgrp) {
			fprintf (stderr,
				 _
				 ("%s: out of memory in update_gshadow\n"),
				 Prog);
			sgr_unlock ();
			return -1;
		}

		if (was_admin && lflg) {
			nsgrp->sg_adm =
			    del_list (nsgrp->sg_adm, user_name);
			nsgrp->sg_adm =
			    add_list (nsgrp->sg_adm, user_newname);
			changed = 1;
			SYSLOG ((LOG_INFO,
				 "change admin `%s' to `%s' in shadow group `%s'",
				 user_name, user_newname, nsgrp->sg_name));
		}
		if (was_member && (!Gflg || is_member)) {
			if (lflg) {
				nsgrp->sg_mem = del_list (nsgrp->sg_mem,
							  user_name);
				nsgrp->sg_mem = add_list (nsgrp->sg_mem,
							  user_newname);
				changed = 1;
				SYSLOG ((LOG_INFO,
					 "change `%s' to `%s' in shadow group `%s'",
					 user_name, user_newname,
					 nsgrp->sg_name));
			}
		} else if (was_member && Gflg && !is_member) {
			nsgrp->sg_mem =
			    del_list (nsgrp->sg_mem, user_name);
			changed = 1;
			SYSLOG ((LOG_INFO,
				 "delete `%s' from shadow group `%s'",
				 user_name, nsgrp->sg_name));
		} else if (!was_member && Gflg && is_member) {
			nsgrp->sg_mem = add_list (nsgrp->sg_mem,
						  lflg ? user_newname :
						  user_name);
			changed = 1;
			SYSLOG ((LOG_INFO, "add `%s' to shadow group `%s'",
				 lflg ? user_newname : user_name,
				 nsgrp->sg_name));
		}
		if (!changed)
			continue;

		changed = 0;

		/* 
		 * Update the group entry to reflect the changes.
		 */
		if (!sgr_update (nsgrp)) {
			fprintf (stderr,
				 _("%s: error adding new group entry\n"),
				 Prog);
			SYSLOG ((LOG_ERR,
				 "error adding shadow group entry"));
			sgr_unlock ();
			return -1;
		}
#ifdef	NDBM
		/*
		 * Update the DBM group file with the new entry as well.
		 */
		if (!sg_dbm_update (nsgrp)) {
			fprintf (stderr,
				 _("%s: cannot add new dbm group entry\n"),
				 Prog);
			SYSLOG ((LOG_ERR,
				 "error adding dbm shadow group entry"));
			sgr_unlock ();
			return -1;
		}
#endif				/* NDBM */
	}
#ifdef NDBM
	endsgent ();
#endif				/* NDBM */
	if (!sgr_close ()) {
		fprintf (stderr,
			 _("%s: cannot rewrite shadow group file\n"),
			 Prog);
		sgr_unlock ();
		return -1;
	}
	sgr_unlock ();
	return 0;
}
static void
update_groups(void)
{
	const struct group *grp;
	struct group *ngrp;
#ifdef	SHADOWGRP
	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 ();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 (!ngrp) {
			exit(13);  /* XXX */
		}
		ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
		if (!gr_update(ngrp))
			fprintf(stderr, _("%s: error updating group entry\n"),
				Prog);

		/*
		 * Update the DBM group file with the new entry as well.
		 */

#ifdef	NDBM
		if (!gr_dbm_update(ngrp))
			fprintf(stderr,
				_("%s: cannot update dbm group entry\n"),
				Prog);
#endif	/* NDBM */
		SYSLOG((LOG_INFO, "delete `%s' from group `%s'\n",
			user_name, ngrp->gr_name));
	}
#ifdef	NDBM
	endgrent ();
#endif	/* NDBM */
#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 ();sgrp;sgrp = sgr_next ()) {
		int 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 (!nsgrp) {
			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))
			fprintf(stderr, _("%s: error updating group entry\n"),
				Prog);
#ifdef	NDBM
		/*
		 * Update the DBM group file with the new entry as well.
		 */

		if (!sg_dbm_update(nsgrp))
			fprintf(stderr,
				_("%s: cannot update dbm group entry\n"),
				Prog);
#endif	/* NDBM */
		SYSLOG((LOG_INFO, "delete `%s' from shadow group `%s'\n",
			user_name, nsgrp->sg_name));
	}
#ifdef	NDBM
	endsgent ();
#endif	/* NDBM */
#endif	/* SHADOWGRP */
}
Exemple #3
0
int main (int argc, char **argv)
{
	const struct group *gr;
	struct group grent;
	const struct sgrp *sg;
	struct sgrp sgent;

	Prog = Basename (argv[0]);

	(void) setlocale (LC_ALL, "");
	(void) bindtextdomain (PACKAGE, LOCALEDIR);
	(void) textdomain (PACKAGE);

	process_root_flag ("-R", argc, argv);

	OPENLOG ("grpconv");

	process_flags (argc, argv);

	if (gr_lock () == 0) {
		fprintf (stderr,
		         _("%s: cannot lock %s; try again later.\n"),
		         Prog, gr_dbname ());
		fail_exit (5);
	}
	gr_locked = true;
	if (gr_open (O_CREAT | O_RDWR) == 0) {
		fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
		fail_exit (1);
	}

	if (sgr_lock () == 0) {
		fprintf (stderr,
		         _("%s: cannot lock %s; try again later.\n"),
		         Prog, sgr_dbname ());
		fail_exit (5);
	}
	sgr_locked = true;
	if (sgr_open (O_CREAT | O_RDWR) == 0) {
		fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ());
		fail_exit (1);
	}

	/*
	 * Remove /etc/gshadow entries for groups not in /etc/group.
	 */
	(void) sgr_rewind ();
	while ((sg = sgr_next ()) != NULL) {
		if (gr_locate (sg->sg_name) != NULL) {
			continue;
		}

		if (sgr_remove (sg->sg_name) == 0) {
			/*
			 * This shouldn't happen (the entry exists) but...
			 */
			fprintf (stderr,
			         _("%s: cannot remove entry '%s' from %s\n"),
			         Prog, sg->sg_name, sgr_dbname ());
			fail_exit (3);
		}
	}

	/*
	 * Update shadow group passwords if non-shadow password is not "x".
	 * Add any missing shadow group entries.
	 */
	(void) gr_rewind ();
	while ((gr = gr_next ()) != NULL) {
		sg = sgr_locate (gr->gr_name);
		if (NULL != sg) {
			/* update existing shadow group entry */
			sgent = *sg;
			if (strcmp (gr->gr_passwd, SHADOW_PASSWD_STRING) != 0)
				sgent.sg_passwd = gr->gr_passwd;
		} else {
			static char *empty = 0;

			/* add new shadow group entry */
			memset (&sgent, 0, sizeof sgent);
			sgent.sg_name = gr->gr_name;
			sgent.sg_passwd = gr->gr_passwd;
			sgent.sg_adm = ∅
		}
		/*
		 * XXX - sg_mem is redundant, it is currently always a copy
		 * of gr_mem. Very few programs actually use sg_mem, and all
		 * of them are in the shadow suite. Maybe this field could
		 * be used for something else? Any suggestions?
		 */
		sgent.sg_mem = gr->gr_mem;

		if (sgr_update (&sgent) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, sgr_dbname (), sgent.sg_name);
			fail_exit (3);
		}
		/* remove password from /etc/group */
		grent = *gr;
		grent.gr_passwd = SHADOW_PASSWD_STRING;	/* XXX warning: const */
		if (gr_update (&grent) == 0) {
			fprintf (stderr,
			         _("%s: failed to prepare the new %s entry '%s'\n"),
			         Prog, gr_dbname (), grent.gr_name);
			fail_exit (3);
		}
	}

	if (sgr_close () == 0) {
		fprintf (stderr,
		         _("%s: failure while writing changes to %s\n"),
		         Prog, sgr_dbname ());
		SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
		fail_exit (3);
	}
	if (gr_close () == 0) {
		fprintf (stderr,
		         _("%s: failure while writing changes to %s\n"),
		         Prog, gr_dbname ());
		SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
		fail_exit (3);
	}
	if (sgr_unlock () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
		SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
		/* continue */
	}
	if (gr_unlock () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
		SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
		/* continue */
	}

	nscd_flush_cache ("group");

	return 0;
}
Exemple #4
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;

#ifdef	SHADOWGRP
	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				/* WITH_AUDIT */
		SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n",
			 user_name, ngrp->gr_name));
	}

	if (getdef_bool ("USERGROUPS_ENAB")) {
		remove_usergroup ();
	}

#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				/* WITH_AUDIT */
		SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n",
		         user_name, nsgrp->sg_name));
	}
#endif				/* SHADOWGRP */
}
Exemple #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 */
}