Make krb5 wrapper library common so they can be used all over
authorSimo Sorce <idra@samba.org>
Sat, 21 Apr 2012 21:26:18 +0000 (17:26 -0400)
committerSimo Sorce <idra@samba.org>
Mon, 23 Apr 2012 23:20:38 +0000 (19:20 -0400)
25 files changed:
auth/credentials/credentials_krb5.c
auth/kerberos/gssapi_pac.c
auth/kerberos/pac_utils.h
auth/kerberos/wscript_build
lib/krb5_wrap/krb5_samba.c [moved from source3/libsmb/clikrb5.c with 84% similarity]
lib/krb5_wrap/krb5_samba.h [moved from source3/include/krb5_protos.h with 66% similarity]
lib/krb5_wrap/wscript_build [new file with mode: 0755]
libcli/auth/krb5_wrap.c [deleted file]
libcli/auth/krb5_wrap.h [deleted file]
libcli/auth/wscript_build [changed mode: 0644->0755]
libcli/smb/smb_seal.c
libcli/smb/wscript_build [changed mode: 0644->0755]
source3/Makefile.in
source3/include/smb_krb5.h
source3/libads/authdata.c
source3/libads/kerberos.c
source3/libads/kerberos_proto.h
source3/librpc/crypto/gse.c
source3/libsmb/cliconnect.c
source3/utils/ntlm_auth.c
source3/wscript_build
source4/auth/kerberos/kerberos.h
source4/auth/kerberos/wscript_build
source4/dsdb/wscript_build [changed mode: 0644->0755]
wscript_build [changed mode: 0644->0755]

index c8b685ea794ac8a16d72fbbd65905e03ff10fdda..480d7c5951c6f5946b4f942d741d5b6cff54606e 100644 (file)
@@ -30,6 +30,7 @@
 #include "auth/kerberos/kerberos_credentials.h"
 #include "auth/kerberos/kerberos_srv_keytab.h"
 #include "auth/kerberos/kerberos_util.h"
+#include "auth/kerberos/pac_utils.h"
 #include "param/param.h"
 
 static void cli_credentials_invalidate_client_gss_creds(
index 05065b2725ba3a091a6606bcb1a53bca4302ba13..d1a79501cce49c4f823c37b1fcb932f05db550a4 100644 (file)
@@ -21,7 +21,7 @@
 #include "includes.h"
 #ifdef HAVE_KRB5
 
-#include "libcli/auth/krb5_wrap.h"
+#include "lib/krb5_wrap/krb5_samba.h"
 #include "auth/kerberos/pac_utils.h"
 
 #if 0
@@ -271,4 +271,49 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-#endif
+
+char *gssapi_error_string(TALLOC_CTX *mem_ctx,
+                         OM_uint32 maj_stat, OM_uint32 min_stat,
+                         const gss_OID mech)
+{
+       OM_uint32 disp_min_stat, disp_maj_stat;
+       gss_buffer_desc maj_error_message;
+       gss_buffer_desc min_error_message;
+       char *maj_error_string, *min_error_string;
+       OM_uint32 msg_ctx = 0;
+
+       char *ret;
+
+       maj_error_message.value = NULL;
+       min_error_message.value = NULL;
+       maj_error_message.length = 0;
+       min_error_message.length = 0;
+
+       disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat,
+                                          GSS_C_GSS_CODE, mech,
+                                          &msg_ctx, &maj_error_message);
+       disp_maj_stat = gss_display_status(&disp_min_stat, min_stat,
+                                          GSS_C_MECH_CODE, mech,
+                                          &msg_ctx, &min_error_message);
+
+       maj_error_string = talloc_strndup(mem_ctx,
+                                         (char *)maj_error_message.value,
+                                         maj_error_message.length);
+
+       min_error_string = talloc_strndup(mem_ctx,
+                                         (char *)min_error_message.value,
+                                         min_error_message.length);
+
+       ret = talloc_asprintf(mem_ctx, "%s: %s",
+                               maj_error_string, min_error_string);
+
+       talloc_free(maj_error_string);
+       talloc_free(min_error_string);
+
+       gss_release_buffer(&disp_min_stat, &maj_error_message);
+       gss_release_buffer(&disp_min_stat, &min_error_message);
+
+       return ret;
+}
+
+#endif /* HAVE_KRB5 */
index 9fe08de834c4da96122a3185bd4111cc8b0fa8ab..bb954597f514ac573114a3f0033ae24b2d03c29b 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef _PAC_UTILS_H
 #define _PAC_UTILS_H
 
-#include "libcli/auth/krb5_wrap.h"
+#include "lib/krb5_wrap/krb5_samba.h"
 struct PAC_SIGNATURE_DATA;
 struct PAC_DATA;
 
@@ -47,4 +47,10 @@ NTSTATUS gssapi_get_session_key(TALLOC_CTX *mem_ctx,
                                gss_ctx_id_t gssapi_context,
                                DATA_BLOB *session_key,
                                uint32_t *keytype);
+
+/* not the best place here, need to move to a more generic gssapi
+ * wrapper later */
+char *gssapi_error_string(TALLOC_CTX *mem_ctx,
+                         OM_uint32 maj_stat, OM_uint32 min_stat,
+                         const gss_OID mech);
 #endif /* _PAC_UTILS_H */
index f49cc517bab6bb12d87d14775ffbed2c69b3a455..97b8879c8efaac3db4991d229f30bafe859fd4fc 100755 (executable)
@@ -1,4 +1,4 @@
 #!/usr/bin/env python
 bld.SAMBA_SUBSYSTEM('KRB5_PAC',
                     source='gssapi_pac.c kerberos_pac.c',
-                    deps='gssapi_krb5 krb5 ndr-krb5pac com_err')
+                    deps='gssapi_krb5 ndr-krb5pac krb5samba')
similarity index 84%
rename from source3/libsmb/clikrb5.c
rename to lib/krb5_wrap/krb5_samba.c
index 792400b3ce238a06f9f263c291e9628b833f65b3..4e555b285331086e515ac564fb906c09a338187e 100644 (file)
@@ -1,30 +1,29 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    simple kerberos5 routines for active directory
    Copyright (C) Andrew Tridgell 2001
    Copyright (C) Luke Howard 2002-2003
    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
    Copyright (C) Guenther Deschner 2005-2009
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "smb_krb5.h"
-#include "../librpc/gen_ndr/krb5pac.h"
-#include "../lib/util/asn1.h"
-#include "libsmb/nmblib.h"
+#include "krb5_samba.h"
+#include "librpc/gen_ndr/krb5pac.h"
+#include "lib/util/asn1.h"
 
 #ifndef KRB5_AUTHDATA_WIN2K_PAC
 #define KRB5_AUTHDATA_WIN2K_PAC 128
 /* MIT krb5 1.7beta3 (in Ubuntu Karmic) is missing the prototype,
    but still has the symbol */
 #if !HAVE_DECL_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE
-krb5_error_code krb5_auth_con_set_req_cksumtype(  
+krb5_error_code krb5_auth_con_set_req_cksumtype(
        krb5_context     context,
-       krb5_auth_context      auth_context,  
+       krb5_auth_context      auth_context,
        krb5_cksumtype     cksumtype);
 #endif
 
+#if !defined(SMB_MALLOC)
+#undef malloc
+#define SMB_MALLOC(s) malloc((s))
+#endif
+
 #if !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES)
 
 #if defined(HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES)
@@ -102,7 +106,7 @@ krb5_error_code krb5_auth_con_set_req_cksumtype(
 }
 #elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS)
 /* MIT */
- bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr)
+bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr)
 {
        memset(pkaddr, '\0', sizeof(krb5_address));
 #if defined(HAVE_IPV6) && defined(ADDRTYPE_INET6)
@@ -125,46 +129,61 @@ krb5_error_code krb5_auth_con_set_req_cksumtype(
 #error UNKNOWN_ADDRTYPE
 #endif
 
- int create_kerberos_key_from_string(krb5_context context,
-                                       krb5_principal host_princ,
-                                       krb5_data *password,
-                                       krb5_keyblock *key,
-                                       krb5_enctype enctype,
-                                       bool no_salt)
+#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_C_STRING_TO_KEY)
+/* MIT */
+int create_kerberos_key_from_string_direct(krb5_context context,
+                                                 krb5_principal host_princ,
+                                                 krb5_data *password,
+                                                 krb5_keyblock *key,
+                                                 krb5_enctype enctype)
 {
-       krb5_principal salt_princ = NULL;
-       int ret;
-       /*
-        * Check if we've determined that the KDC is salting keys for this
-        * principal/enctype in a non-obvious way.  If it is, try to match
-        * its behavior.
-        */
-       if (no_salt) {
-               KRB5_KEY_DATA(key) = (KRB5_KEY_DATA_CAST *)SMB_MALLOC(password->length);
-               if (!KRB5_KEY_DATA(key)) {
-                       return ENOMEM;
-               }
-               memcpy(KRB5_KEY_DATA(key), password->data, password->length);
-               KRB5_KEY_LENGTH(key) = password->length;
-               KRB5_KEY_TYPE(key) = enctype;
-               return 0;
+       int ret = 0;
+       krb5_data salt;
+
+       ret = krb5_principal2salt(context, host_princ, &salt);
+       if (ret) {
+               DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
+               return ret;
        }
-       salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype);
-       ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype);
-       if (salt_princ) {
-               krb5_free_principal(context, salt_princ);
+       ret = krb5_c_string_to_key(context, enctype, password, &salt, key);
+       SAFE_FREE(salt.data);
+
+       return ret;
+}
+#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
+/* Heimdal */
+int create_kerberos_key_from_string_direct(krb5_context context,
+                                                 krb5_principal host_princ,
+                                                 krb5_data *password,
+                                                 krb5_keyblock *key,
+                                                 krb5_enctype enctype)
+{
+       int ret;
+       krb5_salt salt;
+
+       ret = krb5_get_pw_salt(context, host_princ, &salt);
+       if (ret) {
+               DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret)));
+               return ret;
        }
+
+       ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key);
+       krb5_free_salt(context, salt);
+
        return ret;
 }
+#else
+#error UNKNOWN_CREATE_KEY_FUNCTIONS
+#endif
 
 #if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES)
- krb5_error_code get_kerberos_allowed_etypes(krb5_context context, 
+ krb5_error_code get_kerberos_allowed_etypes(krb5_context context,
                                            krb5_enctype **enctypes)
 {
        return krb5_get_permitted_enctypes(context, enctypes);
 }
 #elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES)
- krb5_error_code get_kerberos_allowed_etypes(krb5_context context, 
+ krb5_error_code get_kerberos_allowed_etypes(krb5_context context,
                                            krb5_enctype **enctypes)
 {
 #ifdef HAVE_KRB5_PDU_NONE_DECL
@@ -186,8 +205,8 @@ krb5_error_code krb5_auth_con_set_req_cksumtype(
 }
 #endif
 
-bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, 
-                          DATA_BLOB *edata, 
+bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
+                          DATA_BLOB *edata,
                           DATA_BLOB *edata_out)
 {
        DATA_BLOB edata_contents;
@@ -195,7 +214,7 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
        int edata_type;
 
        if (!edata->length) {
-               return False;
+               return false;
        }
 
        data = asn1_init(mem_ctx);
@@ -209,12 +228,12 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
        asn1_read_Integer(data, &edata_type);
 
        if (edata_type != KRB5_PADATA_PW_SALT) {
-               DEBUG(0,("edata is not of required type %d but of type %d\n", 
+               DEBUG(0,("edata is not of required type %d but of type %d\n",
                        KRB5_PADATA_PW_SALT, edata_type));
                asn1_free(data);
-               return False;
+               return false;
        }
-       
+
        asn1_start_tag(data, ASN1_CONTEXT(2));
        asn1_read_OctetString(data, talloc_tos(), &edata_contents);
        asn1_end_tag(data);
@@ -226,11 +245,11 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
 
        data_blob_free(&edata_contents);
 
-       return True;
+       return true;
 }
 
 
-static bool ads_cleanup_expired_creds(krb5_context context, 
+static bool ads_cleanup_expired_creds(krb5_context context,
                                      krb5_ccache  ccache,
                                      krb5_creds  *credsp)
 {
@@ -245,16 +264,16 @@ static bool ads_cleanup_expired_creds(krb5_context context,
           will expire within 10 seconds.
        */
        if (credsp->times.endtime >= (time(NULL) + 10))
-               return False;
+               return false;
 
-       /* heimdal won't remove creds from a file ccache, and 
-          perhaps we shouldn't anyway, since internally we 
+       /* heimdal won't remove creds from a file ccache, and
+          perhaps we shouldn't anyway, since internally we
           use memory ccaches, and a FILE one probably means that
           we're using creds obtained outside of our exectuable
        */
        if (strequal(cc_type, "FILE")) {
                DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a %s ccache\n", cc_type));
-               return False;
+               return false;
        }
 
        retval = krb5_cc_remove_cred(context, ccache, 0, credsp);
@@ -264,7 +283,7 @@ static bool ads_cleanup_expired_creds(krb5_context context,
                /* If we have an error in this, we want to display it,
                   but continue as though we deleted it */
        }
-       return True;
+       return true;
 }
 
 /* Allocate and setup the auth context into the state we need. */
@@ -345,15 +364,92 @@ static krb5_error_code create_gss_checksum(krb5_data *in_data, /* [inout] */
 }
 #endif
 
+/**************************************************************
+ 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;
+       size_t converted_size;
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       if (!push_utf8_talloc(frame, &utf8_name, name, &converted_size)) {
+               talloc_free(frame);
+               return ENOMEM;
+       }
+
+       ret = krb5_parse_name(context, utf8_name, principal);
+       TALLOC_FREE(frame);
+       return ret;
+}
+
+#if !defined(HAVE_KRB5_FREE_UNPARSED_NAME)
+void krb5_free_unparsed_name(krb5_context context, char *val)
+{
+       SAFE_FREE(val);
+}
+#endif
+
+/**************************************************************
+ krb5_parse_name that returns a UNIX charset name. Must
+ be freed with talloc_free() call.
+**************************************************************/
+
+krb5_error_code smb_krb5_unparse_name(TALLOC_CTX *mem_ctx,
+                                     krb5_context context,
+                                     krb5_const_principal principal,
+                                     char **unix_name)
+{
+       krb5_error_code ret;
+       char *utf8_name;
+       size_t converted_size;
+
+       *unix_name = NULL;
+       ret = krb5_unparse_name(context, principal, &utf8_name);
+       if (ret) {
+               return ret;
+       }
+
+       if (!pull_utf8_talloc(mem_ctx, unix_name, utf8_name, &converted_size)) {
+               krb5_free_unparsed_name(context, utf8_name);
+               return ENOMEM;
+       }
+       krb5_free_unparsed_name(context, utf8_name);
+       return 0;
+}
+
+krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, 
+                                           const char *name, 
+                                           krb5_principal *principal)
+{
+       /* we are cheating here because parse_name will in fact set the realm.
+        * We don't care as the only caller of smb_krb5_parse_name_norealm
+        * ignores the realm anyway when calling
+        * smb_krb5_principal_compare_any_realm later - Guenther */
+
+       return smb_krb5_parse_name(context, name, principal);
+}
+
+bool smb_krb5_principal_compare_any_realm(krb5_context context, 
+                                         krb5_const_principal princ1, 
+                                         krb5_const_principal princ2)
+{
+       return krb5_principal_compare_any_realm(context, princ1, princ2);
+}
+
 /*
   we can't use krb5_mk_req because w2k wants the service to be in a particular format
 */
-static krb5_error_code ads_krb5_mk_req(krb5_context context, 
-                                      krb5_auth_context *auth_context, 
+static krb5_error_code ads_krb5_mk_req(krb5_context context,
+                                      krb5_auth_context *auth_context,
                                       const krb5_flags ap_req_options,
                                       const char *principal,
-                                      krb5_ccache ccache, 
-                                      krb5_data *outbuf, 
+                                      krb5_ccache ccache,
+                                      krb5_data *outbuf,
                                       time_t *expire_time,
                                       const char *impersonate_princ_s)
 {
@@ -363,7 +459,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
        krb5_creds              * credsp;
        krb5_creds                creds;
        krb5_data in_data;
-       bool creds_ready = False;
+       bool creds_ready = false;
        int i = 0, maxtries = 3;
 
        ZERO_STRUCT(in_data);
@@ -386,11 +482,11 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
        /* obtain ticket & session key */
        ZERO_STRUCT(creds);
        if ((retval = krb5_copy_principal(context, server, &creds.server))) {
-               DEBUG(1,("ads_krb5_mk_req: krb5_copy_principal failed (%s)\n", 
+               DEBUG(1,("ads_krb5_mk_req: krb5_copy_principal failed (%s)\n",
                         error_message(retval)));
                goto cleanup_princ;
        }
-       
+
        if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) {
                /* This can commonly fail on smbd startup with no ticket in the cache.
                 * Report at higher level than 1. */
@@ -420,7 +516,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
                }
 
                if (!ads_cleanup_expired_creds(context, ccache, credsp)) {
-                       creds_ready = True;
+                       creds_ready = true;
                }
 
                i++;
@@ -525,7 +621,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
        }
 #endif
 
-       retval = krb5_mk_req_extended(context, auth_context, ap_req_options, 
+       retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
                                      &in_data, credsp, outbuf);
        if (retval) {
                DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", 
@@ -555,6 +651,19 @@ cleanup_princ:
        return retval;
 }
 
+void kerberos_free_data_contents(krb5_context context, krb5_data *pdata)
+{
+#if defined(HAVE_KRB5_FREE_DATA_CONTENTS)
+       if (pdata->data) {
+               krb5_free_data_contents(context, pdata);
+       }
+#elif defined(HAVE_KRB5_DATA_FREE)
+       krb5_data_free(context, pdata);
+#else
+       SAFE_FREE(pdata->data);
+#endif
+}
+
 /*
   get a kerberos5 ticket for the given service
 */
@@ -748,7 +857,7 @@ done:
        if (ret) {
                goto done;
        }
-       
+
        ret = krb5_cc_store_cred(context, ccache, &creds);
 
        if (expire_time) {
@@ -794,10 +903,13 @@ done:
        return ret;
 }
 
- krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr)
+#define MAX_NETBIOSNAME_LEN 16
+ krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr,
+                                                  const char *netbios_name)
 {
        krb5_error_code ret = 0;
-       nstring buf;
+       char buf[MAX_NETBIOSNAME_LEN];
+       int len;
 #if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
        krb5_address **addrs = NULL;
 #elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */
@@ -809,7 +921,15 @@ done:
                return ENOMEM;
        }
 
-       put_name(buf, lp_netbios_name(), ' ', 0x20);
+       /* temporarily duplicate put_name() code here to avoid dependency
+        * issues for a 5 lines function */
+       len = strlen(netbios_name);
+       memcpy(buf, netbios_name,
+               (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1);
+       if (len < MAX_NETBIOSNAME_LEN - 1) {
+               memset(buf + len, ' ', MAX_NETBIOSNAME_LEN - 1 - len);
+       }
+       buf[MAX_NETBIOSNAME_LEN - 1] = 0x20;
 
 #if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
        {
@@ -896,10 +1016,10 @@ done:
                                        krb5_data *packet)
 {
        krb5_error_code ret;
-       bool got_error_code = False;
+       bool got_error_code = false;
 
        DEBUG(10,("handle_krberror_packet: got error packet\n"));
-       
+
 #ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR /* Heimdal */
        {
                krb5_error krberror;
@@ -912,7 +1032,7 @@ done:
 
                if (krberror.e_data == NULL || krberror.e_data->data == NULL) {
                        ret = (krb5_error_code) krberror.error_code;
-                       got_error_code = True;
+                       got_error_code = true;
                }
 
                smb_krb5_free_error(context, &krberror);
@@ -933,7 +1053,7 @@ done:
 #else
                        ret = (krb5_error_code)krberror->error;
 #endif
-                       got_error_code = True;
+                       got_error_code = true;
                }
                smb_krb5_free_error(context, krberror);
        }
@@ -945,30 +1065,47 @@ done:
        return ret;
 }
 
- krb5_error_code smb_krb5_get_init_creds_opt_alloc(krb5_context context,
+krb5_error_code smb_krb5_get_init_creds_opt_alloc(krb5_context context,
                                            krb5_get_init_creds_opt **opt)
 {
        /* Heimdal or modern MIT version */
        return krb5_get_init_creds_opt_alloc(context, opt);
 }
 
- void smb_krb5_get_init_creds_opt_free(krb5_context context,
+void smb_krb5_get_init_creds_opt_free(krb5_context context,
                                krb5_get_init_creds_opt *opt)
 {
        /* Modern MIT or Heimdal version */
        krb5_get_init_creds_opt_free(context, opt);
 }
 
- krb5_enctype smb_get_enctype_from_kt_entry(krb5_keytab_entry *kt_entry)
+krb5_enctype smb_get_enctype_from_kt_entry(krb5_keytab_entry *kt_entry)
 {
        return KRB5_KEY_TYPE(KRB5_KT_KEY(kt_entry));
 }
 
+krb5_error_code smb_krb5_kt_free_entry(krb5_context context,
+                                       krb5_keytab_entry *kt_entry)
+{
+/* Try krb5_free_keytab_entry_contents first, since
+ * MIT Kerberos >= 1.7 has both krb5_free_keytab_entry_contents and
+ * krb5_kt_free_entry but only has a prototype for the first, while the
+ * second is considered private.
+ */
+#if defined(HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS)
+       return krb5_free_keytab_entry_contents(context, kt_entry);
+#elif defined(HAVE_KRB5_KT_FREE_ENTRY)
+       return krb5_kt_free_entry(context, kt_entry);
+#else
+#error UNKNOWN_KT_FREE_FUNCTION
+#endif
+}
+
 
 /* caller needs to free etype_s */
- krb5_error_code smb_krb5_enctype_to_string(krb5_context context, 
-                                           krb5_enctype enctype, 
-                                           char **etype_s)
+krb5_error_code smb_krb5_enctype_to_string(krb5_context context,
+                                          krb5_enctype enctype,
+                                          char **etype_s)
 {
 #ifdef HAVE_KRB5_ENCTYPE_TO_STRING_WITH_KRB5_CONTEXT_ARG
        return krb5_enctype_to_string(context, enctype, etype_s); /* Heimdal */
@@ -991,7 +1128,7 @@ done:
 /**********************************************************************
  * Open a krb5 keytab with flags, handles readonly or readwrite access and
  * allows to process non-default keytab names.
- * @param context krb5_context 
+ * @param context krb5_context
  * @param keytab_name_req string
  * @param write_access bool if writable keytab is required
  * @param krb5_keytab pointer to krb5_keytab (close with krb5_kt_close())
@@ -1003,16 +1140,16 @@ done:
 #define MAX_KEYTAB_NAME_LEN 1100
 #endif
 
- krb5_error_code smb_krb5_open_keytab(krb5_context context,
-                                     const char *keytab_name_req,
-                                     bool write_access,
-                                     krb5_keytab *keytab)
+krb5_error_code smb_krb5_open_keytab(krb5_context context,
+                                    const char *keytab_name_req,
+                                    bool write_access,
+                                    krb5_keytab *keytab)
 {
        krb5_error_code ret = 0;
        TALLOC_CTX *mem_ctx;
        char keytab_string[MAX_KEYTAB_NAME_LEN];
        char *kt_str = NULL;
-       bool found_valid_name = False;
+       bool found_valid_name = false;
        const char *pragma = "FILE";
        const char *tmp = NULL;
 
@@ -1026,7 +1163,7 @@ done:
                return ENOMEM;
        }
 
-#ifdef HAVE_WRFILE_KEYTAB 
+#ifdef HAVE_WRFILE_KEYTAB
        if (write_access) {
                pragma = "WRFILE";
        }
@@ -1039,7 +1176,7 @@ done:
                        goto out;
                }
 
-               if ((strncmp(keytab_name_req, "WRFILE:/", 8) == 0) || 
+               if ((strncmp(keytab_name_req, "WRFILE:/", 8) == 0) ||
                    (strncmp(keytab_name_req, "FILE:/", 6) == 0)) {
                        tmp = keytab_name_req;
                        goto resolve;
@@ -1083,13 +1220,13 @@ done:
 
        while (next_token_talloc(mem_ctx, &tmp, &kt_str, ",")) {
                if (strncmp(kt_str, "WRFILE:", 7) == 0) {
-                       found_valid_name = True;
+                       found_valid_name = true;
                        tmp = kt_str;
                        tmp += 7;
                }
 
                if (strncmp(kt_str, "FILE:", 5) == 0) {
-                       found_valid_name = True;
+                       found_valid_name = true;
                        tmp = kt_str;
                        tmp += 5;
                }
@@ -1545,7 +1682,8 @@ static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
 
 char *kerberos_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
                                                   const char *service,
-                                                  const char *remote_name)
+                                                  const char *remote_name,
+                                                  const char *default_realm)
 {
        char *realm = NULL;
        char *host = NULL;
@@ -1561,7 +1699,7 @@ char *kerberos_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
        }
 
        if (realm == NULL || *realm == '\0') {
-               realm = talloc_strdup(talloc_tos(), lp_realm());
+               realm = talloc_strdup(talloc_tos(), default_realm);
                if (!realm) {
                        return NULL;
                }
@@ -1581,6 +1719,25 @@ char *kerberos_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
        return principal;
 }
 
+char *smb_get_krb5_error_message(krb5_context context,
+                                krb5_error_code code,
+                                TALLOC_CTX *mem_ctx)
+{
+       char *ret;
+
+#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) && defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
+       const char *context_error = krb5_get_error_message(context, code);
+       if (context_error) {
+               ret = talloc_asprintf(mem_ctx, "%s: %s",
+                                       error_message(code), context_error);
+               krb5_free_error_message(context, context_error);
+               return ret;
+       }
+#endif
+       ret = talloc_strdup(mem_ctx, error_message(code));
+       return ret;
+}
+
 #else /* HAVE_KRB5 */
  /* this saves a few linking headaches */
  int cli_krb5_get_ticket(TALLOC_CTX *mem_ctx,
similarity index 66%
rename from source3/include/krb5_protos.h
rename to lib/krb5_wrap/krb5_samba.h
index 99569998a164bf164ed12ee3b01df89d9f2bf431..3800b024adb5cb14482264205380d9816e7270ea 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _INCLUDE_KRB5_PROTOS_H_
-#define _INCLUDE_KRB5_PROTOS_H_
+#ifndef _KRB5_SAMBA_H
+#define _KRB5_SAMBA_H
 
-struct PAC_DATA;
-struct PAC_SIGNATURE_DATA;
+#ifdef HAVE_KRB5
+
+#define KRB5_PRIVATE    1       /* this file uses PRIVATE interfaces! */
+/* this file uses DEPRECATED interfaces! */
+
+#if defined(HAVE_KRB5_DEPRECATED_WITH_IDENTIFIER)
+#define KRB5_DEPRECATED 1
+#else
+#define KRB5_DEPRECATED
+#endif
+
+#include "system/kerberos.h"
+#include "system/network.h"
+
+#ifndef KRB5_ADDR_NETBIOS
+#define KRB5_ADDR_NETBIOS 0x14
+#endif
+
+#ifndef KRB5KRB_ERR_RESPONSE_TOO_BIG
+#define KRB5KRB_ERR_RESPONSE_TOO_BIG (-1765328332L)
+#endif
+
+/* Heimdal uses a slightly different name */
+#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5) && !defined(HAVE_ENCTYPE_ARCFOUR_HMAC)
+#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
+#endif
+
+/* The older versions of heimdal that don't have this
+   define don't seem to use it anyway.  I'm told they
+   always use a subkey */
+#ifndef HAVE_AP_OPTS_USE_SUBKEY
+#define AP_OPTS_USE_SUBKEY 0
+#endif
+
+typedef struct {
+#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
+       krb5_address **addrs;
+#elif defined(HAVE_KRB5_ADDRESSES) /* Heimdal */
+       krb5_addresses *addrs;
+#else
+#error UNKNOWN_KRB5_ADDRESS_TYPE
+#endif /* defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) */
+} smb_krb5_addresses;
+
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY               /* MIT */
+#define KRB5_KT_KEY(k)         (&(k)->key)
+#elif HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK          /* Heimdal */
+#define KRB5_KT_KEY(k)         (&(k)->keyblock)
+#else
+#error krb5_keytab_entry has no key or keyblock member
+#endif /* HAVE_KRB5_KEYTAB_ENTRY_KEY */
 
 /* work around broken krb5.h on sles9 */
 #ifdef SIZEOF_LONG
 #undef SIZEOF_LONG
 #endif
 
+#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */
+#define KRB5_KEY_TYPE(k)       ((k)->keytype)
+#define KRB5_KEY_LENGTH(k)     ((k)->keyvalue.length)
+#define KRB5_KEY_DATA(k)       ((k)->keyvalue.data)
+#define KRB5_KEY_DATA_CAST     void
+#else /* MIT */
+#define KRB5_KEY_TYPE(k)       ((k)->enctype)
+#define KRB5_KEY_LENGTH(k)     ((k)->length)
+#define KRB5_KEY_DATA(k)       ((k)->contents)
+#define KRB5_KEY_DATA_CAST     krb5_octet
+#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
 
-#if defined(HAVE_KRB5)
 krb5_error_code smb_krb5_parse_name(krb5_context context,
                                const char *name, /* in unix charset */
                                 krb5_principal *principal);
@@ -60,18 +119,26 @@ void krb5_free_unparsed_name(krb5_context ctx, char *val);
 #define initialize_krb5_error_table()
 #endif
 
-/* The following definitions come from libsmb/clikrb5.c  */
-
-/* Samba wrapper function for krb5 functionality. */
+/* Samba wrapper functions for krb5 functionality. */
 bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr);
-int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype, bool no_salt);
+int create_kerberos_key_from_string(krb5_context context,
+                                   krb5_principal host_princ,
+                                   krb5_data *password,
+                                   krb5_keyblock *key,
+                                   krb5_enctype enctype,
+                                   bool no_salt);
+int create_kerberos_key_from_string_direct(krb5_context context,
+                                          krb5_principal host_princ,
+                                          krb5_data *password,
+                                          krb5_keyblock *key,
+                                          krb5_enctype enctype);
+
 krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
 bool get_krb5_smb_session_key(TALLOC_CTX *mem_ctx,
                              krb5_context context,
                              krb5_auth_context auth_context,
                              DATA_BLOB *session_key, bool remote);
 krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);
-krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, krb5_principal host_princ, int enctype);
 void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype);
 bool kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2);
 void kerberos_free_data_contents(krb5_context context, krb5_data *pdata);
@@ -83,7 +150,8 @@ bool smb_krb5_principal_compare_any_realm(krb5_context context,
                                          krb5_const_principal princ2);
 krb5_error_code smb_krb5_renew_ticket(const char *ccache_string, const char *client_string, const char *service_string, time_t *expire_time);
 krb5_error_code kpasswd_err_to_krb5_err(krb5_error_code res_code);
-krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr);
+krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr,
+                                                 const char *netbios_name);
 krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr);
 NTSTATUS krb5_to_nt_status(krb5_error_code kerberos_error);
 krb5_error_code nt_status_to_krb5(NTSTATUS nt_status);
@@ -123,9 +191,12 @@ char *smb_krb5_principal_get_realm(krb5_context context,
 
 char *kerberos_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
                                                   const char *service,
-                                                  const char *remote_name);
+                                                  const char *remote_name,
+                                                  const char *default_realm);
 
-#endif /* HAVE_KRB5 */
+char *smb_get_krb5_error_message(krb5_context context,
+                                krb5_error_code code,
+                                TALLOC_CTX *mem_ctx);
 
 int cli_krb5_get_ticket(TALLOC_CTX *mem_ctx,
                        const char *principal, time_t time_offset,
@@ -138,4 +209,7 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
                           DATA_BLOB *edata,
                           DATA_BLOB *edata_out);
 
-#endif /* _INCLUDE_KRB5_PROTOS_H_ */
+#endif /* HAVE_KRB5 */
+
+
+#endif /* _KRB5_SAMBA_H */
diff --git a/lib/krb5_wrap/wscript_build b/lib/krb5_wrap/wscript_build
new file mode 100755 (executable)
index 0000000..c585819
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+bld.SAMBA_LIBRARY('krb5samba',
+                  source='krb5_samba.c',
+                  deps='samba-util asn1util talloc krb5 com_err',
+                 private_library=True
+                 )
diff --git a/libcli/auth/krb5_wrap.c b/libcli/auth/krb5_wrap.c
deleted file mode 100644 (file)
index 55a2246..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   simple kerberos5 routines for active directory
-   Copyright (C) Andrew Tridgell 2001
-   Copyright (C) Luke Howard 2002-2003
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2011
-   Copyright (C) Guenther Deschner 2005-2009
-   Copyright (C) Simo Sorce 2010.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#ifdef HAVE_KRB5
-
-#include "libcli/auth/krb5_wrap.h"
-#include "librpc/gen_ndr/krb5pac.h"
-
-#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_C_STRING_TO_KEY)
-/* MIT */
-int create_kerberos_key_from_string_direct(krb5_context context,
-                                                 krb5_principal host_princ,
-                                                 krb5_data *password,
-                                                 krb5_keyblock *key,
-                                                 krb5_enctype enctype)
-{
-       int ret = 0;
-       krb5_data salt;
-
-       ret = krb5_principal2salt(context, host_princ, &salt);
-       if (ret) {
-               DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
-               return ret;
-       }
-       ret = krb5_c_string_to_key(context, enctype, password, &salt, key);
-       SAFE_FREE(salt.data);
-
-       return ret;
-}
-#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
-/* Heimdal */
-int create_kerberos_key_from_string_direct(krb5_context context,
-                                                 krb5_principal host_princ,
-                                                 krb5_data *password,
-                                                 krb5_keyblock *key,
-                                                 krb5_enctype enctype)
-{
-       int ret;
-       krb5_salt salt;
-
-       ret = krb5_get_pw_salt(context, host_princ, &salt);
-       if (ret) {
-               DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret)));
-               return ret;
-       }
-
-       ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key);
-       krb5_free_salt(context, salt);
-
-       return ret;
-}
-#else
-#error UNKNOWN_CREATE_KEY_FUNCTIONS
-#endif
-
- void kerberos_free_data_contents(krb5_context context, krb5_data *pdata)
-{
-#if defined(HAVE_KRB5_FREE_DATA_CONTENTS)
-       if (pdata->data) {
-               krb5_free_data_contents(context, pdata);
-       }
-#elif defined(HAVE_KRB5_DATA_FREE)
-       krb5_data_free(context, pdata);
-#else
-       SAFE_FREE(pdata->data);
-#endif
-}
-
-
- krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry)
-{
-/* Try krb5_free_keytab_entry_contents first, since
- * MIT Kerberos >= 1.7 has both krb5_free_keytab_entry_contents and
- * krb5_kt_free_entry but only has a prototype for the first, while the
- * second is considered private.
- */
-#if defined(HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS)
-       return krb5_free_keytab_entry_contents(context, kt_entry);
-#elif defined(HAVE_KRB5_KT_FREE_ENTRY)
-       return krb5_kt_free_entry(context, kt_entry);
-#else
-#error UNKNOWN_KT_FREE_FUNCTION
-#endif
-}
-
-/**************************************************************
- 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;
-       size_t converted_size;
-       TALLOC_CTX *frame = talloc_stackframe();
-
-       if (!push_utf8_talloc(frame, &utf8_name, name, &converted_size)) {
-               talloc_free(frame);
-               return ENOMEM;
-       }
-
-       ret = krb5_parse_name(context, utf8_name, principal);
-       TALLOC_FREE(frame);
-       return ret;
-}
-
-#if !defined(HAVE_KRB5_FREE_UNPARSED_NAME)
-static void krb5_free_unparsed_name(krb5_context context, char *val)
-{
-       SAFE_FREE(val);
-}
-#endif
-
-/**************************************************************
- krb5_parse_name that returns a UNIX charset name. Must
- be freed with talloc_free() call.
-**************************************************************/
-
-krb5_error_code smb_krb5_unparse_name(TALLOC_CTX *mem_ctx,
-                                     krb5_context context,
-                                     krb5_const_principal principal,
-                                     char **unix_name)
-{
-       krb5_error_code ret;
-       char *utf8_name;
-       size_t converted_size;
-
-       *unix_name = NULL;
-       ret = krb5_unparse_name(context, principal, &utf8_name);
-       if (ret) {
-               return ret;
-       }
-
-       if (!pull_utf8_talloc(mem_ctx, unix_name, utf8_name, &converted_size)) {
-               krb5_free_unparsed_name(context, utf8_name);
-               return ENOMEM;
-       }
-       krb5_free_unparsed_name(context, utf8_name);
-       return 0;
-}
-
- krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, 
-                                           const char *name, 
-                                           krb5_principal *principal)
-{
-       /* we are cheating here because parse_name will in fact set the realm.
-        * We don't care as the only caller of smb_krb5_parse_name_norealm
-        * ignores the realm anyway when calling
-        * smb_krb5_principal_compare_any_realm later - Guenther */
-
-       return smb_krb5_parse_name(context, name, principal);
-}
-
- bool smb_krb5_principal_compare_any_realm(krb5_context context, 
-                                         krb5_const_principal princ1, 
-                                         krb5_const_principal princ2)
-{
-       return krb5_principal_compare_any_realm(context, princ1, princ2);
-}
-
-char *gssapi_error_string(TALLOC_CTX *mem_ctx, 
-                         OM_uint32 maj_stat, OM_uint32 min_stat, 
-                         const gss_OID mech)
-{
-       OM_uint32 disp_min_stat, disp_maj_stat;
-       gss_buffer_desc maj_error_message;
-       gss_buffer_desc min_error_message;
-       char *maj_error_string, *min_error_string;
-       OM_uint32 msg_ctx = 0;
-
-       char *ret;
-
-       maj_error_message.value = NULL;
-       min_error_message.value = NULL;
-       maj_error_message.length = 0;
-       min_error_message.length = 0;
-       
-       disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE,
-                          mech, &msg_ctx, &maj_error_message);
-       disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE,
-                          mech, &msg_ctx, &min_error_message);
-       
-       maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length);
-
-       min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length);
-
-       ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string);
-
-       talloc_free(maj_error_string);
-       talloc_free(min_error_string);
-
-       gss_release_buffer(&disp_min_stat, &maj_error_message);
-       gss_release_buffer(&disp_min_stat, &min_error_message);
-
-       return ret;
-}
-
-
- char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx)
-{
-       char *ret;
-
-#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) && defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
-       const char *context_error = krb5_get_error_message(context, code);
-       if (context_error) {
-               ret = talloc_asprintf(mem_ctx, "%s: %s", error_message(code), context_error);
-               krb5_free_error_message(context, context_error);
-               return ret;
-       }
-#endif
-       ret = talloc_strdup(mem_ctx, error_message(code));
-       return ret;
-}
-
-#endif
diff --git a/libcli/auth/krb5_wrap.h b/libcli/auth/krb5_wrap.h
deleted file mode 100644 (file)
index 4c0ef93..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   simple kerberos5 routines for active directory
-   Copyright (C) Andrew Tridgell 2001
-   Copyright (C) Luke Howard 2002-2003
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
-   Copyright (C) Guenther Deschner 2005-2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "system/kerberos.h"
-
-#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */
-#define KRB5_KEY_TYPE(k)       ((k)->keytype)
-#define KRB5_KEY_LENGTH(k)     ((k)->keyvalue.length)
-#define KRB5_KEY_DATA(k)       ((k)->keyvalue.data)
-#define KRB5_KEY_DATA_CAST     void
-#else /* MIT */
-#define KRB5_KEY_TYPE(k)       ((k)->enctype)
-#define KRB5_KEY_LENGTH(k)     ((k)->length)
-#define KRB5_KEY_DATA(k)       ((k)->contents)
-#define KRB5_KEY_DATA_CAST     krb5_octet
-#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
-
-int create_kerberos_key_from_string_direct(krb5_context context,
-                                                 krb5_principal host_princ,
-                                                 krb5_data *password,
-                                                 krb5_keyblock *key,
-                                          krb5_enctype enctype);
-void kerberos_free_data_contents(krb5_context context, krb5_data *pdata);
-krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);
-
- krb5_error_code smb_krb5_parse_name(krb5_context context,
-                               const char *name, /* in unix charset */
-                                    krb5_principal *principal);
-krb5_error_code smb_krb5_unparse_name(TALLOC_CTX *mem_ctx,
-                                     krb5_context context,
-                                     krb5_const_principal principal,
-                                     char **unix_name);
- krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, 
-                                           const char *name, 
-                                            krb5_principal *principal);
- bool smb_krb5_principal_compare_any_realm(krb5_context context, 
-                                         krb5_const_principal princ1, 
-                                          krb5_const_principal princ2);
-char *gssapi_error_string(TALLOC_CTX *mem_ctx, 
-                         OM_uint32 maj_stat, OM_uint32 min_stat, 
-                         const gss_OID mech);
-char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx);
-
old mode 100644 (file)
new mode 100755 (executable)
index b4b648e..893cfd9
@@ -2,7 +2,7 @@
 
 bld.SAMBA_LIBRARY('cliauth',
                   source='',
-                  deps='MSRPC_PARSE LIBCLI_AUTH COMMON_SCHANNEL PAM_ERRORS SPNEGO_PARSE KRB5_WRAP errors NTLM_CHECK UTIL_LSARPC',
+                  deps='MSRPC_PARSE LIBCLI_AUTH COMMON_SCHANNEL PAM_ERRORS SPNEGO_PARSE krb5samba errors NTLM_CHECK UTIL_LSARPC',
                   private_library=True,
                   grouping_library=True)
 
@@ -37,7 +37,3 @@ bld.SAMBA_SUBSYSTEM('PAM_ERRORS',
 bld.SAMBA_SUBSYSTEM('SPNEGO_PARSE',
                     source='spnego_parse.c',
                     deps='asn1util')
-
-bld.SAMBA_SUBSYSTEM('KRB5_WRAP',
-                    source='krb5_wrap.c',
-                    deps='gssapi_krb5 krb5 ndr-krb5pac com_err KRB5_PAC')
index d5bb2388bb9b7ce918337de8881f059ab3758074..78af733d00f35736fc5fe64fa61da4574cb8f062 100644 (file)
@@ -20,7 +20,7 @@
 #include "includes.h"
 #include "smb_common.h"
 #if HAVE_KRB5
-#include "libcli/auth/krb5_wrap.h"
+#include "lib/krb5_wrap/krb5_samba.h"
 #endif
 #include "auth/gensec/gensec.h"
 #include "libcli/smb/smb_seal.h"
old mode 100644 (file)
new mode 100755 (executable)
index 7a21d4a..6feed44
@@ -10,7 +10,7 @@ bld.SAMBA_LIBRARY('cli_smb_common',
                smbXcli_base.c
                smb1cli_trans.c
        ''',
-       deps='LIBCRYPTO errors gssapi gensec KRB5_WRAP LIBASYNC_REQ',
+       deps='LIBCRYPTO errors gssapi gensec krb5samba LIBASYNC_REQ',
        public_deps='talloc samba-util',
        private_library=True,
        public_headers='''
index d48d298e725e24a2053143ee7f016e6efc3e5328..1353bd2da8fdec0b1ec2633488f3142cbf494e10 100644 (file)
@@ -559,11 +559,10 @@ LIBSMB_OBJ0 = \
               ../lib/util/asn1.o \
               ../libcli/auth/spnego_parse.o \
               ../libcli/auth/ntlm_check.o \
-              ../libcli/auth/krb5_wrap.o \
               libsmb/ntlmssp.o \
               libsmb/ntlmssp_wrap.o \
               libsmb/auth_generic.o \
-              libsmb/clikrb5.o \
+              ../lib/krb5_wrap/krb5_samba.o \
               libsmb/clispnego.o \
               ../auth/gensec/gensec.o \
               ../auth/gensec/gensec_start.o \
index 88e91e1670b9bf0f9032551f09cf6e5b154c99e5..1f66212321befeaeda9ad0a23df088fc9ac77eec 100644 (file)
@@ -1,82 +1 @@
-/*
-   Unix SMB/CIFS implementation.
-   simple kerberos5 routines for active directory
-   Copyright (C) Andrew Tridgell 2001
-   Copyright (C) Luke Howard 2002-2003
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
-   Copyright (C) Guenther Deschner 2005-2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _HEADER_smb_krb5_h
-#define _HEADER_smb_krb5_h
-
-#ifdef HAVE_KRB5
-
-#define KRB5_PRIVATE    1       /* this file uses PRIVATE interfaces! */
-/* this file uses DEPRECATED interfaces! */
-
-#if defined(HAVE_KRB5_DEPRECATED_WITH_IDENTIFIER)
-#define KRB5_DEPRECATED 1
-#else
-#define KRB5_DEPRECATED
-#endif
-
-#include "libcli/auth/krb5_wrap.h"
-#include "auth/kerberos/pac_utils.h"
-
-#ifndef KRB5_ADDR_NETBIOS
-#define KRB5_ADDR_NETBIOS 0x14
-#endif
-
-#ifndef KRB5KRB_ERR_RESPONSE_TOO_BIG
-#define KRB5KRB_ERR_RESPONSE_TOO_BIG (-1765328332L)
-#endif
-
-/* Heimdal uses a slightly different name */
-#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5) && !defined(HAVE_ENCTYPE_ARCFOUR_HMAC)
-#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
-#endif
-
-/* The older versions of heimdal that don't have this
-   define don't seem to use it anyway.  I'm told they
-   always use a subkey */
-#ifndef HAVE_AP_OPTS_USE_SUBKEY
-#define AP_OPTS_USE_SUBKEY 0
-#endif
-
-typedef struct {
-#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
-       krb5_address **addrs;
-#elif defined(HAVE_KRB5_ADDRESSES) /* Heimdal */
-       krb5_addresses *addrs;
-#else
-#error UNKNOWN_KRB5_ADDRESS_TYPE
-#endif /* defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) */
-} smb_krb5_addresses;
-
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY               /* MIT */
-#define KRB5_KT_KEY(k)         (&(k)->key)
-#elif HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK          /* Heimdal */
-#define KRB5_KT_KEY(k)         (&(k)->keyblock)
-#else
-#error krb5_keytab_entry has no key or keyblock member
-#endif /* HAVE_KRB5_KEYTAB_ENTRY_KEY */
-
-#endif /* HAVE_KRB5 */
-
-#include "krb5_protos.h"
-
-#endif /* _HEADER_smb_krb5_h */
+#include "lib/krb5_wrap/krb5_samba.h"
index 5a8ca28b14ebae4f8564579f5ede7a8d568a1aae..cb218dd7b2bfbf5efca91776c62f7741e9986b71 100644 (file)
@@ -31,6 +31,7 @@
 #include "librpc/crypto/gse.h"
 #include "auth/gensec/gensec.h"
 #include "../libcli/auth/spnego.h"
+#include "auth/kerberos/pac_utils.h"
 
 #ifdef HAVE_KRB5
 
index f1df31ca4fa438236e48cb959fa7d924867c4916..7e953800114d7973ab573610557b1d7bd721b9c6 100644 (file)
@@ -219,7 +219,8 @@ int kerberos_kinit_password_ext(const char *principal,
        }
 #endif
        if (add_netbios_addr) {
-               if ((code = smb_krb5_gen_netbios_krb5_address(&addr))) {
+               if ((code = smb_krb5_gen_netbios_krb5_address(&addr,
+                                                       lp_netbios_name()))) {
                        goto out;
                }
                krb5_get_init_creds_opt_set_address_list(opt, addr->addrs);
@@ -407,6 +408,7 @@ bool kerberos_secrets_store_des_salt( const char* salt )
 /************************************************************************
 ************************************************************************/
 
+static
 char* kerberos_secrets_fetch_des_salt( void )
 {
        char *salt, *key;
@@ -430,6 +432,7 @@ char* kerberos_secrets_fetch_des_salt( void )
  to look for the older tdb keys.  Caller must free if return is not null.
  ************************************************************************/
 
+static
 krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
                                                        krb5_principal host_princ,
                                                        int enctype)
@@ -462,6 +465,38 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
        return ret_princ;
 }
 
+int create_kerberos_key_from_string(krb5_context context,
+                                       krb5_principal host_princ,
+                                       krb5_data *password,
+                                       krb5_keyblock *key,
+                                       krb5_enctype enctype,
+                                       bool no_salt)
+{
+       krb5_principal salt_princ = NULL;
+       int ret;
+       /*
+        * Check if we've determined that the KDC is salting keys for this
+        * principal/enctype in a non-obvious way.  If it is, try to match
+        * its behavior.
+        */
+       if (no_salt) {
+               KRB5_KEY_DATA(key) = (KRB5_KEY_DATA_CAST *)SMB_MALLOC(password->length);
+               if (!KRB5_KEY_DATA(key)) {
+                       return ENOMEM;
+               }
+               memcpy(KRB5_KEY_DATA(key), password->data, password->length);
+               KRB5_KEY_LENGTH(key) = password->length;
+               KRB5_KEY_TYPE(key) = enctype;
+               return 0;
+       }
+       salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype);
+       ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype);
+       if (salt_princ) {
+               krb5_free_principal(context, salt_princ);
+       }
+       return ret;
+}
+
 /************************************************************************
  Routine to set the salting principal for this service.  Active
  Directory may use a non-obvious principal name to generate the salt
index 50c56dc0813d578a3a3dccafb17771dd71b80c20..f7470d2f81ecc17fab5b06887652352df86264be 100644 (file)
@@ -30,6 +30,8 @@
 #ifndef _LIBADS_KERBEROS_PROTO_H_
 #define _LIBADS_KERBEROS_PROTO_H_
 
+#include "system/kerberos.h"
+
 struct PAC_LOGON_INFO;
 
 #include "libads/ads_status.h"
@@ -49,9 +51,6 @@ int kerberos_kinit_password_ext(const char *principal,
 int ads_kdestroy(const char *cc_name);
 char* kerberos_standard_des_salt( void );
 bool kerberos_secrets_store_des_salt( const char* salt );
-char* kerberos_secrets_fetch_des_salt( void );
-char *kerberos_get_default_realm_from_ccache(TALLOC_CTX *mem_ctx);
-char *kerberos_get_realm_from_hostname(TALLOC_CTX *mem_ctx, const char *hostname);
 
 bool kerberos_secrets_store_salting_principal(const char *service,
                                              int enctype,
@@ -90,4 +89,13 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
                                 const char *target_principal, const char *new_password,
                                 int time_offset);
 
+#ifdef HAVE_KRB5
+int create_kerberos_key_from_string(krb5_context context,
+                                       krb5_principal host_princ,
+                                       krb5_data *password,
+                                       krb5_keyblock *key,
+                                       krb5_enctype enctype,
+                                       bool no_salt);
+#endif
+
 #endif /* _LIBADS_KERBEROS_PROTO_H_ */
index 447f9bcb2aa9a31e20b6f65fea0be0bbcfa935c5..96a1240554fc46b82a86ad1d300adbccd289af3d 100644 (file)
 #include "auth/gensec/gensec.h"
 #include "auth/credentials/credentials.h"
 #include "../librpc/gen_ndr/dcerpc.h"
+#include "auth/kerberos/pac_utils.h"
 
 #if defined(HAVE_KRB5)
 
-#include "smb_krb5.h"
 #include "gse_krb5.h"
 
 static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min);
@@ -231,8 +231,8 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
           realm in particular), possibly falling back to
           GSS_C_NT_HOSTBASED_SERVICE
        */
-       name_buffer.value = kerberos_get_principal_from_service_hostname(gse_ctx,
-                                                                        service, server);
+       name_buffer.value = kerberos_get_principal_from_service_hostname(
+                                       gse_ctx, service, server, lp_realm());
        if (!name_buffer.value) {
                status = NT_STATUS_NO_MEMORY;
                goto err_out;
index b9634eb402d038a35df8c788b2cd8e6ae02e8bb1..9c1e3e1275db3dd129acffd62677e2d2de9365ad 100644 (file)
@@ -1962,7 +1962,8 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
                        } else {
                                principal = kerberos_get_principal_from_service_hostname(talloc_tos(),
                                                                                         "cifs",
-                                                                                        remote_name);
+                                                                                        remote_name,
+                                                                                        lp_realm());
                        }
 
                        if (!principal) {
index 84457f6e52160cffcd7b35141378b4902e511a6f..db9e4d0ff1c15fde978113e42c779d212df46b1a 100644 (file)
@@ -45,6 +45,7 @@
 #include "source3/include/auth.h"
 #include "source3/auth/proto.h"
 #include "nsswitch/libwbclient/wbclient.h"
+#include "auth/kerberos/pac_utils.h"
 
 #ifndef PAM_WINBIND_CONFIG_FILE
 #define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf"
@@ -1915,7 +1916,8 @@ static bool manage_client_krb5_init(struct spnego_data spnego)
 
                principal = kerberos_get_principal_from_service_hostname(talloc_tos(),
                                                                         opt_target_service,
-                                                                        opt_target_hostname);
+                                                                        opt_target_hostname,
+                                                                        lp_realm());
 
                if (!principal) {
                        return false;
index 0a4901507113d6f59127d0db98451af164172320..ddd33467cc14409f7c45b79f5954528a3024df4b 100755 (executable)
@@ -88,7 +88,7 @@ PARAM_UTIL_SRC = '''param/util.c'''
 PARAM_WITHOUT_REG_SRC = '''param/loadparm.c
                            lib/sharesec.c lib/ldap_debug_handler.c lib/util_names.c'''
 
-KRBCLIENT_SRC = '''libads/kerberos.c libads/ads_status.c libsmb/clikrb5.c'''
+KRBCLIENT_SRC = '''libads/kerberos.c libads/ads_status.c'''
 
 LIBGPO_SRC0 = '''../libgpo/gpo_ldap.c ../libgpo/gpo_ini.c ../libgpo/gpo_util.c
               ../libgpo/gpo_fetch.c libgpo/gpo_filesync.c ../libgpo/gpo_sec.c
@@ -667,7 +667,7 @@ bld.SAMBA3_LIBRARY('nss_wins',
 
 bld.SAMBA3_LIBRARY('gse',
                    source='librpc/crypto/gse_krb5.c librpc/crypto/gse.c',
-                   deps='KRB5_WRAP gensec param KRBCLIENT secrets3',
+                   deps='krb5samba gensec param KRBCLIENT secrets3',
                    private_library=True)
 
 bld.SAMBA3_LIBRARY('msrpc3',
@@ -782,7 +782,7 @@ bld.SAMBA3_LIBRARY('util_cmdline',
 
 bld.SAMBA3_SUBSYSTEM('KRBCLIENT',
                     source=KRBCLIENT_SRC,
-                    public_deps='KRB5_WRAP k5crypto LIBTSOCKET CLDAP LIBNMB',
+                    public_deps='krb5samba k5crypto LIBTSOCKET CLDAP LIBNMB',
                     vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('samba3util',
@@ -869,13 +869,13 @@ bld.SAMBA3_LIBRARY('smbldap',
 
 bld.SAMBA3_LIBRARY('ads',
                    source=LIBADS_SRC,
-                   deps='cli-ldap-common KRB5_WRAP ldap lber KRBCLIENT param LIBNMB libsmb DCUTIL smbldap',
+                   deps='cli-ldap-common krb5samba ldap lber KRBCLIENT param LIBNMB libsmb DCUTIL smbldap',
                    private_library=True,
                    vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('LIBADS_SERVER',
                     source=LIBADS_SERVER_SRC,
-                    deps='SERVER_MUTEX ndr-krb5pac KRB5_WRAP',
+                    deps='SERVER_MUTEX ndr-krb5pac krb5samba',
                    vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('LIBADS_PRINTER',
@@ -997,7 +997,7 @@ bld.SAMBA3_SUBSYSTEM('LIBNET',
 
 bld.SAMBA3_LIBRARY('net_keytab',
                    source='libnet/libnet_keytab.c',
-                   deps='KRB5_WRAP ads',
+                   deps='krb5samba ads',
                    vars=locals(),
                    private_library=True)
 
@@ -1527,7 +1527,7 @@ bld.SAMBA3_BINARY('ntlm_auth' + bld.env.suffix3,
                  source=NTLM_AUTH_SRC,
                  deps='''
                  talloc
-                 KRB5_WRAP
+                 krb5samba
                  LIBINIPARSER
                  libsmb
                  popt_samba3
index fc2195de8ddbf000c0c845d1e5905f5a08657992..cc02aee27f5fe48612d7866c66d9ad92ca3d320a 100644 (file)
 
 #if defined(HAVE_KRB5)
 
+#include "system/kerberos.h"
 #include "auth/kerberos/krb5_init_context.h"
 #include "librpc/gen_ndr/krb5pac.h"
-#include "libcli/auth/krb5_wrap.h"
+#include "lib/krb5_wrap/krb5_samba.h"
 
 struct auth_user_info_dc;
 struct cli_credentials;
index be41d1b7b30fa15235d100c14fe1a06d6668f882..2ba6d56410725966c02104a6df866a9c7941d3ff 100755 (executable)
@@ -2,14 +2,14 @@
 
 bld.SAMBA_SUBSYSTEM('KRB_INIT_CTX',
                    source='krb5_init_context.c',
-                   deps='krb5 com_err'
+                   deps='krb5samba'
                   )
 
 bld.SAMBA_LIBRARY('authkrb5',
                   source='kerberos.c kerberos_heimdal.c kerberos_pac.c keytab_copy.c',
                   autoproto='proto.h',
-                  public_deps='krb5 ndr-krb5pac samba_socket LIBCLI_RESOLVE com_err asn1',
-                  deps='auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP KRB_INIT_CTX errors',
+                  public_deps='ndr-krb5pac krb5samba samba_socket LIBCLI_RESOLVE asn1',
+                  deps='auth_sam_reply tevent LIBPACKET ndr ldb krb5samba KRB_INIT_CTX KRB5_PAC errors',
                   private_library=True
                   )
 
old mode 100644 (file)
new mode 100755 (executable)
index 0eb4eeb..af0defd
@@ -9,7 +9,7 @@ bld.SAMBA_LIBRARY('samdb',
        public_deps='krb5',
        public_headers='',
        vnum='0.0.1',
-       deps='ndr NDR_DRSUAPI NDR_DRSBLOBS auth_system_session LIBCLI_AUTH ndr SAMDB_SCHEMA ldbsamba samdb-common LIBCLI_DRSUAPI cli-ldap-common samba-util com_err authkrb5 samba-credentials ldbwrap errors',
+       deps='ndr NDR_DRSUAPI NDR_DRSBLOBS auth_system_session LIBCLI_AUTH ndr SAMDB_SCHEMA ldbsamba samdb-common LIBCLI_DRSUAPI cli-ldap-common samba-util com_err authkrb5 samba-credentials ldbwrap errors krb5samba',
        )
 
 
old mode 100644 (file)
new mode 100755 (executable)
index 717d8b0..295c1fa
@@ -133,6 +133,7 @@ bld.RECURSE('source3')
 bld.RECURSE('dfs_server')
 bld.RECURSE('file_server')
 bld.RECURSE('utils')
+bld.RECURSE('lib/krb5_wrap')
 
 bld.RECURSE('testsuite/headers')
 bld.RECURSE('testsuite/libsmbclient/src')