auth: Add cli_credentials_ccache_update_principal()
[metze/samba/wip.git] / auth / credentials / credentials_krb5.c
index b48a9d30741faa5f9f90096773cf658260367d98..6d9cf066c6b74acdec041deb9f4a23b3cba4eb53 100644 (file)
@@ -414,6 +414,67 @@ _PUBLIC_ struct ccache_container *cli_credentials_ccache_get(struct cli_credenti
        return cred->krb5_ccache;
 }
 
+_PUBLIC_ bool cli_credentials_ccache_update_principal(struct cli_credentials *creds)
+{
+       krb5_context context;
+       struct ccache_container *ccc = cli_credentials_ccache_get(cred);
+       krb5_principal cc_principal = NULL;
+       krb5_error_code code;
+       krb5_data *realm_data;
+       char *principal;
+       char *realm;
+       bool ok;
+
+       if (ccc == NULL) {
+               return false;
+       }
+       context = ccc->smb_krb5_context->krb5_context;
+
+       code = krb5_cc_get_principal(context,
+                                    ccc->ccache,
+                                    &cc_principal);
+       if (code != 0) {
+               switch (code) {
+               /* Empty cache */
+               case KRB5_CC_NOTFOUND:
+               case KRB5_FCC_NOFILE:
+                       return true;
+               }
+               return false;
+       }
+
+       code = smb_krb5_unparse_name(creds,
+                                    context,
+                                    cc_principal,
+                                    &principal);
+       if (code != 0) {
+               return false;
+       }
+
+       ok = cli_credentials_set_principal(creds,
+                                          principal,
+                                          CRED_SPECIFIED);
+       TALLOC_FREE(principal);
+       if (!ok) {
+               krb5_free_principal(context, cc_principal);
+               return ok;
+       }
+
+       realm_data = krb5_princ_realm(context, cc_principal);
+
+       realm = talloc_strndup(creds, realm_data->data, realm_data->length);
+       krb5_free_principal(context, cc_principal);
+       if (realm == NULL) {
+               return false;
+       }
+       ok = cli_credentials_set_realm(creds,
+                                      realm,
+                                      CRED_SPECIFIED);
+       TALLOC_FREE(realm);
+
+       return ok;
+}
+
 static int cli_credentials_set_from_ccache(struct cli_credentials *cred, 
                                           struct ccache_container *ccache,
                                           enum credentials_obtained obtained,