From 37cf831c25d3fbcc63a8548fc4ed7ead82562c5b Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 11 Jul 2015 23:07:17 +0000 Subject: Replace custom string array with stringlist(3) --- pw/pw_conf.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 24c0650..33bb6b3 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -104,8 +104,7 @@ static struct userconf config = 1000, 32000, /* Allowed range of uids */ 1000, 32000, /* Allowed range of gids */ 0, /* Days until account expires */ - 0, /* Days until password expires */ - 0 /* size of default_group array */ + 0 /* Days until password expires */ }; static char const *comments[_UC_FIELDS] = @@ -234,10 +233,9 @@ read_userconfig(char const * file) buf = NULL; linecap = 0; - config.numgroups = 200; - config.groups = calloc(config.numgroups, sizeof(char *)); + config.groups = sl_init(); if (config.groups == NULL) - err(1, "calloc()"); + err(1, "sl_init()"); if (file == NULL) file = _PATH_PW_CONF; @@ -316,13 +314,8 @@ read_userconfig(char const * file) ? NULL : newstr(q); break; case _UC_EXTRAGROUPS: - for (i = 0; q != NULL; q = strtok(NULL, toks)) { - if (extendarray(&config.groups, &config.numgroups, i + 2) != -1) - config.groups[i++] = newstr(q); - } - if (i > 0) - while (i < config.numgroups) - config.groups[i++] = NULL; + for (i = 0; q != NULL; q = strtok(NULL, toks)) + sl_add(config.groups, newstr(q)); break; case _UC_DEFAULTCLASS: config.default_class = (q == NULL || !boolean_val(q, 1)) @@ -442,10 +435,10 @@ write_userconfig(char const * file) config.default_group : ""); break; case _UC_EXTRAGROUPS: - for (j = 0; j < config.numgroups && - config.groups[j] != NULL; j++) + for (j = 0; config.groups != NULL && + j < (int)config.groups->sl_cur; j++) sbuf_printf(buf, "%s\"%s\"", j ? - "," : "", config.groups[j]); + "," : "", config.groups->sl_str[j]); quote = 0; break; case _UC_DEFAULTCLASS: -- cgit v1.2.3 From 2d1b974f3a71544c2aa9e4e648a3acad80ed7aaa Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 09:55:47 +0000 Subject: Cast uid/git to uintmax_t when using printf-like functions so the size of uid/gid size remains a implementation detail --- pw/pw_conf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 33bb6b3..d351a8f 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -31,6 +31,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -446,19 +447,19 @@ write_userconfig(char const * file) config.default_class : ""); break; case _UC_MINUID: - sbuf_printf(buf, "%u", config.min_uid); + sbuf_printf(buf, "%ju", (uintmax_t)config.min_uid); quote = 0; break; case _UC_MAXUID: - sbuf_printf(buf, "%u", config.max_uid); + sbuf_printf(buf, "%ju", (uintmax_t)config.max_uid); quote = 0; break; case _UC_MINGID: - sbuf_printf(buf, "%u", config.min_gid); + sbuf_printf(buf, "%ju", (uintmax_t)config.min_gid); quote = 0; break; case _UC_MAXGID: - sbuf_printf(buf, "%u", config.max_gid); + sbuf_printf(buf, "%ju", (uintmax_t)config.max_gid); quote = 0; break; case _UC_EXPIRE: -- cgit v1.2.3 From 8ce0155157b2698e849ebd4aede2567cbc9986ee Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 10:10:13 +0000 Subject: Validate the max_uid/max_gid boundaries and entry type in pw.conf --- pw/pw_conf.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index d351a8f..c6a86b7 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -230,6 +230,7 @@ read_userconfig(char const * file) char *buf, *p; size_t linecap; ssize_t linelen; + const char *errstr; buf = NULL; linecap = 0; @@ -323,20 +324,35 @@ read_userconfig(char const * file) ? NULL : newstr(q); break; case _UC_MINUID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.min_uid = (uid_t) atol(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.min_uid = strtounum(q, 0, UID_MAX, &errstr); + if (errstr) + warnx("Invalid min_uid: '%s', ignoring", q); + } break; case _UC_MAXUID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.max_uid = (uid_t) atol(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.max_uid = strtounum(q, 0, UID_MAX, &errstr); + if (errstr) + warnx("Invalid max_uid: '%s', ignoring", q); + } break; case _UC_MINGID: if ((q = unquote(q)) != NULL && isdigit(*q)) - config.min_gid = (gid_t) atol(q); + errstr = NULL; + config.min_gid = strtounum(q, 0, GID_MAX, &errstr); + if (errstr) + warnx("Invalid min_gid: '%s', ignoring", q); break; case _UC_MAXGID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.max_gid = (gid_t) atol(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.max_gid = strtounum(q, 0, GID_MAX, &errstr); + if (errstr) + warnx("Invalid max_gid: '%s', ignoring", q); + } break; case _UC_EXPIRE: if ((q = unquote(q)) != NULL && isdigit(*q)) -- cgit v1.2.3 From a25394718fcec2b1422b872e24e54ad5c7ae69af Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 10:25:55 +0000 Subject: Validate expiration days and password days from commmand line and pw.conf --- pw/pw_conf.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index c6a86b7..c1b5b33 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -355,12 +355,20 @@ read_userconfig(char const * file) } break; case _UC_EXPIRE: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.expire_days = atoi(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.expire_days = strtonum(q, 0, INT_MAX, &errstr); + if (errstr) + warnx("Invalid expire days: '%s', ignoring", q); + } break; case _UC_PASSWORD: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.password_days = atoi(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.password_days = strtonum(q, 0, INT_MAX, &errstr); + if (errstr) + warnx("Invalid password days: '%s', ignoring", q); + } break; case _UC_FIELDS: case _UC_NONE: -- cgit v1.2.3 From e672bd2533afdd7c7b9be669d3b7bd60f71a84c6 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 11:31:59 +0000 Subject: Fix formatting of new code Fix sorting or errstr Remove useless initialisation or errstr Reported by: bde --- pw/pw_conf.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index c1b5b33..10ded5c 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -228,9 +228,9 @@ read_userconfig(char const * file) { FILE *fp; char *buf, *p; + const char *errstr; size_t linecap; ssize_t linelen; - const char *errstr; buf = NULL; linecap = 0; @@ -325,49 +325,55 @@ read_userconfig(char const * file) break; case _UC_MINUID: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.min_uid = strtounum(q, 0, UID_MAX, &errstr); + config.min_uid = strtounum(q, 0, + UID_MAX, &errstr); if (errstr) - warnx("Invalid min_uid: '%s', ignoring", q); + warnx("Invalid min_uid: '%s';" + " ignoring", q); } break; case _UC_MAXUID: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.max_uid = strtounum(q, 0, UID_MAX, &errstr); + config.max_uid = strtounum(q, 0, + UID_MAX, &errstr); if (errstr) - warnx("Invalid max_uid: '%s', ignoring", q); + warnx("Invalid max_uid: '%s';" + " ignoring", q); } break; case _UC_MINGID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - errstr = NULL; - config.min_gid = strtounum(q, 0, GID_MAX, &errstr); + if ((q = unquote(q)) != NULL) { + config.min_gid = strtounum(q, 0, + GID_MAX, &errstr); if (errstr) - warnx("Invalid min_gid: '%s', ignoring", q); + warnx("Invalid min_gid: '%s';" + " ignoring", q); break; case _UC_MAXGID: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.max_gid = strtounum(q, 0, GID_MAX, &errstr); + config.max_gid = strtounum(q, 0, + GID_MAX, &errstr); if (errstr) - warnx("Invalid max_gid: '%s', ignoring", q); + warnx("Invalid max_gid: '%s';" + " ignoring", q); } break; case _UC_EXPIRE: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.expire_days = strtonum(q, 0, INT_MAX, &errstr); + config.expire_days = strtonum(q, 0, + INT_MAX, &errstr); if (errstr) - warnx("Invalid expire days: '%s', ignoring", q); + warnx("Invalid expire days:" + " '%s'; ignoring", q); } break; case _UC_PASSWORD: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.password_days = strtonum(q, 0, INT_MAX, &errstr); + config.password_days = strtonum(q, 0, + INT_MAX, &errstr); if (errstr) - warnx("Invalid password days: '%s', ignoring", q); + warnx("Invalid password days:" + " '%s'; ignoring", q); } break; case _UC_FIELDS: -- cgit v1.2.3 From 99c28d09467b167abaa8b517679f480b4e21d40b Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 11:52:48 +0000 Subject: Fix build --- pw/pw_conf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 10ded5c..b723c31 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -348,6 +348,7 @@ read_userconfig(char const * file) if (errstr) warnx("Invalid min_gid: '%s';" " ignoring", q); + } break; case _UC_MAXGID: if ((q = unquote(q)) != NULL) { -- cgit v1.2.3 From 5bb254a38fa9e233bcdb24956e1f8ccf2b19182b Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 12:18:48 +0000 Subject: Partial revert of r286152 More work needed on the cli validation --- pw/pw_conf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index b723c31..8ba8c07 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -367,6 +367,8 @@ read_userconfig(char const * file) warnx("Invalid expire days:" " '%s'; ignoring", q); } + if ((q = unquote(q)) != NULL && isdigit(*q)) + config.expire_days = atoi(q); break; case _UC_PASSWORD: if ((q = unquote(q)) != NULL) { -- cgit v1.2.3 From cc2167793425c49a88da118a7b6b48bdb4ad9b81 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 12:20:55 +0000 Subject: Remove things that crept in after badly checked revert --- pw/pw_conf.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 8ba8c07..b723c31 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -367,8 +367,6 @@ read_userconfig(char const * file) warnx("Invalid expire days:" " '%s'; ignoring", q); } - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.expire_days = atoi(q); break; case _UC_PASSWORD: if ((q = unquote(q)) != NULL) { -- cgit v1.2.3 From e773096e9049d4fb494d9ea86a862cd89d62bdfc Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 12:47:50 +0000 Subject: Rewrite parsing subcommands arguments of pw(8) Now each subcommands checks its arguments in a dedicated functions. This helps improving input validation, code readability/maintainability While here: - Add a -y option to pw userdel/usermod so it can maintain NIS servers if nispasswd is not defined in pw.conf(5) - Allow pw -r to remove directory with userdel -r - Fix bug when renaming a user which was not renaming the user name it groups it is a member of. - Only parse pw.conf(5) when needed. --- pw/pw_conf.c | 61 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 31 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index b723c31..41ab79b 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -235,9 +235,6 @@ read_userconfig(char const * file) buf = NULL; linecap = 0; - config.groups = sl_init(); - if (config.groups == NULL) - err(1, "sl_init()"); if (file == NULL) file = _PATH_PW_CONF; @@ -316,8 +313,11 @@ read_userconfig(char const * file) ? NULL : newstr(q); break; case _UC_EXTRAGROUPS: - for (i = 0; q != NULL; q = strtok(NULL, toks)) + for (i = 0; q != NULL; q = strtok(NULL, toks)) { + if (config.groups == NULL) + config.groups = sl_init(); sl_add(config.groups, newstr(q)); + } break; case _UC_DEFAULTCLASS: config.default_class = (q == NULL || !boolean_val(q, 1)) @@ -391,7 +391,7 @@ read_userconfig(char const * file) int -write_userconfig(char const * file) +write_userconfig(struct userconf *cnf, const char *file) { int fd; int i, j; @@ -416,40 +416,39 @@ write_userconfig(char const * file) sbuf_clear(buf); switch (i) { case _UC_DEFAULTPWD: - sbuf_cat(buf, boolean_str(config.default_password)); + sbuf_cat(buf, boolean_str(cnf->default_password)); break; case _UC_REUSEUID: - sbuf_cat(buf, boolean_str(config.reuse_uids)); + sbuf_cat(buf, boolean_str(cnf->reuse_uids)); break; case _UC_REUSEGID: - sbuf_cat(buf, boolean_str(config.reuse_gids)); + sbuf_cat(buf, boolean_str(cnf->reuse_gids)); break; case _UC_NISPASSWD: - sbuf_cat(buf, config.nispasswd ? config.nispasswd : - ""); + sbuf_cat(buf, cnf->nispasswd ? cnf->nispasswd : ""); quote = 0; break; case _UC_DOTDIR: - sbuf_cat(buf, config.dotdir ? config.dotdir : + sbuf_cat(buf, cnf->dotdir ? cnf->dotdir : boolean_str(0)); break; case _UC_NEWMAIL: - sbuf_cat(buf, config.newmail ? config.newmail : + sbuf_cat(buf, cnf->newmail ? cnf->newmail : boolean_str(0)); break; case _UC_LOGFILE: - sbuf_cat(buf, config.logfile ? config.logfile : + sbuf_cat(buf, cnf->logfile ? cnf->logfile : boolean_str(0)); break; case _UC_HOMEROOT: - sbuf_cat(buf, config.home); + sbuf_cat(buf, cnf->home); break; case _UC_HOMEMODE: - sbuf_printf(buf, "%04o", config.homemode); + sbuf_printf(buf, "%04o", cnf->homemode); quote = 0; break; case _UC_SHELLPATH: - sbuf_cat(buf, config.shelldir); + sbuf_cat(buf, cnf->shelldir); break; case _UC_SHELLS: for (j = 0; j < _UC_MAXSHELLS && @@ -459,46 +458,46 @@ write_userconfig(char const * file) quote = 0; break; case _UC_DEFAULTSHELL: - sbuf_cat(buf, config.shell_default ? - config.shell_default : bourne_shell); + sbuf_cat(buf, cnf->shell_default ? + cnf->shell_default : bourne_shell); break; case _UC_DEFAULTGROUP: - sbuf_cat(buf, config.default_group ? - config.default_group : ""); + sbuf_cat(buf, cnf->default_group ? + cnf->default_group : ""); break; case _UC_EXTRAGROUPS: - for (j = 0; config.groups != NULL && - j < (int)config.groups->sl_cur; j++) + for (j = 0; cnf->groups != NULL && + j < (int)cnf->groups->sl_cur; j++) sbuf_printf(buf, "%s\"%s\"", j ? - "," : "", config.groups->sl_str[j]); + "," : "", cnf->groups->sl_str[j]); quote = 0; break; case _UC_DEFAULTCLASS: - sbuf_cat(buf, config.default_class ? - config.default_class : ""); + sbuf_cat(buf, cnf->default_class ? + cnf->default_class : ""); break; case _UC_MINUID: - sbuf_printf(buf, "%ju", (uintmax_t)config.min_uid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->min_uid); quote = 0; break; case _UC_MAXUID: - sbuf_printf(buf, "%ju", (uintmax_t)config.max_uid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->max_uid); quote = 0; break; case _UC_MINGID: - sbuf_printf(buf, "%ju", (uintmax_t)config.min_gid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->min_gid); quote = 0; break; case _UC_MAXGID: - sbuf_printf(buf, "%ju", (uintmax_t)config.max_gid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->max_gid); quote = 0; break; case _UC_EXPIRE: - sbuf_printf(buf, "%d", config.expire_days); + sbuf_printf(buf, "%ld", cnf->expire_days); quote = 0; break; case _UC_PASSWORD: - sbuf_printf(buf, "%d", config.password_days); + sbuf_printf(buf, "%ld", cnf->password_days); quote = 0; break; case _UC_NONE: -- cgit v1.2.3 From 4573132fd44c8bd71211a975ed21e9acbb58ca45 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:22:46 +0000 Subject: Cleanup a bit includes --- pw/pw_conf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 41ab79b..087f48e 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -31,11 +31,11 @@ static const char rcsid[] = #include #include -#include -#include -#include -#include + #include +#include +#include +#include #include "pw.h" -- cgit v1.2.3 From d8b569c5d79b241766aa4c1e90780a2af8bd1e7b Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:50:11 +0000 Subject: Fix build on 32bits --- pw/pw_conf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 087f48e..c79b60a 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -493,11 +493,11 @@ write_userconfig(struct userconf *cnf, const char *file) quote = 0; break; case _UC_EXPIRE: - sbuf_printf(buf, "%ld", cnf->expire_days); + sbuf_printf(buf, "%lld", (long long)cnf->expire_days); quote = 0; break; case _UC_PASSWORD: - sbuf_printf(buf, "%ld", cnf->password_days); + sbuf_printf(buf, "%lld", (long long)cnf->password_days); quote = 0; break; case _UC_NONE: -- cgit v1.2.3 From 3a5dfb13d7ae60d5d8669c118c1efa82ca51d5f5 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 19:49:24 +0000 Subject: Use intmax_t rather than long long --- pw/pw_conf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pw/pw_conf.c') diff --git a/pw/pw_conf.c b/pw/pw_conf.c index c79b60a..e9606b4 100644 --- a/pw/pw_conf.c +++ b/pw/pw_conf.c @@ -493,11 +493,11 @@ write_userconfig(struct userconf *cnf, const char *file) quote = 0; break; case _UC_EXPIRE: - sbuf_printf(buf, "%lld", (long long)cnf->expire_days); + sbuf_printf(buf, "%jd", (intmax_t)cnf->expire_days); quote = 0; break; case _UC_PASSWORD: - sbuf_printf(buf, "%lld", (long long)cnf->password_days); + sbuf_printf(buf, "%jd", (intmax_t)cnf->password_days); quote = 0; break; case _UC_NONE: -- cgit v1.2.3