Exemple #1
0
static void print_groups (const char *member)
{
	int groups = 0;
	struct group *grp;
	struct passwd *pwd;
	int flag = 0;

	setgrent ();

	if ((pwd = getpwnam (member)) == 0) {
		fprintf (stderr, _("unknown user %s\n"), member);
		exit (1);
	}
	while ((grp = getgrent ())) {
		if (is_on_list (grp->gr_mem, member)) {
			if (groups++)
				putchar (' ');

			printf ("%s", grp->gr_name);
			if (grp->gr_gid == pwd->pw_gid)
				flag = 1;
		}
	}
	if (!flag && (grp = getgrgid (pwd->pw_gid))) {
		if (groups++)
			putchar (' ');

		printf ("%s", grp->gr_name);
	}
	if (groups)
		putchar ('\n');
}
Exemple #2
0
static void check_perms (const struct group *gr)
#endif
{
	/*
	 * Only root can use the -M and -A options.
	 */
	if (!amroot && (Aflg || Mflg)) {
		failure ();
	}

#ifdef SHADOWGRP
	if (is_shadowgrp) {
		/*
		 * The policy here for changing a group is that
		 * 1) you must be root or
		 * 2) you must be listed as an administrative member.
		 * Administrative members can do anything to a group that
		 * the root user can.
		 */
		if (!amroot && !is_on_list (sg->sg_adm, myname)) {
			failure ();
		}
	} else
#endif				/* SHADOWGRP */
	{
#ifdef FIRST_MEMBER_IS_ADMIN
		/*
		 * The policy here for changing a group is that
		 * 1) you must be root or
		 * 2) you must be the first listed member of the group.
		 * The first listed member of a group can do anything to
		 * that group that the root user can. The rationale for
		 * this hack is that the FIRST user is probably the most
		 * important user in this entire group.
		 *
		 * This feature enabled by default could be a security
		 * problem when installed on existing systems where the
		 * first group member might be just a normal user.
		 * --marekm
		 */
		if (!amroot) {
			if (gr->gr_mem[0] == (char *) 0) {
				failure ();
			}

			if (strcmp (gr->gr_mem[0], myname) != 0) {
				failure ();
			}
		}
#else				/* ! FIRST_MEMBER_IS_ADMIN */
		if (!amroot) {
			failure ();
		}
#endif
	}
}
Exemple #3
0
static int isgrp (const char *name, const char *group)
{
	struct group *grp;

	grp = getgrnam (group); /* local, no need for xgetgrnam */

	if (!grp || !grp->gr_mem)
		return 0;

	return is_on_list (grp->gr_mem, name);
}
Exemple #4
0
static bool iswheel (const char *username)
{
	struct group *grp;

	grp = getgrnam ("wheel"); /* !USE_PAM, no need for xgetgrnam */
	if (   (NULL ==grp)
	    || (NULL == grp->gr_mem)) {
		return false;
	}
	return is_on_list (grp->gr_mem, username);
}
/* Checks if a user is a member of a group */
static int is_on_group(const char *user_name, const char *group_name)
{
    struct passwd *pwd;
    struct group *grp, *pgrp;
    char uname[LINE_LENGTH], gname[LINE_LENGTH];
    
    if (!strlen(user_name))
        return 0;
    if (!strlen(group_name))
        return 0;
    memset(uname, 0, sizeof(uname));
    strncpy(uname, user_name, LINE_LENGTH);
    memset(gname, 0, sizeof(gname));
    strncpy(gname, group_name, LINE_LENGTH);
        
    setpwent();
    pwd = getpwnam(uname);
    endpwent();
    if (!pwd)
        return 0;

    /* the info about this group */
    setgrent();
    grp = getgrnam(gname);
    endgrent();
    if (!grp)
        return 0;
    
    /* first check: is a member of the group_name group ? */
    if (is_on_list(grp->gr_mem, uname))
        return 1;

    /* next check: user primary group is group_name ? */
    setgrent();
    pgrp = getgrgid(pwd->pw_gid);
    endgrent();
    if (!pgrp)
        return 0;
    if (!strcmp(pgrp->gr_name, gname))
        return 1;
        
    return 0;
}
Exemple #6
0
/*
 * gpasswd - administer the /etc/group file
 */
int main (int argc, char **argv)
{
	struct group grent;
#ifdef SHADOWGRP
	struct sgrp sgent;
#endif
	struct passwd *pw = NULL;

#ifdef WITH_AUDIT
	audit_help_open ();
#endif

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

	/*
	 * Make a note of whether or not this command was invoked by root.
	 * This will be used to bypass certain checks later on. Also, set
	 * the real user ID to match the effective user ID. This will
	 * prevent the invoker from issuing signals which would interfere
	 * with this command.
	 */
	bywho = getuid ();
	Prog = Basename (argv[0]);

	OPENLOG ("gpasswd");
	setbuf (stdout, NULL);
	setbuf (stderr, NULL);

#ifdef SHADOWGRP
	is_shadowgrp = sgr_file_present ();
#endif

	/*
	 * Determine the name of the user that invoked this command. This
	 * is really hit or miss because there are so many ways that command
	 * can be executed and so many ways to trip up the routines that
	 * report the user name.
	 */
	pw = get_my_pwent ();
	if (NULL == pw) {
		fprintf (stderr, _("%s: Cannot determine your user name.\n"),
		         Prog);
		SYSLOG ((LOG_WARN,
		         "Cannot determine the user name of the caller (UID %lu)",
		         (unsigned long) getuid ()));
		exit (E_NOPERM);
	}
	myname = xstrdup (pw->pw_name);

	/*
	 * Register an exit function to warn for any inconsistency that we
	 * could create.
	 */
	if (atexit (do_cleanups) != 0) {
		fprintf(stderr, "%s: cannot set exit function\n", Prog);
		exit (1);
	}

	/* Parse the options */
	process_flags (argc, argv);

	/*
	 * Replicate the group so it can be modified later on.
	 */
#ifdef SHADOWGRP
	get_group (&grent, &sgent);
#else
	get_group (&grent);
#endif

	/*
	 * Check if the user is allowed to change the password of this group.
	 */
#ifdef SHADOWGRP
	check_perms (&grent, &sgent);
#else
	check_perms (&grent);
#endif

	/*
	 * Removing a password is straight forward. Just set the password
	 * field to a "".
	 */
	if (rflg) {
		grent.gr_passwd = "";	/* XXX warning: const */
#ifdef SHADOWGRP
		sgent.sg_passwd = "";	/* XXX warning: const */
#endif
		goto output;
	} else if (Rflg) {
		/*
		 * Same thing for restricting the group. Set the password
		 * field to "!".
		 */
		grent.gr_passwd = "!";	/* XXX warning: const */
#ifdef SHADOWGRP
		sgent.sg_passwd = "!";	/* XXX warning: const */
#endif
		goto output;
	}

	/*
	 * Adding a member to a member list is pretty straightforward as
	 * well. Call the appropriate routine and split.
	 */
	if (aflg) {
		printf (_("Adding user %s to group %s\n"), user, group);
		grent.gr_mem = add_list (grent.gr_mem, user);
#ifdef SHADOWGRP
		if (is_shadowgrp) {
			sgent.sg_mem = add_list (sgent.sg_mem, user);
		}
#endif
		goto output;
	}

	/*
	 * Removing a member from the member list is the same deal as adding
	 * one, except the routine is different.
	 */
	if (dflg) {
		bool removed = false;

		printf (_("Removing user %s from group %s\n"), user, group);

		if (is_on_list (grent.gr_mem, user)) {
			removed = true;
			grent.gr_mem = del_list (grent.gr_mem, user);
		}
#ifdef SHADOWGRP
		if (is_shadowgrp) {
			if (is_on_list (sgent.sg_mem, user)) {
				removed = true;
				sgent.sg_mem = del_list (sgent.sg_mem, user);
			}
		}
#endif
		if (!removed) {
			fprintf (stderr,
			         _("%s: user '%s' is not a member of '%s'\n"),
			         Prog, user, group);
			exit (E_BAD_ARG);
		}
		goto output;
	}
#ifdef SHADOWGRP
	/*
	 * Replacing the entire list of administrators is simple. Check the
	 * list to make sure everyone is a real user. Then slap the new list
	 * in place.
	 */
	if (Aflg) {
		sgent.sg_adm = comma_to_list (admins);
		if (!Mflg) {
			goto output;
		}
	}
#endif				/* SHADOWGRP */

	/*
	 * Replacing the entire list of members is simple. Check the list to
	 * make sure everyone is a real user. Then slap the new list in
	 * place.
	 */
	if (Mflg) {
#ifdef SHADOWGRP
		sgent.sg_mem = comma_to_list (members);
#endif
		grent.gr_mem = comma_to_list (members);
		goto output;
	}

	/*
	 * If the password is being changed, the input and output must both
	 * be a tty. The typical keyboard signals are caught so the termio
	 * modes can be restored.
	 */
	if ((isatty (0) == 0) || (isatty (1) == 0)) {
		fprintf (stderr, _("%s: Not a tty\n"), Prog);
		exit (E_NOPERM);
	}

	catch_signals (0);	/* save tty modes */

	(void) signal (SIGHUP, catch_signals);
	(void) signal (SIGINT, catch_signals);
	(void) signal (SIGQUIT, catch_signals);
	(void) signal (SIGTERM, catch_signals);
#ifdef SIGTSTP
	(void) signal (SIGTSTP, catch_signals);
#endif

	/* Prompt for the new password */
#ifdef SHADOWGRP
	change_passwd (&grent, &sgent);
#else
	change_passwd (&grent);
#endif

	/*
	 * This is the common arrival point to output the new group file.
	 * The freshly crafted entry is in allocated space. The group file
	 * will be locked and opened for writing. The new entry will be
	 * output, etc.
	 */
      output:
	if (setuid (0) != 0) {
		fputs (_("Cannot change ID to root.\n"), stderr);
		SYSLOG ((LOG_ERR, "can't setuid(0)"));
		closelog ();
		exit (E_NOPERM);
	}
	pwd_init ();

	open_files ();

#ifdef SHADOWGRP
	update_group (&grent, &sgent);
#else
	update_group (&grent);
#endif

	close_files ();

	nscd_flush_cache ("group");

	exit (E_SUCCESS);
}
Exemple #7
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;
}
Exemple #8
0
static int update_group (void)
{
	int is_member;
	int was_member;
	int changed;
	const struct group *grp;
	struct group *ngrp;

	/*
	 * Lock and open the group file. This will load all of the group
	 * entries.
	 */
	if (!gr_lock ()) {
		fprintf (stderr, _("%s: error locking group file\n"),
			 Prog);
		SYSLOG ((LOG_ERR, "error locking group file"));
		return -1;
	}
	if (!gr_open (O_RDWR)) {
		fprintf (stderr, _("%s: error opening group file\n"),
			 Prog);
		SYSLOG ((LOG_ERR, "error opening group file"));
		gr_unlock ();
		return -1;
	}

	changed = 0;

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

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

		if (!was_member && !is_member)
			continue;

		ngrp = __gr_dup (grp);
		if (!ngrp) {
			fprintf (stderr,
				 _("%s: out of memory in update_group\n"),
				 Prog);
			gr_unlock ();
			return -1;
		}

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

		changed = 0;
		if (!gr_update (ngrp)) {
			fprintf (stderr,
				 _("%s: error adding new group entry\n"),
				 Prog);
			SYSLOG ((LOG_ERR, "error adding group entry"));
			gr_unlock ();
			return -1;
		}
#ifdef	NDBM
		/*
		 * Update the DBM group file with the new entry as well.
		 */
		if (!gr_dbm_update (ngrp)) {
			fprintf (stderr,
				 _("%s: cannot add new dbm group entry\n"),
				 Prog);
			SYSLOG ((LOG_ERR, "error adding dbm group entry"));
			gr_unlock ();
			return -1;
		}
#endif				/* NDBM */
	}
#ifdef NDBM
	endgrent ();
#endif				/* NDBM */
	if (!gr_close ()) {
		fprintf (stderr, _("%s: cannot rewrite group file\n"),
			 Prog);
		gr_unlock ();
		return -1;
	}
	gr_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 */
}
PAM_EXTERN
int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
			,const char **argv)
{
     int ctrl;
     const char *username;
     char *fromsu;
     struct passwd *pwd, *tpwd;
     struct group *grp;
     int retval = PAM_AUTH_ERR;
     char use_group[BUFSIZ];
    
     /* Init the optional group */
     bzero(use_group,BUFSIZ);
     
     ctrl = _pam_parse(argc, argv, use_group);
     retval = pam_get_user(pamh,&username,NULL);
     if ((retval != PAM_SUCCESS) || (!username)) {
        if (ctrl & PAM_DEBUG_ARG)
            _pam_log(LOG_DEBUG,"can not get the username");
        return PAM_SERVICE_ERR;
     }

     /* su to a uid 0 account ? */
     pwd = getpwnam(username);
     if (!pwd) {
        if (ctrl & PAM_DEBUG_ARG)
            _pam_log(LOG_NOTICE,"unknown user %s",username);
        return PAM_USER_UNKNOWN;
     }
     
     /* Now we know that the username exists, pass on to other modules...
      * the call to pam_get_user made this obsolete, so is commented out
      *
      * pam_set_item(pamh,PAM_USER,(const void *)username);
      */

     /* is this user an UID 0 account ? */
     if(pwd->pw_uid) {
        /* no need to check for wheel */
        return PAM_IGNORE;
     }
     
     if (ctrl & PAM_USE_UID_ARG) {
         tpwd = getpwuid(getuid());
         if (!tpwd) {
            if (ctrl & PAM_DEBUG_ARG)
                _pam_log(LOG_NOTICE,"who is running me ?!");
            return PAM_SERVICE_ERR;
         }
         fromsu = tpwd->pw_name;
     } else {
         fromsu = getlogin();
         if (!fromsu) {
             if (ctrl & PAM_DEBUG_ARG)
                _pam_log(LOG_NOTICE,"who is running me ?!");
             return PAM_SERVICE_ERR;
         }
     }
     
     if (!use_group[0]) {
	 if ((grp = getgrnam("wheel")) == NULL) {
	     grp = getgrgid(0);
	 }
     } else
	 grp = getgrnam(use_group);
        
     if (!grp || !grp->gr_mem) {
        if (ctrl & PAM_DEBUG_ARG) {
            if (!use_group[0])
                _pam_log(LOG_NOTICE,"no members in a GID 0 group");
            else
                _pam_log(LOG_NOTICE,"no members in '%s' group",use_group);
        }
        if (ctrl & PAM_DENY_ARG)
            /* if this was meant to deny access to the members
             * of this group and the group does not exist, allow
             * access
             */
            return PAM_IGNORE;
        else
            return PAM_AUTH_ERR;
     }
        
     if (is_on_list(grp->gr_mem, fromsu)) {
        if (ctrl & PAM_DEBUG_ARG)
            _pam_log(LOG_NOTICE,"Access %s to '%s' for '%s'",
                     (ctrl & PAM_DENY_ARG)?"denied":"granted",
                     fromsu,username);
        if (ctrl & PAM_DENY_ARG)
            return PAM_PERM_DENIED;
        else
            if (ctrl & PAM_TRUST_ARG)
                return PAM_SUCCESS;
            else
                return PAM_IGNORE;
     }

     if (ctrl & PAM_DEBUG_ARG)
        _pam_log(LOG_NOTICE,"Access %s for '%s' to '%s'",
        (ctrl & PAM_DENY_ARG)?"granted":"denied",fromsu,username);
     if (ctrl & PAM_DENY_ARG)
        return PAM_SUCCESS;
     else
        return PAM_PERM_DENIED;
}
Exemple #11
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 #12
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 */
}