📄 domain.c
字号:
switch (q_type) { case T_PTR: /* this is our answer, expand the name, allocate space for it and */ /* set the return information */ rc = dn_expand(answer.qb2, msg_end, msg_ptr, (void *) query_name, MAXDNAME); if (rc >= 0) { *fqdn = (char *) malloc(strlen(query_name) + 1); if (*fqdn == NULL) return FALSE; strcpy(*fqdn, query_name); return TRUE; } break; default: /* unknown response type.. keep looking */ msg_ptr += q_len; } }#endif /* !NO_DNS */ return FALSE;}/**************************************************************************** * check_name_for_ip() * This routine checks to see if a given IP address is a valid IP for a * given name. We need this because lookup_name() only returns the first * IP address in the response, and if a user is coming from a different * IP address for the same machine, we want to make sure that we match * them. ***************************************************************************/int check_name_for_ip(char *name, char *ip){#ifndef NO_DNS#ifdef USE_RES_SEND querybuf question, answer;#else querybuf answer;#endif u_char *msg_end, *msg_ptr; char query_name[MAXDNAME + 1]; int rc, num_answers, num_query, q_type, q_class, q_ttl, q_len; struct in_addr inaddr, qaddr; /* convert the passed IP address into an in_addr (for comparison later) */ /* not all systems have inet_aton(), so use inet_addr() */ if ((qaddr.s_addr = inet_addr(ip)) == (u_long) - 1) { return FALSE; }#ifdef USE_RES_SEND rc = res_mkquery(QUERY, name, C_IN, T_A, NULL, 0, NULL, question.qb2, sizeof(querybuf)); if (rc < 0) { return FALSE; } rc = res_send(question.qb2, rc, answer.qb2, sizeof(querybuf));#else rc = res_query(name, C_IN, T_A, answer.qb2, sizeof(querybuf));#endif if (rc < 0) { return FALSE; } msg_end = (u_char *) & answer + rc; num_answers = ntohs(answer.qb1.ancount); num_query = ntohs(answer.qb1.qdcount); if (num_answers < 1) { /* No answers mean that this hostname doesn't exist.. */ return FALSE; } msg_ptr = answer.qb2 + HFIXEDSZ; /* skip over the query */ for (; (num_query > 0) && (msg_ptr < msg_end); num_query--) { msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; } for (; (num_answers > 0) && (msg_ptr < msg_end); num_answers--) { rc = dn_expand(answer.qb2, msg_end, msg_ptr, (void *) query_name, MAXDNAME); msg_ptr += rc; q_type = _getshort(msg_ptr); msg_ptr += INT16SZ; q_class = _getshort(msg_ptr); msg_ptr += INT16SZ; q_ttl = _getlong(msg_ptr); msg_ptr += INT32SZ; q_len = _getshort(msg_ptr); msg_ptr += INT16SZ; /* look at the type of response that we recieved. If it's a CNAME then */ /* we need to find out what the CNAME's IP is. */ switch (q_type) { case T_CNAME: /* Got a CNAME - hope that there are other answers with the A */ msg_ptr += q_len; break; case T_A: bcopy(msg_ptr, (char *) &inaddr, INADDRSZ); msg_ptr += q_len; if (memcmp(&inaddr, &qaddr, sizeof(struct in_addr)) == 0) { return TRUE; } break; default: /* what the ?? - we don't expect this response type */ return FALSE; } }#endif /* !NO_DNS */ /* no matching IP's */ return FALSE;}/**************************************************************************** * initialize_dns() * initialize the DNS subsystem, set resolver options and collect global * variables. The remote socket is passed to this routine so that it * can set DNS variables related to the remote site. ***************************************************************************/int initialize_dns(struct sockaddr_in *remote_socket){#ifndef NO_DNS struct aclmember *entry = NULL; char *temp_pointer; if (resolver_initialized) return TRUE; /* check to see if the resolver has been initialized already */ if ((_res.options & RES_INIT) == 0) { if ((res_init()) == -1) { /* failed to initialize the resolver */ return FALSE; } } /* load the 'dns resolveroptions X' entries from the config. This will */ /* change when we have the new config file parsing methods */ while (getaclentry("dns", &entry) && ARG0 && ARG1 != NULL) { /* there are other DNS options, we only care about 'resolveroptions' */ if (!strcasecmp(ARG0, "resolveroptions")) { int arg_count; /* read in the options, and set _res.options appropriately */ for (arg_count = 1; ARG[arg_count] != NULL; arg_count++) { int operation = 0; char *option; int table_index; int option_bitvalue; if (ARG[arg_count][0] == '-') { operation = -1; /* want to UNSET option */ option = &ARG[arg_count][1]; } else if (ARG[arg_count][0] == '+') { operation = 1; /* want to SET option */ option = &ARG[arg_count][1]; } if (operation == 0) { /* no operation specified, assume they meant + so do a SET */ operation = 1; option = &ARG[arg_count][0]; } option_bitvalue = 0; /* now lookup option bit value in the resolver_options table */ for (table_index = 0; resolver_options[table_index].token != NULL; table_index++) { if (!strcasecmp(option, resolver_options[table_index].token)) { option_bitvalue = resolver_options[table_index].value; } } /* make sure that we have a valid operation to perform */ if (option_bitvalue == 0) { /* nope. keep looking at other args. */ continue; } /* okay, let's do this operation then */ if (operation < 0) { /* turn *off* option */ _res.options &= ~option_bitvalue; } else { _res.options |= option_bitvalue; } } } } /* save the remote address */ temp_pointer = inet_ntoa(remote_socket->sin_addr); remote_address = (char *) malloc(strlen(temp_pointer) + 1); if (remote_address == NULL) { /* memory error */ return FALSE; } /* size should be identical */ strcpy(remote_address, temp_pointer); /* the old code checks remote_address for 0.0.0.0 and if there's a */ /* match, sets the hostname to 'localhost' - so let's do that for */ /* compatibility and perhaps unknown resolvers which behave this way */ if (!strcmp(remote_address, "0.0.0.0")) { remote_hostname = "localhost"; } else if (lookup_ip(remote_address, &temp_pointer)) { has_reverse_dns = TRUE; /* save the remote hostname (returned from lookup_ip()) */ remote_hostname = (char *) malloc(strlen(temp_pointer) + 1); if (remote_hostname == NULL) { /* memory error */ return FALSE; } /* size should be identical */ strcpy(remote_hostname, temp_pointer); /* ok, we should now have hostname and address based on the real */ /* IP address. Let's check the forward DNS of remote_hostname */ /* and see if we get the same address.. */ has_matching_dns = check_name_for_ip(remote_hostname, inet_ntoa(remote_socket->sin_addr)); } else { has_reverse_dns = FALSE; has_matching_dns = TRUE; /* no reverse, nothing to match */ } resolver_initialized = TRUE;#endif /* !NO_DNS */ return TRUE;}/**************************************************************************** * check_reverse_dns() ***************************************************************************/int check_reverse_dns(void){#ifndef NO_DNS struct aclmember *entry = NULL; int rc = TRUE; /* check the config to see if we care */ while (getaclentry("dns", &entry) && ARG0 && ARG1 != NULL) { if (!strcasecmp(ARG0, "refuse_no_reverse")) { FILE *msg_file; char linebuf[MAXPATHLEN]; char outbuf[MAXPATHLEN]; int code = 530; char *crptr; /* ok, so configuration is telling us to not allow connections */ /* that don't have any reverse DNS */ if (!has_reverse_dns) { /* ok, so we need to kick out this user */ /* check to see if admin wants to override */ if (ARG2 && (!strcasecmp(ARG2, "override"))) { /* Administrative override - but display the warning anyway */ code = 220; } msg_file = fopen(ARG1, "r"); if (msg_file != NULL) { while (fgets(linebuf, sizeof(linebuf), msg_file)) { if ((crptr = strchr(linebuf, '\n')) != NULL) *crptr = '\0'; msg_massage(linebuf, outbuf, sizeof(outbuf)); lreply(code, "%s", outbuf); } fclose(msg_file);#ifndef NO_SUCKING_NEWLINES lreply(code, "");#endif if (code == 530) { reply(code, ""); rc = FALSE; } else { lreply(code, "Administrative Override. Permission granted."); lreply(code, ""); } } } } } return rc;#else /* NO_DNS */ return TRUE;#endif}/**************************************************************************** * check_matching_dns() ***************************************************************************/int check_matching_dns(void){#ifndef NO_DNS struct aclmember *entry = NULL; int rc = TRUE; /* check the config to see if we care */ while (getaclentry("dns", &entry) && ARG0 && ARG1 != NULL) { if (!strcasecmp(ARG0, "refuse_mismatch")) { FILE *msg_file; char linebuf[MAXPATHLEN]; char outbuf[MAXPATHLEN]; int code = 530; char *crptr; /* ok, so configuration is telling us to not allow connections */ /* that don't have any reverse DNS */ if (!has_matching_dns) { /* ok, so we need to kick out this user */ /* check to see if admin wants to override */ if (ARG2 && (!strcasecmp(ARG2, "override"))) { /* Administrative override - but display the warning anyway */ code = 220; } msg_file = fopen(ARG1, "r"); if (msg_file != NULL) { while (fgets(linebuf, sizeof(linebuf), msg_file)) { if ((crptr = strchr(linebuf, '\n')) != NULL) *crptr = '\0'; msg_massage(linebuf, outbuf, sizeof(outbuf)); lreply(code, "%s", outbuf); } fclose(msg_file);#ifndef NO_SUCKING_NEWLINES lreply(code, "");#endif if (code == 530) { reply(code, ""); rc = FALSE; } else { lreply(code, "Administrative Override. Permission granted."); lreply(code, ""); } } } } } return rc;#else /* NO_DNS */ return TRUE;#endif}#endif /* HAVE_LIBRESOLV */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -