diff options
Diffstat (limited to 'source3/libnet')
-rw-r--r-- | source3/libnet/libnet.h | 1 | ||||
-rw-r--r-- | source3/libnet/libnet_keytab.c | 143 | ||||
-rw-r--r-- | source3/libnet/libnet_keytab.h | 40 | ||||
-rw-r--r-- | source3/libnet/libnet_proto.h | 9 | ||||
-rw-r--r-- | source3/libnet/libnet_samsync_keytab.c | 172 |
5 files changed, 211 insertions, 154 deletions
diff --git a/source3/libnet/libnet.h b/source3/libnet/libnet.h index ca393c4393..570009c6f6 100644 --- a/source3/libnet/libnet.h +++ b/source3/libnet/libnet.h @@ -20,6 +20,7 @@ #ifndef __LIBNET_H__ #define __LIBNET_H__ +#include "libnet/libnet_keytab.h" #include "libnet/libnet_samsync.h" #include "libnet/libnet_dssync.h" #include "librpc/gen_ndr/libnet_join.h" diff --git a/source3/libnet/libnet_keytab.c b/source3/libnet/libnet_keytab.c new file mode 100644 index 0000000000..90595e76dd --- /dev/null +++ b/source3/libnet/libnet_keytab.c @@ -0,0 +1,143 @@ +/* + 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 "libnet/libnet.h" + +#ifdef HAVE_KRB5 + +/**************************************************************** +****************************************************************/ + +static int keytab_close(struct libnet_keytab_context *ctx) +{ + if (!ctx) { + return 0; + } + + if (ctx->keytab && ctx->context) { + krb5_kt_close(ctx->context, ctx->keytab); + } + + if (ctx->context) { + krb5_free_context(ctx->context); + } + + if (ctx->ads) { + ads_destroy(&ctx->ads); + } + + TALLOC_FREE(ctx); + + return 0; +} + +/**************************************************************** +****************************************************************/ + +krb5_error_code libnet_keytab_init(TALLOC_CTX *mem_ctx, + const char *keytab_name, + struct libnet_keytab_context **ctx) +{ + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + const char *keytab_string = NULL; + + struct libnet_keytab_context *r; + + r = TALLOC_ZERO_P(mem_ctx, struct libnet_keytab_context); + if (!r) { + return ENOMEM; + } + + talloc_set_destructor(r, keytab_close); + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("keytab_init: could not krb5_init_context: %s\n", + error_message(ret))); + return ret; + } + + ret = smb_krb5_open_keytab(context, keytab_name, true, &keytab); + if (ret) { + DEBUG(1,("keytab_init: smb_krb5_open_keytab failed (%s)\n", + error_message(ret))); + krb5_free_context(context); + return ret; + } + + ret = smb_krb5_keytab_name(mem_ctx, context, keytab, &keytab_string); + if (ret) { + krb5_kt_close(context, keytab); + krb5_free_context(context); + return ret; + } + + r->context = context; + r->keytab = keytab; + r->keytab_name = keytab_string; + + *ctx = r; + + return 0; +} + +/**************************************************************** +****************************************************************/ + +krb5_error_code libnet_keytab_add(struct libnet_keytab_context *ctx) +{ +#if defined(ENCTYPE_ARCFOUR_HMAC) + krb5_error_code ret = 0; + krb5_enctype enctypes[2] = { ENCTYPE_ARCFOUR_HMAC, 0 }; + int i; + + for (i=0; i<ctx->count; i++) { + + struct libnet_keytab_entry *entry = &ctx->entries[i]; + krb5_data password; + + password.data = (char *)entry->password.data; + password.length = entry->password.length; + + ret = smb_krb5_kt_add_entry(ctx->context, + ctx->keytab, + entry->kvno, + entry->principal, + enctypes, + password, + true); + if (ret) { + DEBUG(1,("libnet_keytab_add: " + "Failed to add entry to keytab file\n")); + return ret; + } + } + + return ret; +#else + return -1; +#endif /* defined(ENCTYPE_ARCFOUR_HMAC) */ +} + +#endif /* HAVE_KRB5 */ diff --git a/source3/libnet/libnet_keytab.h b/source3/libnet/libnet_keytab.h new file mode 100644 index 0000000000..30f2f8d1a8 --- /dev/null +++ b/source3/libnet/libnet_keytab.h @@ -0,0 +1,40 @@ +/* + * Unix SMB/CIFS implementation. + * libnet Support + * 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/>. + */ + +#ifdef HAVE_KRB5 + +struct libnet_keytab_entry { + const char *name; + const char *principal; + DATA_BLOB password; + uint32_t kvno; +}; + +struct libnet_keytab_context { + krb5_context context; + krb5_keytab keytab; + const char *keytab_name; + ADS_STRUCT *ads; + const char *dns_domain_name; + uint8_t zero_buf[16]; + uint32_t count; + struct libnet_keytab_entry *entries; +}; + +#endif /* HAVE_KRB5 */ diff --git a/source3/libnet/libnet_proto.h b/source3/libnet/libnet_proto.h index 720b52bcc7..ddd730b1a8 100644 --- a/source3/libnet/libnet_proto.h +++ b/source3/libnet/libnet_proto.h @@ -43,6 +43,15 @@ WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx, _PUBLIC_ void ndr_print_libnet_JoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_JoinCtx *r); _PUBLIC_ void ndr_print_libnet_UnjoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_UnjoinCtx *r); +/* The following definitions come from libnet/libnet_keytab.c */ + +#ifdef HAVE_KRB5 +krb5_error_code libnet_keytab_init(TALLOC_CTX *mem_ctx, + const char *keytab_name, + struct libnet_keytab_context **ctx); +krb5_error_code libnet_keytab_add(struct libnet_keytab_context *ctx); +#endif + /* The following definitions come from libnet/libnet_samsync.c */ NTSTATUS libnet_samsync_init_context(TALLOC_CTX *mem_ctx, diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c index 2208a71563..49d7ac27e2 100644 --- a/source3/libnet/libnet_samsync_keytab.c +++ b/source3/libnet/libnet_samsync_keytab.c @@ -19,118 +19,18 @@ */ #include "includes.h" -#include "utils/net.h" +#include "libnet/libnet.h" #if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) /**************************************************************** ****************************************************************/ -struct samsync_keytab_entry { - const char *name; - const char *principal; - DATA_BLOB password; - uint32_t kvno; -}; - -struct samsync_keytab_context { - krb5_context context; - krb5_keytab keytab; - const char *keytab_name; - ADS_STRUCT *ads; - const char *dns_domain_name; - uint8_t zero_buf[16]; - uint32_t count; - struct samsync_keytab_entry *entries; -}; - -/**************************************************************** -****************************************************************/ - -static int keytab_close(struct samsync_keytab_context *ctx) -{ - if (!ctx) { - return 0; - } - - if (ctx->keytab && ctx->context) { - krb5_kt_close(ctx->context, ctx->keytab); - } - - if (ctx->context) { - krb5_free_context(ctx->context); - } - - if (ctx->ads) { - ads_destroy(&ctx->ads); - } - - TALLOC_FREE(ctx); - - return 0; -} - -/**************************************************************** -****************************************************************/ - -static krb5_error_code keytab_init(TALLOC_CTX *mem_ctx, - const char *keytab_name, - struct samsync_keytab_context **ctx) -{ - krb5_error_code ret = 0; - krb5_context context = NULL; - krb5_keytab keytab = NULL; - const char *keytab_string = NULL; - - struct samsync_keytab_context *r; - - r = TALLOC_ZERO_P(mem_ctx, struct samsync_keytab_context); - if (!r) { - return ENOMEM; - } - - talloc_set_destructor(r, keytab_close); - - initialize_krb5_error_table(); - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("keytab_init: could not krb5_init_context: %s\n", - error_message(ret))); - return ret; - } - - ret = smb_krb5_open_keytab(context, keytab_name, true, &keytab); - if (ret) { - DEBUG(1,("keytab_init: smb_krb5_open_keytab failed (%s)\n", - error_message(ret))); - krb5_free_context(context); - return ret; - } - - ret = smb_krb5_keytab_name(mem_ctx, context, keytab, &keytab_string); - if (ret) { - krb5_kt_close(context, keytab); - krb5_free_context(context); - return ret; - } - - r->context = context; - r->keytab = keytab; - r->keytab_name = keytab_string; - - *ctx = r; - - return 0; -} - -/**************************************************************** -****************************************************************/ - static NTSTATUS keytab_ad_connect(TALLOC_CTX *mem_ctx, const char *domain_name, const char *username, const char *password, - struct samsync_keytab_context *ctx) + struct libnet_keytab_context *ctx) { NTSTATUS status; ADS_STATUS ad_status; @@ -171,71 +71,35 @@ static NTSTATUS keytab_ad_connect(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static krb5_error_code keytab_add(struct samsync_keytab_context *ctx) -{ - krb5_error_code ret = 0; - krb5_enctype enctypes[2] = { ENCTYPE_ARCFOUR_HMAC, 0 }; - int i; - - for (i=0; i<ctx->count; i++) { - - struct samsync_keytab_entry *entry = &ctx->entries[i]; - krb5_data password; - krb5_kvno kvno; - - kvno = ads_get_kvno(ctx->ads, entry->name); - - password.data = (char *)entry->password.data; - password.length = entry->password.length; - - ret = smb_krb5_kt_add_entry(ctx->context, - ctx->keytab, - kvno, - entry->principal, - enctypes, - password, - true); - if (ret) { - DEBUG(1,("keytab_add: Failed to add entry to keytab file\n")); - return ret; - } - } - - return ret; -} - -/**************************************************************** -****************************************************************/ - static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx, enum netr_SamDatabaseID database_id, uint32_t rid, struct netr_DELTA_USER *r, NTSTATUS status, - struct samsync_keytab_context *ctx) + struct libnet_keytab_context *ctx) { uchar nt_passwd[16]; - struct samsync_keytab_entry *entry; + struct libnet_keytab_entry entry; if (memcmp(r->ntpassword.hash, ctx->zero_buf, 16) == 0) { return NT_STATUS_OK; } - entry = TALLOC_ZERO_P(mem_ctx, struct samsync_keytab_entry); - NT_STATUS_HAVE_NO_MEMORY(entry); - sam_pwd_hash(rid, r->ntpassword.hash, nt_passwd, 0); - entry->name = talloc_strdup(mem_ctx, r->account_name.string); - entry->principal = talloc_asprintf(mem_ctx, "%s@%s", - r->account_name.string, - ctx->dns_domain_name); - entry->password = data_blob_talloc(mem_ctx, nt_passwd, 16); + entry.name = talloc_strdup(mem_ctx, r->account_name.string); + entry.principal = talloc_asprintf(mem_ctx, "%s@%s", + r->account_name.string, + ctx->dns_domain_name); + entry.password = data_blob_talloc(mem_ctx, nt_passwd, 16); + entry.kvno = ads_get_kvno(ctx->ads, entry.name); + + NT_STATUS_HAVE_NO_MEMORY(entry.name); + NT_STATUS_HAVE_NO_MEMORY(entry.principal); + NT_STATUS_HAVE_NO_MEMORY(entry.password.data); - NT_STATUS_HAVE_NO_MEMORY(entry->name); - NT_STATUS_HAVE_NO_MEMORY(entry->principal); - ADD_TO_ARRAY(mem_ctx, struct samsync_keytab_entry, *entry, + ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry, &ctx->entries, &ctx->count); return NT_STATUS_OK; @@ -252,10 +116,10 @@ NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx, { NTSTATUS status = NT_STATUS_OK; krb5_error_code ret = 0; - struct samsync_keytab_context *keytab_ctx = NULL; + struct libnet_keytab_context *keytab_ctx = NULL; int i; - ret = keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx); + ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx); if (ret) { status = krb5_to_nt_status(ret); goto out; @@ -286,7 +150,7 @@ NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx, } } - ret = keytab_add(keytab_ctx); + ret = libnet_keytab_add(keytab_ctx); if (ret) { status = krb5_to_nt_status(ret); ctx->error_message = talloc_asprintf(mem_ctx, |