/* return true if access should be allowed */ BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr) { char *client[2]; client[0] = cname; client[1] = caddr; /* if theres no deny list and no allow list then allow access */ if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0)) return(True); /* if there is an allow list but no deny list then allow only hosts on the allow list */ if (!deny_list || *deny_list == 0) return(list_match(allow_list,(char *)client,CLIENT_MATCH)); /* if theres a deny list but no allow list then allow all hosts not on the deny list */ if (!allow_list || *allow_list == 0) return(!list_match(deny_list,(char *)client,CLIENT_MATCH)); /* if there are both type of list then allow all hosts on the allow list */ if (list_match(allow_list,(char *)client,CLIENT_MATCH)) return (True); /* if there are both type of list and it's not on the allow then allow it if its not on the deny */ if (list_match(deny_list,(char *)client,CLIENT_MATCH)) return (False); return (True); }
int 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 */ int match = NO; int end; int lineno = 0; /* for diagnostics */ /* * 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. */ if ((fp = fopen(_PATH_LOGACCESS, "r")) != NULL) { while (!match && fgets(line, sizeof(line), fp)) { lineno++; if (line[end = strlen(line) - 1] != '\n') { syslog(LOG_ERR, "%s: line %d: missing newline or line too long", _PATH_LOGACCESS, lineno); continue; } if (line[0] == '#') continue; /* comment line */ while (end > 0 && isspace(line[end - 1])) end--; line[end] = 0; /* strip trailing whitespace */ if (line[0] == 0) /* skip blank lines */ continue; if (!(perm = strtok(line, fs)) || !(users = strtok(NULL, fs)) || !(froms = strtok(NULL, fs)) || strtok(NULL, fs)) { syslog(LOG_ERR, "%s: line %d: bad field count", _PATH_LOGACCESS, lineno); continue; } if (perm[0] != '+' && perm[0] != '-') { syslog(LOG_ERR, "%s: line %d: bad first field", _PATH_LOGACCESS, lineno); continue; } match = (list_match(froms, from, from_match) && list_match(users, user, user_match)); } fclose(fp); } else if (errno != ENOENT) { syslog(LOG_ERR, "cannot open %s: %m", _PATH_LOGACCESS); } return (match == 0 || (line[0] == '+')); }
static int list_match(char *list, const char *item, int (*match_fn)(const char *, const char *)) { char *tok; int match = NO; /* * Process tokens one at a time. We have exhausted all possible matches * when we reach an "EXCEPT" token or the end of the list. If we do find * a match, look for an "EXCEPT" list and recurse to determine whether * the match is affected by any exceptions. */ for (tok = strtok(list, sep); tok != 0; tok = strtok(NULL, sep)) { if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ break; if ((match = (*match_fn)(tok, item)) != 0) /* YES */ break; } /* Process exceptions to matches. */ if (match != NO) { while ((tok = strtok(NULL, sep)) && strcasecmp(tok, "EXCEPT")) /* VOID */ ; if (tok == 0 || list_match(NULL, item, match_fn) == NO) return (match); } return (NO); }
/* list_match - match an item against a list of tokens with exceptions */ static bool list_match (char *list, const char *item, bool (*match_fn) (const char *, const char*)) { char *tok; bool match = false; /* * Process tokens one at a time. We have exhausted all possible matches * when we reach an "EXCEPT" token or the end of the list. If we do find * a match, look for an "EXCEPT" list and recurse to determine whether * the match is affected by any exceptions. */ for (tok = strtok (list, sep); tok != NULL; tok = strtok ((char *) 0, sep)) { if (strcasecmp (tok, "EXCEPT") == 0) { /* EXCEPT: give up */ break; } match = (*match_fn) (tok, item); if (match) { break; } } /* Process exceptions to matches. */ if (match) { while ( ((tok = strtok ((char *) 0, sep)) != NULL) && (strcasecmp (tok, "EXCEPT") != 0)) /* VOID */ ; if (tok == 0 || !list_match ((char *) 0, item, match_fn)) { return (match); } } return false; }
int ipv4_white_list_match(uint32_t addr, char **descr_ret) { int rv; FUN("ipv4_white_list_match"); rv = list_match(addr, &white_list, &white_list_items, &white_list_alloc, descr_ret); return rv; }
/** * check whether the client belongs to the hosts * for which initial logon should be delayed... */ static bool delay_logon(const char *peer_name, const char *peer_addr) { const char **delay_list = lp_init_logon_delayed_hosts(); const char *peer[2]; if (delay_list == NULL) { return False; } peer[0] = peer_name; peer[1] = peer_addr; return list_match(delay_list, (const char *)peer, client_match); }
/* return true if access should be allowed */ static bool allow_access_internal(const char **deny_list, const char **allow_list, const char *cname, const char *caddr) { const char *client[2]; client[NAME_INDEX] = cname; client[ADDR_INDEX] = caddr; /* if it is loopback then always allow unless specifically denied */ if (strcmp(caddr, "127.0.0.1") == 0 || strcmp(caddr, "::1") == 0) { /* * If 127.0.0.1 matches both allow and deny then allow. * Patch from Steve Langasek [email protected]. */ if (deny_list && list_match(deny_list,client,client_match) && (!allow_list || !list_match(allow_list,client, client_match))) { return false; } return true; } /* if theres no deny list and no allow list then allow access */ if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0)) { return true; } /* if there is an allow list but no deny list then allow only hosts on the allow list */ if (!deny_list || *deny_list == 0) { return(list_match(allow_list,client,client_match)); } /* if theres a deny list but no allow list then allow all hosts not on the deny list */ if (!allow_list || *allow_list == 0) { return(!list_match(deny_list,client,client_match)); } /* if there are both types of list then allow all hosts on the allow list */ if (list_match(allow_list,(const char *)client,client_match)) { return true; } /* if there are both types of list and it's not on the allow then allow it if its not on the deny */ if (list_match(deny_list,(const char *)client,client_match)) { return false; } return true; }
/* return true if access should be allowed */ BOOL allow_access(char *deny_list,char *allow_list, char *cname,char *caddr) { char *client[2]; client[0] = cname; client[1] = caddr; /* if it is loopback then always allow unless specifically denied */ if (strcmp(caddr, "127.0.0.1") == 0) { /* * If 127.0.0.1 matches both allow and deny then allow. * Patch from Steve Langasek [email protected]. */ if (deny_list && list_match(deny_list,(char *)client,client_match) && (!allow_list || !list_match(allow_list,(char *)client, client_match))) { return False; } return True; } /* if theres no deny list and no allow list then allow access */ if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0)) { return(True); } /* if there is an allow list but no deny list then allow only hosts on the allow list */ if (!deny_list || *deny_list == 0) return(list_match(allow_list,(char *)client,client_match)); /* if theres a deny list but no allow list then allow all hosts not on the deny list */ if (!allow_list || *allow_list == 0) return(!list_match(deny_list,(char *)client,client_match)); /* if there are both type of list then allow all hosts on the allow list */ if (list_match(allow_list,(char *)client,client_match)) return (True); /* if there are both type of list and it's not on the allow then allow it if its not on the deny */ if (list_match(deny_list,(char *)client,client_match)) return (False); return (True); }
int process_banned(int sock,char *host) { int n; char buffer[128]; for (n=0;n<bancount;n++) if (list_match(host,banlist[n])) { #ifdef DEBUG fprintf(stderr,"Ban hit '%s'\n",host); #endif if (banmessage[0]!=0) { sprintf(buffer,"540 %s\r\n",banmessage); write(sock,buffer,strlen(buffer)); } close(sock); return 1; } return 0; }
/* (All modifications are marked with the initials "jkf") */ static int list_match(char *list,char *item, int (*match_fn)(char *,char *)) { char *tok; char *listcopy; /* jkf */ int match = NO; /* * [email protected] -- 31 August 1994 -- Stop list_match() * overwriting the list given as its first parameter. */ /* jkf -- can get called recursively with NULL list */ listcopy = (list == 0) ? (char *)0 : strdup(list); /* * Process tokens one at a time. We have exhausted all possible matches * when we reach an "EXCEPT" token or the end of the list. If we do find * a match, look for an "EXCEPT" list and recurse to determine whether * the match is affected by any exceptions. */ for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep)) { if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ break; if ((match = (*match_fn) (tok, item))) /* YES or FAIL */ break; } /* Process exceptions to YES or FAIL matches. */ if (match != NO) { while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT")) /* VOID */ ; if (tok == 0 || list_match((char *) 0, item, match_fn) == NO) { if (listcopy != 0) free(listcopy); /* jkf */ return (match); } } if (listcopy != 0) free(listcopy); /* jkf */ return (NO); }
static int list_match(pam_handle_t *pamh, char *list, char *sptr, struct login_info *item, match_func *match_fn) { char *tok; int match = NO; if (item->debug && list != NULL) 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 * when we reach an "EXCEPT" token or the end of the list. If we do find * a match, look for an "EXCEPT" list and recurse to determine whether * the match is affected by any exceptions. */ for (tok = strtok_r(list, item->sep, &sptr); tok != 0; tok = strtok_r(NULL, item->sep, &sptr)) { if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ break; if ((match = (*match_fn) (pamh, tok, item))) /* YES */ break; } /* Process exceptions to matches. */ if (match != NO) { while ((tok = strtok_r(NULL, item->sep, &sptr)) && strcasecmp(tok, "EXCEPT")) /* VOID */ ; if (tok == 0) return match; if (list_match(pamh, NULL, sptr, item, match_fn) == NO) return YES; /* drop special meaning of ALL */ } return (NO); }
static int login_access (pam_handle_t *pamh, struct login_info *item) { 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 */ int match = NO; int nonall_match = NO; int end; int lineno = 0; /* for diagnostics */ char *sptr; if (item->debug) pam_syslog (pamh, LOG_DEBUG, "login_access: user=%s, from=%s, file=%s", item->user->pw_name, item->from, item->config_file); /* * 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. */ if ((fp = fopen(item->config_file, "r"))!=NULL) { while (!match && fgets(line, sizeof(line), fp)) { lineno++; if (line[end = strlen(line) - 1] != '\n') { pam_syslog(pamh, LOG_ERR, "%s: line %d: missing newline or line too long", item->config_file, lineno); continue; } if (line[0] == '#') continue; /* comment line */ while (end > 0 && isspace(line[end - 1])) end--; line[end] = 0; /* strip trailing whitespace */ if (line[0] == 0) /* skip blank lines */ continue; /* Allow field seperator in last field of froms */ if (!(perm = strtok_r(line, item->fs, &sptr)) || !(users = strtok_r(NULL, item->fs, &sptr)) || !(froms = strtok_r(NULL, "\n", &sptr))) { pam_syslog(pamh, LOG_ERR, "%s: line %d: bad field count", item->config_file, lineno); continue; } if (perm[0] != '+' && perm[0] != '-') { pam_syslog(pamh, LOG_ERR, "%s: line %d: bad first field", item->config_file, lineno); continue; } if (item->debug) pam_syslog (pamh, LOG_DEBUG, "line %d: %s : %s : %s", lineno, perm, users, froms); match = list_match(pamh, users, NULL, item, user_match); if (item->debug) pam_syslog (pamh, LOG_DEBUG, "user_match=%d, \"%s\"", match, item->user->pw_name); if (match) { match = list_match(pamh, froms, NULL, item, from_match); if (!match && perm[0] == '+') { nonall_match = YES; } if (item->debug) pam_syslog (pamh, LOG_DEBUG, "from_match=%d, \"%s\"", match, item->from); } } (void) fclose(fp); } else if (errno == ENOENT) { /* This is no error. */ pam_syslog(pamh, LOG_WARNING, "warning: cannot open %s: %m", item->config_file); } else { pam_syslog(pamh, LOG_ERR, "cannot open %s: %m", item->config_file); return NO; } #ifdef HAVE_LIBAUDIT if (!item->noaudit && line[0] == '-' && (match == YES || (match == ALL && nonall_match == YES))) { pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_LOCATION, "pam_access", 0); } #endif return (match == NO || (line[0] == '+')); }
/* login_access - match username/group and host/tty with access control file */ int 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; /* * 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. */ fp = fopen (TABLE, "r"); if (NULL != fp) { int lineno = 0; /* for diagnostics */ while ( !match && (fgets (line, (int) sizeof (line), fp) == line)) { int end; lineno++; end = (int) strlen (line) - 1; if (line[end] != '\n') { SYSLOG ((LOG_ERR, "%s: line %d: missing newline or line too long", TABLE, lineno)); continue; } if (line[0] == '#') { continue; /* comment line */ } while (end > 0 && isspace (line[end - 1])) { end--; } line[end] = '\0'; /* strip trailing whitespace */ if (line[0] == '\0') { /* skip blank lines */ continue; } if ( ((perm = strtok (line, fs)) == NULL) || ((users = strtok ((char *) 0, fs)) == NULL) || ((froms = strtok ((char *) 0, fs)) == NULL) || (strtok ((char *) 0, fs) != NULL)) { SYSLOG ((LOG_ERR, "%s: line %d: bad field count", TABLE, lineno)); continue; } if (perm[0] != '+' && perm[0] != '-') { SYSLOG ((LOG_ERR, "%s: line %d: bad first field", TABLE, lineno)); continue; } match = ( list_match (froms, from, from_match) && 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 || (line[0] == '+'))?1:0; }