From 537b6a03a677d844b74753c6bfb162e5ca6672cc Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 01:36:56 +0200 Subject: [PATCH 01/12] src/login_nopam.c: Remove string_match() Calling strcaseeq() explicitly is more readable, and it allows removing the comments. The code becomes simpler. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 7b5356ee27..ad39ccdf50 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -77,7 +77,6 @@ static bool list_match (char *list, const char *item, bool (*match_fn) (char *, const char *)); static bool user_match (char *tok, const char *string); static bool from_match (char *tok, const char *string); -static bool string_match (const char *tok, const char *string); static const char *resolve_hostname (const char *string); /* login_access - match username/group and host/tty with access control file */ @@ -229,7 +228,7 @@ static bool user_match (char *tok, const char *string) } else if (strprefix(tok, "@")) { /* netgroup */ return (netgroup_match (tok + 1, NULL, string)); #endif - } else if (string_match (tok, string)) { /* ALL or exact match */ + } else if (strcaseeq(tok, "ALL") || strcaseeq(tok, string)) { return true; /* local, no need for xgetgrnam */ } else if ((group = getgrnam (tok)) != NULL) { /* try group membership */ @@ -303,7 +302,7 @@ static bool from_match (char *tok, const char *string) return (netgroup_match (tok + 1, string, NULL)); } else #endif - if (string_match (tok, string)) { /* ALL or exact match */ + if (strcaseeq(tok, "ALL") || strcaseeq(tok, string)) { return true; } else if (strprefix(tok, ".")) { /* domain: match last fields */ size_t str_len, tok_len; @@ -323,23 +322,6 @@ static bool from_match (char *tok, const char *string) } return false; } - -/* string_match - match a string against one token */ -static bool string_match (const char *tok, const char *string) -{ - - /* - * If the token has the magic value "ALL" the match always succeeds. - * Otherwise, return true if the token fully matches the string. - */ - if (strcaseeq(tok, "ALL")) { /* ALL: always matches */ - return true; - } else if (strcaseeq(tok, string)) { /* try exact match */ - return true; - } - return false; -} - #else /* !USE_PAM */ extern int ISO_C_forbids_an_empty_translation_unit; #endif /* !USE_PAM */ From 51b1f587df4a0f14b9c4e3f49e82e2fd2ad649ca Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 01:55:22 +0200 Subject: [PATCH 02/12] src/login_nopam.c: from_match(): Unify style of conditionals Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index ad39ccdf50..33f515baff 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -309,16 +309,14 @@ static bool from_match (char *tok, const char *string) str_len = strlen (string); tok_len = strlen (tok); - if ( (str_len > tok_len) - && strcaseeq(tok, string + str_len - tok_len)) { + if (str_len > tok_len && strcaseeq(tok, string + str_len - tok_len)) return true; - } } else if (strcaseeq(tok, "LOCAL")) { /* LOCAL: no dots */ if (!strchr(string, '.')) return true; - } else if ( strrspn_(tok, ".") /* network */ - && strprefix(resolve_hostname(string), tok)) { - return true; + } else if (strrspn_(tok, ".") /* network */ + if (strprefix(resolve_hostname(string), tok)) + return true; } return false; } From 36478c11ea6070b537043fc6198dfacd2ce273e9 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 01:57:28 +0200 Subject: [PATCH 03/12] src/login_nopam.c: from_match(): return directly in all cases This simplifies the conditionals, allowing the removal of 'else's. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 33f515baff..3f4af29c56 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -309,14 +309,11 @@ static bool from_match (char *tok, const char *string) str_len = strlen (string); tok_len = strlen (tok); - if (str_len > tok_len && strcaseeq(tok, string + str_len - tok_len)) - return true; + return str_len > tok_len && strcaseeq(tok, string + str_len - tok_len); } else if (strcaseeq(tok, "LOCAL")) { /* LOCAL: no dots */ - if (!strchr(string, '.')) - return true; + return !strchr(string, '.'); } else if (strrspn_(tok, ".") /* network */ - if (strprefix(resolve_hostname(string), tok)) - return true; + return !!strprefix(resolve_hostname(string), tok); } return false; } From fd970d49750af14ed3934b90c1627679dcf760dc Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 02:00:46 +0200 Subject: [PATCH 04/12] src/login_nopam.c: Don't else after return Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 3f4af29c56..0350182460 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -222,16 +222,16 @@ static bool user_match (char *tok, const char *string) * the token is a group that contains the username. */ host = stpsep(tok + 1, "@"); /* split user@host pattern */ - if (host != NULL) { + if (host != NULL) return user_match(tok, string) && from_match(host, myhostname()); #if HAVE_INNETGR - } else if (strprefix(tok, "@")) { /* netgroup */ + if (strprefix(tok, "@")) /* netgroup */ return (netgroup_match (tok + 1, NULL, string)); #endif - } else if (strcaseeq(tok, "ALL") || strcaseeq(tok, string)) { + if (strcaseeq(tok, "ALL") || strcaseeq(tok, string)) return true; /* local, no need for xgetgrnam */ - } else if ((group = getgrnam (tok)) != NULL) { /* try group membership */ + if ((group = getgrnam (tok)) != NULL) { /* try group membership */ int i; for (i = 0; NULL != group->gr_mem[i]; i++) { if (strcaseeq(string, group->gr_mem[i])) { @@ -298,23 +298,22 @@ static bool from_match (char *tok, const char *string) * if it matches the head of the string. */ #if HAVE_INNETGR - if (strprefix(tok, "@")) { /* netgroup */ + if (strprefix(tok, "@")) /* netgroup */ return (netgroup_match (tok + 1, string, NULL)); - } else #endif - if (strcaseeq(tok, "ALL") || strcaseeq(tok, string)) { + if (strcaseeq(tok, "ALL") || strcaseeq(tok, string)) return true; - } else if (strprefix(tok, ".")) { /* domain: match last fields */ + if (strprefix(tok, ".")) { /* domain: match last fields */ size_t str_len, tok_len; str_len = strlen (string); tok_len = strlen (tok); return str_len > tok_len && strcaseeq(tok, string + str_len - tok_len); - } else if (strcaseeq(tok, "LOCAL")) { /* LOCAL: no dots */ + } + if (strcaseeq(tok, "LOCAL")) /* LOCAL: no dots */ return !strchr(string, '.'); - } else if (strrspn_(tok, ".") /* network */ + if (strrspn_(tok, ".") /* network */ return !!strprefix(resolve_hostname(string), tok); - } return false; } #else /* !USE_PAM */ From a3638b9f27a5aa48fe7d9399e1c0a13dc3f63fb7 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 03:05:53 +0200 Subject: [PATCH 05/12] src/login_nopam.c: login_access(): Reduce scope of local variables Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 0350182460..661e29102c 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -85,9 +85,6 @@ login_access(const char *user, const char *from) { FILE *fp; char line[BUFSIZ]; - char *perm; /* becomes permission field */ - char *users; /* becomes list of login names */ - char *froms; /* becomes list of terminals or hosts */ bool match = false; /* @@ -104,6 +101,9 @@ login_access(const char *user, const char *from) && (fgets_a(line, fp) != NULL)) { char *p; + char *perm; /* becomes permission field */ + char *users; /* becomes list of login names */ + char *froms; /* becomes list of terminals or hosts */ lineno++; if (stpsep(line, "\n") == NULL) { From 1244697a7ee27dff8fe133b3dc87a5a5bd8a6018 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:09:14 +0200 Subject: [PATCH 06/12] src/login_nopam.c: login_access(): Move error handling earlier This will allow reducing indentation for the rest of the code. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 661e29102c..7e0d418677 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -91,11 +91,17 @@ login_access(const char *user, const char *from) * Process the table one line at a time and stop at the first match. * Blank lines and lines that begin with a '#' character are ignored. * Non-comment lines are broken at the ':' character. All fields are - * mandatory. The first field should be a "+" or "-" character. A - * non-existing table means no access control. + * mandatory. The first field should be a "+" or "-" character. */ fp = fopen (TABLE, "r"); - if (NULL != fp) { + if (fp == NULL) { + if (errno != ENOENT) { + int err = errno; + SYSLOG(LOG_ERR, "cannot open %s: %s", TABLE, strerror(err)); + } + return true; // A non-existent table means no access control. + } + { intmax_t lineno = 0; /* for diagnostics */ while ( !match && (fgets_a(line, fp) != NULL)) @@ -137,9 +143,6 @@ login_access(const char *user, const char *from) && list_match (users, user, user_match)); } (void) fclose (fp); - } else if (errno != ENOENT) { - int err = errno; - SYSLOG(LOG_ERR, "cannot open %s: %s", TABLE, strerror(err)); } return (!match || strprefix(line, "+"))?1:0; } From 566fa2f5b140cac0e663d979b9f97b34dfbed0f2 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:13:15 +0200 Subject: [PATCH 07/12] src/login_nopam.c: login_access(): Reduce indentation Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 80 +++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 7e0d418677..f86d63d523 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -101,49 +101,49 @@ login_access(const char *user, const char *from) } return true; // A non-existent table means no access control. } + + intmax_t lineno = 0; /* for diagnostics */ + while ( !match + && (fgets_a(line, fp) != NULL)) { - intmax_t lineno = 0; /* for diagnostics */ - while ( !match - && (fgets_a(line, fp) != NULL)) - { - char *p; - char *perm; /* becomes permission field */ - char *users; /* becomes list of login names */ - char *froms; /* becomes list of terminals or hosts */ - - lineno++; - if (stpsep(line, "\n") == NULL) { - SYSLOG(LOG_ERR, - "%s: line %jd: missing newline or line too long", - TABLE, lineno); - continue; - } - if (strprefix(line, "#")) { - continue; /* comment line */ - } - stpcpy(stprspn(line, " \t"), ""); - if (streq(line, "")) { /* skip blank lines */ - continue; - } - p = line; - perm = strsep(&p, ":"); - users = strsep(&p, ":"); - froms = strsep(&p, ":"); - if (froms == NULL || p != NULL) { - SYSLOG(LOG_ERR, "%s: line %jd: bad field count", - TABLE, lineno); - continue; - } - if (perm[0] != '+' && perm[0] != '-') { - SYSLOG(LOG_ERR, "%s: line %jd: bad first field", - TABLE, lineno); - continue; - } - match = ( list_match (froms, from, from_match) - && list_match (users, user, user_match)); + char *p; + char *perm; /* becomes permission field */ + char *users; /* becomes list of login names */ + char *froms; /* becomes list of terminals or hosts */ + + lineno++; + if (stpsep(line, "\n") == NULL) { + SYSLOG(LOG_ERR, + "%s: line %jd: missing newline or line too long", + TABLE, lineno); + continue; } - (void) fclose (fp); + if (strprefix(line, "#")) { + continue; /* comment line */ + } + stpcpy(stprspn(line, " \t"), ""); + if (streq(line, "")) { /* skip blank lines */ + continue; + } + p = line; + perm = strsep(&p, ":"); + users = strsep(&p, ":"); + froms = strsep(&p, ":"); + if (froms == NULL || p != NULL) { + SYSLOG(LOG_ERR, "%s: line %jd: bad field count", + TABLE, lineno); + continue; + } + if (perm[0] != '+' && perm[0] != '-') { + SYSLOG(LOG_ERR, "%s: line %jd: bad first field", + TABLE, lineno); + continue; + } + match = ( list_match(froms, from, from_match) + && list_match(users, user, user_match)); } + (void) fclose(fp); + return (!match || strprefix(line, "+"))?1:0; } From d209643e619f311bc02441eaababd386c759d0c4 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:19:09 +0200 Subject: [PATCH 08/12] src/login_nopam.c: login_access(): Use for instead of while loop And rename the iterator to the usual 'i'. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index f86d63d523..c52bea844b 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -102,20 +102,16 @@ login_access(const char *user, const char *from) return true; // A non-existent table means no access control. } - intmax_t lineno = 0; /* for diagnostics */ - while ( !match - && (fgets_a(line, fp) != NULL)) - { + for (intmax_t i = 1; !match && fgets_a(line, fp) != NULL; i++) { char *p; char *perm; /* becomes permission field */ char *users; /* becomes list of login names */ char *froms; /* becomes list of terminals or hosts */ - lineno++; if (stpsep(line, "\n") == NULL) { SYSLOG(LOG_ERR, "%s: line %jd: missing newline or line too long", - TABLE, lineno); + TABLE, i); continue; } if (strprefix(line, "#")) { @@ -131,12 +127,12 @@ login_access(const char *user, const char *from) froms = strsep(&p, ":"); if (froms == NULL || p != NULL) { SYSLOG(LOG_ERR, "%s: line %jd: bad field count", - TABLE, lineno); + TABLE, i); continue; } if (perm[0] != '+' && perm[0] != '-') { SYSLOG(LOG_ERR, "%s: line %jd: bad first field", - TABLE, lineno); + TABLE, i); continue; } match = ( list_match(froms, from, from_match) From 08befd50450db9a3967611cc49633493bf026fbe Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:32:15 +0200 Subject: [PATCH 09/12] src/login_nopam.c: login_access(): Handle a match earlier This makes the logic more readable, and removes one variable. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index c52bea844b..c14408af4b 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -85,7 +85,6 @@ login_access(const char *user, const char *from) { FILE *fp; char line[BUFSIZ]; - bool match = false; /* * Process the table one line at a time and stop at the first match. @@ -102,7 +101,7 @@ login_access(const char *user, const char *from) return true; // A non-existent table means no access control. } - for (intmax_t i = 1; !match && fgets_a(line, fp) != NULL; i++) { + for (intmax_t i = 1; fgets_a(line, fp) != NULL; i++) { char *p; char *perm; /* becomes permission field */ char *users; /* becomes list of login names */ @@ -135,12 +134,15 @@ login_access(const char *user, const char *from) TABLE, i); continue; } - match = ( list_match(froms, from, from_match) - && list_match(users, user, user_match)); + if ( list_match(froms, from, from_match) + && list_match(users, user, user_match)) + { + fclose(fp); + return !!strprefix(line, "+"); + } } - (void) fclose(fp); - - return (!match || strprefix(line, "+"))?1:0; + fclose(fp); + return true; } /* list_match - match an item against a list of tokens with exceptions */ From 88841c86aab2c13f9eee7c1bffe667e007848a30 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:51:01 +0200 Subject: [PATCH 10/12] src/login_nopam.c: login_access(): Consistently use 'perm' line and perm point to the same thing, but perm is more appropriate. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index c14408af4b..1cdb07a642 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -138,7 +138,7 @@ login_access(const char *user, const char *from) && list_match(users, user, user_match)) { fclose(fp); - return !!strprefix(line, "+"); + return !!strprefix(perm, "+"); } } fclose(fp); From a2606232519e79214546443bd82d2f4c266b9052 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:59:02 +0200 Subject: [PATCH 11/12] src/login_nopam.c: login_access(): Remove redundant comments And remove some superfluous braces. Signed-off-by: Alejandro Colomar --- src/login_nopam.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/login_nopam.c b/src/login_nopam.c index 1cdb07a642..05c9fe47ae 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -86,12 +86,6 @@ login_access(const char *user, const char *from) FILE *fp; char line[BUFSIZ]; - /* - * Process the table one line at a time and stop at the first match. - * Blank lines and lines that begin with a '#' character are ignored. - * Non-comment lines are broken at the ':' character. All fields are - * mandatory. The first field should be a "+" or "-" character. - */ fp = fopen (TABLE, "r"); if (fp == NULL) { if (errno != ENOENT) { @@ -113,13 +107,12 @@ login_access(const char *user, const char *from) TABLE, i); continue; } - if (strprefix(line, "#")) { - continue; /* comment line */ - } + if (strprefix(line, "#")) // comment line + continue; stpcpy(stprspn(line, " \t"), ""); - if (streq(line, "")) { /* skip blank lines */ + if (streq(line, "")) continue; - } + p = line; perm = strsep(&p, ":"); users = strsep(&p, ":"); From 7cc582ca3765897ccb337893f3691b0111401691 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Jun 2026 15:44:30 +0200 Subject: [PATCH 12/12] lib/, src/login_nopam.c: login_access(): Return bool Signed-off-by: Alejandro Colomar --- lib/prototypes.h | 2 +- src/login_nopam.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/prototypes.h b/lib/prototypes.h index d22c477ae1..c3b0d6ef43 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -201,7 +201,7 @@ extern void dolastlog ( #endif /* ENABLE_LASTLOG */ /* login_nopam.c */ -extern int login_access (const char *user, const char *from); +extern bool login_access(const char *user, const char *from); /* loginprompt.c */ extern void login_prompt (char *, int); diff --git a/src/login_nopam.c b/src/login_nopam.c index 05c9fe47ae..c66797ac68 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -80,7 +80,7 @@ static bool from_match (char *tok, const char *string); static const char *resolve_hostname (const char *string); /* login_access - match username/group and host/tty with access control file */ -int +bool login_access(const char *user, const char *from) { FILE *fp;