summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2012-04-21 17:26:18 -0400
committerSimo Sorce <idra@samba.org>2012-04-23 19:20:38 -0400
commit08c733d75fd83fd5e32ced9712d41dd595e0f182 (patch)
treea49d6ebbf1d6c498294862f268d6890a1e6a507f
parentf7070c90b94954835478a09e89a85c03f0f85500 (diff)
downloadsamba-08c733d75fd83fd5e32ced9712d41dd595e0f182.tar.gz
Make krb5 wrapper library common so they can be used all over
-rw-r--r--auth/credentials/credentials_krb5.c1
-rw-r--r--auth/kerberos/gssapi_pac.c49
-rw-r--r--auth/kerberos/pac_utils.h8
-rwxr-xr-xauth/kerberos/wscript_build2
-rw-r--r--lib/krb5_wrap/krb5_samba.c (renamed from source3/libsmb/clikrb5.c)331
-rw-r--r--lib/krb5_wrap/krb5_samba.h (renamed from source3/include/krb5_protos.h)102
-rwxr-xr-xlib/krb5_wrap/wscript_build7
-rw-r--r--libcli/auth/krb5_wrap.c243
-rw-r--r--libcli/auth/krb5_wrap.h62
-rwxr-xr-x[-rw-r--r--]libcli/auth/wscript_build6
-rw-r--r--libcli/smb/smb_seal.c2
-rwxr-xr-x[-rw-r--r--]libcli/smb/wscript_build2
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/smb_krb5.h83
-rw-r--r--source3/libads/authdata.c1
-rw-r--r--source3/libads/kerberos.c37
-rw-r--r--source3/libads/kerberos_proto.h14
-rw-r--r--source3/librpc/crypto/gse.c6
-rw-r--r--source3/libsmb/cliconnect.c3
-rw-r--r--source3/utils/ntlm_auth.c4
-rwxr-xr-xsource3/wscript_build14
-rw-r--r--source4/auth/kerberos/kerberos.h3
-rwxr-xr-xsource4/auth/kerberos/wscript_build6
-rwxr-xr-x[-rw-r--r--]source4/dsdb/wscript_build2
-rwxr-xr-x[-rw-r--r--]wscript_build1
25 files changed, 470 insertions, 522 deletions
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index c8b685ea794..480d7c5951c 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -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(
diff --git a/auth/kerberos/gssapi_pac.c b/auth/kerberos/gssapi_pac.c
index 05065b2725b..d1a79501cce 100644
--- a/auth/kerberos/gssapi_pac.c
+++ b/auth/kerberos/gssapi_pac.c
@@ -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 */
diff --git a/auth/kerberos/pac_utils.h b/auth/kerberos/pac_utils.h
index 9fe08de834c..bb954597f51 100644
--- a/auth/kerberos/pac_utils.h
+++ b/auth/kerberos/pac_utils.h
@@ -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 */
diff --git a/auth/kerberos/wscript_build b/auth/kerberos/wscript_build
index f49cc517bab..97b8879c8ef 100755
--- a/auth/kerberos/wscript_build
+++ b/auth/kerberos/wscript_build
@@ -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')
diff --git a/source3/libsmb/clikrb5.c b/lib/krb5_wrap/krb5_samba.c
index 792400b3ce2..4e555b28533 100644
--- a/source3/libsmb/clikrb5.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -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
@@ -44,12 +43,17 @@
/* 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,
diff --git a/source3/include/krb5_protos.h b/lib/krb5_wrap/krb5_samba.h
index 99569998a16..3800b024adb 100644
--- a/source3/include/krb5_protos.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -20,19 +20,78 @@
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
index 00000000000..c5858198344
--- /dev/null
+++ b/lib/krb5_wrap/wscript_build
@@ -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
index 55a224612d1..00000000000
--- a/libcli/auth/krb5_wrap.c
+++ /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
index 4c0ef93e4c9..00000000000
--- a/libcli/auth/krb5_wrap.h
+++ /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);
-
diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build
index b4b648efa19..893cfd9d958 100644..100755
--- a/libcli/auth/wscript_build
+++ b/libcli/auth/wscript_build
@@ -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')
diff --git a/libcli/smb/smb_seal.c b/libcli/smb/smb_seal.c
index d5bb2388bb9..78af733d00f 100644
--- a/libcli/smb/smb_seal.c
+++ b/libcli/smb/smb_seal.c
@@ -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"
diff --git a/libcli/smb/wscript_build b/libcli/smb/wscript_build
index 7a21d4a4a7d..6feed445df5 100644..100755
--- a/libcli/smb/wscript_build
+++ b/libcli/smb/wscript_build
@@ -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='''
diff --git a/source3/Makefile.in b/source3/Makefile.in
index d48d298e725..1353bd2da8f 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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 \
diff --git a/source3/include/smb_krb5.h b/source3/include/smb_krb5.h
index 88e91e1670b..1f66212321b 100644
--- a/source3/include/smb_krb5.h
+++ b/source3/include/smb_krb5.h
@@ -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"
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
index 5a8ca28b14e..cb218dd7b2b 100644
--- a/source3/libads/authdata.c
+++ b/source3/libads/authdata.c
@@ -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
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index f1df31ca4fa..7e953800114 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -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
diff --git a/source3/libads/kerberos_proto.h b/source3/libads/kerberos_proto.h
index 50c56dc0813..f7470d2f81e 100644
--- a/source3/libads/kerberos_proto.h
+++ b/source3/libads/kerberos_proto.h
@@ -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_ */
diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
index 447f9bcb2aa..96a1240554f 100644
--- a/source3/librpc/crypto/gse.c
+++ b/source3/librpc/crypto/gse.c
@@ -28,10 +28,10 @@
#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;
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index b9634eb402d..9c1e3e1275d 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -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) {
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 84457f6e521..db9e4d0ff1c 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -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;
diff --git a/source3/wscript_build b/source3/wscript_build
index 0a490150711..ddd33467cc1 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -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
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index fc2195de8dd..cc02aee27f5 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -23,9 +23,10 @@
#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;
diff --git a/source4/auth/kerberos/wscript_build b/source4/auth/kerberos/wscript_build
index be41d1b7b30..2ba6d564107 100755
--- a/source4/auth/kerberos/wscript_build
+++ b/source4/auth/kerberos/wscript_build
@@ -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
)
diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build
index 0eb4eebe1fe..af0defdb284 100644..100755
--- a/source4/dsdb/wscript_build
+++ b/source4/dsdb/wscript_build
@@ -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',
)
diff --git a/wscript_build b/wscript_build
index 717d8b0a1a5..295c1fa6d8f 100644..100755
--- a/wscript_build
+++ b/wscript_build
@@ -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')