/* masked_match - match address against netnumber/netmask */ static bool masked_match(const char *tok, const char *slash, const char *s) { struct sockaddr_storage ss_mask; struct sockaddr_storage ss_tok; struct sockaddr_storage ss_host; char *tok_copy = NULL; if (!interpret_string_addr(&ss_host, s, 0)) { return false; } if (*tok == '[') { /* IPv6 address - remove braces. */ tok_copy = SMB_STRDUP(tok+1); if (!tok_copy) { return false; } /* Remove the terminating ']' */ tok_copy[PTR_DIFF(slash,tok)-1] = '\0'; } else { tok_copy = SMB_STRDUP(tok); if (!tok_copy) { return false; } /* Remove the terminating '/' */ tok_copy[PTR_DIFF(slash,tok)] = '\0'; } if (!interpret_string_addr(&ss_tok, tok_copy, 0)) { SAFE_FREE(tok_copy); return false; } SAFE_FREE(tok_copy); if (strlen(slash + 1) > 2) { if (!interpret_string_addr(&ss_mask, slash+1, 0)) { return false; } } else { char *endp = NULL; unsigned long val = strtoul(slash+1, &endp, 0); if (slash+1 == endp || (endp && *endp != '\0')) { return false; } if (!make_netmask(&ss_mask, &ss_tok, val)) { return false; } } return same_net((struct sockaddr *)(void *)&ss_host, (struct sockaddr *)(void *)&ss_tok, (struct sockaddr *)(void *)&ss_mask); }
/** interpret a single element from a interfaces= config line This handles the following different forms: 1) wildcard interface name 2) DNS name 3) IP/masklen 4) ip/mask 5) bcast/mask **/ static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token, struct iface_struct *probed_ifaces, int total_probed, struct interface **local_interfaces, bool enable_ipv6) { struct sockaddr_storage ss; struct sockaddr_storage ss_mask; struct sockaddr_storage ss_net; struct sockaddr_storage ss_bcast; struct iface_struct ifs; char *p; int i; bool added=false; bool goodaddr = false; /* first check if it is an interface name */ for (i=0; i<total_probed; i++) { if (gen_fnmatch(token, probed_ifaces[i].name) == 0) { add_interface(mem_ctx, &probed_ifaces[i], local_interfaces, enable_ipv6); added = true; } } if (added) { return; } /* maybe it is a DNS name */ p = strchr_m(token,'/'); if (p == NULL) { if (!interpret_string_addr(&ss, token, 0)) { DEBUG(2, ("interpret_interface: Can't find address " "for %s\n", token)); return; } for (i=0; i<total_probed; i++) { if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&probed_ifaces[i].ip)) { add_interface(mem_ctx, &probed_ifaces[i], local_interfaces, enable_ipv6); return; } } DEBUG(2,("interpret_interface: " "can't determine interface for %s\n", token)); return; } /* parse it into an IP address/netmasklength pair */ *p = 0; goodaddr = interpret_string_addr(&ss, token, 0); *p++ = '/'; if (!goodaddr) { DEBUG(2,("interpret_interface: " "can't determine interface for %s\n", token)); return; } if (strlen(p) > 2) { goodaddr = interpret_string_addr(&ss_mask, p, 0); if (!goodaddr) { DEBUG(2,("interpret_interface: " "can't determine netmask from %s\n", p)); return; } } else { char *endp = NULL; unsigned long val = strtoul(p, &endp, 0); if (p == endp || (endp && *endp != '\0')) { DEBUG(2,("interpret_interface: " "can't determine netmask value from %s\n", p)); return; } if (!make_netmask(&ss_mask, &ss, val)) { DEBUG(2,("interpret_interface: " "can't apply netmask value %lu from %s\n", val, p)); return; } } make_bcast(&ss_bcast, &ss, &ss_mask); make_net(&ss_net, &ss, &ss_mask); /* Maybe the first component was a broadcast address. */ if (sockaddr_equal((struct sockaddr *)&ss_bcast, (struct sockaddr *)&ss) || sockaddr_equal((struct sockaddr *)&ss_net, (struct sockaddr *)&ss)) { for (i=0; i<total_probed; i++) { if (same_net((struct sockaddr *)&ss, (struct sockaddr *)&probed_ifaces[i].ip, (struct sockaddr *)&ss_mask)) { /* Temporarily replace netmask on * the detected interface - user knows * best.... */ struct sockaddr_storage saved_mask = probed_ifaces[i].netmask; probed_ifaces[i].netmask = ss_mask; DEBUG(2,("interpret_interface: " "using netmask value %s from " "config file on interface %s\n", p, probed_ifaces[i].name)); add_interface(mem_ctx, &probed_ifaces[i], local_interfaces, enable_ipv6); probed_ifaces[i].netmask = saved_mask; return; } } DEBUG(2,("interpret_interface: Can't determine ip for " "broadcast address %s\n", token)); return; } /* Just fake up the interface definition. User knows best. */ DEBUG(2,("interpret_interface: Adding interface %s\n", token)); ZERO_STRUCT(ifs); (void)strlcpy(ifs.name, token, sizeof(ifs.name)); ifs.flags = IFF_BROADCAST; ifs.ip = ss; ifs.netmask = ss_mask; ifs.bcast = ss_bcast; add_interface(mem_ctx, &ifs, local_interfaces, enable_ipv6); }
int check_acl(int fd, const char* ip_address, const char* string_address) { struct acl_s* aclptr; int ret; assert(fd >= 0); assert(ip_address != NULL); assert(string_address != NULL); /* * If there is no access list allow everything. */ aclptr = access_list; if (!aclptr) return 1; while (aclptr) { if (aclptr->type == ACL_STRING) { ret = acl_string_processing(aclptr, ip_address, string_address); if (ret == 0) goto UNAUTHORIZED; else if (ret == 1) return 1; aclptr = aclptr->next; continue; } else { struct in_addr test_addr, match_addr; in_addr_t netmask_addr; if (ip_address[0] == 0) { aclptr = aclptr->next; continue; } /* inet_aton(ip_address, &test_addr); inet_aton(aclptr->location, &match_addr); */ inet_addr(ip_address); inet_addr(aclptr->location); netmask_addr = make_netmask(aclptr->netmask); if ((test_addr.s_addr & netmask_addr) == (match_addr.s_addr & netmask_addr)) { if (aclptr->acl_access == ACL_DENY) goto UNAUTHORIZED; else return 1; } } /* * Dropped through... go on to the next one. */ aclptr = aclptr->next; } /* * Deny all connections by default. */ UNAUTHORIZED: log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].", string_address, ip_address); return 0; }