1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

Make krb5 wrapper library common so they can be used all over

This commit is contained in:
Simo Sorce 2012-04-21 17:26:18 -04:00
parent f7070c90b9
commit 08c733d75f
25 changed files with 471 additions and 523 deletions

View 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(

View 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 */

View 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 */

View File

@ -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')

View 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
@ -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;
}
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);
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
#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,

View File

@ -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 */

7
lib/krb5_wrap/wscript_build Executable file
View File

@ -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
)

View File

@ -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

View File

@ -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);

6
libcli/auth/wscript_build Normal file → Executable file
View File

@ -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')

View 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"

2
libcli/smb/wscript_build Normal file → Executable file
View File

@ -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='''

View 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 \

View 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"

View 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

View 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

View 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_ */

View File

@ -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;

View 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) {

View 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;

View File

@ -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

View File

@ -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;

View File

@ -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
)

2
source4/dsdb/wscript_build Normal file → Executable file
View File

@ -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',
)

1
wscript_build Normal file → Executable file
View File

@ -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')