r15210: Add wrapper functions smb_krb5_parse_name, smb_krb5_unparse_name,
authorJeremy Allison <jra@samba.org>
Mon, 24 Apr 2006 15:57:54 +0000 (15:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:16:28 +0000 (11:16 -0500)
smb_krb5_parse_name_norealm_conv that pull/push from unix charset
to utf8 (which krb5 uses on the wire). This should fix issues when
the unix charset is not compatible with or set to utf8.
Jeremy.

source/libads/kerberos.c
source/libads/kerberos_keytab.c
source/libads/kerberos_verify.c
source/libads/krb5_setpw.c
source/libads/sasl.c
source/libsmb/clikrb5.c

index e5211813d367c3ea030f938d64c4c1d6940ffc37..960709a5f044ae99c5196ac7fd7f9c9f59e114ed 100644 (file)
@@ -90,7 +90,7 @@ int kerberos_kinit_password_ext(const char *principal,
                return code;
        }
        
-       if ((code = krb5_parse_name(ctx, principal, &me))) {
+       if ((code = smb_krb5_parse_name(ctx, principal, &me))) {
                krb5_free_context(ctx); 
                return code;
        }
@@ -260,21 +260,21 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
        char *unparsed_name = NULL, *salt_princ_s = NULL;
        krb5_principal ret_princ = NULL;
 
-       if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) {
+       if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) {
                return (krb5_principal)NULL;
        }
 
        if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) {
-               krb5_free_unparsed_name(context, unparsed_name);
+               SAFE_FREE(unparsed_name);
                return (krb5_principal)NULL;
        }
 
-       if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) {
-               krb5_free_unparsed_name(context, unparsed_name);
+       if (smb_krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) {
+               SAFE_FREE(unparsed_name);
                SAFE_FREE(salt_princ_s);
                return (krb5_principal)NULL;
        }
-       krb5_free_unparsed_name(context, unparsed_name);
+       SAFE_FREE(unparsed_name);
        SAFE_FREE(salt_princ_s);
        return ret_princ;
 }
@@ -308,11 +308,11 @@ BOOL kerberos_secrets_store_salting_principal(const char *service,
                asprintf(&princ_s, "%s@%s", service, lp_realm());
        }
 
-       if (krb5_parse_name(context, princ_s, &princ) != 0) {
+       if (smb_krb5_parse_name(context, princ_s, &princ) != 0) {
                goto out;
                
        }
-       if (krb5_unparse_name(context, princ, &unparsed_name) != 0) {
+       if (smb_krb5_unparse_name(context, princ, &unparsed_name) != 0) {
                goto out;
        }
 
@@ -331,10 +331,8 @@ BOOL kerberos_secrets_store_salting_principal(const char *service,
 
        SAFE_FREE(key);
        SAFE_FREE(princ_s);
+       SAFE_FREE(unparsed_name);
 
-       if (unparsed_name) {
-               krb5_free_unparsed_name(context, unparsed_name);
-       }
        if (context) {
                krb5_free_context(context);
        }
@@ -396,8 +394,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx,
                asprintf(&service_s, "%s@%s", service_principal, lp_realm());
        }
 
-       if ((err = krb5_parse_name(ctx, service_s, &creds.server))) {
-               DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", 
+       if ((err = smb_krb5_parse_name(ctx, service_s, &creds.server))) {
+               DEBUG(0,("get_service_ticket: smb_krb5_parse_name %s failed: %s\n", 
                        service_s, error_message(err)));
                goto out;
        }
@@ -476,8 +474,8 @@ static BOOL verify_service_password(krb5_context ctx,
                asprintf(&salting_s, "%s@%s", salting_principal, lp_realm());
        }
 
-       if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) {
-               DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", 
+       if ((err = smb_krb5_parse_name(ctx, salting_s, &salting_kprinc))) {
+               DEBUG(0,("verify_service_password: smb_krb5_parse_name %s failed: %s\n", 
                        salting_s, error_message(err)));
                goto out;
        }
index f6ed107ee00dcff78f8700c1e5a13273008d1085..fc87b687d14fc80c049edce56e0fb3a10578ec4b 100644 (file)
@@ -130,9 +130,9 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
        /* Guess at how the KDC is salting keys for this principal. */
        kerberos_derive_salting_principal(princ_s);
 
-       ret = krb5_parse_name(context, princ_s, &princ);
+       ret = smb_krb5_parse_name(context, princ_s, &princ);
        if (ret) {
-               DEBUG(1,("ads_keytab_add_entry: krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret)));
+               DEBUG(1,("ads_keytab_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret)));
                goto out;
        }
 
@@ -150,9 +150,10 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
                while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
                        BOOL compare_name_ok = False;
 
-                       ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc);
+                       ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc);
                        if (ret) {
-                               DEBUG(1,("ads_keytab_add_entry: krb5_unparse_name failed (%s)\n", error_message(ret)));
+                               DEBUG(1,("ads_keytab_add_entry: smb_krb5_unparse_name failed (%s)\n",
+                                       error_message(ret)));
                                goto out;
                        }
 
@@ -176,8 +177,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
                                        ktprinc, kt_entry.vno));
                        }
 
-                       krb5_free_unparsed_name(context, ktprinc);
-                       ktprinc = NULL;
+                       SAFE_FREE(ktprinc);
 
                        if (compare_name_ok) {
                                if (kt_entry.vno == kvno - 1) {
@@ -581,9 +581,9 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
                                char *p;
 
                                /* This returns a malloc'ed string in ktprinc. */
-                               ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc);
+                               ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc);
                                if (ret) {
-                                       DEBUG(1,("krb5_unparse_name failed (%s)\n", error_message(ret)));
+                                       DEBUG(1,("smb_krb5_unparse_name failed (%s)\n", error_message(ret)));
                                        goto done;
                                }
                                /*
@@ -606,12 +606,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
                                                break;
                                        }
                                        if (!strcmp(oldEntries[i], ktprinc)) {
-                                               krb5_free_unparsed_name(context, ktprinc);
+                                               SAFE_FREE(ktprinc);
                                                break;
                                        }
                                }
                                if (i == found) {
-                                       krb5_free_unparsed_name(context, ktprinc);
+                                       SAFE_FREE(ktprinc);
                                }
                        }
                        smb_krb5_kt_free_entry(context, &kt_entry);
@@ -620,7 +620,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
                ret = 0;
                for (i = 0; oldEntries[i]; i++) {
                        ret |= ads_keytab_add_entry(ads, oldEntries[i]);
-                       krb5_free_unparsed_name(context, oldEntries[i]);
+                       SAFE_FREE(oldEntries[i]);
                }
                krb5_kt_end_seq_get(context, keytab, &cursor);
        }
index 934c1131eb09be021cd01101d69b93060c4739fd..fa957aa9c0688ae69734b13e9f9dea1150b48cbb 100644 (file)
@@ -90,9 +90,10 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
   
        if (ret != KRB5_KT_END && ret != ENOENT ) {
                while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {
-                       ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s);
+                       ret = smb_krb5_unparse_name(context, kt_entry.principal, &entry_princ_s);
                        if (ret) {
-                               DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret)));
+                               DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_unparse_name failed (%s)\n",
+                                       error_message(ret)));
                                goto out;
                        }
 
@@ -138,8 +139,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
                        }
 
                        /* Free the name we parsed. */
-                       krb5_free_unparsed_name(context, entry_princ_s);
-                       entry_princ_s = NULL;
+                       SAFE_FREE(entry_princ_s);
 
                        /* Free the entry we just read. */
                        smb_krb5_kt_free_entry(context, &kt_entry);
@@ -165,9 +165,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
                }
        }
 
-       if (entry_princ_s) {
-               krb5_free_unparsed_name(context, entry_princ_s);
-       }
+       SAFE_FREE(entry_princ_s);
 
        {
                krb5_keytab_entry zero_kt_entry;
@@ -343,9 +341,9 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
 
        asprintf(&host_princ_s, "%s$", global_myname());
        strlower_m(host_princ_s);
-       ret = krb5_parse_name(context, host_princ_s, &host_princ);
+       ret = smb_krb5_parse_name(context, host_princ_s, &host_princ);
        if (ret) {
-               DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
+               DEBUG(1,("ads_verify_ticket: smb_krb5_parse_name(%s) failed (%s)\n",
                                        host_princ_s, error_message(ret)));
                goto out;
        }
@@ -459,8 +457,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
 #endif
 #endif
 
-       if ((ret = krb5_unparse_name(context, client_principal, principal))) {
-               DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", 
+       if ((ret = smb_krb5_unparse_name(context, client_principal, principal))) {
+               DEBUG(3,("ads_verify_ticket: smb_krb5_unparse_name failed (%s)\n", 
                         error_message(ret)));
                sret = NT_STATUS_LOGON_FAILURE;
                goto out;
index 415c1e92294c111659c9c909e84015824186d280..254ca7b2a3ad19b2c5720a9f1973007ba6ec60cb 100644 (file)
@@ -521,7 +521,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
        realm++;
 
        asprintf(&princ_name, "kadmin/changepw@%s", realm);
-       ret = krb5_parse_name(context, princ_name, &creds.server);
+       ret = smb_krb5_parse_name(context, princ_name, &creds.server);
        if (ret) {
                krb5_cc_close(context, ccache);
                 krb5_free_context(context);
@@ -531,7 +531,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
        free(princ_name);
 
        /* parse the principal we got as a function argument */
-       ret = krb5_parse_name(context, princ, &principal);
+       ret = smb_krb5_parse_name(context, princ, &principal);
        if (ret) {
                krb5_cc_close(context, ccache);
                krb5_free_principal(context, creds.server);
@@ -633,7 +633,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
        return ADS_ERROR_KRB5(ret);
     }
 
-    if ((ret = krb5_parse_name(context, principal,
+    if ((ret = smb_krb5_parse_name(context, principal,
                                     &princ))) {
        krb5_free_context(context);
        DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret)));
index d8d33a924f2c5b1e186ac25da2d3f844a2362cec..a12af43eb37d18dfb1f1e41bb6bb32086e2d3355 100644 (file)
@@ -304,7 +304,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
        if (!ADS_ERR_OK(status)) {
                return status;
        }
-       status = ADS_ERROR_KRB5(krb5_parse_name(ctx, sname, &principal));
+       status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal));
        if (!ADS_ERR_OK(status)) {
                return status;
        }
index 4943f67b77634cdb2017f0d968e4cea683970885..1f43b91e3823d14c8c26090949ef00d751778f94 100644 (file)
 #define KRB5_KEY_DATA(k)       ((k)->contents)
 #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
 
+/**************************************************************
+ Wrappers around kerberos string functions that convert from
+ utf8 -> unix charset and vica versa.
+**************************************************************/
+
+/**************************************************************
+ krb5_parse_name that takes a UNIX charset.
+**************************************************************/
+
+krb5_error_code smb_krb5_parse_name(krb5_context context,
+                               const char *name, /* in unix charset */
+                               krb5_principal *principal)
+{
+       krb5_error_code ret;
+       char *utf8_name;
+
+       if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) {
+               return ENOMEM;
+       }
+
+       ret = krb5_parse_name(context, utf8_name, principal);
+       SAFE_FREE(utf8_name);
+       return ret;
+}
+
+#ifdef HAVE_KRB5_PARSE_NAME_NOREALM
+/**************************************************************
+ krb5_parse_name_norealm that takes a UNIX charset.
+**************************************************************/
+
+static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context,
+                               const char *name, /* in unix charset */
+                               krb5_principal *principal)
+{
+       krb5_error_code ret;
+       char *utf8_name;
+
+       if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) {
+               return ENOMEM;
+       }
+
+       ret = krb5_parse_name_norealm(context, utf8_name, principal);
+       SAFE_FREE(utf8_name);
+       return ret;
+}
+#endif
+
+/**************************************************************
+ krb5_parse_name that returns a UNIX charset name. Must
+ be freed with normal free() call.
+**************************************************************/
+
+krb5_error_code smb_krb5_unparse_name(krb5_context context,
+                                       krb5_const_principal principal,
+                                       char **unix_name)
+{
+       krb5_error_code ret;
+       char *utf8_name;
+
+       ret = krb5_unparse_name(context, principal, &utf8_name);
+       if (ret) {
+               return ret;
+       }
+
+       if (pull_utf8_allocate(unix_name, utf8_name)==-1) {
+               krb5_free_unparsed_name(context, utf8_name);
+               return ENOMEM;
+       }
+       krb5_free_unparsed_name(context, utf8_name);
+       return 0;
+}
+
 #ifndef HAVE_KRB5_SET_REAL_TIME
 /*
  * This function is not in the Heimdal mainline.
@@ -459,7 +531,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
        BOOL creds_ready = False;
        int i = 0, maxtries = 3;
        
-       retval = krb5_parse_name(context, principal, &server);
+       retval = smb_krb5_parse_name(context, principal, &server);
        if (retval) {
                DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal));
                return retval;
@@ -795,10 +867,11 @@ get_key_from_keytab(krb5_context context,
        }
 
        if ( DEBUGLEVEL >= 10 ) {
-               krb5_unparse_name(context, server, &name);
-               DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n", 
-                       kvno, enctype, name));
-               krb5_free_unparsed_name(context, name);
+               if (smb_krb5_unparse_name(context, server, &name) == 0) {
+                       DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n", 
+                               kvno, enctype, name));
+                       SAFE_FREE(name);
+               }
        }
 
        ret = krb5_kt_get_entry(context,
@@ -943,7 +1016,7 @@ out:
                                            krb5_principal *principal)
 {
 #ifdef HAVE_KRB5_PARSE_NAME_NOREALM
-       return krb5_parse_name_norealm(context, name, principal);
+       return smb_krb5_parse_name_norealm_conv(context, name, principal);
 #endif
 
        /* we are cheating here because parse_name will in fact set the realm.
@@ -951,7 +1024,7 @@ out:
         * ignores the realm anyway when calling
         * smb_krb5_principal_compare_any_realm later - Guenther */
 
-       return krb5_parse_name(context, name, principal);
+       return smb_krb5_parse_name(context, name, principal);
 }
 
  BOOL smb_krb5_principal_compare_any_realm(krb5_context context, 
@@ -1022,7 +1095,7 @@ out:
                krb5_creds creds;
        
                if (client_string) {
-                       ret = krb5_parse_name(context, client_string, &client);
+                       ret = smb_krb5_parse_name(context, client_string, &client);
                        if (ret) {
                                goto done;
                        }
@@ -1063,7 +1136,7 @@ out:
                memset(&creds_in, 0, sizeof(creds_in));
 
                if (client_string) {
-                       ret = krb5_parse_name(context, client_string, &creds_in.client);
+                       ret = smb_krb5_parse_name(context, client_string, &creds_in.client);
                        if (ret) {
                                goto done;
                        }
@@ -1075,7 +1148,7 @@ out:
                }
 
                if (service_string) {
-                       ret = krb5_parse_name(context, service_string, &creds_in.server);
+                       ret = smb_krb5_parse_name(context, service_string, &creds_in.server);
                        if (ret) { 
                                goto done;
                        }