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.
(This used to be commit 37ab42afbc9a79cf5b04ce6a1bf4060e9c961199)

source3/libads/kerberos.c
source3/libads/kerberos_keytab.c
source3/libads/kerberos_verify.c
source3/libads/krb5_setpw.c
source3/libads/sasl.c
source3/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;
                        }