Commit 8b5261a9 authored by Mike Hibler's avatar Mike Hibler

Patches for 10.0 and 10.1 release to deal with "pw" bugs.

Fixes issue with user appearing multiple times on a /etc/group line.
parent 137fa49e
diff -Nur src-10.0/lib/libutil/fparseln.c src/lib/libutil/fparseln.c
--- src-10.0/lib/libutil/fparseln.c 2015-01-19 14:26:13.000000000 -0700
+++ src/lib/libutil/fparseln.c 2014-08-16 03:18:25.000000000 -0600
@@ -1,4 +1,4 @@
-/* $NetBSD: fparseln.c,v 1.9 1999/09/20 04:48:06 lukem Exp $ */
+/* $NetBSD: fparseln.c,v 1.7 2007/03/08 19:57:53 drochner Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: releng/10.0/lib/libutil/fparseln.c 121193 2003-10-18 10:04:16Z markm $");
+__FBSDID("$FreeBSD: stable/10/lib/libutil/fparseln.c 270031 2014-08-16 00:54:56Z pfg $");
#include <sys/types.h>
#include <assert.h>
@@ -59,7 +59,7 @@
/* No escape character */
if (esc == '\0')
- return 1;
+ return 0;
/* Count the number of escape characters that precede ours */
for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++)
@@ -135,13 +135,19 @@
cp = &ptr[s - 1];
if (*cp == con && !isescaped(ptr, cp, esc)) {
- s--; /* forget escape */
+ s--; /* forget continuation char */
cnt = 1;
}
}
- if (s == 0 && buf != NULL)
- continue;
+ if (s == 0) {
+ /*
+ * nothing to add, skip realloc except in case
+ * we need a minimal buf to return an empty line
+ */
+ if (cnt || buf != NULL)
+ continue;
+ }
if ((cp = realloc(buf, len + s + 1)) == NULL) {
free(buf);
diff -Nur src-10.0/lib/libutil/gr_util.c src/lib/libutil/gr_util.c
--- src-10.0/lib/libutil/gr_util.c 2015-01-19 14:26:13.000000000 -0700
+++ src/lib/libutil/gr_util.c 2014-11-04 03:13:42.000000000 -0700
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: releng/10.0/lib/libutil/gr_util.c 248102 2013-03-09 13:30:06Z db $");
+__FBSDID("$FreeBSD: stable/10/lib/libutil/gr_util.c 274082 2014-11-04 07:50:48Z bapt $");
#include <sys/param.h>
#include <sys/errno.h>
@@ -170,14 +170,21 @@
size_t len;
int eof, readlen;
- sgr = gr;
+ if (old_gr == NULL && gr == NULL)
+ return(-1);
+
+ sgr = old_gr;
+ /* deleting a group */
if (gr == NULL) {
line = NULL;
- if (old_gr == NULL)
+ } else {
+ if ((line = gr_make(gr)) == NULL)
return (-1);
- sgr = old_gr;
- } else if ((line = gr_make(gr)) == NULL)
- return (-1);
+ }
+
+ /* adding a group */
+ if (sgr == NULL)
+ sgr = gr;
eof = 0;
len = 0;
diff -Nur src-10.0/usr.sbin/pw/pw.h src/usr.sbin/pw/pw.h
--- src-10.0/usr.sbin/pw/pw.h 2015-01-19 14:26:07.000000000 -0700
+++ src/usr.sbin/pw/pw.h 2014-07-07 03:13:46.000000000 -0600
@@ -23,9 +23,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: releng/10.0/usr.sbin/pw/pw.h 242349 2012-10-30 08:00:53Z bapt $
+ * $FreeBSD: stable/10/usr.sbin/pw/pw.h 268346 2014-07-06 23:24:06Z bapt $
*/
+#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff -Nur src-10.0/usr.sbin/pw/pw_conf.c src/usr.sbin/pw/pw_conf.c
--- src-10.0/usr.sbin/pw/pw_conf.c 2015-01-19 14:26:07.000000000 -0700
+++ src/usr.sbin/pw/pw_conf.c 2014-07-07 03:13:46.000000000 -0600
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: releng/10.0/usr.sbin/pw/pw_conf.c 219408 2011-03-08 20:13:29Z jkim $";
+ "$FreeBSD: stable/10/usr.sbin/pw/pw_conf.c 268346 2014-07-06 23:24:06Z bapt $";
#endif /* not lint */
#include <string.h>
@@ -226,35 +226,21 @@
struct userconf *
read_userconfig(char const * file)
{
- FILE *fp;
+ FILE *fp;
+ char *buf, *p;
+ size_t linecap;
+ ssize_t linelen;
+
+ buf = NULL;
+ linecap = 0;
extendarray(&config.groups, &config.numgroups, 200);
memset(config.groups, 0, config.numgroups * sizeof(char *));
if (file == NULL)
file = _PATH_PW_CONF;
- if ((fp = fopen(file, "r")) != NULL) {
- int buflen = LNBUFSZ;
- char *buf = malloc(buflen);
-
- nextline:
- while (fgets(buf, buflen, fp) != NULL) {
- char *p;
-
- while ((p = strchr(buf, '\n')) == NULL) {
- int l;
- if (extendline(&buf, &buflen, buflen + LNBUFSZ) == -1) {
- int ch;
- while ((ch = fgetc(fp)) != '\n' && ch != EOF);
- goto nextline; /* Ignore it */
- }
- l = strlen(buf);
- if (fgets(buf + l, buflen - l, fp) == NULL)
- break; /* Unterminated last line */
- }
-
- if (p != NULL)
- *p = '\0';
+ if ((fp = fopen(file, "r")) != NULL) {
+ while ((linelen = getline(&buf, &linecap, fp)) > 0) {
if (*buf && (p = strtok(buf, " \t\r\n=")) != NULL && *p != '#') {
static char const toks[] = " \t\r\n,=";
char *q = strtok(NULL, toks);
@@ -368,7 +354,8 @@
}
}
}
- free(buf);
+ if (linecap > 0)
+ free(buf);
fclose(fp);
}
return &config;
diff -Nur src-10.0/usr.sbin/pw/pw_group.c src/usr.sbin/pw/pw_group.c
--- src-10.0/usr.sbin/pw/pw_group.c 2015-01-19 14:26:07.000000000 -0700
+++ src/usr.sbin/pw/pw_group.c 2014-11-04 03:13:42.000000000 -0700
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: releng/10.0/usr.sbin/pw/pw_group.c 244738 2012-12-27 14:44:13Z bapt $";
+ "$FreeBSD: stable/10/usr.sbin/pw/pw_group.c 274082 2014-11-04 07:50:48Z bapt $";
#endif /* not lint */
#include <ctype.h>
@@ -51,6 +51,7 @@
pw_group(struct userconf * cnf, int mode, struct cargs * args)
{
int rc;
+ struct carg *a_newname = getarg(args, 'l');
struct carg *a_name = getarg(args, 'n');
struct carg *a_gid = getarg(args, 'g');
struct carg *arg;
@@ -66,6 +67,11 @@
NULL
};
+ if (a_gid != NULL) {
+ if (strspn(a_gid->val, "0123456789") != strlen(a_gid->val))
+ errx(EX_USAGE, "-g expects a number");
+ }
+
if (mode == M_LOCK || mode == M_UNLOCK)
errx(EX_USAGE, "'lock' command is not available for groups");
@@ -140,8 +146,8 @@
if (a_gid)
grp->gr_gid = (gid_t) atoi(a_gid->val);
- if ((arg = getarg(args, 'l')) != NULL)
- grp->gr_name = pw_checkname((u_char *)arg->val, 0);
+ if (a_newname != NULL)
+ grp->gr_name = pw_checkname((u_char *)a_newname->val, 0);
} else {
if (a_name == NULL) /* Required */
errx(EX_DATAERR, "group name required");
@@ -227,10 +233,12 @@
else if (arg->ch == 'm') {
int k = 0;
- while (grp->gr_mem[k] != NULL) {
- if (extendarray(&members, &grmembers, i + 2) != -1)
- members[i++] = grp->gr_mem[k];
- k++;
+ if (grp->gr_mem != NULL) {
+ while (grp->gr_mem[k] != NULL) {
+ if (extendarray(&members, &grmembers, i + 2) != -1)
+ members[i++] = grp->gr_mem[k];
+ k++;
+ }
}
}
@@ -268,8 +276,10 @@
warn("group update");
return EX_IOERR;
}
+
+ arg = a_newname != NULL ? a_newname : a_name;
/* grp may have been invalidated */
- if ((grp = GETGRNAM(a_name->val)) == NULL)
+ if ((grp = GETGRNAM(arg->val)) == NULL)
errx(EX_SOFTWARE, "group disappeared during update");
pw_log(cnf, mode, W_GROUP, "%s(%ld)", grp->gr_name, (long) grp->gr_gid);
@@ -311,6 +321,9 @@
int k;
struct passwd *pwd;
+ if (grp->gr_mem == NULL)
+ return;
+
k = 0;
while (grp->gr_mem[k] != NULL) {
matchFound = false;
@@ -415,8 +428,10 @@
printf("Group Name: %-15s #%lu\n"
" Members: ",
grp->gr_name, (long) grp->gr_gid);
- for (i = 0; grp->gr_mem[i]; i++)
- printf("%s%s", i ? "," : "", grp->gr_mem[i]);
+ if (grp->gr_mem != NULL) {
+ for (i = 0; grp->gr_mem[i]; i++)
+ printf("%s%s", i ? "," : "", grp->gr_mem[i]);
+ }
fputs("\n\n", stdout);
}
return EXIT_SUCCESS;
diff -Nur src-10.0/usr.sbin/pw/pw_user.c src/usr.sbin/pw/pw_user.c
--- src-10.0/usr.sbin/pw/pw_user.c 2015-01-19 14:26:07.000000000 -0700
+++ src/usr.sbin/pw/pw_user.c 2015-01-19 17:11:53.000000000 -0700
@@ -27,7 +27,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: releng/10.0/usr.sbin/pw/pw_user.c 252688 2013-07-04 07:59:11Z des $";
+ "$FreeBSD: stable/10/usr.sbin/pw/pw_user.c 274082 2014-11-04 07:50:48Z bapt $";
#endif /* not lint */
#include <ctype.h>
@@ -321,6 +321,9 @@
(a_uid = a_name)->ch = 'u';
a_name = NULL;
}
+ } else {
+ if (strspn(a_uid->val, "0123456789") != strlen(a_uid->val))
+ errx(EX_USAGE, "-u expects a number");
}
/*
@@ -380,6 +383,8 @@
char file[MAXPATHLEN];
char home[MAXPATHLEN];
uid_t uid = pwd->pw_uid;
+ struct group *gr;
+ char grname[LOGNAMESIZE];
if (strcmp(pwd->pw_name, "root") == 0)
errx(EX_DATAERR, "cannot remove user 'root'");
@@ -406,6 +411,11 @@
*/
sprintf(file, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
strlcpy(home, pwd->pw_dir, sizeof(home));
+ gr = GETGRGID(pwd->pw_gid);
+ if (gr != NULL)
+ strlcpy(grname, gr->gr_name, LOGNAMESIZE);
+ else
+ grname[0] = '\0';
rc = delpwent(pwd);
if (rc == -1)
@@ -425,19 +435,22 @@
}
grp = GETGRNAM(a_name->val);
- if (grp != NULL && *grp->gr_mem == NULL)
+ if (grp != NULL &&
+ (grp->gr_mem == NULL || *grp->gr_mem == NULL) &&
+ strcmp(a_name->val, grname) == 0)
delgrent(GETGRNAM(a_name->val));
SETGRENT();
while ((grp = GETGRENT()) != NULL) {
- int i;
+ int i, j;
char group[MAXLOGNAME];
- for (i = 0; grp->gr_mem[i] != NULL; i++) {
- if (!strcmp(grp->gr_mem[i], a_name->val)) {
- while (grp->gr_mem[i] != NULL) {
- grp->gr_mem[i] = grp->gr_mem[i+1];
- }
- strlcpy(group, grp->gr_name, MAXLOGNAME);
- chggrent(group, grp);
+ if (grp->gr_mem != NULL) {
+ for (i = 0; grp->gr_mem[i] != NULL; i++) {
+ if (!strcmp(grp->gr_mem[i], a_name->val)) {
+ for (j = i; grp->gr_mem[j] != NULL; j++)
+ grp->gr_mem[j] = grp->gr_mem[j+1];
+ strlcpy(group, grp->gr_name, MAXLOGNAME);
+ chggrent(group, grp);
+ }
}
}
}
@@ -741,7 +754,25 @@
*/
if (mode == M_ADD || getarg(args, 'G') != NULL) {
- int i;
+ int i, j;
+ /* First remove the user from all group */
+ SETGRENT();
+ while ((grp = GETGRENT()) != NULL) {
+ char group[MAXLOGNAME];
+ if (grp->gr_mem == NULL)
+ continue;
+ for (i = 0; grp->gr_mem[i] != NULL; i++) {
+ if (strcmp(grp->gr_mem[i] , pwd->pw_name) != 0)
+ continue;
+ for (j = i; grp->gr_mem[j] != NULL ; j++)
+ grp->gr_mem[j] = grp->gr_mem[j+1];
+ strlcpy(group, grp->gr_name, MAXLOGNAME);
+ chggrent(group, grp);
+ }
+ }
+ ENDGRENT();
+
+ /* now add to group where needed */
for (i = 0; cnf->groups[i] != NULL; i++) {
grp = GETGRNAM(cnf->groups[i]);
grp = gr_add(grp, pwd->pw_name);
@@ -908,7 +939,8 @@
errx(EX_NOUSER, "group `%s' is not defined", a_gid->val);
}
gid = grp->gr_gid;
- } else if ((grp = GETGRNAM(nam)) != NULL && grp->gr_mem[0] == NULL) {
+ } else if ((grp = GETGRNAM(nam)) != NULL &&
+ (grp->gr_mem == NULL || grp->gr_mem[0] == NULL)) {
gid = grp->gr_gid; /* Already created? Use it anyway... */
} else {
struct cargs grpargs;
@@ -1182,14 +1214,16 @@
while ((grp=GETGRENT()) != NULL)
{
int i = 0;
- while (grp->gr_mem[i] != NULL)
- {
- if (strcmp(grp->gr_mem[i], pwd->pw_name)==0)
+ if (grp->gr_mem != NULL) {
+ while (grp->gr_mem[i] != NULL)
{
- printf(j++ == 0 ? " Groups: %s" : ",%s", grp->gr_name);
- break;
+ if (strcmp(grp->gr_mem[i], pwd->pw_name)==0)
+ {
+ printf(j++ == 0 ? " Groups: %s" : ",%s", grp->gr_name);
+ break;
+ }
+ ++i;
}
- ++i;
}
}
ENDGRENT();
diff -Nur src-10.0/usr.sbin/pw/pwupd.c src/usr.sbin/pw/pwupd.c
--- src-10.0/usr.sbin/pw/pwupd.c 2015-01-19 14:26:07.000000000 -0700
+++ src/usr.sbin/pw/pwupd.c 2014-07-07 03:13:46.000000000 -0600
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: releng/10.0/usr.sbin/pw/pwupd.c 244711 2012-12-26 18:28:17Z bapt $";
+ "$FreeBSD: stable/10/usr.sbin/pw/pwupd.c 268346 2014-07-06 23:24:06Z bapt $";
#endif /* not lint */
#include <stdio.h>
@@ -45,9 +45,6 @@
#include "pwupd.h"
-#define HAVE_PWDB_C 1
-#define HAVE_PWDB_U 1
-
static char pathpwd[] = _PATH_PWD;
static char * pwpath = pathpwd;
@@ -112,22 +109,14 @@
{
int rc = 0;
- /*
- * First, let's check the see if the database is alright
- * Note: -C is only available in FreeBSD 2.2 and above
- */
-#ifdef HAVE_PWDB_C
rc = pwdb("-C", (char *)NULL); /* Check only */
if (rc == 0) {
-#else
- { /* No -C */
-#endif
int pfd, tfd;
struct passwd *pw = NULL;
struct passwd *old_pw = NULL;
- if (pwd != NULL)
- pw = pw_dup(pwd);
+ if (pwd != NULL)
+ pw = pw_dup(pwd);
if (user != NULL)
old_pw = GETPWNAM(user);
@@ -150,7 +139,7 @@
* in case of deletion of a user, the whole database
* needs to be regenerated
*/
- if (pw_mkdb(pw != NULL ? user : NULL) == -1) {
+ if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) {
pw_fini();
err(1, "pw_mkdb()");
}
diff -Nu pw.orig/pw_user.c pw/pw_user.c
--- pw.orig/pw_user.c 2014-11-11 13:02:22.000000000 -0700
+++ pw/pw_user.c 2015-01-14 22:56:15.000000000 -0700
@@ -754,6 +754,15 @@
int i;
for (i = 0; cnf->groups[i] != NULL; i++) {
grp = GETGRNAM(cnf->groups[i]);
+ /* already on the list? */
+ if (grp->gr_mem != NULL) {
+ int j;
+ for (j = 0; grp->gr_mem[j] != NULL; j++)
+ if (!strcmp(pwd->pw_name, grp->gr_mem[j]))
+ break;
+ if (grp->gr_mem[j])
+ continue;
+ }
grp = gr_add(grp, pwd->pw_name);
/*
* grp can only be NULL in 2 cases:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment