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 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, |