cross-realm-obtain-tokens-afscreds-20040408
authorJeffrey Altman <jaltman@mit.edu>
Fri, 9 Apr 2004 00:32:03 +0000 (00:32 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 9 Apr 2004 00:32:03 +0000 (00:32 +0000)
If afscreds.exe you can now obtain credentials for cell "foo.com" with
credentials from "user@BAR.COM" when specifying a password.  This is a
first step since if there are already valid credentials for "user@BAR.COM"
the password should not be requested.  That would allow you to obtain
tokens for multiple cells with the same kerberos tgt.

src/WINNT/client_creds/afskfw.c

index 7ec3c45..1603a37 100644 (file)
@@ -1184,7 +1184,13 @@ KFW_AFS_get_cred(char * username,
     code = get_cellconfig( cell, (void*)&cellconfig, local_cell);
     if ( code ) goto cleanup;
 
-    realm = afs_realm_of_cell(&cellconfig);  // do not free
+    realm = strchr(username,'@');
+    if (realm) {
+        *realm = '\0';
+        realm++;
+    }
+    if ( !realm[0] )
+        realm = afs_realm_of_cell(&cellconfig);  // do not free
 
     if ( IsDebuggerPresent() ) {
         OutputDebugString("Realm: ");
@@ -2640,7 +2646,8 @@ KFW_AFS_klog(
 
         code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
         if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
-             code == KRB5KRB_ERR_GENERIC /* heimdal */) {
+             code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
+                        code == KRB5KRB_AP_ERR_MSG_TYPE) {
             /* Or service@REALM */
             pkrb5_free_principal(ctx,increds.server);
             increds.server = 0;
@@ -2669,6 +2676,72 @@ KFW_AFS_klog(
                 code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
         }
 
+        if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+              code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
+                         code == KRB5KRB_AP_ERR_MSG_TYPE) &&
+             strcmp(RealmName, realm_of_cell)) {
+            /* Or service/cell@REALM_OF_CELL */
+            strcpy(RealmName, realm_of_cell);
+            pkrb5_free_principal(ctx,increds.server);
+            increds.server = 0;
+            code = pkrb5_build_principal(ctx, &increds.server,
+                                         strlen(RealmName),
+                                         RealmName,
+                                         ServiceName,
+                                         CellName,
+                                         0);
+
+            if ( IsDebuggerPresent() ) {
+                char * cname, *sname;
+                pkrb5_unparse_name(ctx, increds.client, &cname);
+                pkrb5_unparse_name(ctx, increds.server, &sname);
+                OutputDebugString("krb5_get_credentials() returned Service Principal Unknown\n");
+                OutputDebugString("Trying again: getting tickets for \"");
+                OutputDebugString(cname);
+                OutputDebugString("\" and service \"");
+                OutputDebugString(sname);
+                OutputDebugString("\"\n");
+                pkrb5_free_unparsed_name(ctx,cname);
+                pkrb5_free_unparsed_name(ctx,sname);
+                cname = sname = 0;
+            }
+
+            if (!code)
+                code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+
+        
+            if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+                 code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
+                                code == KRB5KRB_AP_ERR_MSG_TYPE) {
+                /* Or service@REALM_OF_CELL */
+                pkrb5_free_principal(ctx,increds.server);
+                increds.server = 0;
+                code = pkrb5_build_principal(ctx, &increds.server,
+                                              strlen(RealmName),
+                                              RealmName,
+                                              ServiceName,
+                                              0);
+
+                if ( IsDebuggerPresent() ) {
+                    char * cname, *sname;
+                    pkrb5_unparse_name(ctx, increds.client, &cname);
+                    pkrb5_unparse_name(ctx, increds.server, &sname);
+                    OutputDebugString("krb5_get_credentials() returned Service Principal Unknown\n");
+                    OutputDebugString("Trying again: getting tickets for \"");
+                    OutputDebugString(cname);
+                    OutputDebugString("\" and service \"");
+                    OutputDebugString(sname);
+                    OutputDebugString("\"\n");
+                    pkrb5_free_unparsed_name(ctx,cname);
+                    pkrb5_free_unparsed_name(ctx,sname);
+                    cname = sname = 0;
+                }
+
+                if (!code)
+                    code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+            }
+        }
+
         if (code) {
             if ( IsDebuggerPresent() ) {
                 char message[256];