summaryrefslogtreecommitdiff
path: root/source3/libnet/libnet_samsync_keytab.c.orig
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-08-10 08:25:02 +1000
committerSimo Sorce <idra@samba.org>2010-08-13 09:08:27 -0400
commit71d80e6be0687ac7c2f3caab5e7b8caf400fe37e (patch)
treea30d558e704bac324809908c55a93bc17cb0c436 /source3/libnet/libnet_samsync_keytab.c.orig
parentfff6fa72ffa7890cee516bd7e65b50bdb8daf51d (diff)
downloadsamba-71d80e6be0687ac7c2f3caab5e7b8caf400fe37e.tar.gz
samba-71d80e6be0687ac7c2f3caab5e7b8caf400fe37e.tar.bz2
samba-71d80e6be0687ac7c2f3caab5e7b8caf400fe37e.zip
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>
Diffstat (limited to 'source3/libnet/libnet_samsync_keytab.c.orig')
-rw-r--r--source3/libnet/libnet_samsync_keytab.c.orig305
1 files changed, 305 insertions, 0 deletions
diff --git a/source3/libnet/libnet_samsync_keytab.c.orig b/source3/libnet/libnet_samsync_keytab.c.orig
new file mode 100644
index 0000000000..134922392c
--- /dev/null
+++ b/source3/libnet/libnet_samsync_keytab.c.orig
@@ -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
+};