Beispiel #1
0
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
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;

}
Beispiel #9
0
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);
}
Beispiel #10
0
/*
 * 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);
}
Beispiel #11
0
/*%
 * 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;
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}
Beispiel #17
0
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();
}
Beispiel #18
0
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);
}
Beispiel #19
0
/*%
 * 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;
}
Beispiel #20
0
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);
}
Beispiel #23
0
static void *
mem_alloc(size_t size) {
	INSIST(dst__memory_pool != NULL);
	return (isc_mem_allocate(dst__memory_pool, size));
}
Beispiel #24
0
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);
}
Beispiel #25
0
/*
 * 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);
}