From 4ab1204d48d11e3671dceb65e745429ff5ee1f9d Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Wed, 5 Dec 2012 13:56:43 +0000 Subject: Remove useless check for NULL prior to free. Approved by: cperciva MFC after: 2 weeks --- pw/bitmap.c | 3 +-- pw/pw_group.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pw/bitmap.c b/pw/bitmap.c index bcfea7e..8e96bff 100644 --- a/pw/bitmap.c +++ b/pw/bitmap.c @@ -50,8 +50,7 @@ bm_alloc(int size) void bm_dealloc(struct bitmap * bm) { - if (bm->map) - free(bm->map); + free(bm->map); } static void diff --git a/pw/pw_group.c b/pw/pw_group.c index f4f2116..fda62b2 100644 --- a/pw/pw_group.c +++ b/pw/pw_group.c @@ -274,8 +274,7 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args) pw_log(cnf, mode, W_GROUP, "%s(%ld)", grp->gr_name, (long) grp->gr_gid); - if (members) - free(members); + free(members); return EXIT_SUCCESS; } -- cgit v1.2.3-56-ge451 From 460a14f4c167f92ba6c42a33854a8a5bc5504797 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Wed, 5 Dec 2012 13:56:46 +0000 Subject: Avoid overflow of file buffer Submitted by: db Approved by: cperciva MFC after: 2 weeks --- pw/pw_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pw/pw_user.c b/pw/pw_user.c index abf1c35..23a7856 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -394,7 +394,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) /* * Remove crontabs */ - sprintf(file, "/var/cron/tabs/%s", pwd->pw_name); + snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); if (access(file, F_OK) == 0) { sprintf(file, "crontab -u %s -r", pwd->pw_name); system(file); -- cgit v1.2.3-56-ge451 From 3ed3b62bd35ad2bc1ec73c566c5b1c49b6ba8bc1 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Wed, 5 Dec 2012 13:56:49 +0000 Subject: Use strdup instead of malloc + strcpy Submitted by: db Approved by: cperciva MFC after: 2 weeks --- pw/pwupd.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pw/pwupd.c b/pw/pwupd.c index 4ab0f01..0f2df7a 100644 --- a/pw/pwupd.c +++ b/pw/pwupd.c @@ -56,12 +56,10 @@ setpwdir(const char * dir) { if (dir == NULL) return -1; - else { - char * d = malloc(strlen(dir)+1); - if (d == NULL) - return -1; - pwpath = strcpy(d, dir); - } + else + pwpath = strdup(dir); + if (pwpath == NULL) + return -1; return 0; } -- cgit v1.2.3-56-ge451 From 3d0fb3a57e72d37356b6a765070b3a2289837f77 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Wed, 5 Dec 2012 13:56:52 +0000 Subject: Avoid overflowing the file buffer Submitted by: db Approved by: cperciva MFC after: 2 weeks --- pw/rm_r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pw/rm_r.c b/pw/rm_r.c index 4ad590b..797ca9d 100644 --- a/pw/rm_r.c +++ b/pw/rm_r.c @@ -52,7 +52,7 @@ rm_r(char const * dir, uid_t uid) while ((e = readdir(d)) != NULL) { if (strcmp(e->d_name, ".") != 0 && strcmp(e->d_name, "..") != 0) { - sprintf(file, "%s/%s", dir, e->d_name); + snprintf(file, sizeof(file), "%s/%s", dir, e->d_name); if (lstat(file, &st) == 0) { /* Need symlinks, not * linked file */ if (S_ISDIR(st.st_mode)) /* Directory - recurse */ -- cgit v1.2.3-56-ge451 From 5ebc65ad1cb4dbb699e760c6a4c6b5b52efa94e0 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Wed, 5 Dec 2012 13:56:56 +0000 Subject: Simplify string duplication: use strdup instead of malloc + strcpy Submitted by: db Approved by: cperciva MFC after: 2 weeks --- pw/grupd.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pw/grupd.c b/pw/grupd.c index e9f6b5e..3f78e95 100644 --- a/pw/grupd.c +++ b/pw/grupd.c @@ -50,12 +50,11 @@ setgrdir(const char * dir) { if (dir == NULL) return -1; - else { - char * d = malloc(strlen(dir)+1); - if (d == NULL) - return -1; - grpath = strcpy(d, dir); - } + else + grpath = strdup(dir); + if (grpath == NULL) + return -1; + return 0; } -- cgit v1.2.3-56-ge451 From 228ea4032d5eee849fa8b83e5e136b3edd92e29f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 26 Dec 2012 18:14:45 +0000 Subject: Fix creating a user and adding it to a group Reported by: "Sam Fourman Jr." , dim --- pw/pw_user.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pw/pw_user.c b/pw/pw_user.c index 23a7856..7df6b85 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -747,6 +747,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (mode == M_ADD || getarg(args, 'G') != NULL) { int i, j; for (i = 0; cnf->groups[i] != NULL; i++) { + char **members; grp = GETGRNAM(cnf->groups[i]); for (j = 0; grp->gr_mem[j] != NULL; j++) { if (!strcmp(grp->gr_mem[j], pwd->pw_name)) @@ -755,15 +756,15 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (grp->gr_mem[j] != NULL) /* user already member of group */ continue; - if (j == 0) - grp->gr_mem = NULL; + members = malloc(sizeof(char *) * (j + 1)); + for (j = 0; grp->gr_mem[j] != NULL; j++) + members[j] = grp->gr_mem[j]; - grp->gr_mem = reallocf(grp->gr_mem, sizeof(*grp->gr_mem) * - (j + 2)); - - grp->gr_mem[j] = pwd->pw_name; - grp->gr_mem[j+1] = NULL; + members[j] = pwd->pw_name; + members[j+1] = NULL; + grp->gr_mem = members; chggrent(cnf->groups[i], grp); + free(members); } } -- cgit v1.2.3-56-ge451 From e8d40660fcad4c4bae334a2a7592616fa484ef3c Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 26 Dec 2012 18:28:17 +0000 Subject: In case of the deletion of a user those whole database has to be regenerated, otherwise the user planned to be deleted remain in the pwd.db while removed from the plain text password file. --- pw/pwupd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pw/pwupd.c b/pw/pwupd.c index 0f2df7a..22662db 100644 --- a/pw/pwupd.c +++ b/pw/pwupd.c @@ -146,7 +146,11 @@ pw_update(struct passwd * pwd, char const * user) pw_fini(); err(1, "pw_copy()"); } - if (pw_mkdb(user) == -1) { + /* + * in case of deletion of a user, the whole database + * needs to be regenerated + */ + if (pw_mkdb(pw != NULL ? user : NULL) == -1) { pw_fini(); err(1, "pw_mkdb()"); } -- cgit v1.2.3-56-ge451 From f5a04a9f49ff5a1dd493c135efbf0e9dde2c97d1 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 26 Dec 2012 23:14:33 +0000 Subject: Fix off-by-one error in memory allocation: j entries, one new and a null terminator is j + 2. Submitted by: Christoph Mallon --- pw/pw_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pw/pw_user.c b/pw/pw_user.c index 7df6b85..43119ed 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -756,7 +756,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (grp->gr_mem[j] != NULL) /* user already member of group */ continue; - members = malloc(sizeof(char *) * (j + 1)); + members = malloc(sizeof(char *) * (j + 2)); for (j = 0; grp->gr_mem[j] != NULL; j++) members[j] = grp->gr_mem[j]; -- cgit v1.2.3-56-ge451 From e02eb3b3d39827fc7edf6c88e3cbb481427b6484 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 26 Dec 2012 23:16:24 +0000 Subject: Simplify copying of group members by using memcpy Submitted by: Christoph Mallon --- pw/pw_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pw/pw_user.c b/pw/pw_user.c index 43119ed..74c1ef9 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -757,8 +757,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) continue; members = malloc(sizeof(char *) * (j + 2)); - for (j = 0; grp->gr_mem[j] != NULL; j++) - members[j] = grp->gr_mem[j]; + memcpy(members, grp->gr_mem, j * sizeof(*members)); members[j] = pwd->pw_name; members[j+1] = NULL; -- cgit v1.2.3-56-ge451 From 6103660c3f4ffd28a0aa58ac0ba88bfb081708cf Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 27 Dec 2012 14:35:06 +0000 Subject: Simplify the code by using the new gr_add function --- pw/pw_user.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/pw/pw_user.c b/pw/pw_user.c index 74c1ef9..5577511 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -745,25 +745,19 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ if (mode == M_ADD || getarg(args, 'G') != NULL) { - int i, j; + int i; for (i = 0; cnf->groups[i] != NULL; i++) { - char **members; grp = GETGRNAM(cnf->groups[i]); - for (j = 0; grp->gr_mem[j] != NULL; j++) { - if (!strcmp(grp->gr_mem[j], pwd->pw_name)) - break; - } - if (grp->gr_mem[j] != NULL) /* user already member of group */ + grp = gr_add(grp, pwd->pw_name); + /* + * grp can only be NULL in 2 cases: + * - the new member is already a member + * - a problem with memory occurs + * in both cases we want to skip now. + */ + if (grp == NULL) continue; - - members = malloc(sizeof(char *) * (j + 2)); - memcpy(members, grp->gr_mem, j * sizeof(*members)); - - members[j] = pwd->pw_name; - members[j+1] = NULL; - grp->gr_mem = members; chggrent(cnf->groups[i], grp); - free(members); } } -- cgit v1.2.3-56-ge451 From 74e95384fa757248d2615bbf644d34d2d5019855 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 27 Dec 2012 14:44:13 +0000 Subject: Fix a regression in "pw group show" introduced r242349: print a newline after printing each group line. PR: bin/174731 Submitted by: Jan Beich --- pw/pw_group.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pw/pw_group.c b/pw/pw_group.c index fda62b2..3259412 100644 --- a/pw/pw_group.c +++ b/pw/pw_group.c @@ -407,7 +407,7 @@ print_group(struct group * grp, int pretty) char *buf = NULL; buf = gr_make(grp); - fputs(buf, stdout); + printf("%s\n", buf); free(buf); } else { int i; -- cgit v1.2.3-56-ge451 From f5d6684c8d9c572b686c5274162e3b17ae77091f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 27 Dec 2012 19:43:29 +0000 Subject: Simplify vnextgrent and vnextpwent reusing pw_scan and gr_scan from libutil. --- pw/pw_vpw.c | 236 +++++++++++++++++------------------------------------------- 1 file changed, 67 insertions(+), 169 deletions(-) diff --git a/pw/pw_vpw.c b/pw/pw_vpw.c index 674b64f..99663be 100644 --- a/pw/pw_vpw.c +++ b/pw/pw_vpw.c @@ -30,6 +30,10 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include +#include +#include +#define _WITH_GETLINE #include #include #include @@ -55,101 +59,44 @@ vsetpwent(void) } static struct passwd * -vnextpwent(char const * nam, uid_t uid, int doclose) +vnextpwent(char const *nam, uid_t uid, int doclose) { - struct passwd * pw = NULL; - static char pwtmp[1024]; - - strlcpy(pwtmp, getpwpath(_MASTERPASSWD), sizeof(pwtmp)); - - if (pwd_fp != NULL || (pwd_fp = fopen(pwtmp, "r")) != NULL) { - int done = 0; - - static struct passwd pwd; - - while (!done && fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL) - { - int i, quickout = 0; - char * q; - char * p = strchr(pwtmp, '\n'); - - if (p == NULL) { - while (fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL && strchr(pwtmp, '\n')==NULL) - ; /* Skip long lines */ - continue; - } - - /* skip comments & empty lines */ - if (*pwtmp =='\n' || *pwtmp == '#') + struct passwd *pw; + char *line; + size_t linecap; + ssize_t linelen; + + pw = NULL; + line = NULL; + linecap = 0; + linelen = 0; + + if (pwd_fp != NULL || (pwd_fp = fopen(getpwpath(_MASTERPASSWD), "r")) != NULL) { + while ((linelen = getline(&line, &linecap, pwd_fp)) > 0) { + /* Skip comments and empty lines */ + if (*line == '\n' || *line == '#') continue; - - i = 0; - q = p = pwtmp; - bzero(&pwd, sizeof pwd); - while (!quickout && (p = strsep(&q, ":\n")) != NULL) { - switch (i++) - { - case 0: /* username */ - pwd.pw_name = p; - if (nam) { - if (strcmp(nam, p) == 0) - done = 1; - else - quickout = 1; - } - break; - case 1: /* password */ - pwd.pw_passwd = p; - break; - case 2: /* uid */ - pwd.pw_uid = atoi(p); - if (uid != (uid_t)-1) { - if (uid == pwd.pw_uid) - done = 1; - else - quickout = 1; - } - break; - case 3: /* gid */ - pwd.pw_gid = atoi(p); - break; - case 4: /* class */ - if (nam == NULL && uid == (uid_t)-1) - done = 1; - pwd.pw_class = p; - break; - case 5: /* change */ - pwd.pw_change = (time_t)atol(p); - break; - case 6: /* expire */ - pwd.pw_expire = (time_t)atol(p); - break; - case 7: /* gecos */ - pwd.pw_gecos = p; - break; - case 8: /* directory */ - pwd.pw_dir = p; - break; - case 9: /* shell */ - pwd.pw_shell = p; - break; - } - } - } + /* trim latest \n */ + if (line[linelen - 1 ] == '\n') + line[linelen - 1] = '\0'; + pw = pw_scan(line, PWSCAN_MASTER); + if (uid != (uid_t)-1) { + if (uid == pw->pw_uid) + break; + } else if (nam != NULL) { + if (strcmp(nam, pw->pw_name) == 0) + break; + } else + break; + free(pw); + pw = NULL; + } if (doclose) vendpwent(); - if (done && pwd.pw_name) { - pw = &pwd; + } + free(line); - #define CKNULL(s) s = s ? s : "" - CKNULL(pwd.pw_passwd); - CKNULL(pwd.pw_class); - CKNULL(pwd.pw_gecos); - CKNULL(pwd.pw_dir); - CKNULL(pwd.pw_shell); - } - } - return pw; + return (pw); } struct passwd * @@ -192,93 +139,44 @@ vsetgrent(void) } static struct group * -vnextgrent(char const * nam, gid_t gid, int doclose) +vnextgrent(char const *nam, gid_t gid, int doclose) { - struct group * gr = NULL; - - static char * grtmp = NULL; - static int grlen = 0; - static char ** mems = NULL; - static int memlen = 0; - - extendline(&grtmp, &grlen, MAXPATHLEN); - strlcpy(grtmp, getgrpath(_GROUP), MAXPATHLEN); - - if (grp_fp != NULL || (grp_fp = fopen(grtmp, "r")) != NULL) { - int done = 0; - - static struct group grp; - - while (!done && fgets(grtmp, grlen, grp_fp) != NULL) - { - int i, quickout = 0; - int mno = 0; - char * q, * p; - const char * sep = ":\n"; - - if ((p = strchr(grtmp, '\n')) == NULL) { - int l; - extendline(&grtmp, &grlen, grlen + PWBUFSZ); - l = strlen(grtmp); - if (fgets(grtmp + l, grlen - l, grp_fp) == NULL) - break; /* No newline terminator on last line */ - } + struct group *gr; + char *line; + size_t linecap; + ssize_t linelen; + + gr = NULL; + line = NULL; + linecap = 0; + linelen = 0; + + if (grp_fp != NULL || (grp_fp = fopen(getgrpath(_GROUP), "r")) != NULL) { + while ((linelen = getline(&line, &linecap, grp_fp)) > 0) { /* Skip comments and empty lines */ - if (*grtmp == '\n' || *grtmp == '#') + if (*line == '\n' || *line == '#') continue; - i = 0; - q = p = grtmp; - bzero(&grp, sizeof grp); - extendarray(&mems, &memlen, 200); - while (!quickout && (p = strsep(&q, sep)) != NULL) { - switch (i++) - { - case 0: /* groupname */ - grp.gr_name = p; - if (nam) { - if (strcmp(nam, p) == 0) - done = 1; - else - quickout = 1; - } - break; - case 1: /* password */ - grp.gr_passwd = p; + /* trim latest \n */ + if (line[linelen - 1 ] == '\n') + line[linelen - 1] = '\0'; + gr = gr_scan(line); + if (gid != (gid_t)-1) { + if (gid == gr->gr_gid) break; - case 2: /* gid */ - grp.gr_gid = atoi(p); - if (gid != (gid_t)-1) { - if (gid == (gid_t)grp.gr_gid) - done = 1; - else - quickout = 1; - } else if (nam == NULL) - done = 1; + } else if (nam != NULL) { + if (strcmp(nam, gr->gr_name) == 0) break; - case 3: - q = p; - sep = ",\n"; - break; - default: - if (*p) { - extendarray(&mems, &memlen, mno + 2); - mems[mno++] = p; - } - break; - } - } - grp.gr_mem = mems; - mems[mno] = NULL; - } + } else + break; + free(gr); + gr = NULL; + } if (doclose) vendgrent(); - if (done && grp.gr_name) { - gr = &grp; - - CKNULL(grp.gr_passwd); - } } - return gr; + free(line); + + return (gr); } struct group * -- cgit v1.2.3-56-ge451