static bool is_allowed(cmd_rec *cmd, pr_netaddr_t *na) { int i; config_rec *c; array_header *allowed_acls; c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllow", FALSE); if(NULL == c) return false; allowed_acls = c->argv[0]; if(NULL == allowed_acls) { pr_log_auth(PR_LOG_ERR, "%s: pr_table_t is NULL. something fatal", MODULE_NAME); return false; } #ifdef DEBUG pr_table_do(allowed_acls, walk_table, NULL, 0); #endif pr_netacl_t **elts = allowed_acls->elts; for (i = 0; i < allowed_acls->nelts; i++) { pr_netacl_t *acl = elts[i]; if(pr_netacl_match(acl, na) == 1) { pr_log_auth(PR_LOG_INFO, "%s: client IP matched with LMDBAllow '%s'. Skip last process", MODULE_NAME, pr_netacl_get_str(cmd->tmp_pool, acl)); return true; } } return false; }
END_TEST START_TEST (netacl_match_test) { pr_netacl_t *acl; pr_netaddr_t *addr; char *acl_str; int have_localdomain = FALSE, res; res = pr_netacl_match(NULL, NULL); fail_unless(res == -2, "Failed to handle NULL arguments"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL"); acl_str = "all"; acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, NULL); fail_unless(res == -2, "Failed to handle NULL addr"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL"); addr = pr_netaddr_get_addr(p, "localhost", NULL); fail_unless(addr != NULL, "Failed to get addr for '%s': %s", "localhost", strerror(errno)); /* It's possible that the DNS name for 'localhost' that is used will * actually be 'localhost.localdomain', depending on the contents of * the host's /etc/hosts file. */ if (strcmp(pr_netaddr_get_dnsstr(addr), "localhost.localdomain") == 0) { have_localdomain = TRUE; } res = pr_netacl_match(NULL, addr); fail_unless(res == -2, "Failed to handle NULL ACL"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL"); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); acl_str = "none"; acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == -1, "Failed to negatively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "127.0.0.1"); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "!127.0.0.1"); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == -1, "Failed to negatively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "192.168.0.1"); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 0, "Failed to match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "!192.168.0.1"); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "127.0.0.0/24"); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "!127.0.0.0/24"); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == -1, "Failed to negatively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "127.0.0."); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); acl_str = pstrdup(p, "!127.0.0."); acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == -1, "Failed to negatively match ACL to addr: %s", strerror(errno)); if (!have_localdomain) { acl_str = pstrdup(p, "localhost"); } else { acl_str = pstrdup(p, "localhost.localdomain"); } acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); if (!have_localdomain) { acl_str = pstrdup(p, "!localhost"); } else { acl_str = pstrdup(p, "!localhost.localdomain"); } acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == -1, "Failed to negatively match ACL to addr: %s", strerror(errno)); if (!have_localdomain) { acl_str = pstrdup(p, "loc*st"); } else { acl_str = pstrdup(p, "loc*st.loc*in"); } acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == 1, "Failed to positively match ACL to addr: %s", strerror(errno)); if (!have_localdomain) { acl_str = pstrdup(p, "!loc*st"); } else { acl_str = pstrdup(p, "!loc*st.loc*in"); } acl = pr_netacl_create(p, acl_str); fail_unless(acl != NULL, "Failed to handle ACL string '%s': %s", acl_str, strerror(errno)); res = pr_netacl_match(acl, addr); fail_unless(res == -1, "Failed to negatively match ACL to addr: %s", strerror(errno)); }
pr_class_t *pr_class_match_addr(pr_netaddr_t *addr) { pr_class_t *cls; pool *tmp_pool; if (!addr) { errno = EINVAL; return NULL; } tmp_pool = make_sub_pool(permanent_pool); for (cls = class_list; cls; cls = cls->cls_next) { array_header *acl_list = cls->cls_acls; pr_netacl_t **acls = acl_list->elts; register int i; int next_class = FALSE; /* For each ACL rule in this class, compare the rule against the given * address. The address matches the given class depending on the * Satisfy setting: if "any", the class matches if any rule matches; * if "all", the class matches only if _all_ rules match. */ for (i = 0; i < acl_list->nelts; i++) { int res; if (next_class) break; if (acls[i] == NULL) continue; switch (cls->cls_satisfy) { case PR_CLASS_SATISFY_ANY: pr_trace_msg(trace_channel, 6, "checking addr '%s' (%s) against class '%s' rule: %s " "(requires any ACL matching)", pr_netaddr_get_ipstr(addr), pr_netaddr_get_dnsstr(addr), cls->cls_name, pr_netacl_get_str(tmp_pool, acls[i])); res = pr_netacl_match(acls[i], addr); if (res == 1) { destroy_pool(tmp_pool); return cls; } break; case PR_CLASS_SATISFY_ALL: pr_trace_msg(trace_channel, 6, "checking addr '%s' (%s) against class '%s' ACL: %s " "(requires all ACLs matching)", pr_netaddr_get_ipstr(addr), pr_netaddr_get_dnsstr(addr), cls->cls_name, pr_netacl_get_str(tmp_pool, acls[i])); res = pr_netacl_match(acls[i], addr); if (res <= 0) next_class = TRUE; break; } } /* If this is a "Satisfy all" class, and all rules have matched * (positively or negatively), then it matches the address. */ if (next_class == FALSE && cls->cls_satisfy == PR_CLASS_SATISFY_ALL && i == acl_list->nelts) { destroy_pool(tmp_pool); return cls; } } destroy_pool(tmp_pool); errno = ENOENT; return NULL; }