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

📄 hdb-ldb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
 			krb5_set_error_string(context, "strupper_talloc: out of memory"); 			return ENOMEM; 		} 		 		ret = krb5_copy_principal(context, principal, &alloc_principal); 		if (ret) { 			return ret; 		}  		free(alloc_principal->name.name_string.val[1]);		alloc_principal->name.name_string.val[1] = strdup(realm_fixed); 		talloc_free(realm_fixed); 		if (!alloc_principal->name.name_string.val[1]) { 			krb5_set_error_string(context, "LDB_fetch: strdup() failed!"); 			return ENOMEM; 		} 		principal = alloc_principal;		realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);	} else {		/* we should lookup trusted domains */		return HDB_ERR_NOENTRY;	}	realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);		ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 				   mem_ctx, 				   principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg);		if (ret != 0) {		krb5_warnx(context, "LDB_fetch: could not find principal in DB");		krb5_set_error_string(context, "LDB_fetch: could not find principal in DB");		return ret;	}	ret = LDB_message2entry(context, db, mem_ctx, 				principal, HDB_LDB_ENT_TYPE_KRBTGT, 				msg[0], realm_ref_msg[0], entry_ex);	if (ret != 0) {		krb5_warnx(context, "LDB_fetch: message2entry failed");		}	return ret;}static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, 					TALLOC_CTX *mem_ctx, 					krb5_const_principal principal,					unsigned flags,					hdb_entry_ex *entry_ex){	krb5_error_code ret;	const char *realm;	struct ldb_message **msg = NULL;	struct ldb_message **realm_ref_msg = NULL;	struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx);	if (principal->name.name_string.len >= 2) {		/* 'normal server' case */		int ldb_ret;		NTSTATUS nt_status;		struct ldb_dn *user_dn, *domain_dn;		char *principal_string;				ret = krb5_unparse_name_flags(context, principal, 					      KRB5_PRINCIPAL_UNPARSE_NO_REALM, 					      &principal_string);		if (ret != 0) {			return ret;		}				/* At this point we may find the host is known to be		 * in a different realm, so we should generate a		 * referral instead */		nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db,							 mem_ctx, principal_string, 							 &user_dn, &domain_dn);		free(principal_string);				if (!NT_STATUS_IS_OK(nt_status)) {			return HDB_ERR_NOENTRY;		}				ldb_ret = gendb_search_dn((struct ldb_context *)db->hdb_db,					  mem_ctx, user_dn, &msg, user_attrs);				if (ldb_ret != 1) {			return HDB_ERR_NOENTRY;		}				ldb_ret = gendb_search((struct ldb_context *)db->hdb_db,				       mem_ctx, partitions_basedn, &realm_ref_msg, realm_ref_attrs, 				       "ncName=%s", ldb_dn_get_linearized(domain_dn));				if (ldb_ret != 1) {			return HDB_ERR_NOENTRY;		}			} else {		struct ldb_dn *realm_dn;		/* server as client principal case, but we must not lookup userPrincipalNames */		realm = krb5_principal_get_realm(context, principal);				ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, 				       mem_ctx, realm, &realm_ref_msg);		if (ret != 0) {			return HDB_ERR_NOENTRY;		}				realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);				ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 					   mem_ctx, 					   principal, HDB_LDB_ENT_TYPE_SERVER, realm_dn, &msg);				if (ret != 0) {			return ret;		}	}	ret = LDB_message2entry(context, db, mem_ctx, 				principal, HDB_LDB_ENT_TYPE_SERVER,				msg[0], realm_ref_msg[0], entry_ex);	if (ret != 0) {		krb5_warnx(context, "LDB_fetch: message2entry failed");		}	return ret;}			static krb5_error_code LDB_fetch(krb5_context context, HDB *db, 				 krb5_const_principal principal,				 unsigned flags,				 hdb_entry_ex *entry_ex){	krb5_error_code ret = HDB_ERR_NOENTRY;	TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context");	if (!mem_ctx) {		krb5_set_error_string(context, "LDB_fetch: talloc_named() failed!");		return ENOMEM;	}	if (flags & HDB_F_GET_CLIENT) {		ret = LDB_fetch_client(context, db, mem_ctx, principal, flags, entry_ex);		if (ret != HDB_ERR_NOENTRY) goto done;	}	if (flags & HDB_F_GET_SERVER) {		ret = LDB_fetch_server(context, db, mem_ctx, principal, flags, entry_ex);		if (ret != HDB_ERR_NOENTRY) goto done;		ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex);		if (ret != HDB_ERR_NOENTRY) goto done;	}	if (flags & HDB_F_GET_KRBTGT) {		ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex);		if (ret != HDB_ERR_NOENTRY) goto done;	}done:	talloc_free(mem_ctx);	return ret;}static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry){	return HDB_ERR_DB_INUSE;}static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal){	return HDB_ERR_DB_INUSE;}struct hdb_ldb_seq {	struct ldb_context *ctx;	int index;	int count;	struct ldb_message **msgs;	struct ldb_message **realm_ref_msgs;};static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry){	krb5_error_code ret;	struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;	TALLOC_CTX *mem_ctx;	hdb_entry_ex entry_ex;	memset(&entry_ex, '\0', sizeof(entry_ex));	if (!priv) {		return HDB_ERR_NOENTRY;	}	mem_ctx = talloc_named(priv, 0, "LDB_seq context");	if (!mem_ctx) {		krb5_set_error_string(context, "LDB_seq: talloc_named() failed!");		return ENOMEM;	}	if (priv->index < priv->count) {		ret = LDB_message2entry(context, db, mem_ctx, 					NULL, HDB_LDB_ENT_TYPE_ANY, 					priv->msgs[priv->index++], 					priv->realm_ref_msgs[0], entry);	} else {		ret = HDB_ERR_NOENTRY;	}	if (ret != 0) {		talloc_free(priv);		db->hdb_dbc = NULL;	} else {		talloc_free(mem_ctx);	}	return ret;}static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags,					hdb_entry_ex *entry){	struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;	struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;	char *realm;	struct ldb_dn *realm_dn = NULL;	struct ldb_result *res = NULL;	struct ldb_message **realm_ref_msgs = NULL;	krb5_error_code ret;	TALLOC_CTX *mem_ctx;	int lret;	if (priv) {		talloc_free(priv);		db->hdb_dbc = NULL;	}	priv = (struct hdb_ldb_seq *) talloc(db, struct hdb_ldb_seq);	if (!priv) {		krb5_set_error_string(context, "talloc: out of memory");		return ENOMEM;	}	priv->ctx = ldb_ctx;	priv->index = 0;	priv->msgs = NULL;	priv->realm_ref_msgs = NULL;	priv->count = 0;	mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");	if (!mem_ctx) {		krb5_set_error_string(context, "LDB_firstkey: talloc_named() failed!");		return ENOMEM;	}	ret = krb5_get_default_realm(context, &realm);	if (ret != 0) {		talloc_free(priv);		return ret;	}			ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, 			       mem_ctx, realm, &realm_ref_msgs);	free(realm);	if (ret != 0) {		talloc_free(priv);		krb5_warnx(context, "LDB_firstkey: could not find realm\n");		return HDB_ERR_NOENTRY;	}	realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msgs[0], "nCName", NULL);	priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs);	lret = ldb_search(ldb_ctx, realm_dn,				 LDB_SCOPE_SUBTREE, "(objectClass=user)",				 user_attrs, &res);	if (lret != LDB_SUCCESS) {		talloc_free(priv);		return HDB_ERR_NOENTRY;	}	priv->count = res->count;	priv->msgs = talloc_steal(priv, res->msgs);	talloc_free(res);	db->hdb_dbc = priv;	ret = LDB_seq(context, db, flags, entry);	if (ret != 0) {    		talloc_free(priv);		db->hdb_dbc = NULL;	} else {		talloc_free(mem_ctx);	}	return ret;}static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags,				   hdb_entry_ex *entry){	return LDB_seq(context, db, flags, entry);}static krb5_error_code LDB_destroy(krb5_context context, HDB *db){	talloc_free(db);	return 0;}/* This interface is to be called by the KDC, which is expecting Samba * calling conventions.  It is also called by a wrapper * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb * code */NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx, 			    struct event_context *ev_ctx, 			    struct loadparm_context *lp_ctx,			    krb5_context context, struct HDB **db, const char *arg){	NTSTATUS nt_status;	struct auth_session_info *session_info;	*db = talloc(mem_ctx, HDB);	if (!*db) {		krb5_set_error_string(context, "malloc: out of memory");		return NT_STATUS_NO_MEMORY;	}	(*db)->hdb_master_key_set = 0;	(*db)->hdb_db = NULL;	nt_status = auth_system_session_info(*db, lp_ctx, &session_info);	if (!NT_STATUS_IS_OK(nt_status)) {		return nt_status;	}		/* The idea here is very simple.  Using Kerberos to	 * authenticate the KDC to the LDAP server is higly likely to	 * be circular.	 *	 * In future we may set this up to use EXERNAL and SSL	 * certificates, for now it will almost certainly be NTLMSSP	*/		cli_credentials_set_kerberos_state(session_info->credentials, 					   CRED_DONT_USE_KERBEROS);	/* Setup the link to LDB */	(*db)->hdb_db = samdb_connect(*db, ev_ctx, lp_ctx, session_info);	if ((*db)->hdb_db == NULL) {		DEBUG(1, ("hdb_ldb_create: Cannot open samdb for KDC backend!"));		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;	}	(*db)->hdb_dbc = NULL;	(*db)->hdb_open = LDB_open;	(*db)->hdb_close = LDB_close;	(*db)->hdb_fetch = LDB_fetch;	(*db)->hdb_store = LDB_store;	(*db)->hdb_remove = LDB_remove;	(*db)->hdb_firstkey = LDB_firstkey;	(*db)->hdb_nextkey = LDB_nextkey;	(*db)->hdb_lock = LDB_lock;	(*db)->hdb_unlock = LDB_unlock;	(*db)->hdb_rename = LDB_rename;	/* we don't implement these, as we are not a lockable database */	(*db)->hdb__get = NULL;	(*db)->hdb__put = NULL;	/* kadmin should not be used for deletes - use other tools instead */	(*db)->hdb__del = NULL;	(*db)->hdb_destroy = LDB_destroy;	return NT_STATUS_OK;}krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg){	NTSTATUS nt_status;	/* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */	nt_status = kdc_hdb_ldb_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, 				       context, db, arg);	if (NT_STATUS_IS_OK(nt_status)) {		return 0;	}	return EINVAL;}

⌨️ 快捷键说明

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