summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pw
diff options
context:
space:
mode:
authordteske <dteske@FreeBSD.org>2014-09-26 23:01:27 +0000
committerdteske <dteske@FreeBSD.org>2014-09-26 23:01:27 +0000
commit786740ec0a6b6304a2be2aa662715d20352cdc45 (patch)
tree07dba38583c97fd2bd801f7ca0921444373bcf86 /usr.sbin/pw
parentb381042f0d278d89c806f97c50b8c888d0922d94 (diff)
downloadFreeBSD-src-786740ec0a6b6304a2be2aa662715d20352cdc45.zip
FreeBSD-src-786740ec0a6b6304a2be2aa662715d20352cdc45.tar.gz
MFC revisions 262864-262865, 263114, 267970:
r262864: Stop pw(8) from segfaulting when given certain input (julian) r262865: Part 2 of bug 187310 (julian) r263114: Fix pw(8) edge-case deletion of group "username" on userdel r267970: Fix infinite-loop during deletion of users from groups PR: 187310, 169471, 191427 Submitted by: Voradesh Yenbut, Alexander Pyhalov, Kim Shrier Obtained from: bug Approved by: re (gjb)
Diffstat (limited to 'usr.sbin/pw')
-rw-r--r--usr.sbin/pw/pw_group.c19
-rw-r--r--usr.sbin/pw/pw_user.c45
2 files changed, 42 insertions, 22 deletions
diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c
index 3259412..391e477 100644
--- a/usr.sbin/pw/pw_group.c
+++ b/usr.sbin/pw/pw_group.c
@@ -227,10 +227,12 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
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++;
+ }
}
}
@@ -311,6 +313,9 @@ delete_members(char ***members, int *grmembers, int *i, struct carg *arg,
int k;
struct passwd *pwd;
+ if (grp->gr_mem == NULL)
+ return;
+
k = 0;
while (grp->gr_mem[k] != NULL) {
matchFound = false;
@@ -415,8 +420,10 @@ print_group(struct group * grp, int pretty)
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 --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index def238c..36c5d9d 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -380,6 +380,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
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 +408,11 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
*/
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 +432,22 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
}
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);
+ }
}
}
}
@@ -908,7 +918,8 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer
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 +1193,16 @@ print_user(struct passwd * pwd, int pretty, int v7)
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();
OpenPOWER on IntegriCloud