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 + -
显示快捷键?