static void * mem_alloc(size_t size) { #ifdef OPENSSL_LEAKS void *ptr; INSIST(dst__memory_pool != NULL); ptr = isc_mem_allocate(dst__memory_pool, size); return (ptr); #else INSIST(dst__memory_pool != NULL); return (isc_mem_allocate(dst__memory_pool, size)); #endif }
isc_result_t dns_keydata_todnskey(dns_rdata_keydata_t *keydata, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { REQUIRE(keydata != NULL && dnskey != NULL); dnskey->common.rdtype = dns_rdatatype_dnskey; dnskey->common.rdclass = keydata->common.rdclass; dnskey->mctx = mctx; dnskey->flags = keydata->flags; dnskey->protocol = keydata->protocol; dnskey->algorithm = keydata->algorithm; dnskey->datalen = keydata->datalen; if (mctx == NULL) dnskey->data = keydata->data; else { dnskey->data = isc_mem_allocate(mctx, dnskey->datalen); if (dnskey->data == NULL) return (ISC_R_NOMEMORY); memcpy(dnskey->data, keydata->data, dnskey->datalen); } return (ISC_R_SUCCESS); }
isc_result_t dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata, dns_rdata_dnskey_t *dnskey, isc_uint32_t refresh, isc_uint32_t addhd, isc_uint32_t removehd, isc_mem_t *mctx) { REQUIRE(keydata != NULL && dnskey != NULL); keydata->common.rdtype = dns_rdatatype_keydata; keydata->common.rdclass = dnskey->common.rdclass; keydata->mctx = mctx; keydata->refresh = refresh; keydata->addhd = addhd; keydata->removehd = removehd; keydata->flags = dnskey->flags; keydata->protocol = dnskey->protocol; keydata->algorithm = dnskey->algorithm; keydata->datalen = dnskey->datalen; if (mctx == NULL) keydata->data = dnskey->data; else { keydata->data = isc_mem_allocate(mctx, keydata->datalen); if (keydata->data == NULL) return (ISC_R_NOMEMORY); memcpy(keydata->data, dnskey->data, keydata->datalen); } return (ISC_R_SUCCESS); }
/*% * Verify. */ static isc_result_t gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; isc_region_t message, r; gss_buffer_desc gmessage, gsig; OM_uint32 minor, gret; gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; unsigned char *buf; char err[1024]; /* * Convert the data we wish to sign into a structure gssapi can * understand. */ isc_buffer_usedregion(ctx->buffer, &message); REGION_TO_GBUFFER(message, gmessage); /* * XXXMLG * It seem that gss_verify_mic() modifies the signature buffer, * at least on Heimdal's implementation. Copy it here to an allocated * buffer. */ buf = isc_mem_allocate(dst__memory_pool, sig->length); if (buf == NULL) return (ISC_R_FAILURE); memmove(buf, sig->base, sig->length); r.base = buf; r.length = sig->length; REGION_TO_GBUFFER(r, gsig); /* * Verify the data. */ gret = gss_verify_mic(&minor, gssctx, &gmessage, &gsig, NULL); isc_mem_free(dst__memory_pool, buf); /* * Convert return codes into something useful to us. */ if (gret != GSS_S_COMPLETE) { gss_log(3, "GSS verify error: %s", gss_error_tostring(gret, minor, err, sizeof(err))); if (gret == GSS_S_DEFECTIVE_TOKEN || gret == GSS_S_BAD_SIG || gret == GSS_S_DUPLICATE_TOKEN || gret == GSS_S_OLD_TOKEN || gret == GSS_S_UNSEQ_TOKEN || gret == GSS_S_GAP_TOKEN || gret == GSS_S_CONTEXT_EXPIRED || gret == GSS_S_NO_CONTEXT || gret == GSS_S_FAILURE) return(DST_R_VERIFYFAILURE); else return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); }
static void get_next_command(void) { char *buf; char *ptr; fflush(stdout); buf = isc_mem_allocate(mctx, COMMSIZE); if (buf == NULL) fatal("memory allocation failure"); isc_app_block(); if (interactive) { #ifdef HAVE_READLINE ptr = readline("> "); if (ptr != NULL) add_history(ptr); #else fputs("> ", stderr); fflush(stderr); ptr = fgets(buf, COMMSIZE, stdin); #endif } else ptr = fgets(buf, COMMSIZE, stdin); isc_app_unblock(); if (ptr == NULL) { in_use = ISC_FALSE; } else do_next_command(ptr); #ifdef HAVE_READLINE if (interactive) free(ptr); #endif isc_mem_free(mctx, buf); }
isc_result_t isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) { char *dir, *file, *slash; slash = strrchr(path, '/'); if (slash == path) { file = ++slash; dir = isc_mem_strdup(mctx, "/"); } else if (slash != NULL) { file = ++slash; dir = isc_mem_allocate(mctx, slash - path); if (dir != NULL) strlcpy(dir, path, slash - path); } else { file = path; dir = isc_mem_strdup(mctx, "."); } if (dir == NULL) return (ISC_R_NOMEMORY); if (*file == '\0') { isc_mem_free(mctx, dir); return (ISC_R_INVALIDFILE); } *dirname = dir; *basename = file; return (ISC_R_SUCCESS); }
ATF_TC_BODY(isc_mem_inuse, tc) { isc_result_t result; isc_mem_t *mctx2 = NULL; size_t before, during, after; ssize_t diff; void *ptr; result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); mctx2 = NULL; result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &mctx2, 0); if (result != ISC_R_SUCCESS) goto out; before = isc_mem_inuse(mctx2); ptr = isc_mem_allocate(mctx2, 1024000); during = isc_mem_inuse(mctx2); isc_mem_free(mctx2, ptr); after = isc_mem_inuse(mctx2); diff = after - before; printf("inuse_before=%lu, inuse_during=%lu, inuse_after=%lu\n", (unsigned long)before, (unsigned long)during, (unsigned long)after); ATF_REQUIRE_EQ(diff, 0); out: if (mctx2 != NULL) isc_mem_destroy(&mctx2); isc_test_end(); }
static isc_result_t odbc_getManyFields(SQLHSTMT *stmnt, SQLSMALLINT startField, SQLSMALLINT endField, char **retData) { isc_result_t result; SQLLEN size; int totSize = 0; SQLSMALLINT i; int j = 0; char *data; REQUIRE(retData != NULL && *retData == NULL); REQUIRE(startField > 0 && startField <= endField); /* determine how large the data is */ for (i=startField; i <= endField; i++) if (sqlOK(SQLColAttribute(stmnt, i, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &size)) && size > 0) { /* always allow for a " " (space) character */ totSize += (size + 1); /* after the data item */ } if (totSize < 1) return ISC_R_FAILURE; /* allow for a "\n" at the end of the string/ */ data = isc_mem_allocate(ns_g_mctx, ++totSize); if (data == NULL) return ISC_R_NOMEMORY; result = ISC_R_FAILURE; /* get the data and concat all fields into a large string */ for (i=startField; i <= endField; i++) { if (sqlOK(SQLGetData(stmnt, i, SQL_C_CHAR, &(data[j]), totSize - j, &size))) { if (size > 0) { j += size; data[j++] = ' '; data[j] = '\0'; result = ISC_R_SUCCESS; } } else { isc_mem_free(ns_g_mctx, data); return ISC_R_FAILURE; } } if (result != ISC_R_SUCCESS) { isc_mem_free(ns_g_mctx, data); return result; } *retData = data; return ISC_R_SUCCESS; }
static void get_next_command (void) { char *buf; char *ptr, *arg; char *input; fflush (stdout); buf = isc_mem_allocate (mctx, COMMSIZE); if (buf == NULL) fatal ("memory allocation failure"); fputs ("> ", stderr); fflush (stderr); isc_app_block (); ptr = fgets (buf, COMMSIZE, stdin); isc_app_unblock (); if (ptr == NULL) { in_use = ISC_FALSE; goto cleanup; } input = buf; ptr = next_token (&input, " \t\r\n"); if (ptr == NULL) goto cleanup; arg = next_token (&input, " \t\r\n"); if ((strcasecmp (ptr, "set") == 0) && (arg != NULL)) setoption (arg); else if ((strcasecmp (ptr, "server") == 0) || (strcasecmp (ptr, "lserver") == 0)) { isc_app_block (); set_nameserver (arg); check_ra = ISC_FALSE; isc_app_unblock (); show_settings (ISC_TRUE, ISC_TRUE); } else if (strcasecmp (ptr, "exit") == 0) { in_use = ISC_FALSE; goto cleanup; } else if (strcasecmp (ptr, "help") == 0 || strcasecmp (ptr, "?") == 0) { printf ("The '%s' command is not yet implemented.\n", ptr); goto cleanup; } else if (strcasecmp (ptr, "finger") == 0 || strcasecmp (ptr, "root") == 0 || strcasecmp (ptr, "ls") == 0 || strcasecmp (ptr, "view") == 0) { printf ("The '%s' command is not implemented.\n", ptr); goto cleanup; } else addlookup (ptr); cleanup: isc_mem_free (mctx, buf); }
/* * Get FMRI for the named process. */ isc_result_t ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { scf_handle_t *h = NULL; int namelen; char *instance; REQUIRE(ins_name != NULL && *ins_name == NULL); if ((h = scf_handle_create(SCF_VERSION)) == NULL) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_handle_create() failed: %s", scf_strerror(scf_error())); return (ISC_R_FAILURE); } if (scf_handle_bind(h) == -1) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_handle_bind() failed: %s", scf_strerror(scf_error())); scf_handle_destroy(h); return (ISC_R_FAILURE); } if ((namelen = scf_myname(h, NULL, 0)) == -1) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_myname() failed: %s", scf_strerror(scf_error())); scf_handle_destroy(h); return (ISC_R_FAILURE); } if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { UNEXPECTED_ERROR(__FILE__, __LINE__, "ns_smf_get_instance memory " "allocation failed: %s", isc_result_totext(ISC_R_NOMEMORY)); scf_handle_destroy(h); return (ISC_R_FAILURE); } if (scf_myname(h, instance, namelen + 1) == -1) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_myname() failed: %s", scf_strerror(scf_error())); scf_handle_destroy(h); isc_mem_free(mctx, instance); return (ISC_R_FAILURE); } scf_handle_destroy(h); *ins_name = instance; return (ISC_R_SUCCESS); }
/*% * build a query string from query segments, and dynamic segments * dynamic segments replace where the tokens %zone%, %record%, %client% * used to be in our queries from named.conf */ char * sdlzh_build_querystring(isc_mem_t *mctx, query_list_t *querylist) { query_segment_t *tseg = NULL; unsigned int length = 0; char *qs = NULL; REQUIRE(mctx != NULL); REQUIRE(querylist != NULL); /* start at the top of the list */ tseg = ISC_LIST_HEAD(*querylist); while (tseg != NULL) { /* * if this is a query segment, use the * precalculated string length */ if (tseg->direct == isc_boolean_true) length += tseg->strlen; else /* calculate string length for dynamic segments. */ length += strlen(* (char**) tseg->sql); /* get the next segment */ tseg = ISC_LIST_NEXT(tseg, link); } /* allocate memory for the string */ qs = isc_mem_allocate(mctx, length + 1); /* couldn't allocate memory, We need more ram! */ if (qs == NULL) return NULL; /* start at the top of the list again */ tseg = ISC_LIST_HEAD(*querylist); /* copy the first item in the list to the query string */ if (tseg->direct == isc_boolean_true) /* query segment */ strcpy(qs, tseg->sql); else strcpy(qs, * (char**) tseg->sql); /* dynamic segment */ /* concatonate the rest of the segments */ while ((tseg = ISC_LIST_NEXT(tseg, link)) != NULL) { if (tseg->direct == isc_boolean_true) /* query segments */ strcat(qs, tseg->sql); else /* dynamic segments */ strcat(qs, * (char**) tseg->sql); } return qs; }
isc_result_t dns_difftuple_create(isc_mem_t *mctx, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata, dns_difftuple_t **tp) { dns_difftuple_t *t; unsigned int size; unsigned char *datap; REQUIRE(tp != NULL && *tp == NULL); /* * Create a new tuple. The variable-size wire-format name data and * rdata immediately follow the dns_difftuple_t structure * in memory. */ size = sizeof(*t) + name->length + rdata->length; t = isc_mem_allocate(mctx, size); if (t == NULL) return (ISC_R_NOMEMORY); t->mctx = NULL; isc_mem_attach(mctx, &t->mctx); t->op = op; datap = (unsigned char *)(t + 1); memmove(datap, name->ndata, name->length); dns_name_init(&t->name, NULL); dns_name_clone(name, &t->name); t->name.ndata = datap; datap += name->length; t->ttl = ttl; memmove(datap, rdata->data, rdata->length); dns_rdata_init(&t->rdata); dns_rdata_clone(rdata, &t->rdata); t->rdata.data = datap; datap += rdata->length; ISC_LINK_INIT(&t->rdata, link); ISC_LINK_INIT(t, link); t->magic = DNS_DIFFTUPLE_MAGIC; INSIST(datap == (unsigned char *)t + size); *tp = t; return (ISC_R_SUCCESS); }
char * isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) { char *target; REQUIRE(mctx != NULL); REQUIRE(source != NULL); target = (char *) isc_mem_allocate(mctx, source->length + 1); if (target != NULL) { memcpy(source->base, target, source->length); target[source->length] = '\0'; } return (target); }
static char * mysqldrv_escape_string(MYSQL *mysql, const char *instr) { char *outstr; unsigned int len; if (instr == NULL) return NULL; len = strlen(instr); outstr = isc_mem_allocate(ns_g_mctx ,(2 * len * sizeof(char)) + 1); if (outstr == NULL) return NULL; mysql_real_escape_string(mysql, outstr, instr, len); return outstr; }
static char * odbc_escape_string(const char *instr) { char *outstr; unsigned int len; if (instr == NULL) return NULL; len = strlen(instr); outstr = isc_mem_allocate(ns_g_mctx ,(2 * len * sizeof(char)) + 1); if (outstr == NULL) return NULL; odbc_makesafe(outstr, instr, len); return outstr; }
static isc_result_t odbc_getField(SQLHSTMT *stmnt, SQLSMALLINT field, char **data) { SQLLEN size; REQUIRE(data != NULL && *data == NULL); if (sqlOK(SQLColAttribute(stmnt, field, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &size)) && size > 0) { *data = isc_mem_allocate(ns_g_mctx, size + 1); if (data != NULL) { if (sqlOK(SQLGetData(stmnt, field, SQL_C_CHAR, *data, size + 1,&size))) return ISC_R_SUCCESS; isc_mem_free(ns_g_mctx, *data); } } return ISC_R_FAILURE; }
ATF_TC_BODY(isc_mem_total, tc) { isc_result_t result; isc_mem_t *mctx2 = NULL; size_t before, after; ssize_t diff; int i; result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Local alloc, free */ mctx2 = NULL; result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &mctx2, 0); if (result != ISC_R_SUCCESS) goto out; before = isc_mem_total(mctx2); for (i = 0; i < 100000; i++) { void *ptr; ptr = isc_mem_allocate(mctx2, 2048); isc_mem_free(mctx2, ptr); } after = isc_mem_total(mctx2); diff = after - before; printf("total_before=%lu, total_after=%lu, total_diff=%lu\n", (unsigned long)before, (unsigned long)after, (unsigned long)diff); /* 2048 +8 bytes extra for size_info */ ATF_CHECK_EQ(diff, (2048 + 8) * 100000); /* ISC_MEMFLAG_INTERNAL */ before = isc_mem_total(mctx); for (i = 0; i < 100000; i++) { void *ptr; ptr = isc_mem_allocate(mctx, 2048); isc_mem_free(mctx, ptr); } after = isc_mem_total(mctx); diff = after - before; printf("total_before=%lu, total_after=%lu, total_diff=%lu\n", (unsigned long)before, (unsigned long)after, (unsigned long)diff); /* 2048 +8 bytes extra for size_info */ ATF_CHECK_EQ(diff, (2048 + 8) * 100000); out: if (mctx2 != NULL) isc_mem_destroy(&mctx2); isc_test_end(); }
static isc_result_t ldap_process_results(LDAP *dbc, LDAPMessage *msg, char ** attrs, void *ptr, isc_boolean_t allnodes) { isc_result_t result = ISC_R_SUCCESS; int i = 0; int j; int len; char *attribute = NULL; LDAPMessage *entry; char *endp = NULL; char *host = NULL; char *type = NULL; char *data = NULL; char **vals = NULL; int ttl; /* make sure there are at least some attributes to process. */ REQUIRE(attrs != NULL || attrs[0] != NULL); /* get the first entry to process */ entry = ldap_first_entry(dbc, msg); if (entry == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP no entries to process."); return (ISC_R_FAILURE); } /* loop through all entries returned */ while (entry != NULL) { /* reset for this loop */ ttl = 0; len = 0; i = 0; attribute = attrs[i]; /* determine how much space we need for data string */ for (j = 0; attrs[j] != NULL; j++) { /* get the list of values for this attribute. */ vals = ldap_get_values(dbc, entry, attrs[j]); /* skip empty attributes. */ if (vals == NULL || ldap_count_values(vals) < 1) continue; /* * we only use the first value. this driver * does not support multi-valued attributes. */ len = len + strlen(vals[0]) + 1; /* free vals for next loop */ ldap_value_free(vals); } /* end for (j = 0; attrs[j] != NULL, j++) loop */ /* allocate memory for data string */ data = isc_mem_allocate(ns_g_mctx, len + 1); if (data == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver unable to allocate memory " "while processing results"); result = ISC_R_FAILURE; goto cleanup; } /* * Make sure data is null termed at the beginning so * we can check if any data was stored to it later. */ data[0] = '\0'; /* reset j to re-use below */ j = 0; /* loop through the attributes in the order specified. */ while (attribute != NULL) { /* get the list of values for this attribute. */ vals = ldap_get_values(dbc, entry, attribute); /* skip empty attributes. */ if (vals == NULL || vals[0] == NULL) { /* increment attibute pointer */ attribute = attrs[++i]; /* start loop over */ continue; } /* * j initially = 0. Increment j each time we * set a field that way next loop will set * next field. */ switch(j) { case 0: j++; /* * convert text to int, make sure it * worked right */ ttl = strtol(vals[0], &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver ttl must " "be a postive number"); goto cleanup; } 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); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dlz-ldap: putnamedrr failed " "for \"%s %s %u %s\", %s", host, type, ttl, data, isc_result_totext(result)); } 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, "dlz-ldap: putrr failed " "for \"%s %u %s\", %s", type, ttl, data, isc_result_totext(result)); } 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); }
/*% * 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; }
static isc_result_t mysql_process_rs(dns_sdlzlookup_t *lookup, MYSQL_RES *rs) { isc_result_t result = ISC_R_NOTFOUND; MYSQL_ROW row; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; 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) { switch(fields) { case 1: /* * one column in rs, it's the data field. use * default type of A record, and default TTL * of 86400 */ result = dns_sdlz_putrr(lookup, "a", 86400, safeGet(row[0])); break; case 2: /* * two columns, data field, and data type. * use default TTL of 86400. */ result = dns_sdlz_putrr(lookup, safeGet(row[0]), 86400, safeGet(row[1])); break; case 3: /* * three columns, all data no defaults. * 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"); } result = dns_sdlz_putrr(lookup, safeGet(row[1]), ttl, safeGet(row[2])); break; default: /* * more than 3 fields, concatenate the last * ones together. figure out how long to make * string. */ for (j=2, len=0; j < fields; j++) { len += strlen(safeGet(row[j])) + 1; } /* * allocate string memory, allow for NULL to * term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* major bummer, 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); /* Yeah, I'd say! */ } /* copy field to tmpString */ strcpy(tmpString, safeGet(row[2])); /* * concat the rest of fields together, space * between each one. */ for (j=3; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, safeGet(row[j])); } /* 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"); } /* ok, now tell Bind about it. */ result = dns_sdlz_putrr(lookup, safeGet(row[1]), ttl, tmpString); /* done, get rid of this thing. */ isc_mem_free(ns_g_mctx, tmpString); } /* I sure hope we were successful */ if (result != ISC_R_SUCCESS) { /* nope, get rid of the Result set, and log a msg */ mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putrr returned error. " "Error code was: %s", isc_result_totext(result)); return (ISC_R_FAILURE); } row = mysql_fetch_row(rs); /* get next row */ } /* free result set memory */ mysql_free_result(rs); /* return result code */ return result; }
static isc_result_t odbc_connect(odbc_instance_t *dbi, odbc_db_t **dbc) { odbc_db_t *ndb = *dbc; SQLRETURN sqlRes; isc_result_t result = ISC_R_SUCCESS; if (ndb != NULL) { /* * if db != null, we have to do some cleanup * if statement handle != null free it */ if (ndb->stmnt != NULL) { SQLFreeHandle(SQL_HANDLE_STMT, ndb->stmnt); ndb->stmnt = NULL; } /* if connection handle != null free it */ if (ndb->dbc != NULL) { SQLFreeHandle(SQL_HANDLE_DBC, ndb->dbc); ndb->dbc = NULL; } } else { ndb = isc_mem_allocate(ns_g_mctx, sizeof(odbc_db_t)); if (ndb == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver unable to allocate memory"); return ISC_R_NOMEMORY; } memset(ndb, 0, sizeof(odbc_db_t)); } sqlRes = SQLAllocHandle(SQL_HANDLE_DBC, dbi->sql_env, &(ndb->dbc)); if (!sqlOK(sqlRes)) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver unable to allocate memory"); result = ISC_R_NOMEMORY; goto cleanup; } sqlRes = SQLConnect(ndb->dbc, dbi->dsn, safeLen(dbi->dsn), dbi->user, safeLen(dbi->user), dbi->pass, safeLen(dbi->pass)); if (!sqlOK(sqlRes)) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver unable to connect"); result = ISC_R_FAILURE; goto cleanup; } sqlRes = SQLAllocHandle(SQL_HANDLE_STMT, ndb->dbc, &(ndb->stmnt)); if (!sqlOK(sqlRes)) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver unable to allocate memory"); result = ISC_R_NOMEMORY; goto cleanup; } *dbc = ndb; return ISC_R_SUCCESS; cleanup: if (ndb != NULL) { /* if statement handle != null free it */ if (ndb->stmnt != NULL) { SQLFreeHandle(SQL_HANDLE_STMT, ndb->stmnt); ndb->stmnt = NULL; } /* if connection handle != null free it */ if (ndb->dbc != NULL) { SQLDisconnect(ndb->dbc); SQLFreeHandle(SQL_HANDLE_DBC, ndb->dbc); ndb->dbc = NULL; } /* free memory holding ndb */ isc_mem_free(ns_g_mctx, ndb); } return result; }
static isc_result_t postgres_process_rs(dns_sdlzlookup_t *lookup, PGresult *rs) { isc_result_t result; unsigned int i; unsigned int rows; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; rows = PQntuples(rs); /* how many rows in result set */ fields = PQnfields(rs); /* how many columns in result set */ for (i=0; i < rows; i++) { switch(fields) { case 1: /* * one column in rs, it's the data field. use * default type of A record, and default TTL * of 86400 */ result = dns_sdlz_putrr(lookup, "a", 86400, PQgetvalue(rs, i, 0)); break; case 2: /* two columns, data field, and data type. * use default TTL of 86400. */ result = dns_sdlz_putrr(lookup, PQgetvalue(rs, i, 0), 86400, PQgetvalue(rs, i, 1)); break; case 3: /* three columns, all data no defaults. * convert text to int, make sure it worked * right. */ ttl = strtol(PQgetvalue(rs, i, 0), &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver ttl must be " "a positive number"); } result = dns_sdlz_putrr(lookup, PQgetvalue(rs, i, 1), ttl, PQgetvalue(rs, i, 2)); break; default: /* * more than 3 fields, concatenate the last * ones together. figure out how long to make * string */ for (j=2, len=0; j < fields; j++) { len += strlen(PQgetvalue(rs, i, j)) + 1; } /* * allocate string memory, allow for NULL to * term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* major bummer, need more ram */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver unable to " "allocate memory for " "temporary string"); PQclear(rs); return (ISC_R_FAILURE); /* Yeah, I'd say! */ } /* copy field to tmpString */ strcpy(tmpString, PQgetvalue(rs, i, 2)); /* * concat the rest of fields together, space * between each one. */ for (j=3; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, PQgetvalue(rs, i, j)); } /* convert text to int, make sure it worked right */ ttl = strtol(PQgetvalue(rs, i, 0), &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver ttl must be " "a postive number"); } /* ok, now tell Bind about it. */ result = dns_sdlz_putrr(lookup, PQgetvalue(rs, i, 1), ttl, tmpString); /* done, get rid of this thing. */ isc_mem_free(ns_g_mctx, tmpString); } /* I sure hope we were successful */ if (result != ISC_R_SUCCESS) { /* nope, get rid of the Result set, and log a msg */ PQclear(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putrr returned error. " "Error code was: %s", isc_result_totext(result)); return (ISC_R_FAILURE); } } /* free result set memory */ PQclear(rs); /* if we did return results, we are successful */ if (rows > 0) return (ISC_R_SUCCESS); /* empty result set, no data found */ return (ISC_R_NOTFOUND); }
static void * mem_alloc(size_t size) { INSIST(dst__memory_pool != NULL); return (isc_mem_allocate(dst__memory_pool, size)); }
isc_result_t isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp) { isc_result_t result; unsigned int i, started = 0; isc_taskmgr_t *manager; /* * Create a new task manager. */ REQUIRE(workers > 0); REQUIRE(managerp != NULL && *managerp == NULL); #ifndef ISC_PLATFORM_USETHREADS UNUSED(i); UNUSED(started); UNUSED(workers); if (taskmgr != NULL) { taskmgr->refs++; *managerp = taskmgr; return (ISC_R_SUCCESS); } #endif /* ISC_PLATFORM_USETHREADS */ manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); manager->magic = TASK_MANAGER_MAGIC; manager->mctx = NULL; result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) goto cleanup_mgr; #ifdef ISC_PLATFORM_USETHREADS manager->workers = 0; manager->threads = isc_mem_allocate(mctx, workers * sizeof(isc_thread_t)); if (manager->threads == NULL) { result = ISC_R_NOMEMORY; goto cleanup_lock; } if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_threads; } if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_workavailable; } #endif /* ISC_PLATFORM_USETHREADS */ if (default_quantum == 0) default_quantum = DEFAULT_DEFAULT_QUANTUM; manager->default_quantum = default_quantum; INIT_LIST(manager->tasks); INIT_LIST(manager->ready_tasks); manager->tasks_running = 0; manager->exclusive_requested = ISC_FALSE; manager->exiting = ISC_FALSE; isc_mem_attach(mctx, &manager->mctx); #ifdef ISC_PLATFORM_USETHREADS LOCK(&manager->lock); /* * Start workers. */ for (i = 0; i < workers; i++) { if (isc_thread_create(run, manager, &manager->threads[manager->workers]) == ISC_R_SUCCESS) { manager->workers++; started++; } } UNLOCK(&manager->lock); if (started == 0) { manager_free(manager); return (ISC_R_NOTHREADS); } isc_thread_setconcurrency(workers); #else /* ISC_PLATFORM_USETHREADS */ manager->refs = 1; taskmgr = manager; #endif /* ISC_PLATFORM_USETHREADS */ *managerp = manager; return (ISC_R_SUCCESS); #ifdef ISC_PLATFORM_USETHREADS cleanup_workavailable: (void)isc_condition_destroy(&manager->work_available); cleanup_threads: isc_mem_free(mctx, manager->threads); cleanup_lock: DESTROYLOCK(&manager->lock); #endif cleanup_mgr: isc_mem_put(mctx, manager, sizeof(*manager)); return (result); }
/* * Perform an update-policy rule check against an external application * over a socket. * * This currently only supports local: for unix domain datagram sockets. * * Note that by using a datagram socket and creating a new socket each * time we avoid the need for locking and allow for parallel access to * the authorization server. */ isc_boolean_t dns_ssu_external_match(dns_name_t *identity, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key, isc_mem_t *mctx) { char b_identity[DNS_NAME_FORMATSIZE]; char b_signer[DNS_NAME_FORMATSIZE]; char b_name[DNS_NAME_FORMATSIZE]; char b_addr[ISC_NETADDR_FORMATSIZE]; char b_type[DNS_RDATATYPE_FORMATSIZE]; char b_key[DST_KEY_FORMATSIZE]; isc_buffer_t *tkey_token = NULL; int fd; const char *sock_path; unsigned int req_len; isc_region_t token_region; unsigned char *data; isc_buffer_t buf; isc_uint32_t token_len = 0; isc_uint32_t reply; ssize_t ret; /* The identity contains local:/path/to/socket */ dns_name_format(identity, b_identity, sizeof(b_identity)); /* For now only local: is supported */ if (strncmp(b_identity, "local:", 6) != 0) { ssu_e_log(3, "ssu_external: invalid socket path '%s'", b_identity); return (ISC_FALSE); } sock_path = &b_identity[6]; fd = ux_socket_connect(sock_path); if (fd == -1) return (ISC_FALSE); if (key != NULL) { dst_key_format(key, b_key, sizeof(b_key)); tkey_token = dst_key_tkeytoken(key); } else b_key[0] = 0; if (tkey_token != NULL) { isc_buffer_region(tkey_token, &token_region); token_len = token_region.length; } /* Format the request elements */ if (signer != NULL) dns_name_format(signer, b_signer, sizeof(b_signer)); else b_signer[0] = 0; dns_name_format(name, b_name, sizeof(b_name)); if (tcpaddr != NULL) isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr)); else b_addr[0] = 0; dns_rdatatype_format(type, b_type, sizeof(b_type)); /* Work out how big the request will be */ req_len = sizeof(isc_uint32_t) + /* Format version */ sizeof(isc_uint32_t) + /* Length */ strlen(b_signer) + 1 + /* Signer */ strlen(b_name) + 1 + /* Name */ strlen(b_addr) + 1 + /* Address */ strlen(b_type) + 1 + /* Type */ strlen(b_key) + 1 + /* Key */ sizeof(isc_uint32_t) + /* tkey_token length */ token_len; /* tkey_token */ /* format the buffer */ data = isc_mem_allocate(mctx, req_len); if (data == NULL) { close(fd); return (ISC_FALSE); } isc_buffer_init(&buf, data, req_len); isc_buffer_putuint32(&buf, SSU_EXTERNAL_VERSION); isc_buffer_putuint32(&buf, req_len); /* Strings must be null-terminated */ isc_buffer_putstr(&buf, b_signer); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_name); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_addr); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_type); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_key); isc_buffer_putuint8(&buf, 0); isc_buffer_putuint32(&buf, token_len); if (tkey_token && token_len != 0) isc_buffer_putmem(&buf, token_region.base, token_len); ENSURE(isc_buffer_availablelength(&buf) == 0); /* Send the request */ ret = write(fd, data, req_len); isc_mem_free(mctx, data); if (ret != (ssize_t) req_len) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); ssu_e_log(3, "ssu_external: unable to send request - %s", strbuf); close(fd); return (ISC_FALSE); } /* Receive the reply */ ret = read(fd, &reply, sizeof(isc_uint32_t)); if (ret != (ssize_t) sizeof(isc_uint32_t)) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); ssu_e_log(3, "ssu_external: unable to receive reply - %s", strbuf); close(fd); return (ISC_FALSE); } close(fd); reply = ntohl(reply); if (reply == 0) { ssu_e_log(3, "ssu_external: denied external auth for '%s'", b_name); return (ISC_FALSE); } else if (reply == 1) { ssu_e_log(3, "ssu_external: allowed external auth for '%s'", b_name); return (ISC_TRUE); } ssu_e_log(3, "ssu_external: invalid reply 0x%08x", reply); return (ISC_FALSE); }
/*% * 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 postgres_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result; PGresult *rs = NULL; unsigned int i; unsigned int rows; 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 = postgres_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) PQclear(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver unable to return " "result set for all nodes query"); return (ISC_R_FAILURE); } rows = PQntuples(rs); /* how many rows in result set */ fields = PQnfields(rs); /* how many columns in result set */ for (i=0; i < rows; i++) { if (fields < 4) { /* gotta have at least 4 columns */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver too few fields " "returned by all nodes query"); } /* convert text to int, make sure it worked right */ ttl = strtol(PQgetvalue(rs, i, 0), &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver ttl must be " "a postive number"); } if (fields == 4) { /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, PQgetvalue(rs, i, 2), PQgetvalue(rs, i, 1), ttl, PQgetvalue(rs, i, 3)); } else { /* * more than 4 fields, concatonat the last * ones together. figure out how long to make * string */ for (j=3, len=0; j < fields; j++) { len += strlen(PQgetvalue(rs, i, 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, "Postgres driver unable to " "allocate memory for " "temporary string"); PQclear(rs); return (ISC_R_FAILURE); } /* copy this field to tmpString */ strcpy(tmpString, PQgetvalue(rs, i, 3)); /* concatonate the rest, with spaces between */ for (j=4; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, PQgetvalue(rs, i, j)); } /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, PQgetvalue(rs, i, 2), PQgetvalue(rs, i, 1), ttl, tmpString); isc_mem_free(ns_g_mctx, tmpString); } /* if we weren't successful, log err msg */ if (result != ISC_R_SUCCESS) { PQclear(rs); 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)); return (ISC_R_FAILURE); } } /* free result set memory */ PQclear(rs); /* if we did return results, we are successful */ if (rows > 0) return (ISC_R_SUCCESS); /* empty result set, no data found */ return (ISC_R_NOTFOUND); }
int main(int argc, char *argv[]) { int i, ch; char *startstr = NULL, *endstr = NULL; dns_fixedname_t fdomain; dns_name_t *domain = NULL; char *output = NULL; char *endp; unsigned char data[65536]; dns_db_t *db; dns_dbversion_t *version; dns_diff_t diff; dns_difftuple_t *tuple; dns_fixedname_t tname; dst_key_t *key = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; dns_rdataclass_t rdclass; isc_result_t result; isc_buffer_t b; isc_region_t r; isc_log_t *log = NULL; keynode_t *keynode; unsigned int eflags; isc_boolean_t pseudorandom = ISC_FALSE; isc_boolean_t tryverify = ISC_FALSE; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("failed to create memory context: %s", isc_result_totext(result)); dns_result_register(); while ((ch = isc_commandline_parse(argc, argv, "as:e:t:r:v:ph")) != -1) { switch (ch) { case 'a': tryverify = ISC_TRUE; break; case 's': startstr = isc_commandline_argument; break; case 'e': endstr = isc_commandline_argument; break; case 't': endp = NULL; ttl = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("TTL must be numeric"); break; case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("verbose level must be numeric"); break; case 'p': pseudorandom = ISC_TRUE; break; case 'h': default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); eflags = ISC_ENTROPY_BLOCKING; if (!pseudorandom) eflags |= ISC_ENTROPY_GOODONLY; result = dst_lib_init(mctx, ectx, eflags); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_stdtime_get(&now); if (startstr != NULL) starttime = strtotime(startstr, now, now); else starttime = now; if (endstr != NULL) endtime = strtotime(endstr, now, starttime); else endtime = starttime + (30 * 24 * 60 * 60); if (ttl == -1) { ttl = 3600; fprintf(stderr, "%s: TTL not specified, assuming 3600\n", program); } setup_logging(verbose, mctx, &log); dns_diff_init(mctx, &diff); rdclass = 0; ISC_LIST_INIT(keylist); for (i = 0; i < argc; i++) { char namestr[DNS_NAME_FORMATSIZE]; isc_buffer_t namebuf; key = NULL; result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC, mctx, &key); if (result != ISC_R_SUCCESS) fatal("error loading key from %s: %s", argv[i], isc_result_totext(result)); if (rdclass == 0) rdclass = dst_key_class(key); isc_buffer_init(&namebuf, namestr, sizeof(namestr)); result = dns_name_tofilenametext(dst_key_name(key), ISC_FALSE, &namebuf); check_result(result, "dns_name_tofilenametext"); isc_buffer_putuint8(&namebuf, 0); if (domain == NULL) { dns_fixedname_init(&fdomain); domain = dns_fixedname_name(&fdomain); dns_name_copy(dst_key_name(key), domain, NULL); } else if (!dns_name_equal(domain, dst_key_name(key))) { char str[DNS_NAME_FORMATSIZE]; dns_name_format(domain, str, sizeof(str)); fatal("all keys must have the same owner - %s " "and %s do not match", str, namestr); } if (output == NULL) { output = isc_mem_allocate(mctx, strlen("keyset-") + strlen(namestr) + 1); if (output == NULL) fatal("out of memory"); sprintf(output, "keyset-%s", namestr); } if (dst_key_iszonekey(key)) { dst_key_t *zonekey = NULL; result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &zonekey); if (result != ISC_R_SUCCESS) fatal("failed to read private key %s: %s", argv[i], isc_result_totext(result)); if (!zonekey_on_list(zonekey)) { keynode = isc_mem_get(mctx, sizeof(keynode_t)); if (keynode == NULL) fatal("out of memory"); keynode->key = zonekey; ISC_LIST_INITANDAPPEND(keylist, keynode, link); } else dst_key_free(&zonekey); } dns_rdata_reset(&rdata); isc_buffer_init(&b, data, sizeof(data)); result = dst_key_todns(key, &b); dst_key_free(&key); if (result != ISC_R_SUCCESS) fatal("failed to convert key %s to a DNS KEY: %s", argv[i], isc_result_totext(result)); isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(&rdata, rdclass, dns_rdatatype_dnskey, &r); tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, domain, ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } db = NULL; result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) fatal("failed to create a database"); version = NULL; dns_db_newversion(db, &version); result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_fixedname_init(&tname); dns_rdataset_init(&rdataset); result = dns_db_find(db, domain, version, dns_rdatatype_dnskey, 0, 0, NULL, dns_fixedname_name(&tname), &rdataset, NULL); check_result(result, "dns_db_find"); if (ISC_LIST_EMPTY(keylist)) fprintf(stderr, "%s: no private zone key found; not self-signing\n", program); for (keynode = ISC_LIST_HEAD(keylist); keynode != NULL; keynode = ISC_LIST_NEXT(keynode, link)) { dns_rdata_reset(&rdata); isc_buffer_init(&b, data, sizeof(data)); result = dns_dnssec_sign(domain, &rdataset, keynode->key, &starttime, &endtime, mctx, &b, &rdata); isc_entropy_stopcallbacksources(ectx); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(keynode->key, keystr, sizeof(keystr)); fatal("failed to sign keyset with key %s: %s", keystr, isc_result_totext(result)); } if (tryverify) { result = dns_dnssec_verify(domain, &rdataset, keynode->key, ISC_TRUE, mctx, &rdata); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(keynode->key, keystr, sizeof(keystr)); fatal("signature from key '%s' failed to " "verify: %s", keystr, isc_result_totext(result)); } } tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, domain, ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_rdataset_disassociate(&rdataset); dns_db_closeversion(db, &version, ISC_TRUE); result = dns_db_dump(db, version, output); if (result != ISC_R_SUCCESS) { char domainstr[DNS_NAME_FORMATSIZE]; dns_name_format(domain, domainstr, sizeof(domainstr)); fatal("failed to write database for %s to %s", domainstr, output); } printf("%s\n", output); dns_db_detach(&db); while (!ISC_LIST_EMPTY(keylist)) { keynode = ISC_LIST_HEAD(keylist); ISC_LIST_UNLINK(keylist, keynode, link); dst_key_free(&keynode->key); isc_mem_put(mctx, keynode, sizeof(keynode_t)); } cleanup_logging(&log); cleanup_entropy(&ectx); isc_mem_free(mctx, output); dst_lib_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }