dlz_ldap_driver.c
来自「非常好的dns解析软件」· C语言 代码 · 共 1,340 行 · 第 1/3 页
C
1,340 行
break; case 1: j++; type = isc_mem_strdup(ns_g_mctx, vals[0]); break; case 2: j++; if (allnodes == isc_boolean_true) { host = isc_mem_strdup(ns_g_mctx, vals[0]); } else { strcpy(data, vals[0]); } break; case 3: j++; if (allnodes == isc_boolean_true) { strcpy(data, vals[0]); } else { strcat(data, " "); strcat(data, vals[0]); } break; default: strcat(data, " "); strcat(data, vals[0]); break; } /* end switch(j) */ /* free values */ ldap_value_free(vals); vals = NULL; /* increment attibute pointer */ attribute = attrs[++i]; } /* end while (attribute != NULL) */ if (type == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver unable " "to retrieve dns type"); result = ISC_R_FAILURE; goto cleanup; } if (strlen(data) < 1) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver unable " "to retrieve dns data"); result = ISC_R_FAILURE; goto cleanup; } if (allnodes == isc_boolean_true) { if (strcasecmp(host, "~") == 0) result = dns_sdlz_putnamedrr( (dns_sdlzallnodes_t *) ptr, "*", type, ttl, data); else result = dns_sdlz_putnamedrr( (dns_sdlzallnodes_t *) ptr, host, type, ttl, data); } else result = dns_sdlz_putrr((dns_sdlzlookup_t *) ptr, type, ttl, data); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver failed " "while sending data to Bind."); goto cleanup; } /* free memory for type, data and host for next loop */ isc_mem_free(ns_g_mctx, type); isc_mem_free(ns_g_mctx, data); if (host != NULL) isc_mem_free(ns_g_mctx, host); /* get the next entry to process */ entry = ldap_next_entry(dbc, entry); } /* end while (entry != NULL) */ cleanup: /* de-allocate memory */ if (vals != NULL) ldap_value_free(vals); if (host != NULL) isc_mem_free(ns_g_mctx, host); if (type != NULL) isc_mem_free(ns_g_mctx, type); if (data != NULL) isc_mem_free(ns_g_mctx, data); return result;}/*% * This function is the real core of the driver. Zone, record * and client strings are passed in (or NULL is passed if the * string is not available). The type of query we want to run * is indicated by the query flag, and the dbdata object is passed * passed in to. dbdata really holds either: * 1) a list of database instances (in multithreaded mode) OR * 2) a single database instance (in single threaded mode) * The function will construct the query and obtain an available * database instance (DBI). It will then run the query and hopefully * obtain a result set. */static isc_result_tldap_get_results(const char *zone, const char *record, const char *client, unsigned int query, void *dbdata, void *ptr){ isc_result_t result; dbinstance_t *dbi = NULL; char *querystring = NULL; LDAPURLDesc *ldap_url = NULL; int ldap_result = 0; LDAPMessage *ldap_msg = NULL; int i; int entries; /* get db instance / connection */#ifdef ISC_PLATFORM_USETHREADS /* find an available DBI from the list */ dbi = ldap_find_avail_conn((db_list_t *) ((ldap_instance_t *)dbdata)->db);#else /* ISC_PLATFORM_USETHREADS */ /* * only 1 DBI - no need to lock instance lock either * only 1 thread in the whole process, no possible contention. */ dbi = (dbinstance_t *) ((ldap_instance_t *)dbdata)->db;#endif /* ISC_PLATFORM_USETHREADS */ /* if DBI is null, can't do anything else */ if (dbi == NULL) return ISC_R_FAILURE; /* set fields */ if (zone != NULL) { dbi->zone = isc_mem_strdup(ns_g_mctx, zone); if (dbi->zone == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } else { dbi->zone = NULL; } if (record != NULL) { dbi->record = isc_mem_strdup(ns_g_mctx, record); if (dbi->record == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } else { dbi->record = NULL; } if (client != NULL) { dbi->client = isc_mem_strdup(ns_g_mctx, client); if (dbi->client == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } else { dbi->client = NULL; } /* what type of query are we going to run? */ switch(query) { case ALLNODES: /* * if the query was not passed in from the config file * then we can't run it. return not_implemented, so * it's like the code for that operation was never * built into the driver.... AHHH flexibility!!! */ if (dbi->allnodes_q == NULL) { result = ISC_R_NOTIMPLEMENTED; goto cleanup; } else { querystring = build_querystring(ns_g_mctx, dbi->allnodes_q); } break; case ALLOWXFR: /* same as comments as ALLNODES */ if (dbi->allowxfr_q == NULL) { result = ISC_R_NOTIMPLEMENTED; goto cleanup; } else { querystring = build_querystring(ns_g_mctx, dbi->allowxfr_q); } break; case AUTHORITY: /* same as comments as ALLNODES */ if (dbi->authority_q == NULL) { result = ISC_R_NOTIMPLEMENTED; goto cleanup; } else { querystring = build_querystring(ns_g_mctx, dbi->authority_q); } break; case FINDZONE: /* this is required. It's the whole point of DLZ! */ if (dbi->findzone_q == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "No query specified for findzone. " "Findzone requires a query"); result = ISC_R_FAILURE; goto cleanup; } else { querystring = build_querystring(ns_g_mctx, dbi->findzone_q); } break; case LOOKUP: /* this is required. It's also a major point of DLZ! */ if (dbi->lookup_q == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "No query specified for lookup. " "Lookup requires a query"); result = ISC_R_FAILURE; goto cleanup; } else { querystring = build_querystring(ns_g_mctx, dbi->lookup_q); } break; default: /* * this should never happen. If it does, the code is * screwed up! */ UNEXPECTED_ERROR(__FILE__, __LINE__, "Incorrect query flag passed to " "ldap_get_results"); result = ISC_R_UNEXPECTED; goto cleanup; } /* if the querystring is null, Bummer, outta RAM. UPGRADE TIME!!! */ if (querystring == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } /* * output the full query string during debug so we can see * what lame error the query has. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1), "\nQuery String: %s\n", querystring); /* break URL down into it's component parts, if error cleanup */ ldap_result = ldap_url_parse(querystring, &ldap_url); if (ldap_result != LDAP_SUCCESS || ldap_url == NULL) { result = ISC_R_FAILURE; goto cleanup; } for (i=0; i < 3; i++) { /* * dbi->dbconn may be null if trying to reconnect on a * previous query failed. */ if (dbi->dbconn == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP driver attempting to re-connect"); result = dlz_ldap_connect((ldap_instance_t *) dbdata, dbi); if (result != ISC_R_SUCCESS) { result = ISC_R_FAILURE; continue; } } /* perform ldap search syncronously */ ldap_result = ldap_search_s((LDAP *) dbi->dbconn, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, ldap_url->lud_attrs, 0, &ldap_msg); /* * check return code. No such object is ok, just * didn't find what we wanted */ switch(ldap_result) { case LDAP_NO_SUCH_OBJECT: isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1), "No object found matching " "query requirements"); result = ISC_R_NOTFOUND; goto cleanup; break; case LDAP_SUCCESS: /* on success do nothing */ result = ISC_R_SUCCESS; i = 3; break; case LDAP_SERVER_DOWN: isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP driver attempting to re-connect"); result = dlz_ldap_connect((ldap_instance_t *) dbdata, dbi); if (result != ISC_R_SUCCESS) result = ISC_R_FAILURE; break; default: /* * other errors not ok. Log error message and * get out */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP error: %s", ldap_err2string(ldap_result)); result = ISC_R_FAILURE; goto cleanup; break; } /* close switch(ldap_result) */ } /* end for (int i=0 i < 3; i++) */ if (result != ISC_R_SUCCESS) goto cleanup; switch(query) { case ALLNODES: result = ldap_process_results((LDAP *) dbi->dbconn, ldap_msg, ldap_url->lud_attrs, ptr, isc_boolean_true); break; case AUTHORITY: case LOOKUP: result = ldap_process_results((LDAP *) dbi->dbconn, ldap_msg, ldap_url->lud_attrs, ptr, isc_boolean_false); break; case ALLOWXFR: entries = ldap_count_entries((LDAP *) dbi->dbconn, ldap_msg); if (entries == 0) result = ISC_R_NOPERM; else if (entries > 0) result = ISC_R_SUCCESS; else result = ISC_R_FAILURE; break; case FINDZONE: entries = ldap_count_entries((LDAP *) dbi->dbconn, ldap_msg); if (entries == 0) result = ISC_R_NOTFOUND; else if (entries > 0) result = ISC_R_SUCCESS; else result = ISC_R_FAILURE; break; default: /* * this should never happen. If it does, the code is * screwed up! */ UNEXPECTED_ERROR(__FILE__, __LINE__, "Incorrect query flag passed to " "ldap_get_results"); result = ISC_R_UNEXPECTED; } cleanup: /* it's always good to cleanup after yourself */ /* if we retrieved results, free them */ if (ldap_msg != NULL) ldap_msgfree(ldap_msg); if (ldap_url != NULL) ldap_free_urldesc(ldap_url); /* cleanup */ if (dbi->zone != NULL) isc_mem_free(ns_g_mctx, dbi->zone); if (dbi->record != NULL) isc_mem_free(ns_g_mctx, dbi->record); if (dbi->client != NULL) isc_mem_free(ns_g_mctx, dbi->client);#ifdef ISC_PLATFORM_USETHREADS /* release the lock so another thread can use this dbi */ isc_mutex_unlock(&dbi->instance_lock);#endif /* ISC_PLATFORM_USETHREADS */ /* release query string */ if (querystring != NULL) isc_mem_free(ns_g_mctx, querystring ); /* return result */ return result;}/* * DLZ methods */static isc_result_tdlz_ldap_allowzonexfr(void *driverarg, void *dbdata, const char *name, const char *client){ isc_result_t result; UNUSED(driverarg); /* check to see if we are authoritative for the zone first */ result = dlz_ldap_findzone(driverarg, dbdata, name); if (result != ISC_R_SUCCESS) { return result; } /* get all the zone data */ return ldap_get_results(name, NULL, client, ALLOWXFR, dbdata, NULL);}static isc_result_tdlz_ldap_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes){ UNUSED(driverarg); return ldap_get_results(zone, NULL, NULL, ALLNODES, dbdata, allnodes);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?