[SCM] Samba Shared Repository - branch master updated
Simo Sorce
idra at samba.org
Thu Jan 28 17:34:17 MST 2010
The branch, master has been updated
via 14e0067... s4:kdc remove dead code and comments
via 7b355d4... s4:kdc Fill in more data fields
via 3ce54a4... s4:kdc move db functions in their own file
via a097527... s4:kdc Use a clearer name for the samba kdc entry
via c6865af... s4:kdc Use better db context structure
from f387ed8... Fix bug #7069 - smbget does not return an error status after some errors
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 14e006747eb28b473e5c8070ef021600e1adeeca
Author: Simo Sorce <idra at samba.org>
Date: Thu Jan 28 19:32:38 2010 -0500
s4:kdc remove dead code and comments
commit 7b355d41b52e9ff0ae705da7a7620f03a1868a19
Author: Simo Sorce <idra at samba.org>
Date: Thu Jan 28 08:58:44 2010 -0500
s4:kdc Fill in more data fields
commit 3ce54a4a973d79012e0ea5a1351393d6b006c809
Author: Simo Sorce <idra at samba.org>
Date: Thu Jan 28 01:27:11 2010 -0500
s4:kdc move db functions in their own file
Keep all heimdal related plugin code within hdb_samba4.c
Move interfaces needed by multiple plugins in db-glue.c
Move sequence context in main db context so that we do
not depend on db->hdb_dbc in the common code.
Remove unnecessary paremeters from function prototypes
commit a097527ab73c781322d643f6f444c0d146d0ce87
Author: Simo Sorce <idra at samba.org>
Date: Thu Jan 28 00:19:59 2010 -0500
s4:kdc Use a clearer name for the samba kdc entry
Renames hdb_samba4_private to samba_kdc_entry
Streamlines members of the entry and the kdc db contextto avoid
unnecessary duplication.
commit c6865af4450432bec3f5383d6c815934ac89d434
Author: Simo Sorce <idra at samba.org>
Date: Thu Jan 28 00:08:36 2010 -0500
s4:kdc Use better db context structure
This allows to use a common structure not tied to hdb_samba4
Also allows to avoid many casts within hdb_samba4 functions
This is the first step to abstract samba kdc databse functions
so they can be used by the MIT forthcoming plugin.
-----------------------------------------------------------------------
Summary of changes:
source4/kdc/config.mk | 14 +-
source4/kdc/db-glue.c | 1513 ++++++++++++++++++++++++++++++++
source4/kdc/db-glue.h | 48 +
source4/kdc/hdb-samba4.c | 1540 ++-------------------------------
source4/kdc/hdb-samba4.h | 37 -
source4/kdc/kdc.c | 30 +-
source4/kdc/kdc.h | 27 +-
source4/kdc/kpasswdd.c | 2 +-
source4/kdc/pac-glue.c | 12 +-
source4/kdc/samba_kdc.h | 44 +
source4/kdc/wdc-samba4.c | 10 +-
source4/libnet/libnet_export_keytab.c | 14 +-
12 files changed, 1731 insertions(+), 1560 deletions(-)
create mode 100644 source4/kdc/db-glue.c
create mode 100644 source4/kdc/db-glue.h
delete mode 100644 source4/kdc/hdb-samba4.h
create mode 100644 source4/kdc/samba_kdc.h
Changeset truncated at 500 lines:
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index c3fc550..93f27a3 100644
--- a/source4/kdc/config.mk
+++ b/source4/kdc/config.mk
@@ -19,7 +19,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o)
CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
PRIVATE_DEPENDENCIES = \
LIBLDB auth_sam auth_sam_reply CREDENTIALS \
- HEIMDAL_HDB LIBSAMBA-HOSTCONFIG
+ HEIMDAL_HDB DB_GLUE LIBSAMBA-HOSTCONFIG
# End SUBSYSTEM HDB
#######################
@@ -48,3 +48,15 @@ PRIVATE_DEPENDENCIES = \
#######################
PAC_GLUE_OBJ_FILES = $(addprefix $(kdcsrcdir)/, pac-glue.o)
+
+#######################
+# Start SUBSYSTEM KDC
+[SUBSYSTEM::DB_GLUE]
+CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
+PRIVATE_DEPENDENCIES = \
+ LIBLDB auth_sam auth_sam_reply CREDENTIALS \
+ HEIMDAL_HDB LIBSAMBA-HOSTCONFIG
+# End SUBSYSTEM KDC
+#######################
+
+DB_GLUE_OBJ_FILES = $(addprefix $(kdcsrcdir)/, db-glue.o)
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
new file mode 100644
index 0000000..c434ccb
--- /dev/null
+++ b/source4/kdc/db-glue.c
@@ -0,0 +1,1513 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Database Glue between Samba and the KDC
+
+ Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005-2009
+ Copyright (C) Simo Sorce <idra at samba.org> 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"
+#include "system/time.h"
+#include "../libds/common/flags.h"
+#include "lib/ldb/include/ldb.h"
+#include "librpc/gen_ndr/netlogon.h"
+#include "libcli/security/security.h"
+#include "auth/auth.h"
+#include "auth/credentials/credentials.h"
+#include "auth/auth_sam.h"
+#include "../lib/util/util_ldb.h"
+#include "dsdb/samdb/samdb.h"
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "librpc/gen_ndr/lsa.h"
+#include "libcli/auth/libcli_auth.h"
+#include "param/param.h"
+#include "../lib/crypto/md4.h"
+#include "system/kerberos.h"
+#include <hdb.h>
+#include "kdc/samba_kdc.h"
+#include "kdc/db-glue.h"
+
+enum samba_kdc_ent_type
+{ SAMBA_KDC_ENT_TYPE_CLIENT, SAMBA_KDC_ENT_TYPE_SERVER,
+ SAMBA_KDC_ENT_TYPE_KRBTGT, SAMBA_KDC_ENT_TYPE_TRUST, SAMBA_KDC_ENT_TYPE_ANY };
+
+enum trust_direction {
+ UNKNOWN = 0,
+ INBOUND = LSA_TRUST_DIRECTION_INBOUND,
+ OUTBOUND = LSA_TRUST_DIRECTION_OUTBOUND
+};
+
+static const char *trust_attrs[] = {
+ "trustPartner",
+ "trustAuthIncoming",
+ "trustAuthOutgoing",
+ "whenCreated",
+ "msDS-SupportedEncryptionTypes",
+ "trustAttributes",
+ "trustDirection",
+ "trustType",
+ NULL
+};
+
+static KerberosTime ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, KerberosTime default_val)
+{
+ const char *tmp;
+ const char *gentime;
+ struct tm tm;
+
+ gentime = ldb_msg_find_attr_as_string(msg, attr, NULL);
+ if (!gentime)
+ return default_val;
+
+ tmp = strptime(gentime, "%Y%m%d%H%M%SZ", &tm);
+ if (tmp == NULL) {
+ return default_val;
+ }
+
+ return timegm(&tm);
+}
+
+static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum samba_kdc_ent_type ent_type)
+{
+ HDBFlags flags = int2HDBFlags(0);
+
+ /* we don't allow kadmin deletes */
+ flags.immutable = 1;
+
+ /* mark the principal as invalid to start with */
+ flags.invalid = 1;
+
+ flags.renewable = 1;
+
+ /* All accounts are servers, but this may be disabled again in the caller */
+ flags.server = 1;
+
+ /* Account types - clear the invalid bit if it turns out to be valid */
+ if (userAccountControl & UF_NORMAL_ACCOUNT) {
+ if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT || ent_type == SAMBA_KDC_ENT_TYPE_ANY) {
+ flags.client = 1;
+ }
+ flags.invalid = 0;
+ }
+
+ if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
+ if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT || ent_type == SAMBA_KDC_ENT_TYPE_ANY) {
+ flags.client = 1;
+ }
+ flags.invalid = 0;
+ }
+ if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) {
+ if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT || ent_type == SAMBA_KDC_ENT_TYPE_ANY) {
+ flags.client = 1;
+ }
+ flags.invalid = 0;
+ }
+ if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) {
+ if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT || ent_type == SAMBA_KDC_ENT_TYPE_ANY) {
+ flags.client = 1;
+ }
+ flags.invalid = 0;
+ }
+
+ /* Not permitted to act as a client if disabled */
+ if (userAccountControl & UF_ACCOUNTDISABLE) {
+ flags.client = 0;
+ }
+ if (userAccountControl & UF_LOCKOUT) {
+ flags.invalid = 1;
+ }
+/*
+ if (userAccountControl & UF_PASSWORD_NOTREQD) {
+ flags.invalid = 1;
+ }
+*/
+/*
+ UF_PASSWORD_CANT_CHANGE and UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED are irrelevent
+*/
+ if (userAccountControl & UF_TEMP_DUPLICATE_ACCOUNT) {
+ flags.invalid = 1;
+ }
+
+/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in samba_kdc_message2entry() */
+
+/*
+ if (userAccountControl & UF_MNS_LOGON_ACCOUNT) {
+ flags.invalid = 1;
+ }
+*/
+ if (userAccountControl & UF_SMARTCARD_REQUIRED) {
+ flags.require_hwauth = 1;
+ }
+ if (userAccountControl & UF_TRUSTED_FOR_DELEGATION) {
+ flags.ok_as_delegate = 1;
+ }
+ if (!(userAccountControl & UF_NOT_DELEGATED)) {
+ flags.forwardable = 1;
+ flags.proxiable = 1;
+ }
+
+ if (userAccountControl & UF_DONT_REQUIRE_PREAUTH) {
+ flags.require_preauth = 0;
+ } else {
+ flags.require_preauth = 1;
+
+ }
+ return flags;
+}
+
+static int samba_kdc_entry_destructor(struct samba_kdc_entry *p)
+{
+ hdb_entry_ex *entry_ex = p->entry_ex;
+ free_hdb_entry(&entry_ex->entry);
+ return 0;
+}
+
+static void samba_kdc_free_entry(krb5_context context, hdb_entry_ex *entry_ex)
+{
+ talloc_free(entry_ex->ctx);
+}
+
+static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
+ struct smb_iconv_convenience *iconv_convenience,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg,
+ unsigned int userAccountControl,
+ hdb_entry_ex *entry_ex)
+{
+ krb5_error_code ret = 0;
+ enum ndr_err_code ndr_err;
+ struct samr_Password *hash;
+ const struct ldb_val *sc_val;
+ struct supplementalCredentialsBlob scb;
+ struct supplementalCredentialsPackage *scpk = NULL;
+ bool newer_keys = false;
+ struct package_PrimaryKerberosBlob _pkb;
+ struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
+ struct package_PrimaryKerberosCtr4 *pkb4 = NULL;
+ uint32_t i;
+ uint32_t allocated_keys = 0;
+
+ entry_ex->entry.keys.val = NULL;
+ entry_ex->entry.keys.len = 0;
+
+ entry_ex->entry.kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0);
+
+ /* Get keys from the db */
+
+ hash = samdb_result_hash(mem_ctx, msg, "unicodePwd");
+ sc_val = ldb_msg_find_ldb_val(msg, "supplementalCredentials");
+
+ /* unicodePwd for enctype 0x17 (23) if present */
+ if (hash) {
+ allocated_keys++;
+ }
+
+ /* supplementalCredentials if present */
+ if (sc_val) {
+ ndr_err = ndr_pull_struct_blob_all(sc_val, mem_ctx, iconv_convenience, &scb,
+ (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ dump_data(0, sc_val->data, sc_val->length);
+ ret = EINVAL;
+ goto out;
+ }
+
+ if (scb.sub.signature != SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
+ NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
+ ret = EINVAL;
+ goto out;
+ }
+
+ for (i=0; i < scb.sub.num_packages; i++) {
+ if (strcmp("Primary:Kerberos-Newer-Keys", scb.sub.packages[i].name) == 0) {
+ scpk = &scb.sub.packages[i];
+ if (!scpk->data || !scpk->data[0]) {
+ scpk = NULL;
+ continue;
+ }
+ newer_keys = true;
+ break;
+ } else if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) == 0) {
+ scpk = &scb.sub.packages[i];
+ if (!scpk->data || !scpk->data[0]) {
+ scpk = NULL;
+ }
+ /*
+ * we don't break here in hope to find
+ * a Kerberos-Newer-Keys package
+ */
+ }
+ }
+ }
+ /*
+ * Primary:Kerberos-Newer-Keys or Primary:Kerberos element
+ * of supplementalCredentials
+ */
+ if (scpk) {
+ DATA_BLOB blob;
+
+ blob = strhex_to_data_blob(mem_ctx, scpk->data);
+ if (!blob.data) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ /* we cannot use ndr_pull_struct_blob_all() here, as w2k and w2k3 add padding bytes */
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb,
+ (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ ret = EINVAL;
+ krb5_set_error_message(context, ret, "samba_kdc_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ krb5_warnx(context, "samba_kdc_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ goto out;
+ }
+
+ if (newer_keys && _pkb.version != 4) {
+ ret = EINVAL;
+ krb5_set_error_message(context, ret, "samba_kdc_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+ krb5_warnx(context, "samba_kdc_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+ goto out;
+ }
+
+ if (!newer_keys && _pkb.version != 3) {
+ ret = EINVAL;
+ krb5_set_error_message(context, ret, "samba_kdc_message2entry_keys: could not parse Primary:Kerberos not version 3");
+ krb5_warnx(context, "samba_kdc_message2entry_keys: could not parse Primary:Kerberos not version 3");
+ goto out;
+ }
+
+ if (_pkb.version == 4) {
+ pkb4 = &_pkb.ctr.ctr4;
+ allocated_keys += pkb4->num_keys;
+ } else if (_pkb.version == 3) {
+ pkb3 = &_pkb.ctr.ctr3;
+ allocated_keys += pkb3->num_keys;
+ }
+ }
+
+ if (allocated_keys == 0) {
+ /* oh, no password. Apparently (comment in
+ * hdb-ldap.c) this violates the ASN.1, but this
+ * allows an entry with no keys (yet). */
+ return 0;
+ }
+
+ /* allocate space to decode into */
+ entry_ex->entry.keys.len = 0;
+ entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(Key));
+ if (entry_ex->entry.keys.val == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ if (hash && !(userAccountControl & UF_USE_DES_KEY_ONLY)) {
+ Key key;
+
+ key.mkvno = 0;
+ key.salt = NULL; /* No salt for this enc type */
+
+ ret = krb5_keyblock_init(context,
+ ENCTYPE_ARCFOUR_HMAC,
+ hash->hash, sizeof(hash->hash),
+ &key.key);
+ if (ret) {
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
+ }
+
+ if (pkb4) {
+ for (i=0; i < pkb4->num_keys; i++) {
+ bool use = true;
+ Key key;
+
+ if (!pkb4->keys[i].value) continue;
+
+ if (userAccountControl & UF_USE_DES_KEY_ONLY) {
+ switch (pkb4->keys[i].keytype) {
+ case ENCTYPE_DES_CBC_CRC:
+ case ENCTYPE_DES_CBC_MD5:
+ break;
+ default:
+ use = false;
+ break;
+ }
+ }
+
+ if (!use) continue;
+
+ key.mkvno = 0;
+ key.salt = NULL;
+
+ if (pkb4->salt.string) {
+ DATA_BLOB salt;
+
+ salt = data_blob_string_const(pkb4->salt.string);
+
+ key.salt = calloc(1, sizeof(*key.salt));
+ if (key.salt == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ key.salt->type = hdb_pw_salt;
+
+ ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length);
+ if (ret) {
+ free(key.salt);
+ key.salt = NULL;
+ goto out;
+ }
+ }
+
+ /* TODO: maybe pass the iteration_count somehow... */
+
+ ret = krb5_keyblock_init(context,
+ pkb4->keys[i].keytype,
+ pkb4->keys[i].value->data,
+ pkb4->keys[i].value->length,
+ &key.key);
+ if (ret == KRB5_PROG_ETYPE_NOSUPP) {
+ DEBUG(2,("Unsupported keytype ignored - type %u\n",
+ pkb4->keys[i].keytype));
+ ret = 0;
+ continue;
+ }
+ if (ret) {
+ if (key.salt) {
+ free_Salt(key.salt);
+ free(key.salt);
+ key.salt = NULL;
+ }
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
+ }
+ } else if (pkb3) {
+ for (i=0; i < pkb3->num_keys; i++) {
+ bool use = true;
+ Key key;
+
+ if (!pkb3->keys[i].value) continue;
+
+ if (userAccountControl & UF_USE_DES_KEY_ONLY) {
+ switch (pkb3->keys[i].keytype) {
+ case ENCTYPE_DES_CBC_CRC:
+ case ENCTYPE_DES_CBC_MD5:
+ break;
+ default:
+ use = false;
+ break;
+ }
+ }
+
+ if (!use) continue;
+
+ key.mkvno = 0;
+ key.salt = NULL;
+
+ if (pkb3->salt.string) {
+ DATA_BLOB salt;
+
+ salt = data_blob_string_const(pkb3->salt.string);
+
+ key.salt = calloc(1, sizeof(*key.salt));
+ if (key.salt == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ key.salt->type = hdb_pw_salt;
+
+ ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length);
+ if (ret) {
+ free(key.salt);
+ key.salt = NULL;
+ goto out;
+ }
+ }
+
+ ret = krb5_keyblock_init(context,
+ pkb3->keys[i].keytype,
+ pkb3->keys[i].value->data,
+ pkb3->keys[i].value->length,
+ &key.key);
+ if (ret) {
+ if (key.salt) {
+ free_Salt(key.salt);
+ free(key.salt);
+ key.salt = NULL;
+ }
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
--
Samba Shared Repository
More information about the samba-cvs
mailing list