⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdb-ldb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd. * Copyright (c) 2004, Andrew Bartlett <abartlet@samba.org>. * Copyright (c) 2004, Stefan Metzmacher <metze@samba.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * 3. Neither the name of PADL Software  nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "includes.h"#include "system/time.h"#include "kdc.h"#include "dsdb/common/flags.h"#include "hdb.h"#include "krb5_locl.h"#include "lib/ldb/include/ldb.h"#include "lib/ldb/include/ldb_errors.h"#include "librpc/gen_ndr/netlogon.h"#include "auth/auth.h"#include "auth/credentials/credentials.h"#include "auth/auth_sam.h"#include "util/util_ldb.h"#include "dsdb/samdb/samdb.h"#include "librpc/ndr/libndr.h"#include "librpc/gen_ndr/ndr_drsblobs.h"#include "libcli/auth/libcli_auth.h"#include "param/param.h"#include "events/events.h"enum hdb_ldb_ent_type { HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER,   HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_ANY };static const char *realm_ref_attrs[] = {	"nCName", 	"dnsRoot", 	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 hdb_ldb_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 == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {			flags.client = 1;		}		flags.invalid = 0;	}		if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {		if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {			flags.client = 1;		}		flags.invalid = 0;	}	if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) {		if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {			flags.client = 1;		}		flags.invalid = 0;	}	if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) {		if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_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 LDB_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 hdb_ldb_destrutor(struct hdb_ldb_private *private){    hdb_entry_ex *entry_ex = private->entry_ex;    free_hdb_entry(&entry_ex->entry);    return 0;}static void hdb_ldb_free_entry(krb5_context context, hdb_entry_ex *entry_ex){	talloc_free(entry_ex->ctx);}static krb5_error_code LDB_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 *scp = NULL;	struct package_PrimaryKerberosBlob _pkb;	struct package_PrimaryKerberosCtr3 *pkb3 = 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;		}		for (i=0; i < scb.sub.num_packages; i++) {			if (scb.sub.packages[i].unknown1 != 0x00000001) {				continue;			}			if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) != 0) {				continue;			}			if (!scb.sub.packages[i].data || !scb.sub.packages[i].data[0]) {				continue;			}			scp = &scb.sub.packages[i];			break;		}	}	/* Primary:Kerberos element of supplementalCredentials */	if (scp) {		DATA_BLOB blob;		blob = strhex_to_data_blob(scp->data);		if (!blob.data) {			ret = ENOMEM;			goto out;		}		talloc_steal(mem_ctx, blob.data);		/* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */		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)) {			krb5_set_error_string(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");			krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");			ret = EINVAL;			goto out;		}		if (_pkb.version != 3) {			krb5_set_error_string(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");			krb5_warnx(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");			ret = EINVAL;			goto out;		}				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_MD5,					 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 (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;			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++;		}	}out:	if (ret != 0) {		entry_ex->entry.keys.len = 0;	}	if (entry_ex->entry.keys.len == 0 && entry_ex->entry.keys.val) {		free(entry_ex->entry.keys.val);		entry_ex->entry.keys.val = NULL;	}	return ret;}/* * Construct an hdb_entry from a directory entry. */static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, 					 TALLOC_CTX *mem_ctx, krb5_const_principal principal,					 enum hdb_ldb_ent_type ent_type, 					 struct ldb_message *msg,					 struct ldb_message *realm_ref_msg,					 hdb_entry_ex *entry_ex){	unsigned int userAccountControl;	int i;	krb5_error_code ret = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -