static isc_result_t mysql_findzone(void *driverarg, void *dbdata, const char *name) { isc_result_t result; MYSQL_RES *rs = NULL; my_ulonglong rows; UNUSED(driverarg); /* run the query and get the result set from the database. */ result = mysql_get_resultset(name, NULL, NULL, FINDZONE, dbdata, &rs); /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS || rs == NULL) { if (rs != NULL) mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable to return " "result set for findzone query"); return (ISC_R_FAILURE); } /* count how many rows in result set */ rows = mysql_num_rows(rs); /* get rid of result set, we are done with it. */ mysql_free_result(rs); /* if we returned any rows, zone is supported. */ if (rows > 0) { mysql_get_resultset(name, NULL, NULL, COUNTZONE, dbdata, NULL); return (ISC_R_SUCCESS); } /* no rows returned, zone is not supported. */ return (ISC_R_NOTFOUND); }
/*% if zone is supported, lookup up a (or multiple) record(s) in it */ static isc_result_t mysql_lookup(const char *zone, const char *name, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; MYSQL_RES *rs = NULL; UNUSED(driverarg); UNUSED(methods); UNUSED(clientinfo); /* run the query and get the result set from the database. */ result = mysql_get_resultset(zone, name, NULL, LOOKUP, dbdata, &rs); /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { if (rs != NULL) mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable to return " "result set for lookup query"); return (ISC_R_FAILURE); } /* * lookup and authority result sets are processed in the same manner * mysql_process_rs does the job for both functions. */ return mysql_process_rs(lookup, rs); }
static isc_result_t mysql_authority(const char *zone, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup) { isc_result_t result; MYSQL_RES *rs = NULL; UNUSED(driverarg); /* run the query and get the result set from the database. */ result = mysql_get_resultset(zone, NULL, NULL, AUTHORITY, dbdata, &rs); /* if we get "not implemented", send it along */ if (result == ISC_R_NOTIMPLEMENTED) return result; /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { if (rs != NULL) mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable to return " "result set for authority query"); return (ISC_R_FAILURE); } /* * lookup and authority result sets are processed in the same * manner mysql_process_rs does the job for both functions. */ return mysql_process_rs(lookup, rs); }
/*% If zone is supported, lookup up a (or multiple) record(s) in it */ isc_result_t dlz_lookup(const char *zone, const char *name, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; MYSQL_RES *rs = NULL; mysql_instance_t *db = (mysql_instance_t *)dbdata; UNUSED(methods); UNUSED(clientinfo); result = mysql_get_resultset(zone, name, NULL, LOOKUP, dbdata, &rs); /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { if (rs != NULL) mysql_free_result(rs); db->log(ISC_LOG_ERROR, "MySQL module unable to return " "result set for lookup query"); return (ISC_R_FAILURE); } /* * lookup and authority result sets are processed in the same * manner: mysql_process_rs does the job for both functions. */ return (mysql_process_rs(db, lookup, rs)); }
/*% * If the lookup function does not return SOA or NS records for the zone, * use this function to get that information for named. */ isc_result_t dlz_authority(const char *zone, void *dbdata, dns_sdlzlookup_t *lookup) { isc_result_t result; MYSQL_RES *rs = NULL; mysql_instance_t *db = (mysql_instance_t *)dbdata; result = mysql_get_resultset(zone, NULL, NULL, AUTHORITY, dbdata, &rs); if (result == ISC_R_NOTIMPLEMENTED) return (result); if (result != ISC_R_SUCCESS) { if (rs != NULL) mysql_free_result(rs); db->log(ISC_LOG_ERROR, "MySQL module unable to return " "result set for authority query"); return (ISC_R_FAILURE); } /* * lookup and authority result sets are processed in the same * manner: mysql_process_rs does the job for both functions. */ return (mysql_process_rs(db, lookup, rs)); }
/*% Determine if the client is allowed to perform a zone transfer */ static isc_result_t mysql_allowzonexfr(void *driverarg, void *dbdata, const char *name, const char *client) { isc_result_t result; MYSQL_RES *rs = NULL; my_ulonglong rows; UNUSED(driverarg); /* first check if the zone is supported by the database. */ result = mysql_findzone(driverarg, dbdata, name); if (result != ISC_R_SUCCESS) return (ISC_R_NOTFOUND); /* * if we get to this point we know the zone is supported by * the database the only questions now are is the zone * transfer is allowed for this client and did the config file * have an allow zone xfr query. * * Run our query, and get a result set from the database. */ result = mysql_get_resultset(name, NULL, client, ALLOWXFR, dbdata, &rs); /* if we get "not implemented", send it along. */ if (result == ISC_R_NOTIMPLEMENTED) return result; /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS || rs == NULL) { if (rs != NULL) mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable to return " "result set for allow xfr query"); return (ISC_R_FAILURE); } /* count how many rows in result set */ rows = mysql_num_rows(rs); /* get rid of result set, we are done with it. */ mysql_free_result(rs); /* if we returned any rows, zone xfr is allowed. */ if (rows > 0) return (ISC_R_SUCCESS); /* no rows returned, zone xfr not allowed */ return (ISC_R_NOPERM); }
/*% determine if the zone is supported by (in) the database */ isc_result_t dlz_findzonedb(void *dbdata, const char *name, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; MYSQL_RES *rs = NULL; my_ulonglong rows; mysql_instance_t *db = (mysql_instance_t *)dbdata; UNUSED(methods); UNUSED(clientinfo); result = mysql_get_resultset(name, NULL, NULL, FINDZONE, dbdata, &rs); if (result != ISC_R_SUCCESS || rs == NULL) { if (rs != NULL) mysql_free_result(rs); db->log(ISC_LOG_ERROR, "MySQL module unable to return " "result set for findzone query"); return (ISC_R_FAILURE); } /* * if we returned any rows, the zone is supported. */ rows = mysql_num_rows(rs); mysql_free_result(rs); if (rows > 0) { mysql_get_resultset(name, NULL, NULL, COUNTZONE, dbdata, NULL); return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); }
/*% Determine if the client is allowed to perform a zone transfer */ isc_result_t dlz_allowzonexfr(void *dbdata, const char *name, const char *client) { isc_result_t result; mysql_instance_t *db = (mysql_instance_t *)dbdata; MYSQL_RES *rs = NULL; my_ulonglong rows; /* first check if the zone is supported by the database. */ result = dlz_findzonedb(dbdata, name, NULL, NULL); if (result != ISC_R_SUCCESS) return (ISC_R_NOTFOUND); /* * if we get to this point we know the zone is supported by * the database the only questions now are is the zone * transfer is allowed for this client and did the config file * have an allow zone xfr query. */ result = mysql_get_resultset(name, NULL, client, ALLOWXFR, dbdata, &rs); if (result == ISC_R_NOTIMPLEMENTED) return (result); if (result != ISC_R_SUCCESS || rs == NULL) { if (rs != NULL) mysql_free_result(rs); db->log(ISC_LOG_ERROR, "MySQL module unable to return " "result set for allow xfr query"); return (ISC_R_FAILURE); } /* * count how many rows in result set; if we returned any, * zone xfr is allowed. */ rows = mysql_num_rows(rs); mysql_free_result(rs); if (rows > 0) return (ISC_R_SUCCESS); return (ISC_R_NOPERM); }
/*% * If the client is allowed to perform a zone transfer, the next order of * business is to get all the nodes in the zone, so bind can respond to the * query. */ static isc_result_t mysql_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result; MYSQL_RES *rs = NULL; MYSQL_ROW row; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; UNUSED(driverarg); /* run the query and get the result set from the database. */ result = mysql_get_resultset(zone, NULL, NULL, ALLNODES, dbdata, &rs); /* if we get "not implemented", send it along */ if (result == ISC_R_NOTIMPLEMENTED) return result; /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { if (rs != NULL) mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable to return " "result set for all nodes query"); return (ISC_R_FAILURE); } result = ISC_R_NOTFOUND; row = mysql_fetch_row(rs); /* get a row from the result set */ fields = mysql_num_fields(rs); /* how many columns in result set */ while (row != NULL) { if (fields < 4) { /* gotta have at least 4 columns */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver too few fields returned " "by all nodes query"); } /* convert text to int, make sure it worked right */ ttl = strtol(safeGet(row[0]), &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver ttl must be " "a postive number"); } if (fields == 4) { /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, safeGet(row[2]), safeGet(row[1]), ttl, safeGet(row[3])); } else { /* * more than 4 fields, concatenate the last * ones together. figure out how long to make * string. */ for (j=3, len=0; j < fields; j++) { len += strlen(safeGet(row[j])) + 1; } /* allocate memory, allow for NULL to term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* we need more ram. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable " "to allocate memory for " "temporary string"); mysql_free_result(rs); return (ISC_R_FAILURE); } /* copy this field to tmpString */ strcpy(tmpString, safeGet(row[3])); /* concatonate the rest, with spaces between */ for (j=4; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, safeGet(row[j])); } /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, safeGet(row[2]), safeGet(row[1]), ttl, tmpString); isc_mem_free(ns_g_mctx, tmpString); } /* if we weren't successful, log err msg */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putnamedrr returned error. " "Error code was: %s", isc_result_totext(result)); result = ISC_R_FAILURE; break; } /* get next row from the result set */ row = mysql_fetch_row(rs); } /* free result set memory */ mysql_free_result(rs); return result; }
/*% * If the client is allowed to perform a zone transfer, the next order of * business is to get all the nodes in the zone, so bind can respond to the * query. */ isc_result_t dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result; mysql_instance_t *db = (mysql_instance_t *)dbdata; MYSQL_RES *rs = NULL; MYSQL_ROW row; unsigned int fields; unsigned int j; char *tmpString; char *endp; int ttl; result = mysql_get_resultset(zone, NULL, NULL, ALLNODES, dbdata, &rs); if (result == ISC_R_NOTIMPLEMENTED) return (result); /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { db->log(ISC_LOG_ERROR, "MySQL module unable to return " "result set for all nodes query"); goto cleanup; } result = ISC_R_NOTFOUND; fields = mysql_num_fields(rs); /* how many columns in result set */ row = mysql_fetch_row(rs); /* get a row from the result set */ while (row != NULL) { if (fields < 4) { db->log(ISC_LOG_ERROR, "MySQL module too few fields returned " "by all nodes query"); result = ISC_R_FAILURE; goto cleanup; } ttl = strtol(safeGet(row[0]), &endp, 10); if (*endp != '\0' || ttl < 0) { db->log(ISC_LOG_ERROR, "MySQL module ttl must be " "a postive number"); result = ISC_R_FAILURE; goto cleanup; } if (fields == 4) { result = db->putnamedrr(allnodes, safeGet(row[2]), safeGet(row[1]), ttl, safeGet(row[3])); } else { unsigned int len = 0; /* * more than 4 fields, concatenate the last * ones together. */ for (j = 3; j < fields; j++) len += strlen(safeGet(row[j])) + 1; tmpString = malloc(len + 1); if (tmpString == NULL) { db->log(ISC_LOG_ERROR, "MySQL module unable to allocate " "memory for temporary string"); result = ISC_R_FAILURE; goto cleanup; } strcpy(tmpString, safeGet(row[3])); for (j = 4; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, safeGet(row[j])); } result = db->putnamedrr(allnodes, safeGet(row[2]), safeGet(row[1]), ttl, tmpString); free(tmpString); } if (result != ISC_R_SUCCESS) { db->log(ISC_LOG_ERROR, "putnamedrr returned error: %s", result); result = ISC_R_FAILURE; break; } row = mysql_fetch_row(rs); } cleanup: if (rs != NULL) mysql_free_result(rs); return (result); }