mirror of
https://github.com/samba-team/samba.git
synced 2025-03-24 10:50:22 +03:00
s3-krb5 Only build ADS support if arcfour-hmac-md5 is available
Modern Kerberos implementations have either defines or enums for these key types, which makes doing #ifdef difficult. This shows up in files such as libnet_samsync_keytab.c, the bulk of which is not compiled on current Fedora 12, for example. The downside is that this makes Samba unconditionally depend on the arcfour-hmac-md5 encryption type at build time. We will no longer support libraries that only support the DES based encryption types. However, the single-DES types that are supported in common with AD are already painfully weak - so much so that they are disabled by default in modern Kerberos libraries. If not found, ADS support will not be compiled in. This means that our 'net ads join' will no longer set the ACB_USE_DES_KEY_ONLY flag, and we will always try to use arcfour-hmac-md5. A future improvement would be to remove the use of the DES encryption types totally, but this would require that any ACB_USE_DES_KEY_ONLY flag be removed from existing joins. Andrew Bartlett Signed-off-by: Simo Sorce <idra@samba.org>
This commit is contained in:
parent
fff6fa72ff
commit
71d80e6be0
@ -4040,6 +4040,7 @@ if test x"$with_ads_support" != x"no"; then
|
||||
[Whether the krb5_keyblock struct has a keyvalue property])
|
||||
fi
|
||||
|
||||
found_arcfour_hmac=no
|
||||
AC_CACHE_CHECK([for ENCTYPE_ARCFOUR_HMAC_MD5],
|
||||
samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
@ -4057,7 +4058,19 @@ if test x"$with_ads_support" != x"no"; then
|
||||
if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5" = x"yes" -a\
|
||||
x"$samba_cv_HAVE_KEYTYPE_ARCFOUR_56" = x"yes"; then
|
||||
AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,1,
|
||||
[Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available])
|
||||
[Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type definition is available])
|
||||
found_arcfour_hmac=yes
|
||||
fi
|
||||
AC_CACHE_CHECK([for ENCTYPE_ARCFOUR_HMAC],
|
||||
samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[krb5_enctype enctype; enctype = ENCTYPE_ARCFOUR_HMAC;],
|
||||
samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC=yes,
|
||||
samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC=no)])
|
||||
if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC" = x"yes"; then
|
||||
AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC,1,
|
||||
[Whether the ENCTYPE_ARCFOUR_HMAC key type definition is available])
|
||||
found_arcfour_hmac=yes
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for AP_OPTS_USE_SUBKEY],
|
||||
@ -4300,6 +4313,11 @@ if test x"$with_ads_support" != x"no"; then
|
||||
# NOTE: all tests should be done before this block!
|
||||
#
|
||||
#
|
||||
if test x"$found_arcfour_hmac" != x"yes"; then
|
||||
AC_MSG_WARN(arcfour-hmac-md5 encryption type not found in -lkrb5)
|
||||
use_ads=no
|
||||
fi
|
||||
|
||||
if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" != x"yes"; then
|
||||
AC_MSG_WARN(krb5_mk_req_extended not found in -lkrb5)
|
||||
use_ads=no
|
||||
|
@ -25,7 +25,7 @@
|
||||
#endif
|
||||
|
||||
/* Heimdal uses a slightly different name */
|
||||
#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
|
||||
#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5) && !defined(HAVE_ENCTYPE_ARCFOUR_HMAC)
|
||||
#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
|
||||
#endif
|
||||
|
||||
|
@ -236,17 +236,16 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
|
||||
krb5_keytab keytab = NULL;
|
||||
krb5_data password;
|
||||
krb5_kvno kvno;
|
||||
krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 };
|
||||
krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC,
|
||||
ENCTYPE_DES_CBC_MD5,
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
0 };
|
||||
char *princ_s = NULL, *short_princ_s = NULL;
|
||||
char *password_s = NULL;
|
||||
char *my_fqdn;
|
||||
TALLOC_CTX *ctx = NULL;
|
||||
char *machine_name;
|
||||
|
||||
#if defined(ENCTYPE_ARCFOUR_HMAC)
|
||||
enctypes[2] = ENCTYPE_ARCFOUR_HMAC;
|
||||
#endif
|
||||
|
||||
initialize_krb5_error_table();
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret) {
|
||||
|
@ -344,9 +344,7 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context,
|
||||
/* Let's make some room for 2 password (old and new)*/
|
||||
krb5_data passwords[2];
|
||||
krb5_enctype enctypes[] = {
|
||||
#if defined(ENCTYPE_ARCFOUR_HMAC)
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
#endif
|
||||
ENCTYPE_DES_CBC_CRC,
|
||||
ENCTYPE_DES_CBC_MD5,
|
||||
ENCTYPE_NULL
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "libnet/libnet_keytab.h"
|
||||
#include "librpc/gen_ndr/ndr_drsblobs.h"
|
||||
|
||||
#if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
|
||||
#if defined(HAVE_ADS)
|
||||
|
||||
static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
|
||||
struct replUpToDateVectorBlob **pold_utdv)
|
||||
@ -601,7 +601,7 @@ static NTSTATUS keytab_process_objects(struct dssync_context *ctx,
|
||||
{
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
#endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
|
||||
#endif /* defined(HAVE_ADS) */
|
||||
|
||||
const struct dssync_ops libnet_dssync_keytab_ops = {
|
||||
.startup = keytab_startup,
|
||||
|
@ -982,12 +982,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
|
||||
/* Fill in the additional account flags now */
|
||||
|
||||
acct_flags |= ACB_PWNOEXP;
|
||||
if (r->out.domain_is_ad) {
|
||||
#if !defined(ENCTYPE_ARCFOUR_HMAC)
|
||||
acct_flags |= ACB_USE_DES_KEY_ONLY;
|
||||
#endif
|
||||
;;
|
||||
}
|
||||
|
||||
/* Set account flags on machine account */
|
||||
ZERO_STRUCT(user_info.info16);
|
||||
|
2187
source3/libnet/libnet_join.c.orig
Normal file
2187
source3/libnet/libnet_join.c.orig
Normal file
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@
|
||||
#include "libnet/libnet_keytab.h"
|
||||
#include "libnet/libnet_samsync.h"
|
||||
|
||||
#if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
|
||||
#if defined(HAVE_ADS)
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
@ -296,7 +296,7 @@ static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
|
||||
#endif /* defined(HAVE_ADS) */
|
||||
|
||||
const struct samsync_ops libnet_samsync_keytab_ops = {
|
||||
.startup = init_keytab,
|
||||
|
305
source3/libnet/libnet_samsync_keytab.c.orig
Normal file
305
source3/libnet/libnet_samsync_keytab.c.orig
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
dump the remote SAM using rpc samsync operations
|
||||
|
||||
Copyright (C) Guenther Deschner 2008.
|
||||
|
||||
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 "ads.h"
|
||||
#include "libnet/libnet_keytab.h"
|
||||
#include "libnet/libnet_samsync.h"
|
||||
|
||||
#if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static NTSTATUS keytab_ad_connect(TALLOC_CTX *mem_ctx,
|
||||
const char *domain_name,
|
||||
const char *username,
|
||||
const char *password,
|
||||
struct libnet_keytab_context *ctx)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ADS_STATUS ad_status;
|
||||
ADS_STRUCT *ads;
|
||||
struct netr_DsRGetDCNameInfo *info = NULL;
|
||||
const char *dc;
|
||||
|
||||
status = dsgetdcname(mem_ctx, NULL, domain_name, NULL, NULL, 0, &info);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
dc = strip_hostname(info->dc_unc);
|
||||
|
||||
ads = ads_init(NULL, domain_name, dc);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ads);
|
||||
|
||||
if (getenv(KRB5_ENV_CCNAME) == NULL) {
|
||||
setenv(KRB5_ENV_CCNAME, "MEMORY:libnet_samsync_keytab", 1);
|
||||
}
|
||||
|
||||
ads->auth.user_name = SMB_STRDUP(username);
|
||||
ads->auth.password = SMB_STRDUP(password);
|
||||
|
||||
ad_status = ads_connect_user_creds(ads);
|
||||
if (!ADS_ERR_OK(ad_status)) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ctx->ads = ads;
|
||||
|
||||
ctx->dns_domain_name = talloc_strdup_upper(mem_ctx, ads->config.realm);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ctx->dns_domain_name);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
uint32_t rid,
|
||||
struct netr_DELTA_USER *r,
|
||||
struct libnet_keytab_context *ctx)
|
||||
{
|
||||
NTSTATUS status;
|
||||
uint32_t kvno = 0;
|
||||
DATA_BLOB blob;
|
||||
|
||||
if (memcmp(r->ntpassword.hash, ctx->zero_buf, 16) == 0) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
kvno = ads_get_kvno(ctx->ads, r->account_name.string);
|
||||
blob = data_blob_const(r->ntpassword.hash, 16);
|
||||
|
||||
status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx,
|
||||
kvno,
|
||||
r->account_name.string,
|
||||
NULL,
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
blob);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
|
||||
struct samsync_context *ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
uint64_t *sequence_num)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
NTSTATUS status;
|
||||
struct libnet_keytab_context *keytab_ctx = NULL;
|
||||
struct libnet_keytab_entry *entry;
|
||||
uint64_t old_sequence_num = 0;
|
||||
const char *principal = NULL;
|
||||
|
||||
ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx);
|
||||
if (ret) {
|
||||
return krb5_to_nt_status(ret);
|
||||
}
|
||||
|
||||
keytab_ctx->clean_old_entries = ctx->clean_old_entries;
|
||||
ctx->private_data = keytab_ctx;
|
||||
|
||||
status = keytab_ad_connect(mem_ctx,
|
||||
ctx->domain_name,
|
||||
ctx->username,
|
||||
ctx->password,
|
||||
keytab_ctx);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(keytab_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
principal = talloc_asprintf(mem_ctx, "SEQUENCE_NUM@%s",
|
||||
keytab_ctx->dns_domain_name);
|
||||
NT_STATUS_HAVE_NO_MEMORY(principal);
|
||||
|
||||
entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
|
||||
mem_ctx);
|
||||
if (entry && (entry->password.length == 8)) {
|
||||
old_sequence_num = BVAL(entry->password.data, 0);
|
||||
}
|
||||
|
||||
if (sequence_num) {
|
||||
*sequence_num = old_sequence_num;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
struct netr_DELTA_ENUM_ARRAY *r,
|
||||
uint64_t *sequence_num,
|
||||
struct samsync_context *ctx)
|
||||
{
|
||||
struct libnet_keytab_context *keytab_ctx =
|
||||
(struct libnet_keytab_context *)ctx->private_data;
|
||||
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < r->num_deltas; i++) {
|
||||
|
||||
switch (r->delta_enum[i].delta_type) {
|
||||
case NETR_DELTA_USER:
|
||||
break;
|
||||
case NETR_DELTA_DOMAIN:
|
||||
if (sequence_num) {
|
||||
*sequence_num =
|
||||
r->delta_enum[i].delta_union.domain->sequence_num;
|
||||
}
|
||||
continue;
|
||||
case NETR_DELTA_MODIFY_COUNT:
|
||||
if (sequence_num) {
|
||||
*sequence_num =
|
||||
*r->delta_enum[i].delta_union.modified_count;
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
status = fetch_sam_entry_keytab(mem_ctx, database_id,
|
||||
r->delta_enum[i].delta_id_union.rid,
|
||||
r->delta_enum[i].delta_union.user,
|
||||
keytab_ctx);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
|
||||
struct samsync_context *ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
uint64_t sequence_num)
|
||||
{
|
||||
struct libnet_keytab_context *keytab_ctx =
|
||||
(struct libnet_keytab_context *)ctx->private_data;
|
||||
krb5_error_code ret;
|
||||
NTSTATUS status;
|
||||
struct libnet_keytab_entry *entry;
|
||||
uint64_t old_sequence_num = 0;
|
||||
const char *principal = NULL;
|
||||
|
||||
principal = talloc_asprintf(mem_ctx, "SEQUENCE_NUM@%s",
|
||||
keytab_ctx->dns_domain_name);
|
||||
NT_STATUS_HAVE_NO_MEMORY(principal);
|
||||
|
||||
|
||||
entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
|
||||
mem_ctx);
|
||||
if (entry && (entry->password.length == 8)) {
|
||||
old_sequence_num = BVAL(entry->password.data, 0);
|
||||
}
|
||||
|
||||
|
||||
if (sequence_num > old_sequence_num) {
|
||||
DATA_BLOB blob;
|
||||
blob = data_blob_talloc_zero(mem_ctx, 8);
|
||||
SBVAL(blob.data, 0, sequence_num);
|
||||
|
||||
status = libnet_keytab_add_to_keytab_entries(mem_ctx, keytab_ctx,
|
||||
0,
|
||||
"SEQUENCE_NUM",
|
||||
NULL,
|
||||
ENCTYPE_NULL,
|
||||
blob);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = libnet_keytab_add(keytab_ctx);
|
||||
if (ret) {
|
||||
status = krb5_to_nt_status(ret);
|
||||
ctx->error_message = talloc_asprintf(ctx,
|
||||
"Failed to add entries to keytab %s: %s",
|
||||
keytab_ctx->keytab_name, error_message(ret));
|
||||
TALLOC_FREE(keytab_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
ctx->result_message = talloc_asprintf(ctx,
|
||||
"Vampired %d accounts to keytab %s",
|
||||
keytab_ctx->count,
|
||||
keytab_ctx->keytab_name);
|
||||
|
||||
status = NT_STATUS_OK;
|
||||
|
||||
done:
|
||||
TALLOC_FREE(keytab_ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
|
||||
struct samsync_context *ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
uint64_t *sequence_num)
|
||||
{
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
struct netr_DELTA_ENUM_ARRAY *r,
|
||||
uint64_t *sequence_num,
|
||||
struct samsync_context *ctx)
|
||||
{
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
|
||||
struct samsync_context *ctx,
|
||||
enum netr_SamDatabaseID database_id,
|
||||
uint64_t sequence_num)
|
||||
{
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
|
||||
|
||||
const struct samsync_ops libnet_samsync_keytab_ops = {
|
||||
.startup = init_keytab,
|
||||
.process_objects = fetch_sam_entries_keytab,
|
||||
.finish = close_keytab
|
||||
};
|
@ -964,9 +964,7 @@ int cli_krb5_get_ticket(TALLOC_CTX *mem_ctx,
|
||||
krb5_ccache ccdef = NULL;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
krb5_enctype enc_types[] = {
|
||||
#ifdef ENCTYPE_ARCFOUR_HMAC
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
#endif
|
||||
ENCTYPE_DES_CBC_MD5,
|
||||
ENCTYPE_DES_CBC_CRC,
|
||||
ENCTYPE_NULL};
|
||||
|
Loading…
x
Reference in New Issue
Block a user