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

📄 pdb_ldap.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   LDAP protocol helper functions for SAMBA   Copyright (C) Jean François Micouleau	1998   Copyright (C) Gerald Carter			2001-2003   Copyright (C) Shahms King			2001   Copyright (C) Andrew Bartlett		2002-2003   Copyright (C) Stefan (metze) Metzmacher	2002-2003       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 2 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, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *//* TODO:*  persistent connections: if using NSS LDAP, many connections are made*      however, using only one within Samba would be nice*  *  Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK**  Other LDAP based login attributes: accountExpires, etc.*  (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT*  structures don't have fields for some of these attributes)**  SSL is done, but can't get the certificate based authentication to work*  against on my test platform (Linux 2.4, OpenLDAP 2.x)*//* NOTE: this will NOT work against an Active Directory server*  due to the fact that the two password fields cannot be retrieved*  from a server; recommend using security = domain in this situation*  and/or winbind*/#include "includes.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_PASSDB#include <lber.h>#include <ldap.h>/* * Work around versions of the LDAP client libs that don't have the OIDs * defined, or have them defined under the old name.   * This functionality is really a factor of the server, not the client  * */#if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)#define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD#elif !defined(LDAP_EXOP_MODIFY_PASSWD)#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"#endif#if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID#elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID        ((ber_tag_t) 0x80U)#endif#if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW#elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW       ((ber_tag_t) 0x82U)#endif#ifndef SAM_ACCOUNT#define SAM_ACCOUNT struct sam_passwd#endif#include "smbldap.h"/********************************************************************** Free a LDAPMessage (one is stored on the SAM_ACCOUNT). **********************************************************************/ void private_data_free_fn(void **result) {	ldap_msgfree(*result);	*result = NULL;}/********************************************************************** Get the attribute name given a user schame version. **********************************************************************/ static const char* get_userattr_key2string( int schema_ver, int key ){	switch ( schema_ver ) {		case SCHEMAVER_SAMBAACCOUNT:			return get_attr_key2string( attrib_map_v22, key );					case SCHEMAVER_SAMBASAMACCOUNT:			return get_attr_key2string( attrib_map_v30, key );					default:			DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));			break;	}	return NULL;}/********************************************************************** Return the list of attribute names given a user schema version.**********************************************************************/const char** get_userattr_list( int schema_ver ){	switch ( schema_ver ) {		case SCHEMAVER_SAMBAACCOUNT:			return get_attr_list( attrib_map_v22 );					case SCHEMAVER_SAMBASAMACCOUNT:			return get_attr_list( attrib_map_v30 );		default:			DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));			break;	}		return NULL;}/************************************************************************** Return the list of attribute names to delete given a user schema version.**************************************************************************/static const char** get_userattr_delete_list( int schema_ver ){	switch ( schema_ver ) {		case SCHEMAVER_SAMBAACCOUNT:			return get_attr_list( attrib_map_to_delete_v22 );					case SCHEMAVER_SAMBASAMACCOUNT:			return get_attr_list( attrib_map_to_delete_v30 );		default:			DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));			break;	}		return NULL;}/******************************************************************* Generate the LDAP search filter for the objectclass based on the  version of the schema we are using.******************************************************************/static const char* get_objclass_filter( int schema_ver ){	static fstring objclass_filter;		switch( schema_ver ) {		case SCHEMAVER_SAMBAACCOUNT:			fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );			break;		case SCHEMAVER_SAMBASAMACCOUNT:			fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );			break;		default:			DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));			break;	}		return objclass_filter;	}/***************************************************************** Scan a sequence number off OpenLDAP's syncrepl contextCSN******************************************************************/static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num){	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;	NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;	LDAPMessage *msg = NULL;	LDAPMessage *entry = NULL;	TALLOC_CTX *mem_ctx;	char **values = NULL;	int rc, num_result, num_values, rid;	pstring suffix;	fstring tok;	const char *p;	const char **attrs;	/* Unfortunatly there is no proper way to detect syncrepl-support in	 * smbldap_connect_system(). The syncrepl OIDs are submitted for publication	 * but do not show up in the root-DSE yet. Neither we can query the	 * subschema-context for the syncProviderSubentry or syncConsumerSubentry	 * objectclass. Currently we require lp_ldap_suffix() to show up as	 * namingContext.  -  Guenther	 */	if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {		return ntstatus;	}	if (!seq_num) {		DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));		return ntstatus;	}	if (!smbldap_has_naming_context(ldap_state->smbldap_state, lp_ldap_suffix())) {		DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "			 "as top-level namingContext\n", lp_ldap_suffix()));		return ntstatus;	}	mem_ctx = talloc_init("ldapsam_get_seq_num");	if (mem_ctx == NULL)		return NT_STATUS_NO_MEMORY;	attrs = TALLOC_ARRAY(mem_ctx, const char *, 2);	/* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */	rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);	if (rid > 0) {		/* consumer syncreplCookie: */		/* csn=20050126161620Z#0000001#00#00000 */		attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");		attrs[1] = NULL;		pstr_sprintf( suffix, "cn=syncrepl%d,%s", rid, lp_ldap_suffix());	} else {		/* provider contextCSN */		/* 20050126161620Z#000009#00#000000 */		attrs[0] = talloc_strdup(mem_ctx, "contextCSN");		attrs[1] = NULL;		pstr_sprintf( suffix, "cn=ldapsync,%s", lp_ldap_suffix());	}	rc = smbldap_search(ldap_state->smbldap_state, suffix,			    LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);	if (rc != LDAP_SUCCESS) {		char *ld_error = NULL;		ldap_get_option(ldap_state->smbldap_state->ldap_struct,				LDAP_OPT_ERROR_STRING, &ld_error);		DEBUG(0,("ldapsam_get_seq_num: Failed search for suffix: %s, error: %s (%s)\n", 			suffix,ldap_err2string(rc), ld_error?ld_error:"unknown"));		SAFE_FREE(ld_error);		goto done;	}	num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg);	if (num_result != 1) {		DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));		goto done;	}	entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg);	if (entry == NULL) {		DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));		goto done;	}	values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, attrs[0]);	if (values == NULL) {		DEBUG(3,("ldapsam_get_seq_num: no values\n"));		goto done;	}	num_values = ldap_count_values(values);	if (num_values == 0) {		DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));		goto done;	}	p = values[0];	if (!next_token(&p, tok, "#", sizeof(tok))) {		DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));		goto done;	}	p = tok;	if (!strncmp(p, "csn=", strlen("csn=")))		p += strlen("csn=");	DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));	*seq_num = generalized_to_unix_time(p);	/* very basic sanity check */	if (*seq_num <= 0) {		DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n", 			(int)*seq_num));		goto done;	}	ntstatus = NT_STATUS_OK; done:	if (values != NULL)		ldap_value_free(values);	if (msg != NULL)		ldap_msgfree(msg);	if (mem_ctx)		talloc_destroy(mem_ctx);	return ntstatus;}/******************************************************************* Run the search by name.******************************************************************/int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, 					  const char *user,					  LDAPMessage ** result,					  const char **attr){	pstring filter;	char *escape_user = escape_ldap_string_alloc(user);	if (!escape_user) {		return LDAP_NO_MEMORY;	}	/*	 * in the filter expression, replace %u with the real name	 * so in ldap filter, %u MUST exist :-)	 */	pstr_sprintf(filter, "(&%s%s)", "(uid=%u)", 		get_objclass_filter(ldap_state->schema_ver));	/* 	 * have to use this here because $ is filtered out	   * in pstring_sub	 */		all_string_sub(filter, "%u", escape_user, sizeof(pstring));	SAFE_FREE(escape_user);	return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);}/******************************************************************* Run the search by rid.******************************************************************/static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state, 					 uint32 rid, LDAPMessage ** result, 					 const char **attr){	pstring filter;	int rc;	pstr_sprintf(filter, "(&(rid=%i)%s)", rid, 		get_objclass_filter(ldap_state->schema_ver));		rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);		return rc;}/******************************************************************* Run the search by SID.******************************************************************/static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state, 					 const DOM_SID *sid, LDAPMessage ** result, 					 const char **attr){	pstring filter;	int rc;	fstring sid_string;	pstr_sprintf(filter, "(&(%s=%s)%s)", 		get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),		sid_to_string(sid_string, sid), 		get_objclass_filter(ldap_state->schema_ver));			rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);		return rc;}/******************************************************************* Delete complete object or objectclass and attrs from object found in search_result depending on lp_ldap_delete_dn******************************************************************/static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,				     LDAPMessage *result,				     const char *objectclass,				     const char **attrs)

⌨️ 快捷键说明

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