summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/docbook/manpages/smb.conf.5.sgml11
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/passdb/pdb_ldap.c156
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 f7216774a2..7aaa189578 100644
--- a/docs/docbook/manpages/smb.conf.5.sgml
+++ b/docs/docbook/manpages/smb.conf.5.sgml
@@ -656,6 +656,7 @@ alias|alias|alias|alias...
<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>
@@ -3435,8 +3436,14 @@ df $1 | tail -1 | awk '{print $2" "$4}'
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 d558b09d24..6baaafbd9c 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -230,6 +230,7 @@ typedef struct
BOOL ldap_trust_ids;
char *szAclCompat;
int ldap_passwd_sync;
+ BOOL ldap_del_only_sam;
BOOL bMsAddPrinterWizard;
BOOL bDNSproxy;
BOOL bWINSsupport;
@@ -1042,6 +1043,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},
@@ -1423,6 +1425,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:
@@ -1654,6 +1657,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 7b54a1d6e3..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,