diff options
Diffstat (limited to 'Linux-PAM/modules/pam_access/pam_access.c')
-rw-r--r-- | Linux-PAM/modules/pam_access/pam_access.c | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/Linux-PAM/modules/pam_access/pam_access.c b/Linux-PAM/modules/pam_access/pam_access.c index 80d94cc9..29a1606c 100644 --- a/Linux-PAM/modules/pam_access/pam_access.c +++ b/Linux-PAM/modules/pam_access/pam_access.c @@ -89,6 +89,9 @@ static const char *sep = ", \t"; /* list-element separator */ #define YES 1 #define NO 0 +/* Only allow group entries of the form "(xyz)" */ +static int only_new_group_syntax = NO; + /* * A structure to bundle up all login-related information to keep the * functional interfaces as generic as possible. @@ -136,6 +139,8 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo, } else if (strcmp (argv[i], "debug") == 0) { pam_access_debug = YES; + } else if (strcmp (argv[i], "nodefgroup") == 0) { + only_new_group_syntax = YES; } else { pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]); } @@ -151,6 +156,7 @@ typedef int match_func (pam_handle_t *, char *, struct login_info *); static int list_match (pam_handle_t *, char *, struct login_info *, match_func *); static int user_match (pam_handle_t *, char *, struct login_info *); +static int group_match (pam_handle_t *, const char *, const char *); static int from_match (pam_handle_t *, char *, struct login_info *); static int string_match (pam_handle_t *, const char *, const char *); static int network_netmask_match (pam_handle_t *, const char *, const char *); @@ -321,6 +327,7 @@ login_access (pam_handle_t *pamh, struct login_info *item) int match = NO; int end; int lineno = 0; /* for diagnostics */ + char *sptr; if (pam_access_debug) pam_syslog (pamh, LOG_DEBUG, @@ -354,9 +361,9 @@ login_access (pam_handle_t *pamh, struct login_info *item) continue; /* Allow field seperator in last field of froms */ - if (!(perm = strtok(line, fs)) - || !(users = strtok((char *) 0, fs)) - || !(froms = strtok((char *) 0, "\n"))) { + if (!(perm = strtok_r(line, fs, &sptr)) + || !(users = strtok_r(NULL, fs, &sptr)) + || !(froms = strtok_r(NULL, "\n", &sptr))) { pam_syslog(pamh, LOG_ERR, "%s: line %d: bad field count", item->config_file, lineno); continue; @@ -398,6 +405,11 @@ static int list_match(pam_handle_t *pamh, { char *tok; int match = NO; + char *sptr; + + if (pam_access_debug) + pam_syslog (pamh, LOG_DEBUG, + "list_match: list=%s, item=%s", list, item->user->pw_name); /* * Process tokens one at a time. We have exhausted all possible matches @@ -406,7 +418,8 @@ static int list_match(pam_handle_t *pamh, * the match is affected by any exceptions. */ - for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) { + for (tok = strtok_r(list, sep, &sptr); tok != 0; + tok = strtok_r(NULL, sep, &sptr)) { if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ break; if ((match = (*match_fn) (pamh, tok, item))) /* YES */ @@ -415,9 +428,9 @@ static int list_match(pam_handle_t *pamh, /* Process exceptions to matches. */ if (match != NO) { - while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT")) + while ((tok = strtok_r(NULL, sep, &sptr)) && strcasecmp(tok, "EXCEPT")) /* VOID */ ; - if (tok == 0 || list_match(pamh, (char *) 0, item, match_fn) == NO) + if (tok == 0 || list_match(pamh, sptr, item, match_fn) == NO) return (match); } return (NO); @@ -425,7 +438,7 @@ static int list_match(pam_handle_t *pamh, /* myhostname - figure out local machine name */ -static char * myhostname(void) +static char *myhostname(void) { static char name[MAXHOSTNAMELEN + 1]; @@ -439,7 +452,7 @@ static char * myhostname(void) /* netgroup_match - match group against machine or user */ static int -netgroup_match (pam_handle_t *pamh, const char *group, +netgroup_match (pam_handle_t *pamh, const char *netgroup, const char *machine, const char *user) { char *mydomain = NULL; @@ -448,11 +461,12 @@ netgroup_match (pam_handle_t *pamh, const char *group, yp_get_default_domain(&mydomain); - retval = innetgr (group, machine, user, mydomain); + retval = innetgr (netgroup, machine, user, mydomain); if (pam_access_debug == YES) pam_syslog (pamh, LOG_DEBUG, - "netgroup_match: %d (group=%s, machine=%s, user=%s, domain=%s)", - retval, group ? group : "NULL", machine ? machine : "NULL", + "netgroup_match: %d (netgroup=%s, machine=%s, user=%s, domain=%s)", + retval, netgroup ? netgroup : "NULL", + machine ? machine : "NULL", user ? user : "NULL", mydomain ? mydomain : "NULL"); return retval; @@ -487,15 +501,45 @@ user_match (pam_handle_t *pamh, char *tok, struct login_info *item) from_match (pamh, at + 1, &fake_item)); } else if (tok[0] == '@') /* netgroup */ return (netgroup_match (pamh, tok + 1, (char *) 0, string)); + else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') + return (group_match (pamh, tok, string)); else if (string_match (pamh, tok, string)) /* ALL or exact match */ - return YES; - else if (pam_modutil_user_in_group_nam_nam (pamh, item->user->pw_name, tok)) + return YES; + else if (only_new_group_syntax == NO && + pam_modutil_user_in_group_nam_nam (pamh, + item->user->pw_name, tok)) /* try group membership */ return YES; return NO; } + +/* group_match - match a username against token named group */ + +static int +group_match (pam_handle_t *pamh, const char *tok, const char* usr) +{ + char grptok[BUFSIZ]; + + if (pam_access_debug) + pam_syslog (pamh, LOG_DEBUG, + "group_match: grp=%s, user=%s", grptok, usr); + + if (strlen(tok) < 3) + return NO; + + /* token is recieved under the format '(...)' */ + memset(grptok, 0, BUFSIZ); + strncpy(grptok, tok + 1, strlen(tok) - 2); + + if (pam_modutil_user_in_group_nam_nam(pamh, usr, grptok)) + return YES; + + return NO; +} + + /* from_match - match a host or tty against a list of tokens */ static int |