static int from_match(const char *tok, const char *string) { int tok_len; int str_len; /* * If a token has the magic value "ALL" the match always succeeds. Return * YES if the token fully matches the string. If the token is a domain * name, return YES if it matches the last fields of the string. If the * token has the magic value "LOCAL", return YES if the string does not * contain a "." character. If the token is a network number, return YES * if it matches the head of the string. */ if (tok[0] == '@') { /* netgroup */ return (netgroup_match(tok + 1, string, NULL)); } else if (string_match(tok, string)) { /* ALL or exact match */ return (YES); } else if (tok[0] == '.') { /* domain: match last fields */ if ((str_len = strlen(string)) > (tok_len = strlen(tok)) && strcasecmp(tok, string + str_len - tok_len) == 0) return (YES); } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ if (strchr(string, '.') == 0) return (YES); } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */ && strncmp(tok, string, tok_len) == 0) { return (YES); } return (NO); }
static int from_match(char *tok, struct login_info *item) { char *string = item->from; int tok_len; int str_len; /* * If a token has the magic value "ALL" the match always succeeds. Return * YES if the token fully matches the string. If the token is a domain * name, return YES if it matches the last fields of the string. If the * token has the magic value "LOCAL", return YES if the string does not * contain a "." character. If the token is a network number, return YES * if it matches the head of the string. */ if (tok[0] == '@') { /* netgroup */ return (netgroup_match(tok + 1, string, (char *) 0)); } else if (string_match(tok, string)) { /* ALL or exact match */ return (YES); } else if (tok[0] == '.') { /* domain: match last fields */ if ((str_len = strlen(string)) > (tok_len = strlen(tok)) && strcasecmp(tok, string + str_len - tok_len) == 0) return (YES); } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ if (strchr(string, '.') == 0) return (YES); #ifdef BROKEN_NETWORK_MATCH } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */ && strncmp(tok, string, tok_len) == 0) { return (YES); #else /* BROKEN_NETWORK_MATCH */ } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* The code below does a more correct check if the address specified by "string" starts from "tok". 1998/01/27 Andrey V. Savochkin <*****@*****.**> */ struct hostent *h; char hn[3+1+3+1+3+1+3+1+1]; int r; h = gethostbyname(string); if (h == NULL) return (NO); if (h->h_addrtype != AF_INET) return (NO); if (h->h_length != 4) return (NO); /* only IPv4 addresses (SAW) */ r = snprintf(hn, sizeof(hn), "%u.%u.%u.%u.", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); if (r < 0 || r >= sizeof(hn)) return (NO); if (!strncmp(tok, hn, tok_len)) return (YES); #endif /* BROKEN_NETWORK_MATCH */ } return (NO); }
static int user_match(char *tok, struct login_info *item) { char *string = item->user->pw_name; struct login_info fake_item; struct group *group; int i; char *at; /* * If a token has the magic value "ALL" the match always succeeds. * Otherwise, return YES if the token fully matches the username, if the * token is a group that contains the username, or if the token is the * name of the user's primary group. */ if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */ *at = 0; fake_item.from = myhostname(); return (user_match(tok, item) && from_match(at + 1, &fake_item)); } else if (tok[0] == '@') { /* netgroup */ return (netgroup_match(tok + 1, (char *) 0, string)); } else if (string_match(tok, string)) { /* ALL or exact match */ return (YES); } else if ((group = getgrnam(tok))) { /* try group membership */ if (item->user->pw_gid == group->gr_gid) return (YES); for (i = 0; group->gr_mem[i]; i++) if (strcasecmp(string, group->gr_mem[i]) == 0) return (YES); } return (NO); }
static int user_match (pam_handle_t *pamh, char *tok, struct login_info *item) { char *string = item->user->pw_name; struct login_info fake_item; char *at; int rv; if (item->debug) pam_syslog (pamh, LOG_DEBUG, "user_match: tok=%s, item=%s", tok, string); /* * If a token has the magic value "ALL" the match always succeeds. * Otherwise, return YES if the token fully matches the username, if the * token is a group that contains the username, or if the token is the * name of the user's primary group. */ /* Try to split on a pattern (@*[^@]+)(@+.*) */ for (at = tok; *at == '@'; ++at); if ((at = strchr(at, '@')) != NULL) { /* split user@host pattern */ if (item->hostname == NULL) return NO; memcpy (&fake_item, item, sizeof(fake_item)); fake_item.from = item->hostname; fake_item.gai_rv = 0; fake_item.res = NULL; fake_item.from_remote_host = 1; /* hostname should be resolvable */ *at = 0; if (!user_match (pamh, tok, item)) return NO; rv = from_match (pamh, at + 1, &fake_item); if (fake_item.gai_rv == 0 && fake_item.res) freeaddrinfo(fake_item.res); return rv; } else if (tok[0] == '@') { /* netgroup */ const char *hostname = NULL; if (tok[1] == '@') { /* add hostname to netgroup match */ if (item->hostname == NULL) return NO; ++tok; hostname = item->hostname; } return (netgroup_match (pamh, tok + 1, hostname, string, item->debug)); } else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') return (group_match (pamh, tok, string, item->debug)); else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */ return rv; else if (item->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; }
/* user_match - match a username against one token */ static bool user_match (const char *tok, const char *string) { struct group *group; #ifdef PRIMARY_GROUP_MATCH struct passwd *userinf; #endif char *at; /* * If a token has the magic value "ALL" the match always succeeds. * Otherwise, return true if the token fully matches the username, or if * the token is a group that contains the username. */ at = strchr (tok + 1, '@'); if (NULL != at) { /* split user@host pattern */ *at = '\0'; return ( user_match (tok, string) && from_match (at + 1, myhostname ())); #if HAVE_INNETGR } else if (tok[0] == '@') { /* netgroup */ return (netgroup_match (tok + 1, (char *) 0, string)); #endif } else if (string_match (tok, string)) { /* ALL or exact match */ return true; /* local, no need for xgetgrnam */ } else if ((group = getgrnam (tok)) != NULL) { /* try group membership */ int i; for (i = 0; NULL != group->gr_mem[i]; i++) { if (strcasecmp (string, group->gr_mem[i]) == 0) { return true; } } #ifdef PRIMARY_GROUP_MATCH /* * If the string is an user whose initial GID matches the token, * accept it. May avoid excessively long lines in /etc/group. * Radu-Adrian Feurdean <*****@*****.**> * * XXX - disabled by default for now. Need to verify that * getpwnam() doesn't have some nasty side effects. --marekm */ /* local, no need for xgetpwnam */ userinf = getpwnam (string); if (NULL != userinf) { if (userinf->pw_gid == group->gr_gid) { return true; } } #endif } return false; }
static int user_match (pam_handle_t *pamh, char *tok, struct login_info *item) { char *string = item->user->pw_name; struct login_info fake_item; char *at; int rv; if (item->debug) pam_syslog (pamh, LOG_DEBUG, "user_match: tok=%s, item=%s", tok, string); /* * If a token has the magic value "ALL" the match always succeeds. * Otherwise, return YES if the token fully matches the username, if the * token is a group that contains the username, or if the token is the * name of the user's primary group. */ if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */ if (item->hostname == NULL) return NO; fake_item.from = item->hostname; *at = 0; return (user_match (pamh, tok, item) && from_match (pamh, at + 1, &fake_item)); } else if (tok[0] == '@') { /* netgroup */ const char *hostname = NULL; if (tok[1] == '@') { /* add hostname to netgroup match */ if (item->hostname == NULL) return NO; ++tok; hostname = item->hostname; } return (netgroup_match (pamh, tok + 1, hostname, string, item->debug)); } else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') return (group_match (pamh, tok, string, item->debug)); else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */ return rv; else if (item->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; }
static int user_match(const char *tok, const char *string) { struct group *group; int i; /* * If a token has the magic value "ALL" the match always succeeds. * Otherwise, return YES if the token fully matches the username, or if * the token is a group that contains the username. */ if (tok[0] == '@') { /* netgroup */ return (netgroup_match(tok + 1, NULL, string)); } else if (string_match(tok, string)) { /* ALL or exact match */ return (YES); } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */ for (i = 0; group->gr_mem[i]; i++) if (strcasecmp(string, group->gr_mem[i]) == 0) return (YES); } return (NO); }
static bool from_match (const char *tok, const char *string) { size_t tok_len; /* * If a token has the magic value "ALL" the match always succeeds. Return * true if the token fully matches the string. If the token is a domain * name, return true if it matches the last fields of the string. If the * token has the magic value "LOCAL", return true if the string does not * contain a "." character. If the token is a network number, return true * if it matches the head of the string. */ #if HAVE_INNETGR if (tok[0] == '@') { /* netgroup */ return (netgroup_match (tok + 1, string, (char *) 0)); } else #endif if (string_match (tok, string)) { /* ALL or exact match */ return true; } else if (tok[0] == '.') { /* domain: match last fields */ size_t str_len; str_len = strlen (string); tok_len = strlen (tok); if ( (str_len > tok_len) && (strcasecmp (tok, string + str_len - tok_len) == 0)) { return true; } } else if (strcasecmp (tok, "LOCAL") == 0) { /* local: no dots */ if (strchr (string, '.') == NULL) { return true; } } else if ( (tok[(tok_len = strlen (tok)) - 1] == '.') /* network */ && (strncmp (tok, resolve_hostname (string), tok_len) == 0)) { return true; } return false; }