}
#ifdef GSSAPI
+
+/*
+ * Get the realm from the users kerberos ticket if possible
+ */
+static void
+get_ticket_realm(isc_mem_t *mctx)
+{
+ krb5_context ctx;
+ krb5_error_code rc;
+ krb5_ccache ccache;
+ krb5_principal princ;
+ char *name, *ticket_realm;
+
+ rc = krb5_init_context(&ctx);
+ if (rc != 0)
+ return;
+
+ rc = krb5_cc_default(ctx, &ccache);
+ if (rc != 0) {
+ krb5_free_context(ctx);
+ return;
+ }
+
+ rc = krb5_cc_get_principal(ctx, ccache, &princ);
+ if (rc != 0) {
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ return;
+ }
+
+ rc = krb5_unparse_name(ctx, princ, &name);
+ if (rc != 0) {
+ krb5_free_principal(ctx, princ);
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ return;
+ }
+
+ ticket_realm = strrchr(name, '@');
+ if (ticket_realm != NULL) {
+ realm = isc_mem_strdup(mctx, ticket_realm);
+ }
+
+ free(name);
+ krb5_free_principal(ctx, princ);
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ if (realm != NULL && debugging)
+ fprintf(stderr, "Found realm from ticket: %s\n", realm+1);
+}
+
+
static void
start_gssrequest(dns_name_t *master, dns_name_t *zone)
{
dns_fixedname_init(&fname);
servname = dns_fixedname_name(&fname);
+ if (realm == NULL)
+ get_ticket_realm(mctx);
+
result = isc_string_printf(servicename, sizeof(servicename),
"DNS/%s%s", namestr, realm ? realm : "");
if (result != ISC_R_SUCCESS)
}
#ifdef GSSAPI
-/*
- * GSSAPI with krb5 doesn't have a way to set the default realm, as it
- * doesn't offer any access to the krb5 context that it uses. The only
- * way to do an nsupdate call on a realm that isn't the default realm in
- * /etc/krb5.conf is to create a temporary krb5.conf and put the right
- * realm in there as the default realm, then set KRB5_CONFIG to point
- * at that temporary krb5.conf. This is a disgusting hack, but it is
- * the best we can do with GSSAPI.
- *
- * To try to reduce the impact, this routine checks if the default
- * realm is already correct. If it is, then we don't need to do
- * anything. If not, then we create the temporary krb5.conf.
- */
-static void
-check_zone(dns_name_t *zone, isc_mem_t *mctx, char **tmpfile) {
- krb5_context ctx;
- int kret;
- char *realm;
- char buf[1024];
- isc_result_t ret;
- FILE *fp = NULL;
- char *p, *template;
-
- if (getenv("KRB5_CONFIG") != NULL) {
- /* the user has specifically set a KRB5_CONFIG to
- use. Don't override it, as they may know what they are
- doing */
- return;
- }
-
- dns_name_format(zone, buf, sizeof(buf));
-
- /* gssapi wants the realm in upper case */
- for (p=buf; *p; p++) {
- if (islower((int)*p))
- *p = toupper((int)*p);
- }
-
- kret = krb5_init_context(&ctx);
- if (kret != 0)
- return;
-
- kret = krb5_get_default_realm(ctx, &realm);
- if (kret == 0 && strcmp(buf, realm) == 0) {
- /* the krb5.conf is correct. */
- krb5_free_context(ctx);
- return;
- }
-
- gss_log(3, "zone '%s' doesn't match KRB5 default realm '%s'",
- buf, realm);
-
- template = isc_mem_strdup(mctx, "/tmp/krb5.conf.XXXXXX");
- if (template == NULL) {
- krb5_free_context(ctx);
- return;
- }
-
- ret = isc_file_openunique(template, &fp);
- if (ret != ISC_R_SUCCESS) {
- krb5_free_context(ctx);
- return;
- }
-
- fprintf(fp, "[libdefaults]\n");
- fprintf(fp, "\tdefault_realm = %s\n", buf);
- fprintf(fp, "\tdns_lookup_kdc = true\n");
- fclose(fp);
-
- setenv("KRB5_CONFIG", template, 1);
-
- *tmpfile = template;
-
- krb5_free_context(ctx);
-}
-
/*
* Format a gssapi error message info into a char ** on the given memory
* context. This is used to return gssapi error messages back up the
REQUIRE(gssctx != NULL);
REQUIRE(mctx != NULL);
- if (zone != NULL && mctx != NULL) {
- check_zone(zone, mctx, &tmpfile);
- }
-
isc_buffer_init(&namebuf, array, sizeof(array));
name_to_gbuffer(name, &namebuf, &gnamebuf);