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

📄 smbldap.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    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.   */#include "includes.h"#include "smbldap.h"#ifndef LDAP_OPT_SUCCESS#define LDAP_OPT_SUCCESS 0#endif/* Try not to hit the up or down server forever */#define SMBLDAP_DONT_PING_TIME 10	/* ping only all 10 seconds */#define SMBLDAP_NUM_RETRIES 8	        /* retry only 8 times */#define SMBLDAP_IDLE_TIME 150		/* After 2.5 minutes disconnect *//* attributes used by Samba 2.2 */ATTRIB_MAP_ENTRY attrib_map_v22[] = {	{ LDAP_ATTR_UID,		"uid" 		},	{ LDAP_ATTR_UIDNUMBER,		LDAP_ATTRIBUTE_UIDNUMBER},	{ LDAP_ATTR_GIDNUMBER,		LDAP_ATTRIBUTE_GIDNUMBER},	{ LDAP_ATTR_UNIX_HOME,		"homeDirectory"	},	{ LDAP_ATTR_PWD_LAST_SET,	"pwdLastSet"	},	{ LDAP_ATTR_PWD_CAN_CHANGE,	"pwdCanChange"	},	{ LDAP_ATTR_PWD_MUST_CHANGE,	"pwdMustChange"	},	{ LDAP_ATTR_LOGON_TIME,		"logonTime" 	},	{ LDAP_ATTR_LOGOFF_TIME,	"logoffTime"	},	{ LDAP_ATTR_KICKOFF_TIME,	"kickoffTime"	},	{ LDAP_ATTR_CN,			"cn"		},	{ LDAP_ATTR_DISPLAY_NAME,	"displayName"	},	{ LDAP_ATTR_HOME_PATH,		"smbHome"	},	{ LDAP_ATTR_HOME_DRIVE,		"homeDrive"	},	{ LDAP_ATTR_LOGON_SCRIPT,	"scriptPath"	},	{ LDAP_ATTR_PROFILE_PATH,	"profilePath"	},	{ LDAP_ATTR_DESC,		"description"	},	{ LDAP_ATTR_USER_WKS,		"userWorkstations"},	{ LDAP_ATTR_USER_RID,		"rid"		},	{ LDAP_ATTR_PRIMARY_GROUP_RID,	"primaryGroupID"},	{ LDAP_ATTR_LMPW,		"lmPassword"	},	{ LDAP_ATTR_NTPW,		"ntPassword"	},	{ LDAP_ATTR_DOMAIN,		"domain"	},	{ LDAP_ATTR_OBJCLASS,		"objectClass"	},	{ LDAP_ATTR_ACB_INFO,		"acctFlags"	},	{ LDAP_ATTR_MOD_TIMESTAMP,	"modifyTimestamp"	},	{ LDAP_ATTR_LIST_END,		NULL 		}};ATTRIB_MAP_ENTRY attrib_map_to_delete_v22[] = {	{ LDAP_ATTR_PWD_LAST_SET,	"pwdLastSet"	},	{ LDAP_ATTR_PWD_CAN_CHANGE,	"pwdCanChange"	},	{ LDAP_ATTR_PWD_MUST_CHANGE,	"pwdMustChange"	},	{ LDAP_ATTR_LOGON_TIME,		"logonTime" 	},	{ LDAP_ATTR_LOGOFF_TIME,	"logoffTime"	},	{ LDAP_ATTR_KICKOFF_TIME,	"kickoffTime"	},	{ LDAP_ATTR_DISPLAY_NAME,	"displayName"	},	{ LDAP_ATTR_HOME_PATH,		"smbHome"	},	{ LDAP_ATTR_HOME_DRIVE,		"homeDrives"	},	{ LDAP_ATTR_LOGON_SCRIPT,	"scriptPath"	},	{ LDAP_ATTR_PROFILE_PATH,	"profilePath"	},	{ LDAP_ATTR_USER_WKS,		"userWorkstations"},	{ LDAP_ATTR_USER_RID,		"rid"		},	{ LDAP_ATTR_PRIMARY_GROUP_RID,	"primaryGroupID"},	{ LDAP_ATTR_LMPW,		"lmPassword"	},	{ LDAP_ATTR_NTPW,		"ntPassword"	},	{ LDAP_ATTR_DOMAIN,		"domain"	},	{ LDAP_ATTR_ACB_INFO,		"acctFlags"	},	{ LDAP_ATTR_LIST_END,		NULL 		}};/* attributes used by Samba 3.0's sambaSamAccount */ATTRIB_MAP_ENTRY attrib_map_v30[] = {	{ LDAP_ATTR_UID,		"uid" 			},	{ LDAP_ATTR_UIDNUMBER,		LDAP_ATTRIBUTE_UIDNUMBER},	{ LDAP_ATTR_GIDNUMBER,		LDAP_ATTRIBUTE_GIDNUMBER},	{ LDAP_ATTR_UNIX_HOME,		"homeDirectory"		},	{ LDAP_ATTR_PWD_LAST_SET,	"sambaPwdLastSet"	},	{ LDAP_ATTR_PWD_CAN_CHANGE,	"sambaPwdCanChange"	},	{ LDAP_ATTR_PWD_MUST_CHANGE,	"sambaPwdMustChange"	},	{ LDAP_ATTR_LOGON_TIME,		"sambaLogonTime" 	},	{ LDAP_ATTR_LOGOFF_TIME,	"sambaLogoffTime"	},	{ LDAP_ATTR_KICKOFF_TIME,	"sambaKickoffTime"	},	{ LDAP_ATTR_CN,			"cn"			},	{ LDAP_ATTR_DISPLAY_NAME,	"displayName"		},	{ LDAP_ATTR_HOME_DRIVE,		"sambaHomeDrive"	},	{ LDAP_ATTR_HOME_PATH,		"sambaHomePath"		},	{ LDAP_ATTR_LOGON_SCRIPT,	"sambaLogonScript"	},	{ LDAP_ATTR_PROFILE_PATH,	"sambaProfilePath"	},	{ LDAP_ATTR_DESC,		"description"		},	{ LDAP_ATTR_USER_WKS,		"sambaUserWorkstations"	},	{ LDAP_ATTR_USER_SID,		LDAP_ATTRIBUTE_SID	},	{ LDAP_ATTR_PRIMARY_GROUP_SID,	"sambaPrimaryGroupSID"	},	{ LDAP_ATTR_LMPW,		"sambaLMPassword"	},	{ LDAP_ATTR_NTPW,		"sambaNTPassword"	},	{ LDAP_ATTR_DOMAIN,		"sambaDomainName"	},	{ LDAP_ATTR_OBJCLASS,		"objectClass"		},	{ LDAP_ATTR_ACB_INFO,		"sambaAcctFlags"	},	{ LDAP_ATTR_MUNGED_DIAL,	"sambaMungedDial"	},	{ LDAP_ATTR_BAD_PASSWORD_COUNT,	"sambaBadPasswordCount" },	{ LDAP_ATTR_BAD_PASSWORD_TIME,	"sambaBadPasswordTime" 	},	{ LDAP_ATTR_PWD_HISTORY,	"sambaPasswordHistory"  },	{ LDAP_ATTR_MOD_TIMESTAMP,	"modifyTimestamp"	},	{ LDAP_ATTR_LOGON_HOURS,	"sambaLogonHours"	},	{ LDAP_ATTR_LIST_END,		NULL 			}};ATTRIB_MAP_ENTRY attrib_map_to_delete_v30[] = {	{ LDAP_ATTR_PWD_LAST_SET,	"sambaPwdLastSet"	},	{ LDAP_ATTR_PWD_CAN_CHANGE,	"sambaPwdCanChange"	},	{ LDAP_ATTR_PWD_MUST_CHANGE,	"sambaPwdMustChange"	},	{ LDAP_ATTR_LOGON_TIME,		"sambaLogonTime" 	},	{ LDAP_ATTR_LOGOFF_TIME,	"sambaLogoffTime"	},	{ LDAP_ATTR_KICKOFF_TIME,	"sambaKickoffTime"	},	{ LDAP_ATTR_HOME_DRIVE,		"sambaHomeDrive"	},	{ LDAP_ATTR_HOME_PATH,		"sambaHomePath"		},	{ LDAP_ATTR_LOGON_SCRIPT,	"sambaLogonScript"	},	{ LDAP_ATTR_PROFILE_PATH,	"sambaProfilePath"	},	{ LDAP_ATTR_USER_WKS,		"sambaUserWorkstations"	},	{ LDAP_ATTR_USER_SID,		LDAP_ATTRIBUTE_SID	},	{ LDAP_ATTR_PRIMARY_GROUP_SID,	"sambaPrimaryGroupSID"	},	{ LDAP_ATTR_LMPW,		"sambaLMPassword"	},	{ LDAP_ATTR_NTPW,		"sambaNTPassword"	},	{ LDAP_ATTR_DOMAIN,		"sambaDomainName"	},	{ LDAP_ATTR_ACB_INFO,		"sambaAcctFlags"	},	{ LDAP_ATTR_MUNGED_DIAL,	"sambaMungedDial"	},	{ LDAP_ATTR_BAD_PASSWORD_COUNT,	"sambaBadPasswordCount" },	{ LDAP_ATTR_BAD_PASSWORD_TIME,	"sambaBadPasswordTime" 	},	{ LDAP_ATTR_PWD_HISTORY,	"sambaPasswordHistory"  },	{ LDAP_ATTR_LOGON_HOURS,	"sambaLogonHours"	},	{ LDAP_ATTR_LIST_END,		NULL 			}};/* attributes used for allocating RIDs */ATTRIB_MAP_ENTRY dominfo_attr_list[] = {	{ LDAP_ATTR_DOMAIN,		"sambaDomainName"	},	{ LDAP_ATTR_NEXT_RID,	        "sambaNextRid"	        },	{ LDAP_ATTR_NEXT_USERRID,	"sambaNextUserRid"	},	{ LDAP_ATTR_NEXT_GROUPRID,	"sambaNextGroupRid"	},	{ LDAP_ATTR_DOM_SID,		LDAP_ATTRIBUTE_SID	},	{ LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},	{ LDAP_ATTR_OBJCLASS,		"objectClass"		},	{ LDAP_ATTR_LIST_END,		NULL			},};/* Samba 3.0 group mapping attributes */ATTRIB_MAP_ENTRY groupmap_attr_list[] = {	{ LDAP_ATTR_GIDNUMBER,		LDAP_ATTRIBUTE_GIDNUMBER},	{ LDAP_ATTR_GROUP_SID,		LDAP_ATTRIBUTE_SID	},	{ LDAP_ATTR_GROUP_TYPE,		"sambaGroupType"	},	{ LDAP_ATTR_SID_LIST,		"sambaSIDList"		},	{ LDAP_ATTR_DESC,		"description"		},	{ LDAP_ATTR_DISPLAY_NAME,	"displayName"		},	{ LDAP_ATTR_CN,			"cn"			},	{ LDAP_ATTR_OBJCLASS,		"objectClass"		},	{ LDAP_ATTR_LIST_END,		NULL			}	};ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {	{ LDAP_ATTR_GROUP_SID,		LDAP_ATTRIBUTE_SID	},	{ LDAP_ATTR_GROUP_TYPE,		"sambaGroupType"	},	{ LDAP_ATTR_DESC,		"description"		},	{ LDAP_ATTR_DISPLAY_NAME,	"displayName"		},	{ LDAP_ATTR_SID_LIST,		"sambaSIDList"		},	{ LDAP_ATTR_LIST_END,		NULL			}	};/* idmap_ldap sambaUnixIdPool */ATTRIB_MAP_ENTRY idpool_attr_list[] = {	{ LDAP_ATTR_UIDNUMBER,		LDAP_ATTRIBUTE_UIDNUMBER},	{ LDAP_ATTR_GIDNUMBER,		LDAP_ATTRIBUTE_GIDNUMBER},	{ LDAP_ATTR_OBJCLASS,		"objectClass"		},	{ LDAP_ATTR_LIST_END,		NULL			}	};ATTRIB_MAP_ENTRY sidmap_attr_list[] = {	{ LDAP_ATTR_SID,		LDAP_ATTRIBUTE_SID	},	{ LDAP_ATTR_UIDNUMBER,		LDAP_ATTRIBUTE_UIDNUMBER},	{ LDAP_ATTR_GIDNUMBER,		LDAP_ATTRIBUTE_GIDNUMBER},	{ LDAP_ATTR_OBJCLASS,		"objectClass"		},	{ LDAP_ATTR_LIST_END,		NULL			}	};/********************************************************************** perform a simple table lookup and return the attribute name  **********************************************************************/  const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key ){	int i = 0;		while ( table[i].attrib != LDAP_ATTR_LIST_END ) {		if ( table[i].attrib == key )			return table[i].name;		i++;	}		return NULL;}/********************************************************************** Return the list of attribute names from a mapping table **********************************************************************/ const char** get_attr_list( ATTRIB_MAP_ENTRY table[] ){	const char **names;	int i = 0;		while ( table[i].attrib != LDAP_ATTR_LIST_END )		i++;	i++;	names = SMB_MALLOC_ARRAY( const char*, i );	if ( !names ) {		DEBUG(0,("get_attr_list: out of memory\n"));		return NULL;	}	i = 0;	while ( table[i].attrib != LDAP_ATTR_LIST_END ) {		names[i] = SMB_STRDUP( table[i].name );		i++;	}	names[i] = NULL;		return names;}/********************************************************************* Cleanup  ********************************************************************/ void free_attr_list( const char **list ){	int i = 0;	if ( !list )		return; 	while ( list[i] ) {		/* SAFE_FREE generates a warning here that can't be gotten rid		 * of with CONST_DISCARD */		if (list[i] != NULL) {			free(CONST_DISCARD(char *, list[i]));		}		i+=1;	}	SAFE_FREE( list );}/******************************************************************* Search an attribute and return the first value found.******************************************************************/ BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,				    const char *attribute, char *value,				    int max_len){	char **values;		if ( !attribute )		return False;			value[0] = '\0';	if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {		DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));				return False;	}		if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) {		DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n", 			  attribute, values[0]));		ldap_value_free(values);		return False;	}		ldap_value_free(values);#ifdef DEBUG_PASSWORDS	DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));#endif		return True;} BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,				  const char *attribute, pstring value){	return smbldap_get_single_attribute(ldap_struct, entry,					    attribute, value, 					    sizeof(pstring));}/************************************************************************ Routine to manage the LDAPMod structure array manage memory used by the array, by each struct, and values ***********************************************************************/ void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value){	LDAPMod **mods;	int i;	int j;	mods = *modlist;	/* sanity checks on the mod values */	if (attribute == NULL || *attribute == '\0') {		return;		}#if 0	/* commented out after discussion with abartlet.  Do not reenable.	   left here so other do not re-add similar code   --jerry */       	if (value == NULL || *value == '\0')		return;#endif	if (mods == NULL) {		mods = SMB_MALLOC_P(LDAPMod *);		if (mods == NULL) {			DEBUG(0, ("make_a_mod: out of memory!\n"));			return;		}		mods[0] = NULL;	}	for (i = 0; mods[i] != NULL; ++i) {		if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))			break;	}	if (mods[i] == NULL) {		mods = SMB_REALLOC_ARRAY (mods, LDAPMod *, i + 2);		if (mods == NULL) {			DEBUG(0, ("make_a_mod: out of memory!\n"));			return;		}		mods[i] = SMB_MALLOC_P(LDAPMod);		if (mods[i] == NULL) {			DEBUG(0, ("make_a_mod: out of memory!\n"));			return;		}		mods[i]->mod_op = modop;		mods[i]->mod_values = NULL;		mods[i]->mod_type = SMB_STRDUP(attribute);		mods[i + 1] = NULL;	}	if (value != NULL) {		char *utf8_value = NULL;		j = 0;		if (mods[i]->mod_values != NULL) {			for (; mods[i]->mod_values[j] != NULL; j++);		}		mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2);					       		if (mods[i]->mod_values == NULL) {			DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));			return;		}		if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {			DEBUG (0, ("make_a_mod: String conversion failure!\n"));			return;		}		mods[i]->mod_values[j] = utf8_value;		mods[i]->mod_values[j + 1] = NULL;	}	*modlist = mods;}/**********************************************************************  Set attribute to newval in LDAP, regardless of what value the  attribute had in LDAP before.*********************************************************************/ void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,		      LDAPMod ***mods,		      const char *attribute, const char *newval){	char oldval[2048]; /* current largest allowed value is mungeddial */	BOOL existed;	if (attribute == NULL) {		/* This can actually happen for ldapsam_compat where we for		 * example don't have a password history */		return;	}	if (existing != NULL) {		existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));	} else {		existed = False;		*oldval = '\0';	}	/* all of our string attributes are case insensitive */		if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {				/* Believe it or not, but LDAP will deny a delete and		   an add at the same time if the values are the		   same... */		DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute));		return;	}	if (existed) {		/* There has been no value before, so don't delete it.		 * Here's a possible race: We might end up with		 * duplicate attributes */		/* By deleting exactly the value we found in the entry this		 * should be race-free in the sense that the LDAP-Server will		 * deny the complete operation if somebody changed the		 * attribute behind our back. */		/* This will also allow modifying single valued attributes 		 * in Novell NDS. In NDS you have to first remove attribute and then		 * you could add new value */				DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval));		smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);	}	/* Regardless of the real operation (add or modify)	   we add the new value here. We rely on deleting	   the old value, should it exist. */	if ((newval != NULL) && (strlen(newval) > 0)) {		DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute, newval));		smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);	}}/********************************************************************** Some varients of the LDAP rebind code do not pass in the third 'arg'  pointer to a void*, so we try and work around it by assuming that the  value of the 'LDAP *' pointer is the same as the one we had passed in **********************************************************************/struct smbldap_state_lookup {	LDAP *ld;	struct smbldap_state *smbldap_state;	struct smbldap_state_lookup *prev, *next;};static struct smbldap_state_lookup *smbldap_state_lookup_list;static struct smbldap_state *smbldap_find_state(LDAP *ld) {	struct smbldap_state_lookup *t;	for (t = smbldap_state_lookup_list; t; t = t->next) {		if (t->ld == ld) {			return t->smbldap_state;		}	}	return NULL;}static void smbldap_delete_state(struct smbldap_state *smbldap_state) {	struct smbldap_state_lookup *t;	for (t = smbldap_state_lookup_list; t; t = t->next) {		if (t->smbldap_state == smbldap_state) {			DLIST_REMOVE(smbldap_state_lookup_list, t);			SAFE_FREE(t);			return;		}	}}static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) {	struct smbldap_state *tmp_ldap_state;	struct smbldap_state_lookup *t;	struct smbldap_state_lookup *tmp;		if ((tmp_ldap_state = smbldap_find_state(ld))) {		SMB_ASSERT(tmp_ldap_state == smbldap_state);		return;	}

⌨️ 快捷键说明

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