From sean@farley.org  Thu Jun  9 01:07:26 2005
Return-Path: <sean@farley.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 1873616A41C
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  9 Jun 2005 01:07:26 +0000 (GMT)
	(envelope-from sean@farley.org)
Received: from mail.farley.org (farley.org [67.64.95.201])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 9E94443D1D
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  9 Jun 2005 01:07:21 +0000 (GMT)
	(envelope-from sean@farley.org)
Received: from thor.farley.org (thor.farley.org [IPv6:2001:470:1f01:290:1::5])
	by mail.farley.org (8.13.1/8.13.1) with ESMTP id j5917JWO053478
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 8 Jun 2005 20:07:19 -0500 (CDT)
	(envelope-from sean@gw.farley.org)
Received: from thor.farley.org (localhost [127.0.0.1])
	by thor.farley.org (8.13.3/8.13.3) with ESMTP id j5917YIU020540
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 8 Jun 2005 20:07:34 -0500 (CDT)
	(envelope-from sean@thor.farley.org)
Received: (from sean@localhost)
	by thor.farley.org (8.13.3/8.13.3/Submit) id j5917YJx020539;
	Wed, 8 Jun 2005 20:07:34 -0500 (CDT)
	(envelope-from sean)
Message-Id: <200506090107.j5917YJx020539@thor.farley.org>
Date: Wed, 8 Jun 2005 20:07:34 -0500 (CDT)
From: Sen Farley <sean-freebsd@farley.org>
Reply-To: Sen Farley <sean-freebsd@farley.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [PATCH] Ability for pw groupmod to delete members
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         82058
>Category:       bin
>Synopsis:       [PATCH] Ability for pw groupmod to delete members
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    scf
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 09 01:10:08 GMT 2005
>Closed-Date:    Thu Feb 28 18:27:03 CST 2008
>Last-Modified:  Thu Feb 28 18:27:03 CST 2008
>Originator:     Sen Farley
>Release:        FreeBSD 5.4-STABLE i386
>Organization:
>Environment:
System: FreeBSD thor.farley.org 5.4-STABLE FreeBSD 5.4-STABLE #2: Fri Jun 3 08:54:24 CDT 2005 root@thor.farley.org:/usr/obj/usr/src/sys/THOR i386

>Description:
pw has the ability to add to a group's members with the -m flag.  I
wrote a patch to give it the ability to delete specified group members
using the -d flag.

>How-To-Repeat:
Example to add member1 and member2 to group1's member list:
pw groupmod group1 -d member1,member2

>Fix:
This patch can also be found here:
http://www.farley.org/freebsd/tmp/pw.patch

diff -u /usr/src/usr.sbin/pw/pw.8 ./pw.8
--- /usr/src/usr.sbin/pw/pw.8	Fri Jul  2 18:12:54 2004
+++ ./pw.8	Wed Jun  8 19:51:57 2005
@@ -152,6 +152,7 @@
 .Op Fl l Ar name
 .Op Fl M Ar members
 .Op Fl m Ar newmembers
+.Op Fl d Ar oldmembers
 .Op Fl h Ar fd | Fl H Ar fd
 .Op Fl N
 .Op Fl P
@@ -754,6 +755,15 @@
 .Fl M ,
 this option allows the
 .Em addition
+of existing users to a group without replacing the existing list of
+members.
+Login names or user ids may be used, and duplicate users are
+silently eliminated.
+.It Fl d Ar oldmembers
+Similar to
+.Fl M ,
+this option allows the
+.Em deletion
 of existing users to a group without replacing the existing list of
 members.
 Login names or user ids may be used, and duplicate users are
diff -u /usr/src/usr.sbin/pw/pw.c ./pw.c
--- /usr/src/usr.sbin/pw/pw.c	Sun Jan 11 12:28:08 2004
+++ ./pw.c	Wed Jun  8 19:51:57 2005
@@ -117,7 +117,7 @@
 		{ /* grp  */
 			"V:C:qn:g:h:H:M:pNPY",
 			"V:C:qn:g:Y",
-			"V:C:qn:g:l:h:H:FM:m:NPY",
+			"V:C:qn:d:g:l:h:H:FM:m:NPY",
 			"V:C:qn:g:FPa",
 			"V:C:q"
 		 }
diff -u /usr/src/usr.sbin/pw/pw_group.c ./pw_group.c
--- /usr/src/usr.sbin/pw/pw_group.c	Sun Jan 11 12:28:08 2004
+++ ./pw_group.c	Wed Jun  8 19:51:57 2005
@@ -207,37 +207,55 @@
 		}
 	}
 
-	if (((arg = getarg(args, 'M')) != NULL || (arg = getarg(args, 'm')) != NULL) && arg->val) {
+	if (((arg = getarg(args, 'M')) != NULL ||
+	    (arg = getarg(args, 'd')) != NULL ||
+	    (arg = getarg(args, 'm')) != NULL) && arg->val) {
 		int	i = 0;
 		char   *p;
 		struct passwd	*pwd;
 
 		/* Make sure this is not stay NULL with -M "" */
 		extendarray(&members, &grmembers, 200);
-		if (arg->ch == 'm') {
+		if (arg->ch == 'd' || arg->ch == 'm') {
 			int	k = 0;
+			int matchFound;
 
 			while (grp->gr_mem[k] != NULL) {
-				if (extendarray(&members, &grmembers, i + 2) != -1) {
-					members[i++] = grp->gr_mem[k];
+				/* Delete requested members. */
+				for (matchFound = 0,
+				    p = strtok(arg->val, ", \t"); p != NULL;
+				    p = strtok(NULL, ", \t")) {
+					if ((pwd = GETPWNAM(p)) == NULL)
+						if (!isdigit((unsigned char)*p) ||
+						    (pwd = getpwuid((uid_t) atoi(p))) == NULL)
+							errx(EX_NOUSER, "user `%s' does not exist", p);
+					if (strcmp(grp->gr_mem[k], pwd->pw_name) == 0) {
+						matchFound = 1;
+						break;
+					}
 				}
+				if (! matchFound)
+					if (extendarray(&members, &grmembers, i + 2) != -1) {
+						members[i++] = grp->gr_mem[k];
+					}
 				k++;
 			}
 		}
-		for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
-			int     j;
-			if ((pwd = GETPWNAM(p)) == NULL) {
-				if (!isdigit((unsigned char)*p) || (pwd = getpwuid((uid_t) atoi(p))) == NULL)
-					errx(EX_NOUSER, "user `%s' does not exist", p);
+		if (arg->ch != 'd')
+			for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
+				int     j;
+				if ((pwd = GETPWNAM(p)) == NULL) {
+					if (!isdigit((unsigned char)*p) || (pwd = getpwuid((uid_t) atoi(p))) == NULL)
+						errx(EX_NOUSER, "user `%s' does not exist", p);
+				}
+				/*
+				 * Check for duplicates
+				 */
+				for (j = 0; j < i && strcmp(members[j], pwd->pw_name)!=0; j++)
+					;
+				if (j == i && extendarray(&members, &grmembers, i + 2) != -1)
+					members[i++] = newstr(pwd->pw_name);
 			}
-			/*
-			 * Check for duplicates
-			 */
-			for (j = 0; j < i && strcmp(members[j], pwd->pw_name)!=0; j++)
-				;
-			if (j == i && extendarray(&members, &grmembers, i + 2) != -1)
-				members[i++] = newstr(pwd->pw_name);
-		}
 		while (i < grmembers)
 			members[i++] = NULL;
 		grp->gr_mem = members;
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->markm 
Responsible-Changed-By: markm 
Responsible-Changed-When: Wed Oct 26 11:19:32 GMT 2005 
Responsible-Changed-Why:  
Looks useful!. I'll take this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=82058 
Responsible-Changed-From-To: markm->scf 
Responsible-Changed-By: scf 
Responsible-Changed-When: Sat Aug 4 13:45:45 CDT 2007 
Responsible-Changed-Why:  
Take care of this PR by permission from markm@. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=82058 
State-Changed-From-To: open->closed 
State-Changed-By: scf 
State-Changed-When: Thu Feb 28 18:22:13 CST 2008 
State-Changed-Why:  
Closed upon the following commit (forgot to add PR to log message): 

scf         2008-02-23 01:25:22 UTC 

FreeBSD src repository 

Modified files: 
usr.sbin/pw          pw.8 pw.c pw_group.c 
Log: 
Add the groupmod '-d' option to pw to allow the deletion of existing users 
from a group without the need to perform the same operation by replacing 
the existing list via the '-M' option.  The '-M' option requires someone 
to fetch the existing members with pw, deleting the undesired members from 
the list and sending the altered list back to pw. 

Approved by:    wes (mentor) 
MFC after:      5 days 

Revision  Changes    Path 
1.43      +10 -0     src/usr.sbin/pw/pw.8 
1.33      +2 -1      src/usr.sbin/pw/pw.c 
1.16      +80 -15    src/usr.sbin/pw/pw_group.c 

http://www.freebsd.org/cgi/query-pr.cgi?pr=82058 
>Unformatted:
