diff options
| -rw-r--r-- | chpass/Makefile | 6 | ||||
| -rw-r--r-- | libutil/gr_util.c | 25 | ||||
| -rw-r--r-- | pw/Makefile | 3 | ||||
| -rw-r--r-- | pw/fileupd.c | 21 | ||||
| -rw-r--r-- | pw/grupd.c | 4 | ||||
| -rw-r--r-- | pw/pw_conf.c | 266 | ||||
| -rw-r--r-- | pw/pw_nis.c | 3 | ||||
| -rw-r--r-- | pw/pw_user.c | 37 | ||||
| -rw-r--r-- | pw/pwupd.c | 109 | ||||
| -rw-r--r-- | pw/pwupd.h | 3 |
10 files changed, 263 insertions, 214 deletions
diff --git a/chpass/Makefile b/chpass/Makefile index 9b3e878..cf3acc6 100644 --- a/chpass/Makefile +++ b/chpass/Makefile @@ -16,9 +16,11 @@ CFLAGS+= -DYP #CFLAGS+=-DRESTRICT_FULLNAME_CHANGE CFLAGS+=-I${.CURDIR}/../../usr.sbin/pwd_mkdb -I${.CURDIR}/../../lib/libc/gen -I. -LIBADD= crypt util +DPADD= ${LIBCRYPT} ${LIBUTIL} +LDADD= -lcrypt -lutil .if ${MK_NIS} != "no" -LIBADD+= ypclnt +DPADD+= ${LIBYPCLNT} +LDADD+= -lypclnt .endif LINKS= ${BINDIR}/chpass ${BINDIR}/chfn diff --git a/libutil/gr_util.c b/libutil/gr_util.c index b0b0b36..465efd9 100644 --- a/libutil/gr_util.c +++ b/libutil/gr_util.c @@ -351,6 +351,8 @@ gr_fini(void) int gr_equal(const struct group *gr1, const struct group *gr2) { + int gr1_ndx; + int gr2_ndx; /* Check that the non-member information is the same. */ if (gr1->gr_name == NULL || gr2->gr_name == NULL) { @@ -366,8 +368,7 @@ gr_equal(const struct group *gr1, const struct group *gr2) if (gr1->gr_gid != gr2->gr_gid) return (false); - /* - * Check all members in both groups. + /* Check all members in both groups. * getgrnam can return gr_mem with a pointer to NULL. * gr_dup and gr_add strip out this superfluous NULL, setting * gr_mem to NULL for no members. @@ -375,18 +376,22 @@ gr_equal(const struct group *gr1, const struct group *gr2) if (gr1->gr_mem != NULL && gr2->gr_mem != NULL) { int i; - for (i = 0; - gr1->gr_mem[i] != NULL && gr2->gr_mem[i] != NULL; i++) { + for (i = 0; gr1->gr_mem[i] != NULL; i++) { if (strcmp(gr1->gr_mem[i], gr2->gr_mem[i]) != 0) return (false); } - if (gr1->gr_mem[i] != NULL || gr2->gr_mem[i] != NULL) - return (false); - } else if (gr1->gr_mem != NULL && gr1->gr_mem[0] != NULL) { - return (false); - } else if (gr2->gr_mem != NULL && gr2->gr_mem[0] != NULL) { - return (false); } + /* Count number of members in both structs */ + gr2_ndx = 0; + if (gr2->gr_mem != NULL) + for(; gr2->gr_mem[gr2_ndx] != NULL; gr2_ndx++) + /* empty */; + gr1_ndx = 0; + if (gr1->gr_mem != NULL) + for(; gr1->gr_mem[gr1_ndx] != NULL; gr1_ndx++) + /* empty */; + if (gr1_ndx != gr2_ndx) + return (false); return (true); } diff --git a/pw/Makefile b/pw/Makefile index 69953da..8c5acf9 100644 --- a/pw/Makefile +++ b/pw/Makefile @@ -8,7 +8,8 @@ SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \ WARNS?= 2 -LIBADD= crypt util sbuf +DPADD= ${LIBCRYPT} ${LIBUTIL} +LDADD= -lcrypt -lutil .include <src.opts.mk> diff --git a/pw/fileupd.c b/pw/fileupd.c index dc32712..7df4bb1 100644 --- a/pw/fileupd.c +++ b/pw/fileupd.c @@ -29,11 +29,32 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include <stdio.h> +#include <fcntl.h> #include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <errno.h> +#include <unistd.h> #include "pwupd.h" int +extendline(char **buf, int * buflen, int needed) +{ + if (needed > *buflen) { + char *tmp = realloc(*buf, needed); + if (tmp == NULL) + return -1; + *buf = tmp; + *buflen = needed; + } + return *buflen; +} + +int extendarray(char ***buf, int * buflen, int needed) { if (needed > *buflen) { @@ -35,6 +35,10 @@ static const char rcsid[] = #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <stdarg.h> +#include <sys/types.h> +#include <sys/stat.h> #include <sys/param.h> #include "pwupd.h" diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 99d3e8f..1289b3e 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -29,12 +29,9 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <sys/types.h> -#include <sys/sbuf.h> #include <string.h> #include <ctype.h> #include <fcntl.h> -#include <err.h> #include "pw.h" @@ -212,17 +209,20 @@ boolean_str(int val) char * newstr(char const * p) { - char *q; + char *q = NULL; - if ((p = unquote(p)) == NULL) - return (NULL); + if ((p = unquote(p)) != NULL) { + int l = strlen(p) + 1; - if ((q = strdup(p)) == NULL) - err(1, "strdup()"); - - return (q); + if ((q = malloc(l)) != NULL) + memcpy(q, p, l); + } + return q; } +#define LNBUFSZ 1024 + + struct userconf * read_userconfig(char const * file) { @@ -234,10 +234,8 @@ read_userconfig(char const * file) buf = NULL; linecap = 0; - config.numgroups = 200; - config.groups = calloc(config.numgroups, sizeof(char *)); - if (config.groups == NULL) - err(1, "calloc()"); + extendarray(&config.groups, &config.numgroups, 200); + memset(config.groups, 0, config.numgroups * sizeof(char *)); if (file == NULL) file = _PATH_PW_CONF; @@ -368,132 +366,138 @@ int write_userconfig(char const * file) { int fd; - int i, j; - struct sbuf *buf; - FILE *fp; if (file == NULL) file = _PATH_PW_CONF; - if ((fd = open(file, O_CREAT|O_RDWR|O_TRUNC|O_EXLOCK, 0644)) == -1) - return (0); + if ((fd = open(file, O_CREAT | O_RDWR | O_TRUNC | O_EXLOCK, 0644)) != -1) { + FILE *fp; - if ((fp = fdopen(fd, "w")) == NULL) { - close(fd); - return (0); - } - - buf = sbuf_new_auto(); - for (i = _UC_NONE; i < _UC_FIELDS; i++) { - int quote = 1; - - sbuf_clear(buf); - switch (i) { - case _UC_DEFAULTPWD: - sbuf_cat(buf, boolean_str(config.default_password)); - break; - case _UC_REUSEUID: - sbuf_cat(buf, boolean_str(config.reuse_uids)); - break; - case _UC_REUSEGID: - sbuf_cat(buf, boolean_str(config.reuse_gids)); - break; - case _UC_NISPASSWD: - sbuf_cat(buf, config.nispasswd ? config.nispasswd : - ""); - quote = 0; - break; - case _UC_DOTDIR: - sbuf_cat(buf, config.dotdir ? config.dotdir : - boolean_str(0)); - break; - case _UC_NEWMAIL: - sbuf_cat(buf, config.newmail ? config.newmail : - boolean_str(0)); - break; - case _UC_LOGFILE: - sbuf_cat(buf, config.logfile ? config.logfile : - boolean_str(0)); - break; - case _UC_HOMEROOT: - sbuf_cat(buf, config.home); - break; - case _UC_HOMEMODE: - sbuf_printf(buf, "%04o", config.homemode); - quote = 0; - break; - case _UC_SHELLPATH: - sbuf_cat(buf, config.shelldir); - break; - case _UC_SHELLS: - for (j = 0; j < _UC_MAXSHELLS && - system_shells[j] != NULL; j++) - sbuf_printf(buf, "%s\"%s\"", j ? - "," : "", system_shells[j]); - quote = 0; - break; - case _UC_DEFAULTSHELL: - sbuf_cat(buf, config.shell_default ? - config.shell_default : bourne_shell); - break; - case _UC_DEFAULTGROUP: - sbuf_cat(buf, config.default_group ? - config.default_group : ""); - break; - case _UC_EXTRAGROUPS: - for (j = 0; j < config.numgroups && - config.groups[j] != NULL; j++) - sbuf_printf(buf, "%s\"%s\"", j ? - "," : "", config.groups[j]); - quote = 0; - break; - case _UC_DEFAULTCLASS: - sbuf_cat(buf, config.default_class ? - config.default_class : ""); - break; - case _UC_MINUID: - sbuf_printf(buf, "%lu", (unsigned long) config.min_uid); - quote = 0; - break; - case _UC_MAXUID: - sbuf_printf(buf, "%lu", (unsigned long) config.max_uid); - quote = 0; - break; - case _UC_MINGID: - sbuf_printf(buf, "%lu", (unsigned long) config.min_gid); - quote = 0; - break; - case _UC_MAXGID: - sbuf_printf(buf, "%lu", (unsigned long) config.max_gid); - quote = 0; - break; - case _UC_EXPIRE: - sbuf_printf(buf, "%d", config.expire_days); - quote = 0; - break; - case _UC_PASSWORD: - sbuf_printf(buf, "%d", config.password_days); - quote = 0; - break; - case _UC_NONE: - break; - } - sbuf_finish(buf); + if ((fp = fdopen(fd, "w")) == NULL) + close(fd); + else { + int i, j, k; + int len = LNBUFSZ; + char *buf = malloc(len); - if (comments[i]) - fputs(comments[i], fp); + for (i = _UC_NONE; i < _UC_FIELDS; i++) { + int quote = 1; + char const *val = buf; - if (*kwds[i]) { - if (quote) - fprintf(fp, "%s = \"%s\"\n", kwds[i], - sbuf_data(buf)); - else - fprintf(fp, "%s = %s\n", kwds[i], sbuf_data(buf)); + *buf = '\0'; + switch (i) { + case _UC_DEFAULTPWD: + val = boolean_str(config.default_password); + break; + case _UC_REUSEUID: + val = boolean_str(config.reuse_uids); + break; + case _UC_REUSEGID: + val = boolean_str(config.reuse_gids); + break; + case _UC_NISPASSWD: + val = config.nispasswd ? config.nispasswd : ""; + quote = 0; + break; + case _UC_DOTDIR: + val = config.dotdir ? config.dotdir : boolean_str(0); + break; + case _UC_NEWMAIL: + val = config.newmail ? config.newmail : boolean_str(0); + break; + case _UC_LOGFILE: + val = config.logfile ? config.logfile : boolean_str(0); + break; + case _UC_HOMEROOT: + val = config.home; + break; + case _UC_HOMEMODE: + sprintf(buf, "%04o", config.homemode); + quote = 0; + break; + case _UC_SHELLPATH: + val = config.shelldir; + break; + case _UC_SHELLS: + for (j = k = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) { + char lbuf[64]; + int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", system_shells[j]); + if (l < 0) + l = 0; + if (l + k + 1 < len || extendline(&buf, &len, len + LNBUFSZ) != -1) { + strcpy(buf + k, lbuf); + k += l; + } + } + quote = 0; + break; + case _UC_DEFAULTSHELL: + val = config.shell_default ? config.shell_default : bourne_shell; + break; + case _UC_DEFAULTGROUP: + val = config.default_group ? config.default_group : ""; + break; + case _UC_EXTRAGROUPS: + extendarray(&config.groups, &config.numgroups, 200); + for (j = k = 0; j < config.numgroups && config.groups[j] != NULL; j++) { + char lbuf[64]; + int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", config.groups[j]); + if (l < 0) + l = 0; + if (l + k + 1 < len || extendline(&buf, &len, len + 1024) != -1) { + strcpy(buf + k, lbuf); + k += l; + } + } + quote = 0; + break; + case _UC_DEFAULTCLASS: + val = config.default_class ? config.default_class : ""; + break; + case _UC_MINUID: + sprintf(buf, "%lu", (unsigned long) config.min_uid); + quote = 0; + break; + case _UC_MAXUID: + sprintf(buf, "%lu", (unsigned long) config.max_uid); + quote = 0; + break; + case _UC_MINGID: + sprintf(buf, "%lu", (unsigned long) config.min_gid); + quote = 0; + break; + case _UC_MAXGID: + sprintf(buf, "%lu", (unsigned long) config.max_gid); + quote = 0; + break; + case _UC_EXPIRE: + sprintf(buf, "%d", config.expire_days); + quote = 0; + break; + case _UC_PASSWORD: + sprintf(buf, "%d", config.password_days); + quote = 0; + break; + case _UC_NONE: + break; + } + + if (comments[i]) + fputs(comments[i], fp); + + if (*kwds[i]) { + if (quote) + fprintf(fp, "%s = \"%s\"\n", kwds[i], val); + else + fprintf(fp, "%s = %s\n", kwds[i], val); #if debugging - printf("WROTE: %s = %s\n", kwds[i], sbuf_data(buf)); + printf("WROTE: %s = %s\n", kwds[i], val); #endif + } + } + free(buf); + return fclose(fp) != EOF; } } - sbuf_delete(buf); - return (fclose(fp) != EOF); + return 0; } diff --git a/pw/pw_nis.c b/pw/pw_nis.c index c786cc7..918fc30 100644 --- a/pw/pw_nis.c +++ b/pw/pw_nis.c @@ -29,6 +29,9 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <err.h> #include <pwd.h> diff --git a/pw/pw_user.c b/pw/pw_user.c index b058aab..483148a 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -40,6 +40,7 @@ static const char rcsid[] = #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> +#include <unistd.h> #include <login_cap.h> #include <pwd.h> #include <grp.h> @@ -184,7 +185,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * But we create a symlink from cnf->home -> "/usr" -> cnf->home */ if (strchr(cnf->home+1, '/') == NULL) { - snprintf(dbuf, MAXPATHLEN, "/usr%s", cnf->home); + strcpy(dbuf, "/usr"); + strncat(dbuf, cnf->home, MAXPATHLEN-5); if (mkdir(dbuf, _DEF_DIRMODE) != -1 || errno == EEXIST) { chown(dbuf, 0, 0); /* @@ -362,9 +364,11 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (mode == M_LOCK) { if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) == 0) errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name); - asprintf(&passtmp, "%s%s", locked_str, pwd->pw_passwd); + passtmp = malloc(strlen(pwd->pw_passwd) + sizeof(locked_str)); if (passtmp == NULL) /* disaster */ errx(EX_UNAVAILABLE, "out of memory"); + strcpy(passtmp, locked_str); + strcat(passtmp, pwd->pw_passwd); pwd->pw_passwd = passtmp; edited = 1; } else if (mode == M_UNLOCK) { @@ -397,7 +401,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); if (access(file, F_OK) == 0) { - snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); + sprintf(file, "crontab -u %s -r", pwd->pw_name); system(file); } } @@ -405,7 +409,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * Save these for later, since contents of pwd may be * invalidated by deletion */ - snprintf(file, sizeof(file), "%s/%s", _PATH_MAILDIR, pwd->pw_name); + sprintf(file, "%s/%s", _PATH_MAILDIR, pwd->pw_name); strlcpy(home, pwd->pw_dir, sizeof(home)); gr = GETGRGID(pwd->pw_gid); if (gr != NULL) @@ -811,7 +815,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ if (mode == M_ADD) { if (!PWALTDIR()) { - snprintf(line, sizeof(line), "%s/%s", _PATH_MAILDIR, pwd->pw_name); + sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name); close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents & * mtime */ chown(line, pwd->pw_uid, pwd->pw_gid); @@ -955,7 +959,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer * function will happily handle that case for us and exit. */ if (GETGRGID(prefer) == NULL) { - snprintf(tmp, sizeof(tmp), "%u", prefer); + sprintf(tmp, "%lu", (unsigned long) prefer); addarg(&grpargs, 'g', tmp); } if (getarg(args, 'N')) @@ -1018,16 +1022,17 @@ static char * pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user) { struct carg *arg = getarg(args, 'd'); - static char home[128]; if (arg) - return (arg->val); - - if (cnf->home == NULL || *cnf->home == '\0') - errx(EX_CONFIG, "no base home directory set"); - snprintf(home, sizeof(home), "%s/%s", cnf->home, user); + return arg->val; + else { + static char home[128]; - return (home); + if (cnf->home == NULL || *cnf->home == '\0') + errx(EX_CONFIG, "no base home directory set"); + sprintf(home, "%s/%s", cnf->home, user); + return home; + } } static char * @@ -1048,12 +1053,12 @@ shell_path(char const * path, char *shells[], char *sh) static char shellpath[256]; if (sh != NULL) { - snprintf(shellpath, sizeof(shellpath), "%s/%s", p, sh); + sprintf(shellpath, "%s/%s", p, sh); if (access(shellpath, X_OK) == 0) return shellpath; } else for (i = 0; i < _UC_MAXSHELLS && shells[i] != NULL; i++) { - snprintf(shellpath, sizeof(shellpath), "%s/%s", p, shells[i]); + sprintf(shellpath, "%s/%s", p, shells[i]); if (access(shellpath, X_OK) == 0) return shellpath; } @@ -1303,7 +1308,7 @@ rmat(uid_t uid) st.st_uid == uid) { char tmp[MAXPATHLEN]; - snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s", e->d_name); + sprintf(tmp, "/usr/bin/atrm %s", e->d_name); system(tmp); } } @@ -33,6 +33,7 @@ static const char rcsid[] = #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <stdarg.h> #include <pwd.h> #include <libutil.h> #include <errno.h> @@ -51,13 +52,12 @@ int setpwdir(const char * dir) { if (dir == NULL) - return (-1); + return -1; else pwpath = strdup(dir); if (pwpath == NULL) - return (-1); - - return (0); + return -1; + return 0; } char * @@ -66,20 +66,23 @@ getpwpath(char const * file) static char pathbuf[MAXPATHLEN]; snprintf(pathbuf, sizeof pathbuf, "%s/%s", pwpath, file); - - return (pathbuf); + return pathbuf; } static int -pwdb_check(void) +pwdb(char *arg,...) { int i = 0; pid_t pid; + va_list ap; char *args[10]; args[i++] = _PATH_PWD_MKDB; - args[i++] = "-C"; - + va_start(ap, arg); + while (i < 6 && arg != NULL) { + args[i++] = arg; + arg = va_arg(ap, char *); + } if (pwpath != pathpwd) { args[i++] = "-d"; args[i++] = pwpath; @@ -97,66 +100,65 @@ pwdb_check(void) if (WEXITSTATUS(i)) i = EIO; } - - return (i); + va_end(ap); + return i; } static int pw_update(struct passwd * pwd, char const * user) { - struct passwd *pw = NULL; - struct passwd *old_pw = NULL; - int rc, pfd, tfd; - - if ((rc = pwdb_check()) != 0) - return (rc); - - if (pwd != NULL) - pw = pw_dup(pwd); - - if (user != NULL) - old_pw = GETPWNAM(user); - - if (pw_init(pwpath, NULL)) - err(1, "pw_init()"); - if ((pfd = pw_lock()) == -1) { + int rc = 0; + + rc = pwdb("-C", (char *)NULL); /* Check only */ + if (rc == 0) { + int pfd, tfd; + struct passwd *pw = NULL; + struct passwd *old_pw = NULL; + + if (pwd != NULL) + pw = pw_dup(pwd); + + if (user != NULL) + old_pw = GETPWNAM(user); + + if (pw_init(pwpath, NULL)) + err(1, "pw_init()"); + if ((pfd = pw_lock()) == -1) { + pw_fini(); + err(1, "pw_lock()"); + } + if ((tfd = pw_tmp(-1)) == -1) { + pw_fini(); + err(1, "pw_tmp()"); + } + if (pw_copy(pfd, tfd, pw, old_pw) == -1) { + pw_fini(); + err(1, "pw_copy()"); + } + /* + * in case of deletion of a user, the whole database + * needs to be regenerated + */ + if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) { + pw_fini(); + err(1, "pw_mkdb()"); + } + free(pw); pw_fini(); - err(1, "pw_lock()"); } - if ((tfd = pw_tmp(-1)) == -1) { - pw_fini(); - err(1, "pw_tmp()"); - } - if (pw_copy(pfd, tfd, pw, old_pw) == -1) { - pw_fini(); - err(1, "pw_copy()"); - } - /* - * in case of deletion of a user, the whole database - * needs to be regenerated - */ - if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) { - pw_fini(); - err(1, "pw_mkdb()"); - } - free(pw); - pw_fini(); - - return (0); + return 0; } int addpwent(struct passwd * pwd) { - - return (pw_update(pwd, NULL)); + return pw_update(pwd, NULL); } int chgpwent(char const * login, struct passwd * pwd) { - - return (pw_update(pwd, login)); + return pw_update(pwd, login); } int @@ -165,6 +167,5 @@ delpwent(struct passwd * pwd) char login[MAXLOGNAME]; strlcpy(login, pwd->pw_name, MAXLOGNAME); - - return (pw_update(NULL, login)); + return pw_update(NULL, login); } @@ -112,7 +112,10 @@ void vendgrent(void); void copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid); void rm_r(char const * dir, uid_t uid); +int extendline(char **buf, int *buflen, int needed); int extendarray(char ***buf, int *buflen, int needed); __END_DECLS +#define PWBUFSZ 1024 + #endif /* !_PWUPD_H */ |
