diff options
| -rw-r--r-- | docs/docbook/manpages/smb.conf.5.sgml | 11 | ||||
| -rw-r--r-- | source3/param/loadparm.c | 4 | ||||
| -rw-r--r-- | source3/passdb/pdb_ldap.c | 156 | 
3 files changed, 110 insertions, 61 deletions
diff --git a/docs/docbook/manpages/smb.conf.5.sgml b/docs/docbook/manpages/smb.conf.5.sgml index fb3e51d5a8..08a23a22bd 100644 --- a/docs/docbook/manpages/smb.conf.5.sgml +++ b/docs/docbook/manpages/smb.conf.5.sgml @@ -657,6 +657,7 @@  		<listitem><para><link linkend="LARGEREADWRITE"><parameter>large readwrite</parameter></link></para></listitem>  		<listitem><para><link linkend="LDAPADMINDN"><parameter>ldap admin dn</parameter></link></para></listitem> +		<listitem><para><link linkend="LDAPDELONLYSAMATTR"><parameter>ldap del only sam attr</parameter></link></para></listitem>  		<listitem><para><link linkend="LDAPFILTER"><parameter>ldap filter</parameter></link></para></listitem>                  <listitem><para><link linkend="LDAPPORT"><parameter>ldap port</parameter></link></para></listitem>                  <listitem><para><link linkend="LDAPSERVER"><parameter>ldap server</parameter></link></para></listitem> @@ -3432,8 +3433,14 @@  		page for more information on how to accmplish this.  		</para> -		 -		<para>Default : <emphasis>none</emphasis></para> +		<varlistentry> +		<term><anchor id="LDAPDELONLYSAMATTR"/>ldap del only sam attr (G)</term> +		<listitem><para> This parameter specifies whether a delete +		operation in the ldapsam deletes only the Samba-specific +		attributes or the complete LDAP entry. +		</para> +	 +		<para>Default : <emphasis>ldap del only sam attr = yes</emphasis></para>  		</listitem>  		</varlistentry> diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 366ee13ec2..0c2eedf311 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -219,6 +219,7 @@ typedef struct  	BOOL ldap_trust_ids;  	char *szAclCompat;  	int ldap_passwd_sync;  +	BOOL ldap_del_only_sam;  	BOOL bMsAddPrinterWizard;  	BOOL bDNSproxy;  	BOOL bWINSsupport; @@ -1025,6 +1026,7 @@ static struct parm_struct parm_table[] = {  	{"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},  	{"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},  	{"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, +	{"ldap del only sam attr", P_BOOL, P_GLOBAL, &Globals.ldap_del_only_sam, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},  	{"Miscellaneous Options", P_SEP, P_SEPARATOR},  	{"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, @@ -1406,6 +1408,7 @@ static void init_globals(void)  	string_set(&Globals.szLdapAdminDn, "");  	Globals.ldap_ssl = LDAP_SSL_ON;  	Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF; +	Globals.ldap_del_only_sam = True;  /* these parameters are set to defaults that are more appropriate     for the increasing samba install base: @@ -1629,6 +1632,7 @@ FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)  FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)  FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)  FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids) +FN_GLOBAL_BOOL(lp_ldap_del_only_sam, &Globals.ldap_del_only_sam)  FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)  FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)  FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index fcb0234e98..2571ecd33a 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -847,6 +847,84 @@ static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, c  	*modlist = mods;  } +/******************************************************************* + Delete complete object or objectclass and attrs from + object found in search_result depending on lp_ldap_del_only_sam +******************************************************************/ +static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state, +				     LDAPMessage *result, +				     const char *objectclass, +				     const char **attrs) +{ +	int rc; +	LDAPMessage *entry; +	LDAPMod **mods = NULL; +	char *name, *dn; +	BerElement *ptr = NULL; + +	rc = ldap_count_entries(ldap_state->ldap_struct, result); + +	if (rc != 1) { +		DEBUG(0, ("Entry must exist exactly once!\n")); +		return NT_STATUS_UNSUCCESSFUL; +	} + +	entry = ldap_first_entry(ldap_state->ldap_struct, result); +	dn    = ldap_get_dn(ldap_state->ldap_struct, entry); + +	if (!lp_ldap_del_only_sam()) { +		NTSTATUS ret = NT_STATUS_OK; +		rc = ldapsam_delete(ldap_state, dn); + +		if (rc != LDAP_SUCCESS) { +			DEBUG(0, ("Could not delete object %s\n", dn)); +			ret = NT_STATUS_UNSUCCESSFUL; +		} +		ldap_memfree(dn); +		return ret; +	} + +	/* Ok, delete only the SAM attributes */ + +	for (name = ldap_first_attribute(ldap_state->ldap_struct, entry, &ptr); +	     name != NULL; +	     name = ldap_next_attribute(ldap_state->ldap_struct, entry, ptr)) { + +		const char **attrib; + +		/* We are only allowed to delete the attributes that +		   really exist. */ + +		for (attrib = attrs; *attrib != NULL; attrib++) { +			if (StrCaseCmp(*attrib, name) == 0) { +				DEBUG(10, ("deleting attribute %s\n", name)); +				make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL); +			} +		} + +		ldap_memfree(name); +	} + +	if (ptr != NULL) { +		ber_free(ptr, 0); +	} +	 +	make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass); + +	rc = ldapsam_modify(ldap_state, dn, mods); +	ldap_mods_free(mods, 1); + +	if (rc != LDAP_SUCCESS) { +		DEBUG(0, ("could not delete attributes for %s, error: %s\n", +			  dn, ldap_err2string(rc))); +		ldap_memfree(dn); +		return NT_STATUS_UNSUCCESSFUL; +	} + +	ldap_memfree(dn); +	return NT_STATUS_OK; +} +					    /* New Interface is being implemented here */  /********************************************************************** @@ -1772,9 +1850,13 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_A  	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;  	const char *sname;  	int rc; -	char *dn; -	LDAPMessage *entry;  	LDAPMessage *result; +	NTSTATUS ret; +	const char *sam_user_attrs[] = +	{ "lmPassword", "ntPassword", "pwdLastSet", "logonTime", "logoffTime", +	  "kickoffTime", "pwdCanChange", "pwdMustChange", "acctFlags", +	  "displayName", "smbHome", "homeDrive", "scriptPath", "profilePath", +	  "userWorkstations", "primaryGroupID", "domain", "rid", NULL };  	if (!sam_acct) {  		DEBUG(0, ("sam_acct was NULL!\n")); @@ -1790,30 +1872,10 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_A  		return NT_STATUS_NO_SUCH_USER;  	} -	if (ldap_count_entries (ldap_state->ldap_struct, result) == 0) { -		DEBUG (0, ("User doesn't exit!\n")); -		ldap_msgfree (result); -		return NT_STATUS_NO_SUCH_USER; -	} - -	entry = ldap_first_entry (ldap_state->ldap_struct, result); -	dn = ldap_get_dn (ldap_state->ldap_struct, entry); +	ret = ldapsam_delete_entry(ldap_state, result, "sambaAccount", +				   sam_user_attrs);  	ldap_msgfree(result); -	 -	rc = ldapsam_delete(ldap_state, dn); - -	ldap_memfree (dn); -	if (rc != LDAP_SUCCESS) { -		char *ld_error; -		ldap_get_option (ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); -		DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n", -			sname, ldap_err2string (rc), ld_error)); -		free (ld_error); -		return NT_STATUS_CANNOT_DELETE; -	} - -	DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname)); -	return NT_STATUS_OK; +	return ret;  }  /********************************************************************** @@ -2322,12 +2384,13 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,  	struct ldapsam_privates *ldap_state =  		(struct ldapsam_privates *)methods->private_data;  	pstring sidstring, filter; -	int rc; -	char *dn;  	LDAPMessage *result; -	LDAPMessage *entry; -	LDAPMod **mods; +	int rc; +	NTSTATUS ret; +	const char *sam_group_attrs[] = { "ntSid", "ntGroupType", +					  "description", "displayName", +					  NULL };  	sid_to_string(sidstring, &sid);  	snprintf(filter, sizeof(filter)-1,  		 "(&(objectClass=sambaGroupMapping)(ntSid=%s))", sidstring); @@ -2335,38 +2398,13 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,  	rc = ldapsam_search_one_group(ldap_state, filter, &result);  	if (rc != LDAP_SUCCESS) { -		return NT_STATUS_UNSUCCESSFUL; -	} - -	if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) { -		DEBUG(0, ("Group must exist exactly once\n")); -		ldap_msgfree(result); -		return NT_STATUS_UNSUCCESSFUL; -	} - -	entry = ldap_first_entry(ldap_state->ldap_struct, result); -	dn = ldap_get_dn(ldap_state->ldap_struct, entry); -        ldap_msgfree(result); - -	mods = NULL; -	make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", "sambaGroupMapping"); -	make_a_mod(&mods, LDAP_MOD_DELETE, "ntSid", NULL); -	make_a_mod(&mods, LDAP_MOD_DELETE, "ntGroupType", NULL); -	make_a_mod(&mods, LDAP_MOD_DELETE, "description", NULL); -	make_a_mod(&mods, LDAP_MOD_DELETE, "displayName", NULL); -	 -	rc = ldapsam_modify(ldap_state, dn, mods); - -	ldap_mods_free(mods, 1); - -	if (rc != LDAP_SUCCESS) { -		DEBUG(0, ("failed to delete group %s\n", sidstring)); -                return NT_STATUS_CANNOT_DELETE; +		return NT_STATUS_NO_SUCH_GROUP;  	} -	DEBUG(2, ("successfully delete group mapping %s in LDAP\n", -		  sidstring)); -	return NT_STATUS_OK; +	ret = ldapsam_delete_entry(ldap_state, result, "sambaGroupMapping", +				   sam_group_attrs); +	ldap_msgfree(result); +	return ret;  }  static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,  | 
