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

📄 hdb-ldb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	krb5_boolean is_computer = FALSE;	const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg, "dnsRoot", NULL);	char *realm = strupper_talloc(mem_ctx, dnsdomain);	struct loadparm_context *lp_ctx = ldb_get_opaque((struct ldb_context *)db->hdb_db, "loadparm");	struct ldb_dn *domain_dn = samdb_result_dn((struct ldb_context *)db->hdb_db,							mem_ctx,							realm_ref_msg,							"nCName",							ldb_dn_new(mem_ctx, (struct ldb_context *)db->hdb_db, NULL));	struct hdb_ldb_private *private;	NTTIME acct_expiry;	struct ldb_message_element *objectclasses;	struct ldb_val computer_val;	computer_val.data = discard_const_p(uint8_t,"computer");	computer_val.length = strlen((const char *)computer_val.data);		objectclasses = ldb_msg_find_element(msg, "objectClass");		if (objectclasses && ldb_msg_find_val(objectclasses, &computer_val)) {		is_computer = TRUE;	}	memset(entry_ex, 0, sizeof(*entry_ex));	if (!realm) {		krb5_set_error_string(context, "talloc_strdup: out of memory");		ret = ENOMEM;		goto out;	}				private = talloc(mem_ctx, struct hdb_ldb_private);	if (!private) {		ret = ENOMEM;		goto out;	}	private->entry_ex = entry_ex;	private->iconv_convenience = lp_iconv_convenience(lp_ctx);	private->netbios_name = lp_netbios_name(lp_ctx);	talloc_set_destructor(private, hdb_ldb_destrutor);	entry_ex->ctx = private;	entry_ex->free_entry = hdb_ldb_free_entry;	userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);		entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));	if (ent_type == HDB_LDB_ENT_TYPE_ANY && principal == NULL) {		const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);		if (!samAccountName) {			krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");			ret = ENOENT;			goto out;		}		samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);		krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL);	} else {		char *strdup_realm;		ret = copy_Principal(principal, entry_ex->entry.principal);		if (ret) {			krb5_clear_error_string(context);			goto out;		}		/* While we have copied the client principal, tests		 * show that Win2k3 returns the 'corrected' realm, not		 * the client-specified realm.  This code attempts to		 * replace the client principal's realm with the one		 * we determine from our records */				/* this has to be with malloc() */		strdup_realm = strdup(realm);		if (!strdup_realm) {			ret = ENOMEM;			krb5_clear_error_string(context);			goto out;		}		free(*krb5_princ_realm(context, entry_ex->entry.principal));		krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm);	}	entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);	if (ent_type == HDB_LDB_ENT_TYPE_KRBTGT) {		entry_ex->entry.flags.invalid = 0;		entry_ex->entry.flags.server = 1;		entry_ex->entry.flags.forwardable = 1;		entry_ex->entry.flags.ok_as_delegate = 1;	}	if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) {		if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) {			entry_ex->entry.flags.server = 0;		}	}	/* use 'whenCreated' */	entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0);	/* use '???' */	entry_ex->entry.created_by.principal = NULL;	entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));	if (entry_ex->entry.modified_by == NULL) {		krb5_set_error_string(context, "malloc: out of memory");		ret = ENOMEM;		goto out;	}	/* use 'whenChanged' */	entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0);	/* use '???' */	entry_ex->entry.modified_by->principal = NULL;	entry_ex->entry.valid_start = NULL;	acct_expiry = samdb_result_account_expires(msg);	if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {		entry_ex->entry.valid_end = NULL;	} else {		entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end));		if (entry_ex->entry.valid_end == NULL) {			ret = ENOMEM;			goto out;		}		*entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);	}	if (ent_type != HDB_LDB_ENT_TYPE_KRBTGT) {		NTTIME must_change_time			= samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx, 							     domain_dn, msg);		if (must_change_time == 0x7FFFFFFFFFFFFFFFULL) {			entry_ex->entry.pw_end = NULL;		} else {			entry_ex->entry.pw_end = malloc(sizeof(*entry_ex->entry.pw_end));			if (entry_ex->entry.pw_end == NULL) {				ret = ENOMEM;				goto out;			}			*entry_ex->entry.pw_end = nt_time_to_unix(must_change_time);		}	} else {		entry_ex->entry.pw_end = NULL;	}				entry_ex->entry.max_life = NULL;	entry_ex->entry.max_renew = NULL;	entry_ex->entry.generation = NULL;	/* Get keys from the db */	ret = LDB_message2entry_keys(context, private->iconv_convenience, private, msg, userAccountControl, entry_ex);	if (ret) {		/* Could be bougus data in the entry, or out of memory */		goto out;	}	entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));	if (entry_ex->entry.etypes == NULL) {		krb5_clear_error_string(context);		ret = ENOMEM;		goto out;	}	entry_ex->entry.etypes->len = entry_ex->entry.keys.len;	entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));	if (entry_ex->entry.etypes->val == NULL) {		krb5_clear_error_string(context);		ret = ENOMEM;		goto out;	}	for (i=0; i < entry_ex->entry.etypes->len; i++) {		entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype;	}	private->msg = talloc_steal(private, msg);	private->realm_ref_msg = talloc_steal(private, realm_ref_msg);	private->samdb = (struct ldb_context *)db->hdb_db;	out:	if (ret != 0) {		/* This doesn't free ent itself, that is for the eventual caller to do */		hdb_free_entry(context, entry_ex);	} else {		talloc_steal(db, entry_ex->ctx);	}	return ret;}static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_context *ldb_ctx, 										    TALLOC_CTX *mem_ctx,					    krb5_const_principal principal,					    enum hdb_ldb_ent_type ent_type,					    struct ldb_dn *realm_dn,					    struct ldb_message ***pmsg){	krb5_error_code ret;	int lret;	char *filter = NULL;	const char * const *princ_attrs = user_attrs;	char *short_princ;	char *short_princ_talloc;	struct ldb_result *res = NULL;	ret = krb5_unparse_name_flags(context, principal,  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);	if (ret != 0) {		krb5_set_error_string(context, "LDB_lookup_principal: could not parse principal");		krb5_warnx(context, "LDB_lookup_principal: could not parse principal");		return ret;	}	short_princ_talloc = talloc_strdup(mem_ctx, short_princ);	free(short_princ);	if (!short_princ_talloc) {		krb5_set_error_string(context, "LDB_lookup_principal: talloc_strdup() failed!");		return ENOMEM;	}	switch (ent_type) {	case HDB_LDB_ENT_TYPE_CLIENT:		/* Can't happen */		return EINVAL;	case HDB_LDB_ENT_TYPE_ANY:		/* Can't happen */		return EINVAL;	case HDB_LDB_ENT_TYPE_KRBTGT:		filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", 					 KRB5_TGS_NAME);		break;	case HDB_LDB_ENT_TYPE_SERVER:		filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", 					 short_princ_talloc);		break;	}	if (!filter) {		krb5_set_error_string(context, "talloc_asprintf: out of memory");		return ENOMEM;	}	lret = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, filter, princ_attrs, &res);	if (lret != LDB_SUCCESS) {		DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx)));		return HDB_ERR_NOENTRY;	} else if (res->count == 0 || res->count > 1) {		DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count));		talloc_free(res);		return HDB_ERR_NOENTRY;	}	talloc_steal(mem_ctx, res->msgs);	*pmsg = res->msgs;	talloc_free(res);	return 0;}static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context *ldb_ctx, 					TALLOC_CTX *mem_ctx,					const char *realm,					struct ldb_message ***pmsg){ 	int ret;	struct ldb_result *cross_ref_res;	struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx);	ret = ldb_search_exp_fmt(ldb_ctx, mem_ctx, &cross_ref_res,			partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs,			"(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",			realm, realm);	if (ret != LDB_SUCCESS) {		DEBUG(3, ("Failed to search to lookup realm(%s): %s\n", realm, ldb_errstring(ldb_ctx)));		talloc_free(cross_ref_res);		return HDB_ERR_NOENTRY;	} else if (cross_ref_res->count == 0 || cross_ref_res->count > 1) {		DEBUG(3, ("Failed find a single entry for realm %s: got %d\n", realm, cross_ref_res->count));		talloc_free(cross_ref_res);		return HDB_ERR_NOENTRY;	}	if (pmsg) {		*pmsg = cross_ref_res->msgs;		talloc_steal(mem_ctx, cross_ref_res->msgs);	}	talloc_free(cross_ref_res);	return 0;}static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode){	if (db->hdb_master_key_set) {		krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n");		krb5_set_error_string(context, "LDB_open: use of a master key incompatible with LDB\n");		return HDB_ERR_NOENTRY;	}			return 0;}static krb5_error_code LDB_close(krb5_context context, HDB *db){	return 0;}static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation){	return 0;}static krb5_error_code LDB_unlock(krb5_context context, HDB *db){	return 0;}static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name){	return HDB_ERR_DB_INUSE;}static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, 					TALLOC_CTX *mem_ctx, 					krb5_const_principal principal,					unsigned flags,					hdb_entry_ex *entry_ex) {	NTSTATUS nt_status;	char *principal_string;	krb5_error_code ret;	struct ldb_message **msg = NULL;	struct ldb_message **realm_ref_msg = NULL;	ret = krb5_unparse_name(context, principal, &principal_string);		if (ret != 0) {		return ret;	}		nt_status = sam_get_results_principal((struct ldb_context *)db->hdb_db,					      mem_ctx, principal_string, 					      &msg, &realm_ref_msg);	free(principal_string);	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {		return HDB_ERR_NOENTRY;	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MEMORY)) {		return ENOMEM;	} else if (!NT_STATUS_IS_OK(nt_status)) {		return EINVAL;	}		ret = LDB_message2entry(context, db, mem_ctx, 				principal, HDB_LDB_ENT_TYPE_CLIENT,				msg[0], realm_ref_msg[0], entry_ex);	return ret;}static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, 					TALLOC_CTX *mem_ctx, 					krb5_const_principal principal,					unsigned flags,					hdb_entry_ex *entry_ex){	krb5_error_code ret;	struct ldb_message **msg = NULL;	struct ldb_message **realm_ref_msg = NULL;	struct ldb_dn *realm_dn;	krb5_principal alloc_principal = NULL;	if (principal->name.name_string.len != 2	    || (strcmp(principal->name.name_string.val[0], KRB5_TGS_NAME) != 0)) {		/* Not a krbtgt */		return HDB_ERR_NOENTRY;	}	/* krbtgt case.  Either us or a trusted realm */	if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,			      mem_ctx, principal->name.name_string.val[1], &realm_ref_msg) == 0)) {		/* us */		 		/* Cludge, cludge cludge.  If the realm part of krbtgt/realm, 		 * is in our db, then direct the caller at our primary 		 * krgtgt */ 		 		const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg[0], "dnsRoot", NULL); 		char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain); 		if (!realm_fixed) {

⌨️ 快捷键说明

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