fallback to GSS_C_NT_HOSTBASED_SERVICE hostbased-fallback
authorAndrew Tridgell <tridge@samba.org>
Sun, 5 Dec 2010 02:46:59 +0000 (13:46 +1100)
committerAndrew Tridgell <tridge@samba.org>
Sun, 5 Dec 2010 02:46:59 +0000 (13:46 +1100)
lib/dns/gssapictx.c

index 77692921cafec64ac933039c82dd21669383f805..2ddca3490dffdb67658a3c3d7e13210d25339b75 100644 (file)
@@ -619,17 +619,6 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
                dst_gssapi_check_zone(zone, mctx, &tmpfile);
        }
 
-       isc_buffer_init(&namebuf, array, sizeof(array));
-       name_to_gbuffer(name, &namebuf, &gnamebuf);
-
-       /* Get the name as a GSS name */
-       gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
-       if (gret != GSS_S_COMPLETE) {
-               gss_err_message(mctx, gret, minor, err_message);
-               result = ISC_R_FAILURE;
-               goto out;
-       }
-
        if (intoken != NULL) {
                /* Don't call gss_release_buffer for gintoken! */
                REGION_TO_GBUFFER(*intoken, gintoken);
@@ -644,10 +633,44 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
         */
        flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG;
 
+#ifdef GSS_C_DELEG_POLICY_FLAG
+       /* see discussion by Love ├ůstrand on bind-workers list 3rd
+          December 2010 */
+       flags |= GSS_C_DELEG_POLICY_FLAG;
+#endif
+
+
+       isc_buffer_init(&namebuf, array, sizeof(array));
+       name_to_gbuffer(name, &namebuf, &gnamebuf);
+
+       /* try first with GSS_C_NO_OID */
+       gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
+       if (gret != GSS_S_COMPLETE) {
+               gss_err_message(mctx, gret, minor, err_message);
+               result = ISC_R_FAILURE;
+               goto out;
+       }
+
        gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx,
                                    gname, GSS_SPNEGO_MECHANISM, flags,
                                    0, NULL, gintokenp,
                                    NULL, &gouttoken, &ret_flags, NULL);
+       if (gret != GSS_S_COMPLETE && 
+           gret != GSS_S_CONTINUE_NEEDED && 
+           gnamebuf.length > 4 &&
+           strncmp((char *)gnamebuf.value, "DNS/", 4) == 0) {
+               /* try again with GSS_C_NT_HOSTBASED_SERVICE and a
+                * DNS@hostname form for name. This should allow for
+                * cross-realm trusts */
+               ((char *)gnamebuf.value)[3] = '@';
+               gret = gss_import_name(&minor, &gnamebuf, GSS_C_NT_HOSTBASED_SERVICE, &gname);
+               if (gret == GSS_S_COMPLETE) {
+                       gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx,
+                                                   gname, GSS_SPNEGO_MECHANISM, flags,
+                                                   0, NULL, gintokenp,
+                                                   NULL, &gouttoken, &ret_flags, NULL);
+               }
+       }
 
        if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) {
                gss_err_message(mctx, gret, minor, err_message);