Fix bug 4901
[samba.git] / source / passdb / pdb_ldap.c
index 0c7efd3fb97deea7b4f71d9777a90f3a4f111831..d941abb00e68763279dda1dfb0a32e49c07f8581 100644 (file)
@@ -10,7 +10,7 @@
     
    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
     
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -19,8 +19,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
 */
 
    
 */
 
@@ -160,7 +159,8 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
 
 static const char* get_objclass_filter( int schema_ver )
 {
 
 static const char* get_objclass_filter( int schema_ver )
 {
-       static fstring objclass_filter;
+       fstring objclass_filter;
+       char *result;
        
        switch( schema_ver ) {
                case SCHEMAVER_SAMBAACCOUNT:
        
        switch( schema_ver ) {
                case SCHEMAVER_SAMBAACCOUNT:
@@ -171,10 +171,13 @@ static const char* get_objclass_filter( int schema_ver )
                        break;
                default:
                        DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
                        break;
                default:
                        DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
+                       objclass_filter[0] = '\0';
                        break;
        }
        
                        break;
        }
        
-       return objclass_filter; 
+       result = talloc_strdup(talloc_tos(), objclass_filter);
+       SMB_ASSERT(result != NULL);
+       return result;
 }
 
 /*****************************************************************
 }
 
 /*****************************************************************
@@ -190,8 +193,8 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
        TALLOC_CTX *mem_ctx;
        char **values = NULL;
        int rc, num_result, num_values, rid;
        TALLOC_CTX *mem_ctx;
        char **values = NULL;
        int rc, num_result, num_values, rid;
-       pstring suffix;
-       fstring tok;
+       char *suffix = NULL;
+       char *tok;
        const char *p;
        const char **attrs;
 
        const char *p;
        const char **attrs;
 
@@ -212,7 +215,7 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
                return ntstatus;
        }
 
                return ntstatus;
        }
 
-       if (!smbldap_has_naming_context(ldap_state->smbldap_state, lp_ldap_suffix())) {
+       if (!smbldap_has_naming_context(ldap_state->smbldap_state->ldap_struct, 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;
                DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
                         "as top-level namingContext\n", lp_ldap_suffix()));
                return ntstatus;
@@ -223,7 +226,10 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       attrs = TALLOC_ARRAY(mem_ctx, const char *, 2);
+       if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 2)) == NULL) {
+               ntstatus = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
 
        /* 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 we got a syncrepl-rid (up to three digits long) we speak with a consumer */
        rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
@@ -233,16 +239,25 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
                /* csn=20050126161620Z#0000001#00#00000 */
                attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
                attrs[1] = NULL;
                /* 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());
-
+               suffix = talloc_asprintf(mem_ctx,
+                               "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
+               if (!suffix) {
+                       ntstatus = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
        } else {
 
                /* provider contextCSN */
                /* 20050126161620Z#000009#00#000000 */
                attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
                attrs[1] = NULL;
        } 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());
+               suffix = talloc_asprintf(mem_ctx,
+                               "cn=ldapsync,%s", lp_ldap_suffix());
 
 
+               if (!suffix) {
+                       ntstatus = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
        }
 
        rc = smbldap_search(ldap_state->smbldap_state, suffix,
        }
 
        rc = smbldap_search(ldap_state->smbldap_state, suffix,
@@ -277,7 +292,7 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
        }
 
        p = values[0];
        }
 
        p = values[0];
-       if (!next_token(&p, tok, "#", sizeof(tok))) {
+       if (!next_token_talloc(mem_ctx, &p, &tok, "#")) {
                DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
                goto done;
        }
                DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
                goto done;
        }
@@ -314,13 +329,14 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
  Run the search by name.
 ******************************************************************/
 
  Run the search by name.
 ******************************************************************/
 
-int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, 
+int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
                                          const char *user,
                                          LDAPMessage ** result,
                                          const char **attr)
 {
                                          const char *user,
                                          LDAPMessage ** result,
                                          const char **attr)
 {
-       pstring filter;
+       char *filter = NULL;
        char *escape_user = escape_ldap_string_alloc(user);
        char *escape_user = escape_ldap_string_alloc(user);
+       int ret = -1;
 
        if (!escape_user) {
                return LDAP_NO_MEMORY;
 
        if (!escape_user) {
                return LDAP_NO_MEMORY;
@@ -330,37 +346,50 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
         * in the filter expression, replace %u with the real name
         * so in ldap filter, %u MUST exist :-)
         */
         * in the filter expression, replace %u with the real name
         * so in ldap filter, %u MUST exist :-)
         */
-       pstr_sprintf(filter, "(&%s%s)", "(uid=%u)", 
+       filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
                get_objclass_filter(ldap_state->schema_ver));
                get_objclass_filter(ldap_state->schema_ver));
-
-       /* 
+       if (!filter) {
+               SAFE_FREE(escape_user);
+               return LDAP_NO_MEMORY;
+       }
+       /*
         * have to use this here because $ is filtered out
         * have to use this here because $ is filtered out
-          * in pstring_sub
+        * in string_sub
         */
         */
-       
 
 
-       all_string_sub(filter, "%u", escape_user, sizeof(pstring));
+       filter = talloc_all_string_sub(talloc_tos(),
+                               filter, "%u", escape_user);
        SAFE_FREE(escape_user);
        SAFE_FREE(escape_user);
+       if (!filter) {
+               return LDAP_NO_MEMORY;
+       }
 
 
-       return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
+       ret = smbldap_search_suffix(ldap_state->smbldap_state,
+                       filter, attr, result);
+       TALLOC_FREE(filter);
+       return ret;
 }
 
 /*******************************************************************
  Run the search by rid.
 ******************************************************************/
 
 }
 
 /*******************************************************************
  Run the search by rid.
 ******************************************************************/
 
-static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state, 
-                                        uint32 rid, LDAPMessage ** result, 
+static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
+                                        uint32 rid, LDAPMessage ** result,
                                         const char **attr)
 {
                                         const char **attr)
 {
-       pstring filter;
+       char *filter = NULL;
        int rc;
 
        int rc;
 
-       pstr_sprintf(filter, "(&(rid=%i)%s)", rid, 
+       filter = talloc_asprintf(talloc_tos(), "(&(rid=%i)%s)", rid,
                get_objclass_filter(ldap_state->schema_ver));
                get_objclass_filter(ldap_state->schema_ver));
-       
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
-       
+       if (!filter) {
+               return LDAP_NO_MEMORY;
+       }
+
+       rc = smbldap_search_suffix(ldap_state->smbldap_state,
+                       filter, attr, result);
+       TALLOC_FREE(filter);
        return rc;
 }
 
        return rc;
 }
 
@@ -368,21 +397,27 @@ static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
  Run the search by SID.
 ******************************************************************/
 
  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)
+static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
+                                const DOM_SID *sid, LDAPMessage ** result,
+                                const char **attr)
 {
 {
-       pstring filter;
+       char *filter = NULL;
        int rc;
        fstring sid_string;
 
        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), 
+       filter = talloc_asprintf(talloc_tos(), "(&(%s=%s)%s)",
+               get_userattr_key2string(ldap_state->schema_ver,
+                       LDAP_ATTR_USER_SID),
+               sid_to_fstring(sid_string, sid),
                get_objclass_filter(ldap_state->schema_ver));
                get_objclass_filter(ldap_state->schema_ver));
-               
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
-       
+       if (!filter) {
+               return LDAP_NO_MEMORY;
+       }
+
+       rc = smbldap_search_suffix(ldap_state->smbldap_state,
+                       filter, attr, result);
+
+       TALLOC_FREE(filter);
        return rc;
 }
 
        return rc;
 }
 
@@ -435,24 +470,32 @@ static int ldapsam_delete_entry(struct ldapsam_privates *priv,
        if (ptr != NULL) {
                ber_free(ptr, 0);
        }
        if (ptr != NULL) {
                ber_free(ptr, 0);
        }
-       
+
        smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
        talloc_autofree_ldapmod(mem_ctx, mods);
        smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
        talloc_autofree_ldapmod(mem_ctx, mods);
-       
+
        return smbldap_modify(priv->smbldap_state, dn, mods);
 }
        return smbldap_modify(priv->smbldap_state, dn, mods);
 }
-                 
+
 static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
 {
 static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
 {
-       pstring temp;   
+       char *temp;
        struct tm tm;
 
        struct tm tm;
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
+       temp = smbldap_talloc_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
                        get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
                        get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
-                       temp))
+                       talloc_tos());
+       if (!temp) {
                return (time_t) 0;
                return (time_t) 0;
+       }
 
 
-       strptime(temp, "%Y%m%d%H%M%SZ", &tm);
+       if ( !strptime(temp, "%Y%m%d%H%M%SZ", &tm)) {
+               DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
+                       (char*)temp));
+               TALLOC_FREE(temp);
+               return (time_t) 0;
+       }
+       TALLOC_FREE(temp);
        tzset();
        return timegm(&tm);
 }
        tzset();
        return timegm(&tm);
 }
@@ -462,100 +505,104 @@ static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state,
  (Based on init_sam_from_buffer in pdb_tdb.c)
 *********************************************************************/
 
  (Based on init_sam_from_buffer in pdb_tdb.c)
 *********************************************************************/
 
-static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state, 
+static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                                struct samu * sampass,
                                LDAPMessage * entry)
 {
        time_t  logon_time,
                        logoff_time,
                        kickoff_time,
                                struct samu * sampass,
                                LDAPMessage * entry)
 {
        time_t  logon_time,
                        logoff_time,
                        kickoff_time,
-                       pass_last_set_time, 
-                       pass_can_change_time, 
+                       pass_last_set_time,
+                       pass_can_change_time,
                        pass_must_change_time,
                        ldap_entry_time,
                        bad_password_time;
                        pass_must_change_time,
                        ldap_entry_time,
                        bad_password_time;
-       pstring         username, 
-                       domain,
-                       nt_username,
-                       fullname,
-                       homedir,
-                       dir_drive,
-                       logon_script,
-                       profile_path,
-                       acct_desc,
-                       workstations;
-       char            munged_dial[2048];
-       uint32          user_rid; 
+       char *username = NULL,
+                       *domain = NULL,
+                       *nt_username = NULL,
+                       *fullname = NULL,
+                       *homedir = NULL,
+                       *dir_drive = NULL,
+                       *logon_script = NULL,
+                       *profile_path = NULL,
+                       *acct_desc = NULL,
+                       *workstations = NULL,
+                       *munged_dial = NULL;
+       uint32          user_rid;
        uint8           smblmpwd[LM_HASH_LEN],
                        smbntpwd[NT_HASH_LEN];
        uint8           smblmpwd[LM_HASH_LEN],
                        smbntpwd[NT_HASH_LEN];
-       BOOL            use_samba_attrs = True;
+       bool            use_samba_attrs = True;
        uint32          acct_ctrl = 0;
        uint16          logon_divs;
        uint32          acct_ctrl = 0;
        uint16          logon_divs;
-       uint16          bad_password_count = 0, 
+       uint16          bad_password_count = 0,
                        logon_count = 0;
        uint32 hours_len;
        uint8           hours[MAX_HOURS_LEN];
                        logon_count = 0;
        uint32 hours_len;
        uint8           hours[MAX_HOURS_LEN];
-       pstring temp;
+       char *temp = NULL;
        LOGIN_CACHE     *cache_entry = NULL;
        uint32          pwHistLen;
        LOGIN_CACHE     *cache_entry = NULL;
        uint32          pwHistLen;
-       pstring         tmpstring;
-       BOOL expand_explicit = lp_passdb_expand_explicit();
-
-       /*
-        * do a little initialization
-        */
-       username[0]     = '\0';
-       domain[0]       = '\0';
-       nt_username[0]  = '\0';
-       fullname[0]     = '\0';
-       homedir[0]      = '\0';
-       dir_drive[0]    = '\0';
-       logon_script[0] = '\0';
-       profile_path[0] = '\0';
-       acct_desc[0]    = '\0';
-       munged_dial[0]  = '\0';
-       workstations[0] = '\0';
-        
+       bool expand_explicit = lp_passdb_expand_explicit();
+       bool ret = false;
+       TALLOC_CTX *ctx = talloc_init("init_sam_from_ldap");
 
 
+       if (!ctx) {
+               return false;
+       }
        if (sampass == NULL || ldap_state == NULL || entry == NULL) {
                DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
        if (sampass == NULL || ldap_state == NULL || entry == NULL) {
                DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
-               return False;
+               goto fn_exit;
        }
 
        if (priv2ld(ldap_state) == NULL) {
                DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
                          "ldap_struct is NULL!\n"));
        }
 
        if (priv2ld(ldap_state) == NULL) {
                DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
                          "ldap_struct is NULL!\n"));
-               return False;
+               goto fn_exit;
        }
        }
-       
-       if (!smbldap_get_single_pstring(priv2ld(ldap_state), entry, "uid",
-                                       username)) {
+
+       if (!(username = smbldap_talloc_single_attribute(priv2ld(ldap_state),
+                                       entry,
+                                       "uid",
+                                       ctx))) {
                DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
                          "this user!\n"));
                DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
                          "this user!\n"));
-               return False;
+               goto fn_exit;
        }
 
        DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
 
        }
 
        DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
 
-       pstrcpy(nt_username, username);
+       nt_username = talloc_strdup(ctx, username);
+       if (!nt_username) {
+               goto fn_exit;
+       }
+
+       domain = talloc_strdup(ctx, ldap_state->domain_name);
+       if (!domain) {
+               goto fn_exit;
+       }
 
 
-       pstrcpy(domain, ldap_state->domain_name);
-       
        pdb_set_username(sampass, username, PDB_SET);
 
        pdb_set_domain(sampass, domain, PDB_DEFAULT);
        pdb_set_nt_username(sampass, nt_username, PDB_SET);
 
        /* deal with different attributes between the schema first */
        pdb_set_username(sampass, username, PDB_SET);
 
        pdb_set_domain(sampass, domain, PDB_DEFAULT);
        pdb_set_nt_username(sampass, nt_username, PDB_SET);
 
        /* deal with different attributes between the schema first */
-       
+
        if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
        if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
-               if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
+               if ((temp = smbldap_talloc_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_userattr_key2string(ldap_state->schema_ver,
+                                       LDAP_ATTR_USER_SID),
+                               ctx))!=NULL) {
                        pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
                }
        } else {
                        pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
                }
        } else {
-               if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
+               if ((temp = smbldap_talloc_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_userattr_key2string(ldap_state->schema_ver,
+                                       LDAP_ATTR_USER_RID),
+                               ctx))!=NULL) {
                        user_rid = (uint32)atol(temp);
                        pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
                }
                        user_rid = (uint32)atol(temp);
                        pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
                }
@@ -563,58 +610,81 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 
        if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
                DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n", 
 
        if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
                DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n", 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_USER_SID),
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_USER_RID),
                        username));
                return False;
        }
 
                        username));
                return False;
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) {
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_PWD_LAST_SET),
+                       ctx);
+       if (temp) {
                pass_last_set_time = (time_t) atol(temp);
                pass_last_set_time = (time_t) atol(temp);
-               pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
+               pdb_set_pass_last_set_time(sampass,
+                               pass_last_set_time, PDB_SET);
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) {
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_LOGON_TIME),
+                       ctx);
+       if (temp) {
                logon_time = (time_t) atol(temp);
                pdb_set_logon_time(sampass, logon_time, PDB_SET);
        }
 
                logon_time = (time_t) atol(temp);
                pdb_set_logon_time(sampass, logon_time, PDB_SET);
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) {
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_LOGOFF_TIME),
+                       ctx);
+       if (temp) {
                logoff_time = (time_t) atol(temp);
                pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
        }
 
                logoff_time = (time_t) atol(temp);
                pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) {
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_KICKOFF_TIME),
+                       ctx);
+       if (temp) {
                kickoff_time = (time_t) atol(temp);
                pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
        }
 
                kickoff_time = (time_t) atol(temp);
                pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) {
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_PWD_CAN_CHANGE),
+                       ctx);
+       if (temp) {
                pass_can_change_time = (time_t) atol(temp);
                pass_can_change_time = (time_t) atol(temp);
-               pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
+               pdb_set_pass_can_change_time(sampass,
+                               pass_can_change_time, PDB_SET);
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) {    
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_PWD_MUST_CHANGE),
+                       ctx);
+       if (temp) {
                pass_must_change_time = (time_t) atol(temp);
                pass_must_change_time = (time_t) atol(temp);
-               pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
+               pdb_set_pass_must_change_time(sampass,
+                               pass_must_change_time, PDB_SET);
        }
 
        /* recommend that 'gecos' and 'displayName' should refer to the same
        }
 
        /* recommend that 'gecos' and 'displayName' should refer to the same
@@ -623,95 +693,142 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
         * that fits your needs; using cn then displayName rather than 'userFullName'
         */
 
         * that fits your needs; using cn then displayName rather than 'userFullName'
         */
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) {
-               if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) {
-                       /* leave as default */
-               } else {
+       fullname = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_DISPLAY_NAME),
+                       ctx);
+       if (fullname) {
+               pdb_set_fullname(sampass, fullname, PDB_SET);
+       } else {
+               fullname = smbldap_talloc_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_userattr_key2string(ldap_state->schema_ver,
+                                       LDAP_ATTR_CN),
+                               ctx);
+               if (fullname) {
                        pdb_set_fullname(sampass, fullname, PDB_SET);
                }
                        pdb_set_fullname(sampass, fullname, PDB_SET);
                }
-       } else {
-               pdb_set_fullname(sampass, fullname, PDB_SET);
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive)) 
-       {
-               pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
-       } else {
+       dir_drive = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_HOME_DRIVE),
+                       ctx);
+       if (dir_drive) {
                pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
                pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
+       } else {
+               pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir)) 
-       {
-               pdb_set_homedir( sampass, 
-                       talloc_sub_basic(sampass, username, lp_logon_home()),
-                       PDB_DEFAULT );
-       } else {
-               pstrcpy( tmpstring, homedir );
+       homedir = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_HOME_PATH),
+                       ctx);
+       if (homedir) {
                if (expand_explicit) {
                if (expand_explicit) {
-                       standard_sub_basic( username, tmpstring,
-                                           sizeof(tmpstring) );
+                       homedir = talloc_sub_basic(ctx,
+                                               username,
+                                               domain,
+                                               homedir);
+                       if (!homedir) {
+                               goto fn_exit;
+                       }
                }
                }
-               pdb_set_homedir(sampass, tmpstring, PDB_SET);
-       }
-
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script)) 
-       {
-               pdb_set_logon_script( sampass, 
-                       talloc_sub_basic(sampass, username, lp_logon_script()), 
-                       PDB_DEFAULT );
+               pdb_set_homedir(sampass, homedir, PDB_SET);
        } else {
        } else {
-               pstrcpy( tmpstring, logon_script );
+               pdb_set_homedir(sampass,
+                       talloc_sub_basic(ctx, username, domain,
+                                        lp_logon_home()),
+                       PDB_DEFAULT);
+       }
+
+       logon_script = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_LOGON_SCRIPT),
+                       ctx);
+       if (logon_script) {
                if (expand_explicit) {
                if (expand_explicit) {
-                       standard_sub_basic( username, tmpstring,
-                                           sizeof(tmpstring) );
+                       logon_script = talloc_sub_basic(ctx,
+                                               username,
+                                               domain,
+                                               logon_script);
+                       if (!logon_script) {
+                               goto fn_exit;
+                       }
                }
                }
-               pdb_set_logon_script(sampass, tmpstring, PDB_SET);
+               pdb_set_logon_script(sampass, logon_script, PDB_SET);
+       } else {
+               pdb_set_logon_script(sampass,
+                       talloc_sub_basic(ctx, username, domain,
+                                        lp_logon_script()),
+                       PDB_DEFAULT );
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path)) 
-       {
-               pdb_set_profile_path( sampass, 
-                       talloc_sub_basic( sampass, username, lp_logon_path()),
-                       PDB_DEFAULT );
-       } else {
-               pstrcpy( tmpstring, profile_path );
+       profile_path = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_PROFILE_PATH),
+                       ctx);
+       if (profile_path) {
                if (expand_explicit) {
                if (expand_explicit) {
-                       standard_sub_basic( username, tmpstring,
-                                           sizeof(tmpstring) );
+                       profile_path = talloc_sub_basic(ctx,
+                                               username,
+                                               domain,
+                                               profile_path);
+                       if (!profile_path) {
+                               goto fn_exit;
+                       }
                }
                }
-               pdb_set_profile_path(sampass, tmpstring, PDB_SET);
+               pdb_set_profile_path(sampass, profile_path, PDB_SET);
+       } else {
+               pdb_set_profile_path(sampass,
+                       talloc_sub_basic(ctx, username, domain,
+                                         lp_logon_path()),
+                       PDB_DEFAULT );
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc)) 
-       {
-               /* leave as default */
-       } else {
+       acct_desc = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_DESC),
+                       ctx);
+       if (acct_desc) {
                pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
        }
 
                pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) {
-               /* leave as default */;
-       } else {
+       workstations = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_USER_WKS),
+                       ctx);
+       if (workstations) {
                pdb_set_workstations(sampass, workstations, PDB_SET);
        }
 
                pdb_set_workstations(sampass, workstations, PDB_SET);
        }
 
-       if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, 
-               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial, sizeof(munged_dial))) {
-               /* leave as default */;
-       } else {
+       munged_dial = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_MUNGED_DIAL),
+                       ctx);
+       if (munged_dial) {
                pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
        }
                pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
        }
-       
+
        /* FIXME: hours stuff should be cleaner */
        /* FIXME: hours stuff should be cleaner */
-       
+
        logon_divs = 168;
        hours_len = 21;
        memset(hours, 0xff, hours_len);
        logon_divs = 168;
        hours_len = 21;
        memset(hours, 0xff, hours_len);
@@ -720,7 +837,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                char *user_dn;
                size_t pwd_len;
                char clear_text_pw[512];
                char *user_dn;
                size_t pwd_len;
                char clear_text_pw[512];
-   
+
                /* Make call to Novell eDirectory ldap extension to get clear text password.
                        NOTE: This will only work if we have an SSL connection to eDirectory. */
                user_dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
                /* Make call to Novell eDirectory ldap extension to get clear text password.
                        NOTE: This will only work if we have an SSL connection to eDirectory. */
                user_dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
@@ -730,39 +847,54 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                        pwd_len = sizeof(clear_text_pw);
                        if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
                                nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
                        pwd_len = sizeof(clear_text_pw);
                        if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
                                nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
-                               if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
+                               if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
+                                       SAFE_FREE(user_dn);
                                        return False;
                                        return False;
+                               }
                                ZERO_STRUCT(smblmpwd);
                                ZERO_STRUCT(smblmpwd);
-                               if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
+                               if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
+                                       SAFE_FREE(user_dn);
                                        return False;
                                        return False;
+                               }
                                ZERO_STRUCT(smbntpwd);
                                use_samba_attrs = False;
                        }
                                ZERO_STRUCT(smbntpwd);
                                use_samba_attrs = False;
                        }
+
+                       SAFE_FREE(user_dn);
+
                } else {
                        DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
                }
        }
 
        if (use_samba_attrs) {
                } else {
                        DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
                }
        }
 
        if (use_samba_attrs) {
-               if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
-                       /* leave as default */
-               } else {
+               temp = smbldap_talloc_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_userattr_key2string(ldap_state->schema_ver,
+                                       LDAP_ATTR_LMPW),
+                               ctx);
+               if (temp) {
                        pdb_gethexpwd(temp, smblmpwd);
                        memset((char *)temp, '\0', strlen(temp)+1);
                        pdb_gethexpwd(temp, smblmpwd);
                        memset((char *)temp, '\0', strlen(temp)+1);
-                       if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
-                               return False;
+                       if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
+                               goto fn_exit;
+                       }
                        ZERO_STRUCT(smblmpwd);
                }
 
                        ZERO_STRUCT(smblmpwd);
                }
 
-               if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
-                       /* leave as default */
-               } else {
+               temp = smbldap_talloc_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_userattr_key2string(ldap_state->schema_ver,
+                                       LDAP_ATTR_NTPW),
+                               ctx);
+               if (temp) {
                        pdb_gethexpwd(temp, smbntpwd);
                        memset((char *)temp, '\0', strlen(temp)+1);
                        pdb_gethexpwd(temp, smbntpwd);
                        memset((char *)temp, '\0', strlen(temp)+1);
-                       if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
-                               return False;
+                       if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
+                               goto fn_exit;
+                       }
                        ZERO_STRUCT(smbntpwd);
                }
        }
                        ZERO_STRUCT(smbntpwd);
                }
        }
@@ -773,30 +905,42 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
        if (pwHistLen > 0){
                uint8 *pwhist = NULL;
                int i;
        if (pwHistLen > 0){
                uint8 *pwhist = NULL;
                int i;
+               char *history_string = TALLOC_ARRAY(ctx, char,
+                                               MAX_PW_HISTORY_LEN*64);
+
+               if (!history_string) {
+                       goto fn_exit;
+               }
 
 
-               /* We can only store (sizeof(pstring)-1)/64 password history entries. */
-               pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
+               pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
 
 
-               if ((pwhist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN)) == NULL){
-                       DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
-                       return False;
+               if ((pwhist = TALLOC_ARRAY(ctx, uint8,
+                                       pwHistLen * PW_HISTORY_ENTRY_LEN)) ==
+                               NULL){
+                       DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
+                       goto fn_exit;
                }
                memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
 
                }
                memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
 
-               if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), temp)) {
-                       /* leave as default - zeros */
-               } else {
-                       BOOL hex_failed = False;
+               if (smbldap_get_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_userattr_key2string(ldap_state->schema_ver,
+                                       LDAP_ATTR_PWD_HISTORY),
+                               history_string,
+                               MAX_PW_HISTORY_LEN*64)) {
+                       bool hex_failed = false;
                        for (i = 0; i < pwHistLen; i++){
                                /* Get the 16 byte salt. */
                        for (i = 0; i < pwHistLen; i++){
                                /* Get the 16 byte salt. */
-                               if (!pdb_gethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
-                                       hex_failed = True;
+                               if (!pdb_gethexpwd(&history_string[i*64],
+                                       &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
+                                       hex_failed = true;
                                        break;
                                }
                                /* Get the 16 byte MD5 hash of salt+passwd. */
                                        break;
                                }
                                /* Get the 16 byte MD5 hash of salt+passwd. */
-                               if (!pdb_gethexpwd(&temp[(i*64)+32],
-                                               &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN])) {
+                               if (!pdb_gethexpwd(&history_string[(i*64)+32],
+                                       &pwhist[(i*PW_HISTORY_ENTRY_LEN)+
+                                               PW_HISTORY_SALT_LEN])) {
                                        hex_failed = True;
                                        break;
                                }
                                        hex_failed = True;
                                        break;
                                }
@@ -808,58 +952,75 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                        }
                }
                if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
                        }
                }
                if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
-                       SAFE_FREE(pwhist);
-                       return False;
+                       goto fn_exit;
                }
                }
-               SAFE_FREE(pwhist);
        }
 
        }
 
-       if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
-               acct_ctrl |= ACB_NORMAL;
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_ACB_INFO),
+                       ctx);
+       if (temp) {
                acct_ctrl = pdb_decode_acct_ctrl(temp);
 
                acct_ctrl = pdb_decode_acct_ctrl(temp);
 
-               if (acct_ctrl == 0)
+               if (acct_ctrl == 0) {
                        acct_ctrl |= ACB_NORMAL;
                        acct_ctrl |= ACB_NORMAL;
+               }
 
                pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
 
                pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
+       } else {
+               acct_ctrl |= ACB_NORMAL;
        }
 
        pdb_set_hours_len(sampass, hours_len, PDB_SET);
        pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
 
        }
 
        pdb_set_hours_len(sampass, hours_len, PDB_SET);
        pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
-                       /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_BAD_PASSWORD_COUNT),
+                       ctx);
+       if (temp) {
                bad_password_count = (uint32) atol(temp);
                bad_password_count = (uint32) atol(temp);
-               pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
+               pdb_set_bad_password_count(sampass,
+                               bad_password_count, PDB_SET);
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) {
-               /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_BAD_PASSWORD_TIME),
+                       ctx);
+       if (temp) {
                bad_password_time = (time_t) atol(temp);
                pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
        }
 
 
                bad_password_time = (time_t) atol(temp);
                pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
        }
 
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) {
-                       /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_LOGON_COUNT),
+                       ctx);
+       if (temp) {
                logon_count = (uint32) atol(temp);
                pdb_set_logon_count(sampass, logon_count, PDB_SET);
        }
 
        /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
 
                logon_count = (uint32) atol(temp);
                pdb_set_logon_count(sampass, logon_count, PDB_SET);
        }
 
        /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
 
-       if(!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
-               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS), temp)) {
-                       /* leave as default */
-       } else {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_userattr_key2string(ldap_state->schema_ver,
+                               LDAP_ATTR_LOGON_HOURS),
+                       ctx);
+       if (temp) {
                pdb_gethexhours(temp, hours);
                memset((char *)temp, '\0', strlen(temp) +1);
                pdb_set_hours(sampass, hours, PDB_SET);
                pdb_gethexhours(temp, hours);
                memset((char *)temp, '\0', strlen(temp) +1);
                pdb_set_hours(sampass, hours, PDB_SET);
@@ -867,8 +1028,12 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
        }
 
        if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
        }
 
        if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
-               if (smbldap_get_single_pstring(priv2ld(ldap_state), entry,
-                                              "uidNumber", temp)) {
+               temp = smbldap_talloc_single_attribute(
+                               priv2ld(ldap_state),
+                               entry,
+                               "uidNumber",
+                               ctx);
+               if (temp) {
                        /* We've got a uid, feed the cache */
                        uid_t uid = strtoul(temp, NULL, 10);
                        store_uid_sid_cache(pdb_get_user_sid(sampass), uid);
                        /* We've got a uid, feed the cache */
                        uid_t uid = strtoul(temp, NULL, 10);
                        store_uid_sid_cache(pdb_get_user_sid(sampass), uid);
@@ -876,43 +1041,52 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
        }
 
        /* check the timestamp of the cache vs ldap entry */
        }
 
        /* check the timestamp of the cache vs ldap entry */
-       if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state, 
-                                                           entry)))
-               return True;
+       if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
+                                                           entry))) {
+               ret = true;
+               goto fn_exit;
+       }
 
        /* see if we have newer updates */
        if (!(cache_entry = login_cache_read(sampass))) {
                DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
                           (unsigned int)pdb_get_bad_password_count(sampass),
                           (unsigned int)pdb_get_bad_password_time(sampass)));
 
        /* see if we have newer updates */
        if (!(cache_entry = login_cache_read(sampass))) {
                DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
                           (unsigned int)pdb_get_bad_password_count(sampass),
                           (unsigned int)pdb_get_bad_password_time(sampass)));
-               return True;
+               ret = true;
+               goto fn_exit;
        }
 
        }
 
-       DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n", 
-                 (unsigned int)ldap_entry_time, (unsigned int)cache_entry->entry_timestamp, 
+       DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
+                 (unsigned int)ldap_entry_time,
+                 (unsigned int)cache_entry->entry_timestamp,
                  (unsigned int)cache_entry->bad_password_time));
 
        if (ldap_entry_time > cache_entry->entry_timestamp) {
                /* cache is older than directory , so
                  (unsigned int)cache_entry->bad_password_time));
 
        if (ldap_entry_time > cache_entry->entry_timestamp) {
                /* cache is older than directory , so
-                  we need to delete the entry but allow the 
+                  we need to delete the entry but allow the
                   fields to be written out */
                login_cache_delentry(sampass);
        } else {
                /* read cache in */
                   fields to be written out */
                login_cache_delentry(sampass);
        } else {
                /* read cache in */
-               pdb_set_acct_ctrl(sampass, 
-                                 pdb_get_acct_ctrl(sampass) | 
+               pdb_set_acct_ctrl(sampass,
+                                 pdb_get_acct_ctrl(sampass) |
                                  (cache_entry->acct_ctrl & ACB_AUTOLOCK),
                                  PDB_SET);
                                  (cache_entry->acct_ctrl & ACB_AUTOLOCK),
                                  PDB_SET);
-               pdb_set_bad_password_count(sampass, 
-                                          cache_entry->bad_password_count, 
+               pdb_set_bad_password_count(sampass,
+                                          cache_entry->bad_password_count,
                                           PDB_SET);
                                           PDB_SET);
-               pdb_set_bad_password_time(sampass, 
-                                         cache_entry->bad_password_time, 
+               pdb_set_bad_password_time(sampass,
+                                         cache_entry->bad_password_time,
                                          PDB_SET);
        }
 
                                          PDB_SET);
        }
 
+       ret = true;
+
+  fn_exit:
+
+       TALLOC_FREE(ctx);
        SAFE_FREE(cache_entry);
        SAFE_FREE(cache_entry);
-       return True;
+       return ret;
 }
 
 /**********************************************************************
 }
 
 /**********************************************************************
@@ -920,13 +1094,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
  (Based on init_buffer_from_sam in pdb_tdb.c)
 *********************************************************************/
 
  (Based on init_buffer_from_sam in pdb_tdb.c)
 *********************************************************************/
 
-static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, 
+static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                                LDAPMessage *existing,
                                LDAPMod *** mods, struct samu * sampass,
                                LDAPMessage *existing,
                                LDAPMod *** mods, struct samu * sampass,
-                               BOOL (*need_update)(const struct samu *,
+                               bool (*need_update)(const struct samu *,
                                                    enum pdb_elements))
 {
                                                    enum pdb_elements))
 {
-       pstring temp;
+       char *temp = NULL;
        uint32 rid;
 
        if (mods == NULL || sampass == NULL) {
        uint32 rid;
 
        if (mods == NULL || sampass == NULL) {
@@ -936,46 +1110,56 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
 
        *mods = NULL;
 
 
        *mods = NULL;
 
-       /* 
+       /*
         * took out adding "objectclass: sambaAccount"
         * do this on a per-mod basis
         */
         * took out adding "objectclass: sambaAccount"
         * do this on a per-mod basis
         */
-       if (need_update(sampass, PDB_USERNAME))
+       if (need_update(sampass, PDB_USERNAME)) {
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, 
                              "uid", pdb_get_username(sampass));
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, 
                              "uid", pdb_get_username(sampass));
+               if (ldap_state->is_nds_ldap) {
+                       smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, 
+                                     "cn", pdb_get_username(sampass));
+                       smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, 
+                                     "sn", pdb_get_username(sampass));
+               }
+       }
 
        DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
 
        /* only update the RID if we actually need to */
        if (need_update(sampass, PDB_USERSID)) {
                fstring sid_string;
 
        DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
 
        /* only update the RID if we actually need to */
        if (need_update(sampass, PDB_USERSID)) {
                fstring sid_string;
-               fstring dom_sid_string;
                const DOM_SID *user_sid = pdb_get_user_sid(sampass);
                const DOM_SID *user_sid = pdb_get_user_sid(sampass);
-               
+
                switch ( ldap_state->schema_ver ) {
                        case SCHEMAVER_SAMBAACCOUNT:
                                if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
                                        DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n", 
                switch ( ldap_state->schema_ver ) {
                        case SCHEMAVER_SAMBAACCOUNT:
                                if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
                                        DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n", 
-                                               sid_to_string(sid_string, user_sid), 
-                                               sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
+                                                 sid_string_dbg(user_sid),
+                                                 sid_string_dbg(
+                                                         &ldap_state->domain_sid)));
                                        return False;
                                }
                                        return False;
                                }
-                               slprintf(temp, sizeof(temp) - 1, "%i", rid);
+                               if (asprintf(&temp, "%i", rid) < 0) {
+                                       return false;
+                               }
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), 
                                        temp);
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), 
                                        temp);
+                               SAFE_FREE(temp);
                                break;
                                break;
-                               
+
                        case SCHEMAVER_SAMBASAMACCOUNT:
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), 
                        case SCHEMAVER_SAMBASAMACCOUNT:
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), 
-                                       sid_to_string(sid_string, user_sid));                                 
+                                       sid_to_fstring(sid_string, user_sid));
                                break;
                                break;
-                               
+
                        default:
                                DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
                                break;
                        default:
                                DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
                                break;
-               }               
+               }
        }
 
        /* we don't need to store the primary group RID - so leaving it
        }
 
        /* we don't need to store the primary group RID - so leaving it
@@ -983,40 +1167,43 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
 
        if (need_update(sampass, PDB_GROUPSID)) {
                fstring sid_string;
 
        if (need_update(sampass, PDB_GROUPSID)) {
                fstring sid_string;
-               fstring dom_sid_string;
                const DOM_SID *group_sid = pdb_get_group_sid(sampass);
                const DOM_SID *group_sid = pdb_get_group_sid(sampass);
-               
+
                switch ( ldap_state->schema_ver ) {
                        case SCHEMAVER_SAMBAACCOUNT:
                                if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
                                        DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
                switch ( ldap_state->schema_ver ) {
                        case SCHEMAVER_SAMBAACCOUNT:
                                if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
                                        DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
-                                               sid_to_string(sid_string, group_sid),
-                                               sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
+                                                 sid_string_dbg(group_sid),
+                                                 sid_string_dbg(
+                                                         &ldap_state->domain_sid)));
                                        return False;
                                }
 
                                        return False;
                                }
 
-                               slprintf(temp, sizeof(temp) - 1, "%i", rid);
+                               if (asprintf(&temp, "%i", rid) < 0) {
+                                       return false;
+                               }
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, 
                                        LDAP_ATTR_PRIMARY_GROUP_RID), temp);
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, 
                                        LDAP_ATTR_PRIMARY_GROUP_RID), temp);
+                               SAFE_FREE(temp);
                                break;
                                break;
-                               
+
                        case SCHEMAVER_SAMBASAMACCOUNT:
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, 
                        case SCHEMAVER_SAMBASAMACCOUNT:
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                        get_userattr_key2string(ldap_state->schema_ver, 
-                                       LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
+                                       LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_fstring(sid_string, group_sid));
                                break;
                                break;
-                               
+
                        default:
                                DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
                                break;
                }
                        default:
                                DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
                                break;
                }
-               
+
        }
        }
-       
+
        /* displayName, cn, and gecos should all be the same
         *  most easily accomplished by giving them the same OID
        /* displayName, cn, and gecos should all be the same
         *  most easily accomplished by giving them the same OID
-        *  gecos isn't set here b/c it should be handled by the 
+        *  gecos isn't set here b/c it should be handled by the
         *  add-user script
         *  We change displayName only and fall back to cn if
         *  it does not exist.
         *  add-user script
         *  We change displayName only and fall back to cn if
         *  it does not exist.
@@ -1036,17 +1223,17 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), 
                        pdb_get_workstations(sampass));
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), 
                        pdb_get_workstations(sampass));
-       
+
        if (need_update(sampass, PDB_MUNGEDDIAL))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), 
                        pdb_get_munged_dial(sampass));
        if (need_update(sampass, PDB_MUNGEDDIAL))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), 
                        pdb_get_munged_dial(sampass));
-       
+
        if (need_update(sampass, PDB_SMBHOME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), 
                        pdb_get_homedir(sampass));
        if (need_update(sampass, PDB_SMBHOME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), 
                        pdb_get_homedir(sampass));
-                       
+
        if (need_update(sampass, PDB_DRIVE))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), 
        if (need_update(sampass, PDB_DRIVE))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), 
@@ -1062,43 +1249,58 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), 
                        pdb_get_profile_path(sampass));
 
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), 
                        pdb_get_profile_path(sampass));
 
-       slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
+       if (asprintf(&temp, "%li", pdb_get_logon_time(sampass)) < 0) {
+               return false;
+       }
        if (need_update(sampass, PDB_LOGONTIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
        if (need_update(sampass, PDB_LOGONTIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
+       SAFE_FREE(temp);
 
 
-       slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
+       if (asprintf(&temp, "%li", pdb_get_logoff_time(sampass)) < 0) {
+               return false;
+       }
        if (need_update(sampass, PDB_LOGOFFTIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
        if (need_update(sampass, PDB_LOGOFFTIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
+       SAFE_FREE(temp);
 
 
-       slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
+       if (asprintf(&temp, "%li", pdb_get_kickoff_time(sampass)) < 0) {
+               return false;
+       }
        if (need_update(sampass, PDB_KICKOFFTIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
        if (need_update(sampass, PDB_KICKOFFTIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
+       SAFE_FREE(temp);
 
 
-       slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
+       if (asprintf(&temp, "%li", pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
+               return false;
+       }
        if (need_update(sampass, PDB_CANCHANGETIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
        if (need_update(sampass, PDB_CANCHANGETIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
+       SAFE_FREE(temp);
 
 
-       slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
+       if (asprintf(&temp, "%li", pdb_get_pass_must_change_time(sampass)) < 0) {
+               return false;
+       }
        if (need_update(sampass, PDB_MUSTCHANGETIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
        if (need_update(sampass, PDB_MUSTCHANGETIME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
-
+       SAFE_FREE(temp);
 
        if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
                        || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
 
                if (need_update(sampass, PDB_LMPASSWD)) {
 
        if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
                        || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
 
                if (need_update(sampass, PDB_LMPASSWD)) {
-                       const uchar *lm_pw =  pdb_get_lanman_passwd(sampass);
+                       const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
                        if (lm_pw) {
                        if (lm_pw) {
-                               pdb_sethexpwd(temp, lm_pw,
+                               char pwstr[34];
+                               pdb_sethexpwd(pwstr, lm_pw,
                                              pdb_get_acct_ctrl(sampass));
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), 
                                              pdb_get_acct_ctrl(sampass));
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), 
-                                                temp);
+                                                pwstr);
                        } else {
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), 
                        } else {
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), 
@@ -1106,13 +1308,14 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                        }
                }
                if (need_update(sampass, PDB_NTPASSWD)) {
                        }
                }
                if (need_update(sampass, PDB_NTPASSWD)) {
-                       const uchar *nt_pw =  pdb_get_nt_passwd(sampass);
+                       const uchar *nt_pw = pdb_get_nt_passwd(sampass);
                        if (nt_pw) {
                        if (nt_pw) {
-                               pdb_sethexpwd(temp, nt_pw,
+                               char pwstr[34];
+                               pdb_sethexpwd(pwstr, nt_pw,
                                              pdb_get_acct_ctrl(sampass));
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), 
                                              pdb_get_acct_ctrl(sampass));
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), 
-                                                temp);
+                                                pwstr);
                        } else {
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), 
                        } else {
                                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), 
@@ -1121,52 +1324,64 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                }
 
                if (need_update(sampass, PDB_PWHISTORY)) {
                }
 
                if (need_update(sampass, PDB_PWHISTORY)) {
+                       char *pwstr = NULL;
                        uint32 pwHistLen = 0;
                        pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
                        uint32 pwHistLen = 0;
                        pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+
+                       pwstr = SMB_MALLOC_ARRAY(char, 1024);
+                       if (!pwstr) {
+                               return false;
+                       }
                        if (pwHistLen == 0) {
                                /* Remove any password history from the LDAP store. */
                        if (pwHistLen == 0) {
                                /* Remove any password history from the LDAP store. */
-                               memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
-                               temp[64] = '\0';
+                               memset(pwstr, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
+                               pwstr[64] = '\0';
                        } else {
                        } else {
-                               int i; 
+                               int i;
                                uint32 currHistLen = 0;
                                const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
                                if (pwhist != NULL) {
                                uint32 currHistLen = 0;
                                const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
                                if (pwhist != NULL) {
-                                       /* We can only store (sizeof(pstring)-1)/64 password history entries. */
-                                       pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
+                                       /* We can only store (1024-1/64 password history entries. */
+                                       pwHistLen = MIN(pwHistLen, ((1024-1)/64));
                                        for (i=0; i< pwHistLen && i < currHistLen; i++) {
                                                /* Store the salt. */
                                        for (i=0; i< pwHistLen && i < currHistLen; i++) {
                                                /* Store the salt. */
-                                               pdb_sethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
+                                               pdb_sethexpwd(&pwstr[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
                                                /* Followed by the md5 hash of salt + md4 hash */
                                                /* Followed by the md5 hash of salt + md4 hash */
-                                               pdb_sethexpwd(&temp[(i*64)+32],
+                                               pdb_sethexpwd(&pwstr[(i*64)+32],
                                                        &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
                                                        &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
-                                               DEBUG(100, ("temp=%s\n", temp));
+                                               DEBUG(100, ("pwstr=%s\n", pwstr));
                                        }
                                        }
-                               } 
+                               }
                        }
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), 
                        }
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), 
-                                        temp);
+                                        pwstr);
+                       SAFE_FREE(pwstr);
                }
 
                if (need_update(sampass, PDB_PASSLASTSET)) {
                }
 
                if (need_update(sampass, PDB_PASSLASTSET)) {
-                       slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
+                       if (asprintf(&temp, "%li",
+                               pdb_get_pass_last_set_time(sampass)) < 0) {
+                               return false;
+                       }
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), 
                                temp);
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                                get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), 
                                temp);
+                       SAFE_FREE(temp);
                }
        }
 
        if (need_update(sampass, PDB_HOURS)) {
                const uint8 *hours = pdb_get_hours(sampass);
                if (hours) {
                }
        }
 
        if (need_update(sampass, PDB_HOURS)) {
                const uint8 *hours = pdb_get_hours(sampass);
                if (hours) {
-                       pdb_sethexhours(temp, hours);
+                       char hourstr[44];
+                       pdb_sethexhours(hourstr, hours);
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
                                existing,
                                mods,
                                get_userattr_key2string(ldap_state->schema_ver,
                                                LDAP_ATTR_LOGON_HOURS),
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
                                existing,
                                mods,
                                get_userattr_key2string(ldap_state->schema_ver,
                                                LDAP_ATTR_LOGON_HOURS),
-                               temp);
+                               hourstr);
                }
        }
 
                }
        }
 
@@ -1175,7 +1390,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), 
                        pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
 
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), 
                        pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
 
-       /* password lockout cache: 
+       /* password lockout cache:
           - If we are now autolocking or clearing, we write to ldap
           - If we are clearing, we delete the cache entry
           - If the count is > 0, we update the cache
           - If we are now autolocking or clearing, we write to ldap
           - If we are clearing, we delete the cache entry
           - If the count is > 0, we update the cache
@@ -1196,23 +1411,29 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                if ((badcount >= pol) || (badcount == 0)) {
                        DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
                                (unsigned int)badcount, (unsigned int)badtime));
                if ((badcount >= pol) || (badcount == 0)) {
                        DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
                                (unsigned int)badcount, (unsigned int)badtime));
-                       slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount);
+                       if (asprintf(&temp, "%li", (long)badcount) < 0) {
+                               return false;
+                       }
                        smbldap_make_mod(
                                ldap_state->smbldap_state->ldap_struct,
                        smbldap_make_mod(
                                ldap_state->smbldap_state->ldap_struct,
-                               existing, mods, 
+                               existing, mods,
                                get_userattr_key2string(
                                get_userattr_key2string(
-                                       ldap_state->schema_ver, 
+                                       ldap_state->schema_ver,
                                        LDAP_ATTR_BAD_PASSWORD_COUNT),
                                temp);
                                        LDAP_ATTR_BAD_PASSWORD_COUNT),
                                temp);
+                       SAFE_FREE(temp);
 
 
-                       slprintf (temp, sizeof (temp) - 1, "%li", badtime);
+                       if (asprintf(&temp, "%li", badtime) < 0) {
+                               return false;
+                       }
                        smbldap_make_mod(
                        smbldap_make_mod(
-                               ldap_state->smbldap_state->ldap_struct, 
+                               ldap_state->smbldap_state->ldap_struct,
                                existing, mods,
                                get_userattr_key2string(
                                existing, mods,
                                get_userattr_key2string(
-                                       ldap_state->schema_ver, 
-                                       LDAP_ATTR_BAD_PASSWORD_TIME), 
+                                       ldap_state->schema_ver,
+                                       LDAP_ATTR_BAD_PASSWORD_TIME),
                                temp);
                                temp);
+                       SAFE_FREE(temp);
                }
                if (badcount == 0) {
                        DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
                }
                if (badcount == 0) {
                        DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
@@ -1233,60 +1454,6 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
        return True;
 }
 
        return True;
 }
 
-/**********************************************************************
- Connect to LDAP server for password enumeration.
-*********************************************************************/
-
-static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
-{
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
-       int rc;
-       pstring filter, suffix;
-       const char **attr_list;
-       BOOL machine_mask = False, user_mask = False;
-
-       pstr_sprintf( filter, "(&%s%s)", "(uid=%u)", 
-               get_objclass_filter(ldap_state->schema_ver));
-       all_string_sub(filter, "%u", "*", sizeof(pstring));
-
-       machine_mask    = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
-       user_mask       = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
-
-       if (machine_mask) {
-               pstrcpy(suffix, lp_ldap_machine_suffix());
-       } else if (user_mask) {
-               pstrcpy(suffix, lp_ldap_user_suffix());
-       } else {
-               pstrcpy(suffix, lp_ldap_suffix());
-       }
-
-       DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n", 
-               acb_mask, suffix));
-
-       attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
-       rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, 
-                           attr_list, 0, &ldap_state->result);
-       TALLOC_FREE( attr_list );
-
-       if (rc != LDAP_SUCCESS) {
-               DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
-               DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
-               ldap_msgfree(ldap_state->result);
-               ldap_state->result = NULL;
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
-               ldap_count_entries(ldap_state->smbldap_state->ldap_struct, 
-               ldap_state->result), suffix));
-
-       ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
-                                ldap_state->result);
-       ldap_state->index = 0;
-
-       return NT_STATUS_OK;
-}
-
 /**********************************************************************
  End enumeration of the LDAP password list.
 *********************************************************************/
 /**********************************************************************
  End enumeration of the LDAP password list.
 *********************************************************************/
@@ -1300,32 +1467,6 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods)
        }
 }
 
        }
 }
 
-/**********************************************************************
-Get the next entry in the LDAP password database.
-*********************************************************************/
-
-static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods,
-                                   struct samu *user)
-{
-       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       struct ldapsam_privates *ldap_state =
-               (struct ldapsam_privates *)my_methods->private_data;
-       BOOL bret = False;
-
-       while (!bret) {
-               if (!ldap_state->entry)
-                       return ret;
-               
-               ldap_state->index++;
-               bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
-               
-               ldap_state->entry = ldap_next_entry(priv2ld(ldap_state),
-                                                   ldap_state->entry); 
-       }
-
-       return NT_STATUS_OK;
-}
-
 static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
                        const char *new_attr)
 {
 static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
                        const char *new_attr)
 {
@@ -1459,7 +1600,6 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu
        LDAPMessage *entry = NULL;
        int count;
        int rc;
        LDAPMessage *entry = NULL;
        int count;
        int rc;
-       fstring sid_string;
 
        rc = ldapsam_get_ldap_user_by_sid(ldap_state, 
                                          sid, &result); 
 
        rc = ldapsam_get_ldap_user_by_sid(ldap_state, 
                                          sid, &result); 
@@ -1469,13 +1609,14 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu
        count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
        
        if (count < 1) {
        count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
        
        if (count < 1) {
-               DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
-                      count));
+               DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
+                         "count=%d\n", sid_string_dbg(sid), count));
                ldap_msgfree(result);
                return NT_STATUS_NO_SUCH_USER;
        }  else if (count > 1) {
                ldap_msgfree(result);
                return NT_STATUS_NO_SUCH_USER;
        }  else if (count > 1) {
-               DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
-                      count));
+               DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID "
+                         "[%s]. Failing. count=%d\n", sid_string_dbg(sid),
+                         count));
                ldap_msgfree(result);
                return NT_STATUS_NO_SUCH_USER;
        }
                ldap_msgfree(result);
                return NT_STATUS_NO_SUCH_USER;
        }
@@ -1498,11 +1639,6 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu
        return NT_STATUS_OK;
 }      
 
        return NT_STATUS_OK;
 }      
 
-static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state)
-{
-       return smbldap_has_extension(ldap_state, LDAP_EXOP_MODIFY_PASSWD);
-}
-
 /********************************************************************
  Do the actual modification - also change a plaintext passord if 
  it it set.
 /********************************************************************
  Do the actual modification - also change a plaintext passord if 
  it it set.
@@ -1511,12 +1647,12 @@ static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state)
 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, 
                                     struct samu *newpwd, char *dn,
                                     LDAPMod **mods, int ldap_op, 
 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, 
                                     struct samu *newpwd, char *dn,
                                     LDAPMod **mods, int ldap_op, 
-                                    BOOL (*need_update)(const struct samu *, enum pdb_elements))
+                                    bool (*need_update)(const struct samu *, enum pdb_elements))
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        int rc;
        
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        int rc;
        
-       if (!my_methods || !newpwd || !dn) {
+       if (!newpwd || !dn) {
                return NT_STATUS_INVALID_PARAMETER;
        }
        
                return NT_STATUS_INVALID_PARAMETER;
        }
        
@@ -1525,10 +1661,16 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                /* may be password change below however */
        } else {
                switch(ldap_op) {
                /* may be password change below however */
        } else {
                switch(ldap_op) {
-                       case LDAP_MOD_ADD: 
-                               smbldap_set_mod(&mods, LDAP_MOD_ADD, 
-                                               "objectclass", 
-                                               LDAP_OBJ_ACCOUNT);
+                       case LDAP_MOD_ADD:
+                               if (ldap_state->is_nds_ldap) {
+                                       smbldap_set_mod(&mods, LDAP_MOD_ADD, 
+                                                       "objectclass", 
+                                                       "inetOrgPerson");
+                               } else {
+                                       smbldap_set_mod(&mods, LDAP_MOD_ADD, 
+                                                       "objectclass", 
+                                                       LDAP_OBJ_ACCOUNT);
+                               }
                                rc = smbldap_add(ldap_state->smbldap_state, 
                                                 dn, mods);
                                break;
                                rc = smbldap_add(ldap_state->smbldap_state, 
                                                 dn, mods);
                                break;
@@ -1559,7 +1701,9 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                char *utf8_dn;
 
                if (!ldap_state->is_nds_ldap) {
                char *utf8_dn;
 
                if (!ldap_state->is_nds_ldap) {
-                       if (!ldapsam_can_pwchange_exop(ldap_state->smbldap_state)) {
+
+                       if (!smbldap_has_extension(ldap_state->smbldap_state->ldap_struct, 
+                                                  LDAP_EXOP_MODIFY_PASSWD)) {
                                DEBUG(2, ("ldap password change requested, but LDAP "
                                          "server does not support it -- ignoring\n"));
                                return NT_STATUS_OK;
                                DEBUG(2, ("ldap password change requested, but LDAP "
                                          "server does not support it -- ignoring\n"));
                                return NT_STATUS_OK;
@@ -1571,19 +1715,21 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                }
 
                if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
                }
 
                if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+                       SAFE_FREE(utf8_password);
                        return NT_STATUS_NO_MEMORY;
                }
 
                if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
                        DEBUG(0,("ber_alloc_t returns NULL\n"));
                        SAFE_FREE(utf8_password);
                        return NT_STATUS_NO_MEMORY;
                }
 
                if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
                        DEBUG(0,("ber_alloc_t returns NULL\n"));
                        SAFE_FREE(utf8_password);
+                       SAFE_FREE(utf8_dn);
                        return NT_STATUS_UNSUCCESSFUL;
                }
 
                ber_printf (ber, "{");
                ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
                ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
                        return NT_STATUS_UNSUCCESSFUL;
                }
 
                ber_printf (ber, "{");
                ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
                ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
-               ber_printf (ber, "N}");
+               ber_printf (ber, "n}");
 
                if ((rc = ber_flatten (ber, &bv))<0) {
                        DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
 
                if ((rc = ber_flatten (ber, &bv))<0) {
                        DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
@@ -1623,6 +1769,10 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                                pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
                        SAFE_FREE(ld_error);
                        ber_bvfree(bv);
                                pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
                        SAFE_FREE(ld_error);
                        ber_bvfree(bv);
+#if defined(LDAP_CONSTRAINT_VIOLATION)
+                       if (rc == LDAP_CONSTRAINT_VIOLATION)
+                               return NT_STATUS_PASSWORD_RESTRICTION;
+#endif
                        return NT_STATUS_UNSUCCESSFUL;
                } else {
                        DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
                        return NT_STATUS_UNSUCCESSFUL;
                } else {
                        DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
@@ -1705,7 +1855,7 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
  we need LDAP modification.
 *********************************************************************/
 
  we need LDAP modification.
 *********************************************************************/
 
-static BOOL element_is_changed(const struct samu *sampass,
+static bool element_is_changed(const struct samu *sampass,
                               enum pdb_elements element)
 {
        return IS_SAM_CHANGED(sampass, element);
                               enum pdb_elements element)
 {
        return IS_SAM_CHANGED(sampass, element);
@@ -1726,9 +1876,12 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc
        LDAPMod **mods = NULL;
        const char **attr_list;
 
        LDAPMod **mods = NULL;
        const char **attr_list;
 
-       result = pdb_get_backend_private_data(newpwd, my_methods);
+       result = (LDAPMessage *)pdb_get_backend_private_data(newpwd, my_methods);
        if (!result) {
                attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
        if (!result) {
                attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
+               if (pdb_get_username(newpwd) == NULL) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
                rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
                TALLOC_FREE( attr_list );
                if (rc != LDAP_SUCCESS) {
                rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
                TALLOC_FREE( attr_list );
                if (rc != LDAP_SUCCESS) {
@@ -1760,8 +1913,9 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc
                        ldap_mods_free(mods,True);
                return NT_STATUS_UNSUCCESSFUL;
        }
                        ldap_mods_free(mods,True);
                return NT_STATUS_UNSUCCESSFUL;
        }
-       
-       if (mods == NULL) {
+
+       if ((lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_ONLY)
+           && (mods == NULL)) {
                DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
                         pdb_get_username(newpwd)));
                SAFE_FREE(dn);
                DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
                         pdb_get_username(newpwd)));
                SAFE_FREE(dn);
@@ -1769,9 +1923,26 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc
        }
        
        ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
        }
        
        ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
-       ldap_mods_free(mods,True);
+
+       if (mods != NULL) {
+               ldap_mods_free(mods,True);
+       }
+
        SAFE_FREE(dn);
 
        SAFE_FREE(dn);
 
+       /*
+        * We need to set the backend private data to NULL here. For example
+        * setuserinfo level 25 does a pdb_update_sam_account twice on the
+        * same one, and with the explicit delete / add logic for attribute
+        * values the second time we would use the wrong "old" value which
+        * does not exist in LDAP anymore. Thus the LDAP server would refuse
+        * the update.
+        * The existing LDAPMessage is still being auto-freed by the
+        * destructor.
+        */
+       pdb_set_backend_private_data(newpwd, NULL, NULL, my_methods,
+                                    PDB_CHANGED);
+
        if (!NT_STATUS_IS_OK(ret)) {
                return ret;
        }
        if (!NT_STATUS_IS_OK(ret)) {
                return ret;
        }
@@ -1787,12 +1958,13 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc
 ***************************************************************************/
 
 static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
 ***************************************************************************/
 
 static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
-                                          struct samu *old_acct, 
+                                          struct samu *old_acct,
                                           const char *newname)
 {
        const char *oldname;
        int rc;
                                           const char *newname)
 {
        const char *oldname;
        int rc;
-       pstring rename_script;
+       char *rename_script = NULL;
+       fstring oldname_lower, newname_lower;
 
        if (!old_acct) {
                DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
 
        if (!old_acct) {
                DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
@@ -1802,28 +1974,55 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
                DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
                DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
-               
+
        oldname = pdb_get_username(old_acct);
 
        oldname = pdb_get_username(old_acct);
 
-        /* rename the posix user */
-        pstrcpy(rename_script, lp_renameuser_script());
+       /* rename the posix user */
+       rename_script = SMB_STRDUP(lp_renameuser_script());
+       if (rename_script == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
 
-       if (!(*rename_script))
+       if (!(*rename_script)) {
+               SAFE_FREE(rename_script);
                return NT_STATUS_ACCESS_DENIED;
                return NT_STATUS_ACCESS_DENIED;
+       }
 
 
-       DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n", 
+       DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
                   oldname, newname));
 
                   oldname, newname));
 
-       /* we have to allow the account name to end with a '$' */
-       string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
-                   True, False, True);
-       string_sub2(rename_script, "%uold", oldname, sizeof(pstring), 
-                   True, False, True);
-       rc = smbrun(rename_script, NULL);
+       /* We have to allow the account name to end with a '$'.
+          Also, follow the semantics in _samr_create_user() and lower case the
+          posix name but preserve the case in passdb */
+
+       fstrcpy( oldname_lower, oldname );
+       strlower_m( oldname_lower );
+       fstrcpy( newname_lower, newname );
+       strlower_m( newname_lower );
+       rename_script = realloc_string_sub2(rename_script,
+                                       "%unew",
+                                       newname_lower,
+                                       true,
+                                       true);
+       if (rename_script) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       rename_script = realloc_string_sub2(rename_script,
+                                       "%uold",
+                                       oldname_lower,
+                                       true,
+                                       true);
+       rc = smbrun(rename_script, NULL);
 
 
-       DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n", 
+       DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
                          rename_script, rc));
 
                          rename_script, rc));
 
+       SAFE_FREE(rename_script);
+
+       if (rc == 0) {
+               smb_nscd_flush_user_cache();
+       }
+
        if (rc)
                return NT_STATUS_UNSUCCESSFUL;
 
        if (rc)
                return NT_STATUS_UNSUCCESSFUL;
 
@@ -1835,7 +2034,7 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
  we need LDAP modification.
  *********************************************************************/
 
  we need LDAP modification.
  *********************************************************************/
 
-static BOOL element_is_set_or_changed(const struct samu *sampass,
+static bool element_is_set_or_changed(const struct samu *sampass,
                                      enum pdb_elements element)
 {
        return (IS_SAM_SET(sampass, element) ||
                                      enum pdb_elements element)
 {
        return (IS_SAM_SET(sampass, element) ||
@@ -1853,174 +2052,205 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
        int rc;
        LDAPMessage     *result = NULL;
        LDAPMessage     *entry  = NULL;
        int rc;
        LDAPMessage     *result = NULL;
        LDAPMessage     *entry  = NULL;
-       pstring         dn;
        LDAPMod         **mods = NULL;
        int             ldap_op = LDAP_MOD_REPLACE;
        uint32          num_result;
        const char      **attr_list;
        LDAPMod         **mods = NULL;
        int             ldap_op = LDAP_MOD_REPLACE;
        uint32          num_result;
        const char      **attr_list;
-       char            *escape_user;
+       char *escape_user = NULL;
        const char      *username = pdb_get_username(newpwd);
        const DOM_SID   *sid = pdb_get_user_sid(newpwd);
        const char      *username = pdb_get_username(newpwd);
        const DOM_SID   *sid = pdb_get_user_sid(newpwd);
-       pstring         filter;
-       fstring         sid_string;
+       char *filter = NULL;
+       char *dn = NULL;
+       NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+       TALLOC_CTX *ctx = talloc_init("ldapsam_add_sam_account");
+
+       if (!ctx) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        if (!username || !*username) {
                DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
 
        if (!username || !*username) {
                DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fn_exit;
        }
 
        /* free this list after the second search or in case we exit on failure */
        }
 
        /* free this list after the second search or in case we exit on failure */
-       attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
+       attr_list = get_userattr_list(ctx, ldap_state->schema_ver);
 
        rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
 
        if (rc != LDAP_SUCCESS) {
 
        rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
 
        if (rc != LDAP_SUCCESS) {
-               TALLOC_FREE( attr_list );
-               return NT_STATUS_UNSUCCESSFUL;
+               goto fn_exit;
        }
 
        if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
                DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n", 
                         username));
        }
 
        if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
                DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n", 
                         username));
-               ldap_msgfree(result);
-               TALLOC_FREE( attr_list );
-               return NT_STATUS_UNSUCCESSFUL;
+               goto fn_exit;
        }
        ldap_msgfree(result);
        result = NULL;
 
        if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
        }
        ldap_msgfree(result);
        result = NULL;
 
        if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
-               rc = ldapsam_get_ldap_user_by_sid(ldap_state, 
-                                                 sid, &result); 
+               rc = ldapsam_get_ldap_user_by_sid(ldap_state,
+                                                 sid, &result);
                if (rc == LDAP_SUCCESS) {
                        if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
                if (rc == LDAP_SUCCESS) {
                        if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
-                               DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n", 
-                                        sid_to_string(sid_string, sid)));
-                               TALLOC_FREE( attr_list );
-                               ldap_msgfree(result);
-                               return NT_STATUS_UNSUCCESSFUL;
+                               DEBUG(0,("ldapsam_add_sam_account: SID '%s' "
+                                        "already in the base, with samba "
+                                        "attributes\n", sid_string_dbg(sid)));
+                               goto fn_exit;
                        }
                        ldap_msgfree(result);
                        }
                        ldap_msgfree(result);
+                       result = NULL;
                }
        }
 
        /* does the entry already exist but without a samba attributes?
           we need to return the samba attributes here */
                }
        }
 
        /* does the entry already exist but without a samba attributes?
           we need to return the samba attributes here */
-          
+
        escape_user = escape_ldap_string_alloc( username );
        escape_user = escape_ldap_string_alloc( username );
-       pstrcpy( filter, "(uid=%u)" );
-       all_string_sub( filter, "%u", escape_user, sizeof(filter) );
-       SAFE_FREE( escape_user );
+       filter = talloc_strdup(attr_list, "(uid=%u)");
+       if (!filter) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fn_exit;
+       }
+       filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
+       if (!filter) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fn_exit;
+       }
+       SAFE_FREE(escape_user);
 
 
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, 
+       rc = smbldap_search_suffix(ldap_state->smbldap_state,
                                   filter, attr_list, &result);
        if ( rc != LDAP_SUCCESS ) {
                                   filter, attr_list, &result);
        if ( rc != LDAP_SUCCESS ) {
-               TALLOC_FREE( attr_list );
-               return NT_STATUS_UNSUCCESSFUL;
+               goto fn_exit;
        }
 
        num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
        }
 
        num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-       
+
        if (num_result > 1) {
                DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
        if (num_result > 1) {
                DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
-               TALLOC_FREE( attr_list );
-               ldap_msgfree(result);
-               return NT_STATUS_UNSUCCESSFUL;
+               goto fn_exit;
        }
        }
-       
+
        /* Check if we need to update an existing entry */
        if (num_result == 1) {
                char *tmp;
        /* Check if we need to update an existing entry */
        if (num_result == 1) {
                char *tmp;
-               
+
                DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
                ldap_op = LDAP_MOD_REPLACE;
                entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
                DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
                ldap_op = LDAP_MOD_REPLACE;
                entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
-               tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
+               tmp = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
                if (!tmp) {
                if (!tmp) {
-                       TALLOC_FREE( attr_list );
-                       ldap_msgfree(result);
-                       return NT_STATUS_UNSUCCESSFUL;
+                       goto fn_exit;
                }
                }
-               slprintf (dn, sizeof (dn) - 1, "%s", tmp);
+               dn = talloc_asprintf(ctx, "%s", tmp);
                SAFE_FREE(tmp);
                SAFE_FREE(tmp);
+               if (!dn) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto fn_exit;
+               }
 
        } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
 
                /* There might be a SID for this account already - say an idmap entry */
 
 
        } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
 
                /* There might be a SID for this account already - say an idmap entry */
 
-               pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))", 
-                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
-                        sid_to_string(sid_string, sid),
-                        LDAP_OBJ_IDMAP_ENTRY,
-                        LDAP_OBJ_SID_ENTRY);
-               
+               filter = talloc_asprintf(ctx,
+                               "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
+                                get_userattr_key2string(ldap_state->schema_ver,
+                                        LDAP_ATTR_USER_SID),
+                                sid_string_talloc(ctx, sid),
+                                LDAP_OBJ_IDMAP_ENTRY,
+                                LDAP_OBJ_SID_ENTRY);
+               if (!filter) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto fn_exit;
+               }
+
                /* free old result before doing a new search */
                if (result != NULL) {
                        ldap_msgfree(result);
                        result = NULL;
                }
                /* free old result before doing a new search */
                if (result != NULL) {
                        ldap_msgfree(result);
                        result = NULL;
                }
-               rc = smbldap_search_suffix(ldap_state->smbldap_state, 
+               rc = smbldap_search_suffix(ldap_state->smbldap_state,
                                           filter, attr_list, &result);
                                           filter, attr_list, &result);
-                       
+
                if ( rc != LDAP_SUCCESS ) {
                if ( rc != LDAP_SUCCESS ) {
-                       TALLOC_FREE( attr_list );
-                       return NT_STATUS_UNSUCCESSFUL;
+                       goto fn_exit;
                }
                }
-               
+
                num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
                num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-               
+
                if (num_result > 1) {
                if (num_result > 1) {
-                       DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
-                       TALLOC_FREE( attr_list );
-                       ldap_msgfree(result);
-                       return NT_STATUS_UNSUCCESSFUL;
+                       DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
+                       goto fn_exit;
                }
                }
-               
+
                /* Check if we need to update an existing entry */
                if (num_result == 1) {
                        char *tmp;
                /* Check if we need to update an existing entry */
                if (num_result == 1) {
                        char *tmp;
-                       
+
                        DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
                        ldap_op = LDAP_MOD_REPLACE;
                        entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
                        tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
                        if (!tmp) {
                        DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
                        ldap_op = LDAP_MOD_REPLACE;
                        entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
                        tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
                        if (!tmp) {
-                               TALLOC_FREE( attr_list );
-                               ldap_msgfree(result);
-                               return NT_STATUS_UNSUCCESSFUL;
+                               goto fn_exit;
                        }
                        }
-                       slprintf (dn, sizeof (dn) - 1, "%s", tmp);
+                       dn = talloc_asprintf(ctx, "%s", tmp);
                        SAFE_FREE(tmp);
                        SAFE_FREE(tmp);
+                       if (!dn) {
+                               status = NT_STATUS_NO_MEMORY;
+                               goto fn_exit;
+                       }
                }
        }
                }
        }
-       
-       TALLOC_FREE( attr_list );
 
        if (num_result == 0) {
 
        if (num_result == 0) {
+               char *escape_username;
                /* Check if we need to add an entry */
                DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
                ldap_op = LDAP_MOD_ADD;
                /* Check if we need to add an entry */
                DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
                ldap_op = LDAP_MOD_ADD;
+
+               escape_username = escape_rdn_val_string_alloc(username);
+               if (!escape_username) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto fn_exit;
+               }
+
                if (username[strlen(username)-1] == '$') {
                if (username[strlen(username)-1] == '$') {
-                       slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
+                       dn = talloc_asprintf(ctx,
+                                       "uid=%s,%s",
+                                       escape_username,
+                                       lp_ldap_machine_suffix());
                } else {
                } else {
-                       slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
+                       dn = talloc_asprintf(ctx,
+                                       "uid=%s,%s",
+                                       escape_username,
+                                       lp_ldap_user_suffix());
+               }
+
+               SAFE_FREE(escape_username);
+               if (!dn) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto fn_exit;
                }
        }
 
        if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
                                element_is_set_or_changed)) {
                DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
                }
        }
 
        if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
                                element_is_set_or_changed)) {
                DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
-               ldap_msgfree(result);
-               if (mods != NULL)
-                       ldap_mods_free(mods,True);
-               return NT_STATUS_UNSUCCESSFUL;          
+               if (mods != NULL) {
+                       ldap_mods_free(mods, true);
+               }
+               goto fn_exit;
        }
        }
-       
-       ldap_msgfree(result);
 
        if (mods == NULL) {
                DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
 
        if (mods == NULL) {
                DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
-               return NT_STATUS_UNSUCCESSFUL;
+               goto fn_exit;
        }
        switch ( ldap_state->schema_ver ) {
                case SCHEMAVER_SAMBAACCOUNT:
        }
        switch ( ldap_state->schema_ver ) {
                case SCHEMAVER_SAMBAACCOUNT:
@@ -2038,14 +2268,23 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
                         pdb_get_username(newpwd),dn));
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
                         pdb_get_username(newpwd),dn));
-               ldap_mods_free(mods, True);
-               return ret;
+               ldap_mods_free(mods, true);
+               goto fn_exit;
        }
 
        DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
        }
 
        DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
-       ldap_mods_free(mods, True);
-       
-       return NT_STATUS_OK;
+       ldap_mods_free(mods, true);
+
+       status = NT_STATUS_OK;
+
+  fn_exit:
+
+       TALLOC_FREE(ctx);
+       SAFE_FREE(escape_user);
+       if (result) {
+               ldap_msgfree(result);
+       }
+       return status;
 }
 
 /**********************************************************************
 }
 
 /**********************************************************************
@@ -2060,7 +2299,7 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
        const char **attr_list;
 
        attr_list = get_attr_list(NULL, groupmap_attr_list);
        const char **attr_list;
 
        attr_list = get_attr_list(NULL, groupmap_attr_list);
-       rc = smbldap_search(ldap_state->smbldap_state, 
+       rc = smbldap_search(ldap_state->smbldap_state,
                            lp_ldap_group_suffix (), scope,
                            filter, attr_list, 0, result);
        TALLOC_FREE(attr_list);
                            lp_ldap_group_suffix (), scope,
                            filter, attr_list, 0, result);
        TALLOC_FREE(attr_list);
@@ -2071,77 +2310,122 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
 /**********************************************************************
  *********************************************************************/
 
 /**********************************************************************
  *********************************************************************/
 
-static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
+static bool init_group_from_ldap(struct ldapsam_privates *ldap_state,
                                 GROUP_MAP *map, LDAPMessage *entry)
 {
                                 GROUP_MAP *map, LDAPMessage *entry)
 {
-       pstring temp;
+       char *temp = NULL;
+       TALLOC_CTX *ctx = talloc_init("init_group_from_ldap");
 
        if (ldap_state == NULL || map == NULL || entry == NULL ||
                        ldap_state->smbldap_state->ldap_struct == NULL) {
                DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
 
        if (ldap_state == NULL || map == NULL || entry == NULL ||
                        ldap_state->smbldap_state->ldap_struct == NULL) {
                DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
-               return False;
+               TALLOC_FREE(ctx);
+               return false;
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) {
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_attr_key2string(groupmap_attr_list,
+                               LDAP_ATTR_GIDNUMBER),
+                       ctx);
+       if (!temp) {
                DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n", 
                        get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
                DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n", 
                        get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
-               return False;
+               TALLOC_FREE(ctx);
+               return false;
        }
        DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
 
        map->gid = (gid_t)atol(temp);
 
        }
        DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
 
        map->gid = (gid_t)atol(temp);
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) {
+       TALLOC_FREE(temp);
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_attr_key2string(groupmap_attr_list,
+                               LDAP_ATTR_GROUP_SID),
+                       ctx);
+       if (!temp) {
                DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
                        get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
                DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
                        get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
-               return False;
+               TALLOC_FREE(ctx);
+               return false;
        }
        }
-       
+
        if (!string_to_sid(&map->sid, temp)) {
                DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
        if (!string_to_sid(&map->sid, temp)) {
                DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
-               return False;
+               TALLOC_FREE(ctx);
+               return false;
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) {
+       TALLOC_FREE(temp);
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_attr_key2string(groupmap_attr_list,
+                               LDAP_ATTR_GROUP_TYPE),
+                       ctx);
+       if (!temp) {
                DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
                        get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
                DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
                        get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
-               return False;
+               TALLOC_FREE(ctx);
+               return false;
        }
        }
-       map->sid_name_use = (enum SID_NAME_USE)atol(temp);
+       map->sid_name_use = (enum lsa_SidType)atol(temp);
 
        if ((map->sid_name_use < SID_NAME_USER) ||
                        (map->sid_name_use > SID_NAME_UNKNOWN)) {
                DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
 
        if ((map->sid_name_use < SID_NAME_USER) ||
                        (map->sid_name_use > SID_NAME_UNKNOWN)) {
                DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
-               return False;
+               TALLOC_FREE(ctx);
+               return false;
        }
 
        }
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) {
-               temp[0] = '\0';
-               if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp)) 
-               {
+       TALLOC_FREE(temp);
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_attr_key2string(groupmap_attr_list,
+                               LDAP_ATTR_DISPLAY_NAME),
+                       ctx);
+       if (!temp) {
+               temp = smbldap_talloc_single_attribute(
+                               ldap_state->smbldap_state->ldap_struct,
+                               entry,
+                               get_attr_key2string(groupmap_attr_list,
+                                       LDAP_ATTR_CN),
+                               ctx);
+               if (!temp) {
                        DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
 for gidNumber(%lu)\n",(unsigned long)map->gid));
                        DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
 for gidNumber(%lu)\n",(unsigned long)map->gid));
-                       return False;
+                       TALLOC_FREE(ctx);
+                       return false;
                }
        }
        fstrcpy(map->nt_name, temp);
 
                }
        }
        fstrcpy(map->nt_name, temp);
 
-       if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
-                       get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) {
-               temp[0] = '\0';
+       TALLOC_FREE(temp);
+       temp = smbldap_talloc_single_attribute(
+                       ldap_state->smbldap_state->ldap_struct,
+                       entry,
+                       get_attr_key2string(groupmap_attr_list,
+                               LDAP_ATTR_DESC),
+                       ctx);
+       if (!temp) {
+               temp = talloc_strdup(ctx, "");
+               if (!temp) {
+                       TALLOC_FREE(ctx);
+                       return false;
+               }
        }
        fstrcpy(map->comment, temp);
 
        }
        fstrcpy(map->comment, temp);
 
-       if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
+       if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
                store_gid_sid_cache(&map->sid, map->gid);
        }
 
                store_gid_sid_cache(&map->sid, map->gid);
        }
 
-       return True;
+       TALLOC_FREE(ctx);
+       return true;
 }
 
 /**********************************************************************
 }
 
 /**********************************************************************
@@ -2165,7 +2449,8 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
        count = ldap_count_entries(priv2ld(ldap_state), result);
 
        if (count < 1) {
        count = ldap_count_entries(priv2ld(ldap_state), result);
 
        if (count < 1) {
-               DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
+               DEBUG(4, ("ldapsam_getgroup: Did not find group, filter was "
+                         "%s\n", filter));
                ldap_msgfree(result);
                return NT_STATUS_NO_SUCH_GROUP;
        }
                ldap_msgfree(result);
                return NT_STATUS_NO_SUCH_GROUP;
        }
@@ -2201,14 +2486,20 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
                                 DOM_SID sid)
 {
 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
                                 DOM_SID sid)
 {
-       pstring filter;
+       char *filter = NULL;
+       NTSTATUS status;
+       fstring tmp;
 
 
-       pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
-               LDAP_OBJ_GROUPMAP, 
+       if (asprintf(&filter, "(&(objectClass=%s)(%s=%s))",
+               LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
-               sid_string_static(&sid));
+               sid_to_fstring(tmp, &sid)) < 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
 
-       return ldapsam_getgroup(methods, filter, map);
+       status = ldapsam_getgroup(methods, filter, map);
+       SAFE_FREE(filter);
+       return status;
 }
 
 /**********************************************************************
 }
 
 /**********************************************************************
@@ -2217,14 +2508,19 @@ static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
                                 gid_t gid)
 {
 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
                                 gid_t gid)
 {
-       pstring filter;
+       char *filter = NULL;
+       NTSTATUS status;
 
 
-       pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
+       if (asprintf(&filter, "(&(objectClass=%s)(%s=%lu))",
                LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
                LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
-               (unsigned long)gid);
+               (unsigned long)gid) < 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
 
-       return ldapsam_getgroup(methods, filter, map);
+       status = ldapsam_getgroup(methods, filter, map);
+       SAFE_FREE(filter);
+       return status;
 }
 
 /**********************************************************************
 }
 
 /**********************************************************************
@@ -2233,43 +2529,30 @@ static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
                                 const char *name)
 {
 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
                                 const char *name)
 {
-       pstring filter;
+       char *filter = NULL;
        char *escape_name = escape_ldap_string_alloc(name);
        char *escape_name = escape_ldap_string_alloc(name);
+       NTSTATUS status;
 
        if (!escape_name) {
                return NT_STATUS_NO_MEMORY;
        }
 
 
        if (!escape_name) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
+       if (asprintf(&filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
                LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
                LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
-               get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
-
-       SAFE_FREE(escape_name);
-
-       return ldapsam_getgroup(methods, filter, map);
-}
-
-static void add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
-                                   uint32 rid, uint32 **pp_rids, size_t *p_num)
-{
-       size_t i;
-
-       for (i=0; i<*p_num; i++) {
-               if ((*pp_rids)[i] == rid)
-                       return;
+               get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
+               escape_name) < 0) {
+               SAFE_FREE(escape_name);
+               return NT_STATUS_NO_MEMORY;
        }
        }
-       
-       *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
-
-       if (*pp_rids == NULL)
-               return;
 
 
-       (*pp_rids)[*p_num] = rid;
-       *p_num += 1;
+       SAFE_FREE(escape_name);
+       status = ldapsam_getgroup(methods, filter, map);
+       SAFE_FREE(filter);
+       return status;
 }
 
 }
 
-static BOOL ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
+static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
                                           LDAPMessage *entry,
                                           const DOM_SID *domain_sid,
                                           uint32 *rid)
                                           LDAPMessage *entry,
                                           const DOM_SID *domain_sid,
                                           uint32 *rid)
@@ -2290,7 +2573,7 @@ static BOOL ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
 
        if (sid_compare_domain(&sid, domain_sid) != 0) {
                DEBUG(10, ("SID %s is not in expected domain %s\n",
 
        if (sid_compare_domain(&sid, domain_sid) != 0) {
                DEBUG(10, ("SID %s is not in expected domain %s\n",
-                          str, sid_string_static(domain_sid)));
+                          str, sid_string_dbg(domain_sid)));
                return False;
        }
 
                return False;
        }
 
@@ -2326,10 +2609,16 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
        *p_num_members = 0;
 
        filter = talloc_asprintf(mem_ctx,
        *p_num_members = 0;
 
        filter = talloc_asprintf(mem_ctx,
-                                "(&(objectClass=sambaGroupMapping)"
-                                "(objectClass=posixGroup)"
+                                "(&(objectClass=%s)"
+                                "(objectClass=%s)"
                                 "(sambaSID=%s))",
                                 "(sambaSID=%s))",
-                                sid_string_static(group));
+                                LDAP_OBJ_POSIXGROUP,
+                                LDAP_OBJ_GROUPMAP,
+                                sid_string_talloc(mem_ctx, group));
+       if (filter == NULL) {
+               ret = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
 
        rc = smbldap_search(conn, lp_ldap_group_suffix(),
                            LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
 
        rc = smbldap_search(conn, lp_ldap_group_suffix(),
                            LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
@@ -2344,7 +2633,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
 
        if (count > 1) {
                DEBUG(1, ("Found more than one groupmap entry for %s\n",
 
        if (count > 1) {
                DEBUG(1, ("Found more than one groupmap entry for %s\n",
-                         sid_string_static(group)));
+                         sid_string_dbg(group)));
                ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
                goto done;
        }
                ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
                goto done;
        }
@@ -2369,27 +2658,38 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
 
        if (values) {
 
 
        if (values) {
 
-               filter = talloc_strdup(mem_ctx, "(&(objectClass=sambaSamAccount)(|");
+               filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBASAMACCOUNT);
                if (filter == NULL) {
                        ret = NT_STATUS_NO_MEMORY;
                        goto done;
                }
 
                for (memberuid = values; *memberuid != NULL; memberuid += 1) {
                if (filter == NULL) {
                        ret = NT_STATUS_NO_MEMORY;
                        goto done;
                }
 
                for (memberuid = values; *memberuid != NULL; memberuid += 1) {
-                       filter = talloc_asprintf_append(filter, "(uid=%s)", *memberuid);
+                       char *escape_memberuid;
+
+                       escape_memberuid = escape_ldap_string_alloc(*memberuid);
+                       if (escape_memberuid == NULL) {
+                               ret = NT_STATUS_NO_MEMORY;
+                               goto done;
+                       }
+                       
+                       filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
                        if (filter == NULL) {
                        if (filter == NULL) {
+                               SAFE_FREE(escape_memberuid);
                                ret = NT_STATUS_NO_MEMORY;
                                goto done;
                        }
                                ret = NT_STATUS_NO_MEMORY;
                                goto done;
                        }
+
+                       SAFE_FREE(escape_memberuid);
                }
 
                }
 
-               filter = talloc_asprintf_append(filter, "))");
+               filter = talloc_asprintf_append_buffer(filter, "))");
                if (filter == NULL) {
                        ret = NT_STATUS_NO_MEMORY;
                        goto done;
                }
 
                if (filter == NULL) {
                        ret = NT_STATUS_NO_MEMORY;
                        goto done;
                }
 
-               rc = smbldap_search(conn, lp_ldap_user_suffix(),
+               rc = smbldap_search(conn, lp_ldap_suffix(),
                                    LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
                                    &result);
 
                                    LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
                                    &result);
 
@@ -2431,16 +2731,21 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
 
                        sid_peek_rid(&sid, &rid);
 
 
                        sid_peek_rid(&sid, &rid);
 
-                       add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
-                                               p_num_members);
+                       if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
+                                               p_num_members)) {
+                               ret = NT_STATUS_NO_MEMORY;
+                               goto done;
+                       }
                }
        }
 
        filter = talloc_asprintf(mem_ctx,
                }
        }
 
        filter = talloc_asprintf(mem_ctx,
-                                "(&(objectClass=sambaSamAccount)"
-                                "(gidNumber=%s))", gidstr);
+                                "(&(objectClass=%s)"
+                                "(gidNumber=%s))",
+                                LDAP_OBJ_SAMBASAMACCOUNT,
+                                gidstr);
 
 
-       rc = smbldap_search(conn, lp_ldap_user_suffix(),
+       rc = smbldap_search(conn, lp_ldap_suffix(),
                            LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
                            &result);
 
                            LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
                            &result);
 
@@ -2465,8 +2770,11 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
                        goto done;
                }
 
                        goto done;
                }
 
-               add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
-                                       p_num_members);
+               if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
+                                       p_num_members)) {
+                       ret = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
        }
 
        ret = NT_STATUS_OK;
        }
 
        ret = NT_STATUS_OK;
@@ -2489,39 +2797,86 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
        struct smbldap_state *conn = ldap_state->smbldap_state;
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
        struct smbldap_state *conn = ldap_state->smbldap_state;
-       pstring filter;
+       char *filter;
        const char *attrs[] = { "gidNumber", "sambaSID", NULL };
        char *escape_name;
        const char *attrs[] = { "gidNumber", "sambaSID", NULL };
        char *escape_name;
-       int rc;
-       LDAPMessage *msg = NULL;
+       int rc, count;
+       LDAPMessage *result = NULL;
        LDAPMessage *entry;
        LDAPMessage *entry;
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
        size_t num_sids, num_gids;
        size_t num_sids, num_gids;
-       gid_t primary_gid;
+       char *gidstr;
+       gid_t primary_gid = -1;
 
        *pp_sids = NULL;
        num_sids = 0;
 
 
        *pp_sids = NULL;
        num_sids = 0;
 
-       if (!sid_to_gid(pdb_get_group_sid(user), &primary_gid)) {
-               DEBUG(1, ("sid_to_gid failed for user's primary group\n"));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       if (pdb_get_username(user) == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        escape_name = escape_ldap_string_alloc(pdb_get_username(user));
        }
 
        escape_name = escape_ldap_string_alloc(pdb_get_username(user));
-
        if (escape_name == NULL)
                return NT_STATUS_NO_MEMORY;
 
        if (escape_name == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       pstr_sprintf(filter, "(&(objectClass=posixGroup)"
-                    "(|(memberUid=%s)(gidNumber=%d)))",
-                    escape_name, primary_gid);
+       /* retrieve the users primary gid */
+       filter = talloc_asprintf(mem_ctx,
+                                "(&(objectClass=%s)(uid=%s))",
+                                LDAP_OBJ_SAMBASAMACCOUNT,
+                                escape_name);
+       if (filter == NULL) {
+               ret = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       rc = smbldap_search(conn, lp_ldap_suffix(),
+                           LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
+
+       if (rc != LDAP_SUCCESS)
+               goto done;
+
+       talloc_autofree_ldapmsg(mem_ctx, result);
+
+       count = ldap_count_entries(priv2ld(ldap_state), result);
+
+       switch (count) {
+       case 0: 
+               DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
+               ret = NT_STATUS_NO_SUCH_USER;
+               goto done;
+       case 1:
+               entry = ldap_first_entry(priv2ld(ldap_state), result);
+
+               gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
+               if (!gidstr) {
+                       DEBUG (1, ("Unable to find the member's gid!\n"));
+                       ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+                       goto done;
+               }
+               primary_gid = strtoul(gidstr, NULL, 10);
+               break;
+       default:
+               DEBUG(1, ("found more than one account with the same user name ?!\n"));
+               ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+               goto done;
+       }
+
+       filter = talloc_asprintf(mem_ctx,
+                                "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%d)))",
+                                LDAP_OBJ_POSIXGROUP, escape_name, primary_gid);
+       if (filter == NULL) {
+               ret = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
 
        rc = smbldap_search(conn, lp_ldap_group_suffix(),
 
        rc = smbldap_search(conn, lp_ldap_group_suffix(),
-                           LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg);
+                           LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
 
        if (rc != LDAP_SUCCESS)
                goto done;
 
 
        if (rc != LDAP_SUCCESS)
                goto done;
 
+       talloc_autofree_ldapmsg(mem_ctx, result);
+
        num_gids = 0;
        *pp_gids = NULL;
 
        num_gids = 0;
        *pp_gids = NULL;
 
@@ -2530,13 +2885,20 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
 
        /* We need to add the primary group as the first gid/sid */
 
 
        /* We need to add the primary group as the first gid/sid */
 
-       add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids);
+       if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
+               ret = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
 
        /* This sid will be replaced later */
 
 
        /* This sid will be replaced later */
 
-       add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids, &num_sids);
+       ret = add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids,
+                                     &num_sids);
+       if (!NT_STATUS_IS_OK(ret)) {
+               goto done;
+       }
 
 
-       for (entry = ldap_first_entry(conn->ldap_struct, msg);
+       for (entry = ldap_first_entry(conn->ldap_struct, result);
             entry != NULL;
             entry = ldap_next_entry(conn->ldap_struct, entry))
        {
             entry != NULL;
             entry = ldap_next_entry(conn->ldap_struct, entry))
        {
@@ -2566,10 +2928,16 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
                if (gid == primary_gid) {
                        sid_copy(&(*pp_sids)[0], &sid);
                } else {
                if (gid == primary_gid) {
                        sid_copy(&(*pp_sids)[0], &sid);
                } else {
-                       add_gid_to_array_unique(mem_ctx, gid, pp_gids,
-                                               &num_gids);
-                       add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
-                                               &num_sids);
+                       if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
+                                               &num_gids)) {
+                               ret = NT_STATUS_NO_MEMORY;
+                               goto done;
+                       }
+                       ret = add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
+                                                     &num_sids);
+                       if (!NT_STATUS_IS_OK(ret)) {
+                               goto done;
+                       }
                }
        }
 
                }
        }
 
@@ -2581,15 +2949,12 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
 
        *p_num_groups = num_sids;
 
 
        *p_num_groups = num_sids;
 
-       result = NT_STATUS_OK;
+       ret = NT_STATUS_OK;
 
  done:
 
        SAFE_FREE(escape_name);
 
  done:
 
        SAFE_FREE(escape_name);
-       if (msg != NULL)
-               ldap_msgfree(msg);
-
-       return result;
+       return ret;
 }
 
 /**********************************************************************
 }
 
 /**********************************************************************
@@ -2632,7 +2997,7 @@ static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
                        "sambaGroupMapping");
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaSid",
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
                        "sambaGroupMapping");
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaSid",
-                        sid_string_static(&map->sid));
+                        sid_string_talloc(mem_ctx, &map->sid));
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaGroupType",
                         talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaGroupType",
                         talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
@@ -2674,7 +3039,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
        }
 
        filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
        }
 
        filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
-                                sid_string_static(&map->sid));
+                                sid_string_talloc(mem_ctx, &map->sid));
        if (filter == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto done;
        if (filter == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto done;
@@ -2688,8 +3053,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
            (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) > 0)) {
 
                DEBUG(3, ("SID %s already present in LDAP, refusing to add "
            (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) > 0)) {
 
                DEBUG(3, ("SID %s already present in LDAP, refusing to add "
-                         "group mapping entry\n",
-                         sid_string_static(&map->sid)));
+                         "group mapping entry\n", sid_string_dbg(&map->sid)));
                result = NT_STATUS_GROUP_EXISTS;
                goto done;
        }
                result = NT_STATUS_GROUP_EXISTS;
                goto done;
        }
@@ -2704,20 +3068,11 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
                break;
 
        case SID_NAME_ALIAS:
                break;
 
        case SID_NAME_ALIAS:
-               if (!sid_check_is_in_our_domain(&map->sid)) {
-                       DEBUG(3, ("Refusing to map sid %s as an alias, not "
-                                 "in our domain\n",
-                                 sid_string_static(&map->sid)));
-                       result = NT_STATUS_INVALID_PARAMETER;
-                       goto done;
-               }
-               break;
-
-       case SID_NAME_WKN_GRP:
-               if (!sid_check_is_in_builtin(&map->sid)) {
-                       DEBUG(3, ("Refusing to map sid %s as an alias, not "
-                                 "in builtin domain\n",
-                                 sid_string_static(&map->sid)));
+               if (!sid_check_is_in_our_domain(&map->sid) 
+                       && !sid_check_is_in_builtin(&map->sid) ) 
+               {
+                       DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
+                                 sid_string_dbg(&map->sid)));
                        result = NT_STATUS_INVALID_PARAMETER;
                        goto done;
                }
                        result = NT_STATUS_INVALID_PARAMETER;
                        goto done;
                }
@@ -2741,7 +3096,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
 
        if (pdb_gid_to_sid(map->gid, &sid)) {
                DEBUG(3, ("Gid %d is already mapped to SID %s, refusing to "
 
        if (pdb_gid_to_sid(map->gid, &sid)) {
                DEBUG(3, ("Gid %d is already mapped to SID %s, refusing to "
-                         "add\n", map->gid, sid_string_static(&sid)));
+                         "add\n", map->gid, sid_string_dbg(&sid)));
                result = NT_STATUS_GROUP_EXISTS;
                goto done;
        }
                result = NT_STATUS_GROUP_EXISTS;
                goto done;
        }
@@ -2750,7 +3105,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
         * the best we can get out of LDAP. */
 
        dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
         * the best we can get out of LDAP. */
 
        dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
-                            sid_string_static(&map->sid),
+                            sid_string_talloc(mem_ctx, &map->sid),
                             lp_ldap_group_suffix());
        if (dn == NULL) {
                result = NT_STATUS_NO_MEMORY;
                             lp_ldap_group_suffix());
        if (dn == NULL) {
                result = NT_STATUS_NO_MEMORY;
@@ -2765,7 +3120,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
                         "sambaGroupMapping");
 
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaSid",
                         "sambaGroupMapping");
 
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaSid",
-                        sid_string_static(&map->sid));
+                        sid_string_talloc(mem_ctx, &map->sid));
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaGroupType",
                         talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "displayName",
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaGroupType",
                         talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "displayName",
@@ -2814,11 +3169,12 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
        /* Make 100% sure that sid, gid and type are not changed by looking up
         * exactly the values we're given in LDAP. */
 
        /* Make 100% sure that sid, gid and type are not changed by looking up
         * exactly the values we're given in LDAP. */
 
-       filter = talloc_asprintf(mem_ctx, "(&(objectClass=sambaGroupMapping)"
+       filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)"
                                 "(sambaSid=%s)(gidNumber=%u)"
                                 "(sambaGroupType=%d))",
                                 "(sambaSid=%s)(gidNumber=%u)"
                                 "(sambaGroupType=%d))",
-                                sid_string_static(&map->sid), map->gid,
-                                map->sid_name_use);
+                                LDAP_OBJ_GROUPMAP,
+                                sid_string_talloc(mem_ctx, &map->sid),
+                                map->gid, map->sid_name_use);
        if (filter == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto done;
        if (filter == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto done;
@@ -2896,7 +3252,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
 
        filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
                                 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID,
 
        filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
                                 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID,
-                                sid_string_static(&sid));
+                                sid_string_talloc(mem_ctx, &sid));
        if (filter == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto done;
        if (filter == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto done;
@@ -2957,15 +3313,18 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
-                                   BOOL update)
+                                   bool update)
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)my_methods->private_data;
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)my_methods->private_data;
-       fstring filter;
+       char *filter = NULL;
        int rc;
        const char **attr_list;
 
        int rc;
        const char **attr_list;
 
-       pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
+       filter = talloc_asprintf(NULL, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
+       if (!filter) {
+               return NT_STATUS_NO_MEMORY;
+       }
        attr_list = get_attr_list( NULL, groupmap_attr_list );
        rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
                            LDAP_SCOPE_SUBTREE, filter,
        attr_list = get_attr_list( NULL, groupmap_attr_list );
        rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
                            LDAP_SCOPE_SUBTREE, filter,
@@ -2979,9 +3338,12 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
                          lp_ldap_group_suffix(), filter));
                ldap_msgfree(ldap_state->result);
                ldap_state->result = NULL;
                          lp_ldap_group_suffix(), filter));
                ldap_msgfree(ldap_state->result);
                ldap_state->result = NULL;
+               TALLOC_FREE(filter);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
                return NT_STATUS_UNSUCCESSFUL;
        }
 
+       TALLOC_FREE(filter);
+
        DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
                  ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
                                     ldap_state->result)));
        DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
                  ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
                                     ldap_state->result)));
@@ -3011,7 +3373,7 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)my_methods->private_data;
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)my_methods->private_data;
-       BOOL bret = False;
+       bool bret = False;
 
        while (!bret) {
                if (!ldap_state->entry)
 
        while (!bret) {
                if (!ldap_state->entry)
@@ -3033,13 +3395,12 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
-                                          enum SID_NAME_USE sid_name_use,
+                                          const DOM_SID *domsid, enum lsa_SidType sid_name_use,
                                           GROUP_MAP **pp_rmap,
                                           size_t *p_num_entries,
                                           GROUP_MAP **pp_rmap,
                                           size_t *p_num_entries,
-                                          BOOL unix_only)
+                                          bool unix_only)
 {
        GROUP_MAP map;
 {
        GROUP_MAP map;
-       GROUP_MAP *mapt;
        size_t entries = 0;
 
        *p_num_entries = 0;
        size_t entries = 0;
 
        *p_num_entries = 0;
@@ -3064,17 +3425,14 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
                        continue;
                }
 
                        continue;
                }
 
-               mapt=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
-               if (!mapt) {
+               (*pp_rmap)=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
+               if (!(*pp_rmap)) {
                        DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
                                 "enlarge group map!\n"));
                        DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
                                 "enlarge group map!\n"));
-                       SAFE_FREE(*pp_rmap);
                        return NT_STATUS_UNSUCCESSFUL;
                }
                        return NT_STATUS_UNSUCCESSFUL;
                }
-               else
-                       (*pp_rmap) = mapt;
 
 
-               mapt[entries] = map;
+               (*pp_rmap)[entries] = map;
 
                entries += 1;
 
 
                entries += 1;
 
@@ -3093,18 +3451,19 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
-       char *dn;
+       char *dn = NULL;
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        int count;
        LDAPMod **mods = NULL;
        int rc;
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        int count;
        LDAPMod **mods = NULL;
        int rc;
-       enum SID_NAME_USE type = SID_NAME_USE_NONE;
+       enum lsa_SidType type = SID_NAME_USE_NONE;
+       fstring tmp;
 
 
-       pstring filter;
+       char *filter = NULL;
 
        if (sid_check_is_in_builtin(alias)) {
 
        if (sid_check_is_in_builtin(alias)) {
-               type = SID_NAME_WKN_GRP;
+               type = SID_NAME_ALIAS;
        }
 
        if (sid_check_is_in_our_domain(alias)) {
        }
 
        if (sid_check_is_in_our_domain(alias)) {
@@ -3113,18 +3472,22 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
 
        if (type == SID_NAME_USE_NONE) {
                DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
 
        if (type == SID_NAME_USE_NONE) {
                DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
-                         sid_string_static(alias)));
+                         sid_string_dbg(alias)));
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
-       pstr_sprintf(filter,
+       if (asprintf(&filter,
                     "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
                     "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
-                    LDAP_OBJ_GROUPMAP, sid_string_static(alias),
-                    type);
+                    LDAP_OBJ_GROUPMAP, sid_to_fstring(tmp, alias),
+                    type) < 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        if (ldapsam_search_one_group(ldap_state, filter,
 
        if (ldapsam_search_one_group(ldap_state, filter,
-                                    &result) != LDAP_SUCCESS)
+                                    &result) != LDAP_SUCCESS) {
+               SAFE_FREE(filter);
                return NT_STATUS_NO_SUCH_ALIAS;
                return NT_STATUS_NO_SUCH_ALIAS;
+       }
 
        count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
                                   result);
 
        count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
                                   result);
@@ -3132,6 +3495,7 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
        if (count < 1) {
                DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
                ldap_msgfree(result);
        if (count < 1) {
                DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
                ldap_msgfree(result);
+               SAFE_FREE(filter);
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
@@ -3139,9 +3503,12 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
                DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
                          "filter %s: count=%d\n", filter, count));
                ldap_msgfree(result);
                DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
                          "filter %s: count=%d\n", filter, count));
                ldap_msgfree(result);
+               SAFE_FREE(filter);
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
+       SAFE_FREE(filter);
+
        entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 result);
 
        entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 result);
 
@@ -3159,7 +3526,7 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
        smbldap_set_mod(&mods, modop,
                        get_attr_key2string(groupmap_attr_list,
                                            LDAP_ATTR_SID_LIST),
        smbldap_set_mod(&mods, modop,
                        get_attr_key2string(groupmap_attr_list,
                                            LDAP_ATTR_SID_LIST),
-                       sid_string_static(member));
+                       sid_to_fstring(tmp, member));
 
        rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
 
 
        rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
 
@@ -3207,17 +3574,18 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        int count;
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        int count;
-       char **values;
+       char **values = NULL;
        int i;
        int i;
-       pstring filter;
+       char *filter = NULL;
        size_t num_members = 0;
        size_t num_members = 0;
-       enum SID_NAME_USE type = SID_NAME_USE_NONE;
+       enum lsa_SidType type = SID_NAME_USE_NONE;
+       fstring tmp;
 
        *pp_members = NULL;
        *p_num_members = 0;
 
        if (sid_check_is_in_builtin(alias)) {
 
        *pp_members = NULL;
        *p_num_members = 0;
 
        if (sid_check_is_in_builtin(alias)) {
-               type = SID_NAME_WKN_GRP;
+               type = SID_NAME_ALIAS;
        }
 
        if (sid_check_is_in_our_domain(alias)) {
        }
 
        if (sid_check_is_in_our_domain(alias)) {
@@ -3226,18 +3594,22 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
 
        if (type == SID_NAME_USE_NONE) {
                DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
 
        if (type == SID_NAME_USE_NONE) {
                DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
-                         sid_string_static(alias)));
+                         sid_string_dbg(alias)));
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
-       pstr_sprintf(filter,
+       if (asprintf(&filter,
                     "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
                     "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
-                    LDAP_OBJ_GROUPMAP, sid_string_static(alias),
-                    type);
+                    LDAP_OBJ_GROUPMAP, sid_to_fstring(tmp, alias),
+                    type) < 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        if (ldapsam_search_one_group(ldap_state, filter,
 
        if (ldapsam_search_one_group(ldap_state, filter,
-                                    &result) != LDAP_SUCCESS)
+                                    &result) != LDAP_SUCCESS) {
+               SAFE_FREE(filter);
                return NT_STATUS_NO_SUCH_ALIAS;
                return NT_STATUS_NO_SUCH_ALIAS;
+       }
 
        count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
                                   result);
 
        count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
                                   result);
@@ -3245,6 +3617,7 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
        if (count < 1) {
                DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
                ldap_msgfree(result);
        if (count < 1) {
                DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
                ldap_msgfree(result);
+               SAFE_FREE(filter);
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
@@ -3252,9 +3625,12 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
                DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
                          "filter %s: count=%d\n", filter, count));
                ldap_msgfree(result);
                DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
                          "filter %s: count=%d\n", filter, count));
                ldap_msgfree(result);
+               SAFE_FREE(filter);
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
                return NT_STATUS_NO_SUCH_ALIAS;
        }
 
+       SAFE_FREE(filter);
+
        entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 result);
 
        entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 result);
 
@@ -3277,11 +3653,18 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
 
        for (i=0; i<count; i++) {
                DOM_SID member;
 
        for (i=0; i<count; i++) {
                DOM_SID member;
+               NTSTATUS status;
 
                if (!string_to_sid(&member, values[i]))
                        continue;
 
 
                if (!string_to_sid(&member, values[i]))
                        continue;
 
-               add_sid_to_array(NULL, &member, pp_members, &num_members);
+               status = add_sid_to_array(NULL, &member, pp_members,
+                                         &num_members);
+               if (!NT_STATUS_IS_OK(status)) {
+                       ldap_value_free(values);
+                       ldap_msgfree(result);
+                       return status;
+               }
        }
 
        *p_num_members = num_members;
        }
 
        *p_num_members = num_members;
@@ -3310,10 +3693,10 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        int i;
        int rc;
        char *filter;
        int i;
        int rc;
        char *filter;
-       enum SID_NAME_USE type = SID_NAME_USE_NONE;
+       enum lsa_SidType type = SID_NAME_USE_NONE;
 
        if (sid_check_is_builtin(domain_sid)) {
 
        if (sid_check_is_builtin(domain_sid)) {
-               type = SID_NAME_WKN_GRP;
+               type = SID_NAME_ALIAS;
        }
 
        if (sid_check_is_domain(domain_sid)) {
        }
 
        if (sid_check_is_domain(domain_sid)) {
@@ -3322,7 +3705,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
 
        if (type == SID_NAME_USE_NONE) {
                DEBUG(5, ("SID %s is neither builtin nor domain!\n",
 
        if (type == SID_NAME_USE_NONE) {
                DEBUG(5, ("SID %s is neither builtin nor domain!\n",
-                         sid_string_static(domain_sid)));
+                         sid_string_dbg(domain_sid)));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -3333,10 +3716,15 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        for (i=0; i<num_members; i++)
                filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
                                         filter,
        for (i=0; i<num_members; i++)
                filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
                                         filter,
-                                        sid_string_static(&members[i]));
+                                        sid_string_talloc(mem_ctx,
+                                                          &members[i]));
 
        filter = talloc_asprintf(mem_ctx, "%s))", filter);
 
 
        filter = talloc_asprintf(mem_ctx, "%s))", filter);
 
+       if (filter == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
                            LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
 
        rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
                            LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
 
@@ -3365,8 +3753,11 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
                if (!sid_peek_check_rid(domain_sid, &sid, &rid))
                        continue;
 
                if (!sid_peek_check_rid(domain_sid, &sid, &rid))
                        continue;
 
-               add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
-                                       p_num_alias_rids);
+               if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
+                                       p_num_alias_rids)) {
+                       ldap_msgfree(result);
+                       return NT_STATUS_NO_MEMORY;
+               }
        }
 
        ldap_msgfree(result);
        }
 
        ldap_msgfree(result);
@@ -3386,8 +3777,6 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
 
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
 
-       const char *attrs[2];
-
        DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
 
        if (!ldap_state->domain_dn) {
        DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
 
        if (!ldap_state->domain_dn) {
@@ -3401,9 +3790,6 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
                return ntstatus;
        }
 
                return ntstatus;
        }
 
-       attrs[0] = policy_attr;
-       attrs[1] = NULL;
-
        slprintf(value_string, sizeof(value_string) - 1, "%i", value);
 
        smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
        slprintf(value_string, sizeof(value_string) - 1, "%i", value);
 
        smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
@@ -3429,11 +3815,6 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
                                           int policy_index, uint32 value)
 {
 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
                                           int policy_index, uint32 value)
 {
-       if (!account_policy_migrated(False)) {
-               return (account_policy_set(policy_index, value)) ?
-                       NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-       }
-
        return ldapsam_set_account_policy_in_ldap(methods, policy_index,
                                                  value);
 }
        return ldapsam_set_account_policy_in_ldap(methods, policy_index,
                                                  value);
 }
@@ -3522,11 +3903,6 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
 
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
 
-       if (!account_policy_migrated(False)) {
-               return (account_policy_get(policy_index, value))
-                       ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-       }
-
        if (cache_account_policy_get(policy_index, value)) {
                DEBUG(11,("ldapsam_get_account_policy: got valid value from "
                          "cache\n"));
        if (cache_account_policy_get(policy_index, value)) {
                DEBUG(11,("ldapsam_get_account_policy: got valid value from "
                          "cache\n"));
@@ -3578,7 +3954,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
                                    int num_rids,
                                    uint32 *rids,
                                    const char **names,
                                    int num_rids,
                                    uint32 *rids,
                                    const char **names,
-                                   uint32 *attrs)
+                                   enum lsa_SidType *attrs)
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
@@ -3589,7 +3965,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
        NTSTATUS result = NT_STATUS_NO_MEMORY;
        TALLOC_CTX *mem_ctx;
        LDAP *ld;
        NTSTATUS result = NT_STATUS_NO_MEMORY;
        TALLOC_CTX *mem_ctx;
        LDAP *ld;
-       BOOL is_builtin;
+       bool is_builtin;
 
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
 
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
@@ -3613,10 +3989,10 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
 
        for (i=0; i<num_rids; i++) {
                DOM_SID sid;
 
        for (i=0; i<num_rids; i++) {
                DOM_SID sid;
-               sid_copy(&sid, domain_sid);
-               sid_append_rid(&sid, rids[i]);
-               allsids = talloc_asprintf_append(allsids, "(sambaSid=%s)",
-                                                sid_string_static(&sid));
+               sid_compose(&sid, domain_sid, rids[i]);
+               allsids = talloc_asprintf_append_buffer(
+                       allsids, "(sambaSid=%s)",
+                       sid_string_talloc(mem_ctx, &sid));
                if (allsids == NULL) {
                        goto done;
                }
                if (allsids == NULL) {
                        goto done;
                }
@@ -3629,8 +4005,8 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
                const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
 
                filter = talloc_asprintf(
                const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
 
                filter = talloc_asprintf(
-                       mem_ctx, ("(&(objectClass=sambaSamAccount)(|%s))"),
-                       allsids);
+                       mem_ctx, ("(&(objectClass=%s)(|%s))"),
+                       LDAP_OBJ_SAMBASAMACCOUNT, allsids);
 
                if (filter == NULL) {
                        goto done;
 
                if (filter == NULL) {
                        goto done;
@@ -3698,8 +4074,8 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
                                             "sambaGroupType", NULL };
 
                filter = talloc_asprintf(
                                             "sambaGroupType", NULL };
 
                filter = talloc_asprintf(
-                       mem_ctx, "(&(objectClass=sambaGroupMapping)(|%s))",
-                       allsids);
+                       mem_ctx, "(&(objectClass=%s)(|%s))",
+                       LDAP_OBJ_GROUPMAP, allsids);
                if (filter == NULL) {
                        goto done;
                }
                if (filter == NULL) {
                        goto done;
                }
@@ -3729,7 +4105,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
                uint32 rid;
                int rid_index;
                const char *attr;
                uint32 rid;
                int rid_index;
                const char *attr;
-               enum SID_NAME_USE type;
+               enum lsa_SidType type;
                const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
 
                attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
                const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
 
                attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
@@ -3740,10 +4116,10 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
                        continue;
                }
 
                        continue;
                }
 
-               type = atol(attr);
+               type = (enum lsa_SidType)atol(attr);
 
                /* Consistency checks */
 
                /* Consistency checks */
-               if ((is_builtin && (type != SID_NAME_WKN_GRP)) ||
+               if ((is_builtin && (type != SID_NAME_ALIAS)) ||
                    (!is_builtin && ((type != SID_NAME_ALIAS) &&
                                     (type != SID_NAME_DOM_GRP)))) {
                        DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
                    (!is_builtin && ((type != SID_NAME_ALIAS) &&
                                     (type != SID_NAME_DOM_GRP)))) {
                        DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
@@ -3827,11 +4203,18 @@ const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
                num += 1;
        va_end(ap);
 
                num += 1;
        va_end(ap);
 
-       result = TALLOC_ARRAY(mem_ctx, const char *, num+1);
+       if ((result = TALLOC_ARRAY(mem_ctx, const char *, num+1)) == NULL) {
+               return NULL;
+       }
 
        va_start(ap, mem_ctx);
 
        va_start(ap, mem_ctx);
-       for (i=0; i<num; i++)
-               result[i] = talloc_strdup(mem_ctx, va_arg(ap, const char*));
+       for (i=0; i<num; i++) {
+               result[i] = talloc_strdup(result, va_arg(ap, const char*));
+               if (result[i] == NULL) {
+                       talloc_free(result);
+                       return NULL;
+               }
+       }
        va_end(ap);
 
        result[num] = NULL;
        va_end(ap);
 
        result[num] = NULL;
@@ -3852,15 +4235,16 @@ struct ldap_search_state {
        void *pagedresults_cookie;
 
        LDAPMessage *entries, *current_entry;
        void *pagedresults_cookie;
 
        LDAPMessage *entries, *current_entry;
-       BOOL (*ldap2displayentry)(struct ldap_search_state *state,
+       bool (*ldap2displayentry)(struct ldap_search_state *state,
                                  TALLOC_CTX *mem_ctx,
                                  LDAP *ld, LDAPMessage *entry,
                                  struct samr_displayentry *result);
 };
 
                                  TALLOC_CTX *mem_ctx,
                                  LDAP *ld, LDAPMessage *entry,
                                  struct samr_displayentry *result);
 };
 
-static BOOL ldapsam_search_firstpage(struct pdb_search *search)
+static bool ldapsam_search_firstpage(struct pdb_search *search)
 {
 {
-       struct ldap_search_state *state = search->private_data;
+       struct ldap_search_state *state =
+               (struct ldap_search_state *)search->private_data;
        LDAP *ld;
        int rc = LDAP_OPERATIONS_ERROR;
 
        LDAP *ld;
        int rc = LDAP_OPERATIONS_ERROR;
 
@@ -3910,9 +4294,10 @@ static BOOL ldapsam_search_firstpage(struct pdb_search *search)
        return True;
 }
 
        return True;
 }
 
-static BOOL ldapsam_search_nextpage(struct pdb_search *search)
+static bool ldapsam_search_nextpage(struct pdb_search *search)
 {
 {
-       struct ldap_search_state *state = search->private_data;
+       struct ldap_search_state *state =
+               (struct ldap_search_state *)search->private_data;
        int rc;
 
        if (!state->connection->paged_results) {
        int rc;
 
        if (!state->connection->paged_results) {
@@ -3939,11 +4324,12 @@ static BOOL ldapsam_search_nextpage(struct pdb_search *search)
        return True;
 }
 
        return True;
 }
 
-static BOOL ldapsam_search_next_entry(struct pdb_search *search,
+static bool ldapsam_search_next_entry(struct pdb_search *search,
                                      struct samr_displayentry *entry)
 {
                                      struct samr_displayentry *entry)
 {
-       struct ldap_search_state *state = search->private_data;
-       BOOL result;
+       struct ldap_search_state *state =
+               (struct ldap_search_state *)search->private_data;
+       bool result;
 
  retry:
        if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
 
  retry:
        if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
@@ -3977,7 +4363,8 @@ static BOOL ldapsam_search_next_entry(struct pdb_search *search,
 
 static void ldapsam_search_end(struct pdb_search *search)
 {
 
 static void ldapsam_search_end(struct pdb_search *search)
 {
-       struct ldap_search_state *state = search->private_data;
+       struct ldap_search_state *state =
+               (struct ldap_search_state *)search->private_data;
        int rc;
 
        if (state->pagedresults_cookie == NULL)
        int rc;
 
        if (state->pagedresults_cookie == NULL)
@@ -4005,7 +4392,7 @@ static void ldapsam_search_end(struct pdb_search *search)
        return;
 }
 
        return;
 }
 
-static BOOL ldapuser2displayentry(struct ldap_search_state *state,
+static bool ldapuser2displayentry(struct ldap_search_state *state,
                                  TALLOC_CTX *mem_ctx,
                                  LDAP *ld, LDAPMessage *entry,
                                  struct samr_displayentry *result)
                                  TALLOC_CTX *mem_ctx,
                                  LDAP *ld, LDAPMessage *entry,
                                  struct samr_displayentry *result)
@@ -4081,7 +4468,7 @@ static BOOL ldapuser2displayentry(struct ldap_search_state *state,
 
        if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
                DEBUG(0, ("sid %s does not belong to our domain\n",
 
        if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
                DEBUG(0, ("sid %s does not belong to our domain\n",
-                         sid_string_static(&sid)));
+                         sid_string_dbg(&sid)));
                return False;
        }
 
                return False;
        }
 
@@ -4089,11 +4476,12 @@ static BOOL ldapuser2displayentry(struct ldap_search_state *state,
 }
 
 
 }
 
 
-static BOOL ldapsam_search_users(struct pdb_methods *methods,
+static bool ldapsam_search_users(struct pdb_methods *methods,
                                 struct pdb_search *search,
                                 uint32 acct_flags)
 {
                                 struct pdb_search *search,
                                 uint32 acct_flags)
 {
-       struct ldapsam_privates *ldap_state = methods->private_data;
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
        struct ldap_search_state *state;
 
        state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
        struct ldap_search_state *state;
 
        state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
@@ -4136,7 +4524,7 @@ static BOOL ldapsam_search_users(struct pdb_methods *methods,
        return ldapsam_search_firstpage(search);
 }
 
        return ldapsam_search_firstpage(search);
 }
 
-static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
+static bool ldapgroup2displayentry(struct ldap_search_state *state,
                                   TALLOC_CTX *mem_ctx,
                                   LDAP *ld, LDAPMessage *entry,
                                   struct samr_displayentry *result)
                                   TALLOC_CTX *mem_ctx,
                                   LDAP *ld, LDAPMessage *entry,
                                   struct samr_displayentry *result)
@@ -4229,25 +4617,15 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
                case SID_NAME_DOM_GRP:
                case SID_NAME_ALIAS:
 
                case SID_NAME_DOM_GRP:
                case SID_NAME_ALIAS:
 
-                       if (!sid_peek_check_rid(get_global_sam_sid(), &sid,
-                                               &result->rid)) {
+                       if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid) 
+                               && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid)) 
+                       {
                                DEBUG(0, ("%s is not in our domain\n",
                                DEBUG(0, ("%s is not in our domain\n",
-                                         sid_string_static(&sid)));
+                                         sid_string_dbg(&sid)));
                                return False;
                        }
                        break;
        
                                return False;
                        }
                        break;
        
-               case SID_NAME_WKN_GRP:
-
-                       if (!sid_peek_check_rid(&global_sid_Builtin, &sid,
-                                               &result->rid)) {
-
-                               DEBUG(0, ("%s is not in builtin sid\n",
-                                         sid_string_static(&sid)));
-                               return False;
-                       }
-                       break;
-
                default:
                        DEBUG(0,("unkown group type: %d\n", group_type));
                        return False;
                default:
                        DEBUG(0,("unkown group type: %d\n", group_type));
                        return False;
@@ -4256,12 +4634,15 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
        return True;
 }
 
        return True;
 }
 
-static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
+static bool ldapsam_search_grouptype(struct pdb_methods *methods,
                                     struct pdb_search *search,
                                     struct pdb_search *search,
-                                    enum SID_NAME_USE type)
+                                     const DOM_SID *sid,
+                                    enum lsa_SidType type)
 {
 {
-       struct ldapsam_privates *ldap_state = methods->private_data;
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
        struct ldap_search_state *state;
        struct ldap_search_state *state;
+       fstring tmp;
 
        state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
        if (state == NULL) {
 
        state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
        if (state == NULL) {
@@ -4276,7 +4657,8 @@ static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
        state->scope = LDAP_SCOPE_SUBTREE;
        state->filter = talloc_asprintf(search->mem_ctx,
                                        "(&(objectclass=sambaGroupMapping)"
        state->scope = LDAP_SCOPE_SUBTREE;
        state->filter = talloc_asprintf(search->mem_ctx,
                                        "(&(objectclass=sambaGroupMapping)"
-                                       "(sambaGroupType=%d))", type);
+                                       "(sambaGroupType=%d)(sambaSID=%s*))", 
+                                       type, sid_to_fstring(tmp, sid));
        state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
                                    "displayName", "description",
                                    "sambaGroupType", NULL);
        state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
                                    "displayName", "description",
                                    "sambaGroupType", NULL);
@@ -4298,29 +4680,20 @@ static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
        return ldapsam_search_firstpage(search);
 }
 
        return ldapsam_search_firstpage(search);
 }
 
-static BOOL ldapsam_search_groups(struct pdb_methods *methods,
+static bool ldapsam_search_groups(struct pdb_methods *methods,
                                  struct pdb_search *search)
 {
                                  struct pdb_search *search)
 {
-       return ldapsam_search_grouptype(methods, search, SID_NAME_DOM_GRP);
+       return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
 }
 
 }
 
-static BOOL ldapsam_search_aliases(struct pdb_methods *methods,
+static bool ldapsam_search_aliases(struct pdb_methods *methods,
                                   struct pdb_search *search,
                                   const DOM_SID *sid)
 {
                                   struct pdb_search *search,
                                   const DOM_SID *sid)
 {
-       if (sid_check_is_domain(sid))
-               return ldapsam_search_grouptype(methods, search,
-                                               SID_NAME_ALIAS);
-
-       if (sid_check_is_builtin(sid))
-               return ldapsam_search_grouptype(methods, search,
-                                               SID_NAME_WKN_GRP);
-
-       DEBUG(5, ("Don't know SID %s\n", sid_string_static(sid)));
-       return False;
+       return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
 }
 
 }
 
-static BOOL ldapsam_rid_algorithm(struct pdb_methods *methods)
+static bool ldapsam_rid_algorithm(struct pdb_methods *methods)
 {
        return False;
 }
 {
        return False;
 }
@@ -4337,6 +4710,7 @@ static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
        char *value;
        int rc;
        uint32 nextRid = 0;
        char *value;
        int rc;
        uint32 nextRid = 0;
+       const char *dn;
 
        TALLOC_CTX *mem_ctx;
 
 
        TALLOC_CTX *mem_ctx;
 
@@ -4400,9 +4774,12 @@ static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
                         talloc_asprintf(mem_ctx, "%d", nextRid));
        talloc_autofree_ldapmod(mem_ctx, mods);
 
                         talloc_asprintf(mem_ctx, "%d", nextRid));
        talloc_autofree_ldapmod(mem_ctx, mods);
 
-       rc = smbldap_modify(smbldap_state,
-                           smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry),
-                           mods);
+       if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       rc = smbldap_modify(smbldap_state, dn, mods);
 
        /* ACCESS_DENIED is used as a placeholder for "the modify failed,
         * please retry" */
 
        /* ACCESS_DENIED is used as a placeholder for "the modify failed,
         * please retry" */
@@ -4418,39 +4795,46 @@ static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
        return status;
 }
 
        return status;
 }
 
-static BOOL ldapsam_new_rid(struct pdb_methods *methods, uint32 *rid)
+static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32 *rid)
 {
        int i;
 
        for (i=0; i<10; i++) {
 {
        int i;
 
        for (i=0; i<10; i++) {
-               NTSTATUS result = ldapsam_get_new_rid(methods->private_data,
-                                                     rid);
+               NTSTATUS result = ldapsam_get_new_rid(
+                       (struct ldapsam_privates *)methods->private_data, rid);
                if (NT_STATUS_IS_OK(result)) {
                if (NT_STATUS_IS_OK(result)) {
-                       return True;
+                       return result;
                }
 
                if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
                }
 
                if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
-                       return False;
+                       return result;
                }
 
                /* The ldap update failed (maybe a race condition), retry */
        }
 
        /* Tried 10 times, fail. */
                }
 
                /* The ldap update failed (maybe a race condition), retry */
        }
 
        /* Tried 10 times, fail. */
-       return False;
+       return NT_STATUS_ACCESS_DENIED;
 }
 
 }
 
-static BOOL ldapsam_sid_to_id(struct pdb_methods *methods,
+static bool ldapsam_new_rid(struct pdb_methods *methods, uint32 *rid)
+{
+       NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
+       return NT_STATUS_IS_OK(result) ? True : False;
+}
+
+static bool ldapsam_sid_to_id(struct pdb_methods *methods,
                              const DOM_SID *sid,
                              const DOM_SID *sid,
-                             union unid_t *id, enum SID_NAME_USE *type)
+                             union unid_t *id, enum lsa_SidType *type)
 {
 {
-       struct ldapsam_privates *priv = methods->private_data;
+       struct ldapsam_privates *priv =
+               (struct ldapsam_privates *)methods->private_data;
        char *filter;
        const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
                                NULL };
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        char *filter;
        const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
                                NULL };
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
-       BOOL ret = False;
+       bool ret = False;
        char *value;
        int rc;
 
        char *value;
        int rc;
 
@@ -4464,9 +4848,9 @@ static BOOL ldapsam_sid_to_id(struct pdb_methods *methods,
 
        filter = talloc_asprintf(mem_ctx,
                                 "(&(sambaSid=%s)"
 
        filter = talloc_asprintf(mem_ctx,
                                 "(&(sambaSid=%s)"
-                                "(|(objectClass=sambaGroupMapping)"
-                                "(objectClass=sambaSamAccount)))",
-                                sid_string_static(sid));
+                                "(|(objectClass=%s)(objectClass=%s)))",
+                                sid_string_talloc(mem_ctx, sid),
+                                LDAP_OBJ_GROUPMAP, LDAP_OBJ_SAMBASAMACCOUNT);
        if (filter == NULL) {
                DEBUG(5, ("talloc_asprintf failed\n"));
                goto done;
        if (filter == NULL) {
                DEBUG(5, ("talloc_asprintf failed\n"));
                goto done;
@@ -4504,7 +4888,7 @@ static BOOL ldapsam_sid_to_id(struct pdb_methods *methods,
                }
 
                id->gid = strtoul(gid_str, NULL, 10);
                }
 
                id->gid = strtoul(gid_str, NULL, 10);
-               *type = strtoul(value, NULL, 10);
+               *type = (enum lsa_SidType)strtoul(value, NULL, 10);
                ret = True;
                goto done;
        }
                ret = True;
                goto done;
        }
@@ -4550,8 +4934,8 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
        uint32 num_result;
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
        uint32 num_result;
-       BOOL is_machine = False;
-       BOOL add_posix = False;
+       bool is_machine = False;
+       bool add_posix = False;
        LDAPMod **mods = NULL;
        struct samu *user;
        char *filter;
        LDAPMod **mods = NULL;
        struct samu *user;
        char *filter;
@@ -4568,12 +4952,16 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
        NTSTATUS ret;
        int rc;
        
        NTSTATUS ret;
        int rc;
        
-       if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') {
+       if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
+             acb_info & ACB_WSTRUST ||
+             acb_info & ACB_SVRTRUST ||
+             acb_info & ACB_DOMTRUST) {
                is_machine = True;
        }
 
        username = escape_ldap_string_alloc(name);
                is_machine = True;
        }
 
        username = escape_ldap_string_alloc(name);
-       filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=posixAccount))", username);
+       filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
+                                username, LDAP_OBJ_POSIXACCOUNT);
        SAFE_FREE(username);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        SAFE_FREE(username);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
@@ -4620,13 +5008,12 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
        }
        
        /* Create the basic samu structure and generate the mods for the ldap commit */
        }
        
        /* Create the basic samu structure and generate the mods for the ldap commit */
-       if (!NT_STATUS_IS_OK((ret = ldapsam_get_new_rid(ldap_state, rid)))) {
+       if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
                DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
                return ret;
        }
 
                DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
                return ret;
        }
 
-       sid_copy(&user_sid, get_global_sam_sid());
-       sid_append_rid(&user_sid, *rid);
+       sid_compose(&user_sid, get_global_sam_sid(), *rid);
 
        user = samu_new(tmp_ctx);
        if (!user) {
 
        user = samu_new(tmp_ctx);
        if (!user) {
@@ -4643,9 +5030,16 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
                return NT_STATUS_UNSUCCESSFUL;
        }
        if (is_machine) {
                return NT_STATUS_UNSUCCESSFUL;
        }
        if (is_machine) {
-               if (!pdb_set_acct_ctrl(user, ACB_WSTRUST | ACB_DISABLED, PDB_SET)) {
-                       DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
-                       return NT_STATUS_UNSUCCESSFUL;
+               if (acb_info & ACB_NORMAL) {
+                       if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
+                               DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
+               } else {
+                       if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
+                               DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
                }
        } else {
                if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
                }
        } else {
                if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
@@ -4664,19 +5058,14 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       switch ( ldap_state->schema_ver ) {
-               case SCHEMAVER_SAMBAACCOUNT:
-                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBAACCOUNT);
-                       break;
-               case SCHEMAVER_SAMBASAMACCOUNT:
-                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
-                       break;
-               default:
-                       DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
-                       break;
+       if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
+               DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
        }
        }
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
 
        if (add_posix) {
 
        if (add_posix) {
+               char *escape_name;
+
                DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
 
                /* retrieve the Domain Users group gid */
                DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
 
                /* retrieve the Domain Users group gid */
@@ -4703,12 +5092,21 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
                }
                uidstr = talloc_asprintf(tmp_ctx, "%d", uid);
                gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
                }
                uidstr = talloc_asprintf(tmp_ctx, "%d", uid);
                gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
+
+               escape_name = escape_rdn_val_string_alloc(name);
+               if (!escape_name) {
+                       DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+
                if (is_machine) {
                if (is_machine) {
-                       dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", name, lp_ldap_machine_suffix ());
+                       dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix ());
                } else {
                } else {
-                       dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", name, lp_ldap_user_suffix ());
+                       dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix ());
                }
 
                }
 
+               SAFE_FREE(escape_name);
+
                if (!homedir || !shell || !uidstr || !gidstr || !dn) {
                        DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
                        return NT_STATUS_NO_MEMORY;
                if (!homedir || !shell || !uidstr || !gidstr || !dn) {
                        DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
                        return NT_STATUS_NO_MEMORY;
@@ -4757,9 +5155,14 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *
        
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(uid=%s)"
        
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(uid=%s)"
-                                "(objectClass=posixAccount)"
-                                "(objectClass=sambaSamAccount))",
-                                pdb_get_username(sam_acct));
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                pdb_get_username(sam_acct),
+                                LDAP_OBJ_POSIXACCOUNT,
+                                LDAP_OBJ_SAMBASAMACCOUNT);
+       if (filter == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
@@ -4820,7 +5223,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
        uint32 num_result;
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
        uint32 num_result;
-       BOOL is_new_entry = False;
+       bool is_new_entry = False;
        LDAPMod **mods = NULL;
        char *filter;
        char *groupsidstr;
        LDAPMod **mods = NULL;
        char *filter;
        char *groupsidstr;
@@ -4833,7 +5236,8 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        int rc;
        
        groupname = escape_ldap_string_alloc(name);
        int rc;
        
        groupname = escape_ldap_string_alloc(name);
-       filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=posixGroup))", groupname);
+       filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
+                                groupname, LDAP_OBJ_POSIXGROUP);
        SAFE_FREE(groupname);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        SAFE_FREE(groupname);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
@@ -4884,6 +5288,8 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        }
 
        if (num_result == 0) {
        }
 
        if (num_result == 0) {
+               char *escape_name;
+
                DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
 
                is_new_entry = True;
                DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
 
                is_new_entry = True;
@@ -4895,7 +5301,16 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
                }
 
                gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
                }
 
                gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
-               dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", name, lp_ldap_group_suffix());
+
+               escape_name = escape_rdn_val_string_alloc(name);
+               if (!escape_name) {
+                       DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix());
+
+               SAFE_FREE(escape_name);
 
                if (!gidstr || !dn) {
                        DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
 
                if (!gidstr || !dn) {
                        DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
@@ -4907,15 +5322,15 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
        }
 
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
        }
 
-       if (!NT_STATUS_IS_OK((ret = ldapsam_get_new_rid(ldap_state, rid)))) {
+       if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
                DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
                return ret;
        }
 
                DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
                return ret;
        }
 
-       sid_copy(&group_sid, get_global_sam_sid());
-       sid_append_rid(&group_sid, *rid);
+       sid_compose(&group_sid, get_global_sam_sid(), *rid);
 
 
-       groupsidstr = talloc_strdup(tmp_ctx, sid_string_static(&group_sid));
+       groupsidstr = talloc_strdup(tmp_ctx, sid_string_talloc(tmp_ctx,
+                                                              &group_sid));
        grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
 
        if (!groupsidstr || !grouptype) {
        grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
 
        if (!groupsidstr || !grouptype) {
@@ -4923,7 +5338,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
                return NT_STATUS_NO_MEMORY;
        }
 
                return NT_STATUS_NO_MEMORY;
        }
 
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "sambaGroupMapping");
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
@@ -4966,14 +5381,18 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_
        int rc;
 
        /* get the group sid */
        int rc;
 
        /* get the group sid */
-       sid_copy(&group_sid, get_global_sam_sid());
-       sid_append_rid(&group_sid, rid);
+       sid_compose(&group_sid, get_global_sam_sid(), rid);
 
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(sambaSID=%s)"
 
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(sambaSID=%s)"
-                                "(objectClass=posixGroup)"
-                                "(objectClass=sambaGroupMapping))",
-                                sid_string_static(&group_sid));
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                sid_string_talloc(tmp_ctx, &group_sid),
+                                LDAP_OBJ_POSIXGROUP,
+                                LDAP_OBJ_GROUPMAP);
+       if (filter == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
@@ -5015,9 +5434,11 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_
        /* check no user have this group marked as primary group */
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(gidNumber=%s)"
        /* check no user have this group marked as primary group */
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(gidNumber=%s)"
-                                "(objectClass=posixAccount)"
-                                "(objectClass=sambaSamAccount))",
-                                gidstr);
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                gidstr,
+                                LDAP_OBJ_POSIXACCOUNT,
+                                LDAP_OBJ_SAMBASAMACCOUNT);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
@@ -5071,18 +5492,21 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
        }
        
        /* get member sid  */
        }
        
        /* get member sid  */
-       sid_copy(&member_sid, get_global_sam_sid());
-       sid_append_rid(&member_sid, member_rid);
+       sid_compose(&member_sid, get_global_sam_sid(), member_rid);
 
        /* get the group sid */
 
        /* get the group sid */
-       sid_copy(&group_sid, get_global_sam_sid());
-       sid_append_rid(&group_sid, group_rid);
+       sid_compose(&group_sid, get_global_sam_sid(), group_rid);
 
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(sambaSID=%s)"
 
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(sambaSID=%s)"
-                                "(objectClass=posixAccount)"
-                                "(objectClass=sambaSamAccount))",
-                                sid_string_static(&member_sid));
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                sid_string_talloc(tmp_ctx, &member_sid),
+                                LDAP_OBJ_POSIXACCOUNT,
+                                LDAP_OBJ_SAMBASAMACCOUNT);
+       if (filter == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        /* get the member uid */
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
 
        /* get the member uid */
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
@@ -5128,7 +5552,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
                }
 
                if (user_gid == group_gid) {
                }
 
                if (user_gid == group_gid) {
-                       DEBUG (3, ("ldapsam_change_groupmem: can't remove user from it's own primary group!\n"));
+                       DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
                        return NT_STATUS_MEMBERS_PRIMARY_GROUP;
                }
        }
                        return NT_STATUS_MEMBERS_PRIMARY_GROUP;
                }
        }
@@ -5142,9 +5566,11 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
 
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(sambaSID=%s)"
 
        filter = talloc_asprintf(tmp_ctx,
                                 "(&(sambaSID=%s)"
-                                "(objectClass=posixGroup)"
-                                "(objectClass=sambaGroupMapping))",
-                                sid_string_static(&group_sid));
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                sid_string_talloc(tmp_ctx, &group_sid),
+                                LDAP_OBJ_POSIXGROUP,
+                                LDAP_OBJ_GROUPMAP);
 
        /* get the group */
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
 
        /* get the group */
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
@@ -5223,6 +5649,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
        uint32 num_result;
        LDAPMod **mods = NULL;
        char *filter;
        uint32 num_result;
        LDAPMod **mods = NULL;
        char *filter;
+       char *escape_username;
        char *gidstr;
        const char *dn = NULL;
        gid_t gid;
        char *gidstr;
        const char *dn = NULL;
        gid_t gid;
@@ -5239,12 +5666,25 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
                DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
                return NT_STATUS_NO_MEMORY;
        }
                DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
                return NT_STATUS_NO_MEMORY;
        }
-       
+
+       escape_username = escape_ldap_string_alloc(pdb_get_username(sampass));
+       if (escape_username== NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        filter = talloc_asprintf(mem_ctx,
                                 "(&(uid=%s)"
        filter = talloc_asprintf(mem_ctx,
                                 "(&(uid=%s)"
-                                "(objectClass=posixAccount)"
-                                "(objectClass=sambaSamAccount))",
-                                pdb_get_username(sampass));
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                escape_username,
+                                LDAP_OBJ_POSIXACCOUNT,
+                                LDAP_OBJ_SAMBASAMACCOUNT);
+
+       SAFE_FREE(escape_username);
+
+       if (filter == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
@@ -5297,6 +5737,317 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
 
+
+/**********************************************************************
+ trusted domains functions
+ *********************************************************************/
+
+static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
+                          const char *domain)
+{
+       return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
+                              ldap_state->domain_dn);
+}
+
+static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
+                                 const char *domain, LDAPMessage **entry)
+{
+       int rc;
+       char *filter;
+       int scope = LDAP_SCOPE_SUBTREE;
+       const char **attrs = NULL; /* NULL: get all attrs */
+       int attrsonly = 0; /* 0: return values too */
+       LDAPMessage *result = NULL;
+       char *trusted_dn;
+       uint32 num_result;
+
+       filter = talloc_asprintf(talloc_tos(),
+                                "(&(objectClass=%s)(sambaDomainName=%s))",
+                                LDAP_OBJ_TRUSTDOM_PASSWORD, domain);
+
+       trusted_dn = trusteddom_dn(ldap_state, domain);
+       if (trusted_dn == NULL) {
+               return False;
+       }
+       rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
+                           filter, attrs, attrsonly, &result);
+
+       if (rc == LDAP_NO_SUCH_OBJECT) {
+               *entry = NULL;
+               return True;
+       }
+
+       if (rc != LDAP_SUCCESS) {
+               return False;
+       }
+
+       num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+       if (num_result > 1) {
+               DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
+                         "sambaTrustedDomainPassword object for domain '%s'"
+                         "?!\n", domain));
+               return False;
+       }
+
+       if (num_result == 0) {
+               DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
+                         "sambaTrustedDomainPassword object for domain %s.\n",
+                         domain));
+               *entry = NULL;
+       } else {
+               *entry = ldap_first_entry(priv2ld(ldap_state), result);
+       }
+
+       return True;
+}
+
+static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
+                                     const char *domain,
+                                     char** pwd,
+                                     DOM_SID *sid,
+                                     time_t *pass_last_set_time)
+{
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
+       LDAPMessage *entry = NULL;
+
+       DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
+
+       if (!get_trusteddom_pw_int(ldap_state, domain, &entry) ||
+           (entry == NULL))
+       {
+               return False;
+       }
+
+       /* password */
+       if (pwd != NULL) {
+               char *pwd_str;
+               pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
+                               entry, "sambaClearTextPassword", talloc_tos());
+               if (pwd_str == NULL) {
+                       return False;
+               }
+               /* trusteddom_pw routines do not use talloc yet... */
+               *pwd = SMB_STRDUP(pwd_str);
+               if (*pwd == NULL) {
+                       return False;
+               }
+       }
+
+       /* last change time */
+       if (pass_last_set_time != NULL) {
+               char *time_str;
+               time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
+                               entry, "sambaPwdLastSet", talloc_tos());
+               if (time_str == NULL) {
+                       return False;
+               }
+               *pass_last_set_time = (time_t)atol(time_str);
+       }
+
+       /* domain sid */
+       if (sid != NULL) {
+               char *sid_str;
+               DOM_SID *dom_sid;
+               sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
+                                                         entry, "sambaSID",
+                                                         talloc_tos());
+               if (sid_str == NULL) {
+                       return False;
+               }
+               dom_sid = string_sid_talloc(talloc_tos(), sid_str);
+               if (dom_sid == NULL) {
+                       return False;
+               }
+               sid_copy(sid, dom_sid);
+       }
+
+       return True;
+}
+
+static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
+                                     const char* domain,
+                                     const char* pwd,
+                                     const DOM_SID *sid)
+{
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
+       LDAPMessage *entry = NULL;
+       LDAPMod **mods = NULL;
+       char *prev_pwd = NULL;
+       char *trusted_dn = NULL;
+       int rc;
+
+       DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
+
+       /*
+        * get the current entry (if there is one) in order to put the
+        * current password into the previous password attribute
+        */
+       if (!get_trusteddom_pw_int(ldap_state, domain, &entry)) {
+               return False;
+       }
+
+       mods = NULL;
+       smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
+                        "sambaTrustedDomainPassword");
+       smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
+                        domain);
+       smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
+                        sid_string_tos(sid));
+       smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
+                        talloc_asprintf(talloc_tos(), "%li", time(NULL)));
+       smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
+                        "sambaClearTextPassword", pwd);
+       if (entry != NULL) {
+               prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
+                               entry, "sambaClearTextPassword", talloc_tos());
+               if (prev_pwd != NULL) {
+                       smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
+                                        "sambaPreviousClearTextPassword",
+                                        prev_pwd);
+               }
+       }
+
+       trusted_dn = trusteddom_dn(ldap_state, domain);
+       if (trusted_dn == NULL) {
+               return False;
+       }
+       if (entry == NULL) {
+               rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
+       } else {
+               rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
+       }
+
+       if (rc != LDAP_SUCCESS) {
+               DEBUG(1, ("error writing trusted domain password!\n"));
+               return False;
+       }
+
+       return True;
+}
+
+static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
+                                     const char *domain)
+{
+       int rc;
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
+       LDAPMessage *entry = NULL;
+       const char *trusted_dn;
+
+       if (!get_trusteddom_pw_int(ldap_state, domain, &entry)) {
+               return False;
+       }
+
+       if (entry == NULL) {
+               DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
+                         "%s\n", domain));
+               return True;
+       }
+
+       trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
+                                      entry);
+       if (trusted_dn == NULL) {
+               DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
+               return False;
+       }
+
+       rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
+       if (rc != LDAP_SUCCESS) {
+               return False;
+       }
+
+       return True;
+}
+
+static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
+                                        TALLOC_CTX *mem_ctx,
+                                        uint32 *num_domains,
+                                        struct trustdom_info ***domains)
+{
+       int rc;
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
+       char *filter;
+       int scope = LDAP_SCOPE_SUBTREE;
+       const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
+       int attrsonly = 0; /* 0: return values too */
+       LDAPMessage *result = NULL;
+       LDAPMessage *entry = NULL;
+
+       filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)",
+                                LDAP_OBJ_TRUSTDOM_PASSWORD);
+
+       rc = smbldap_search(ldap_state->smbldap_state,
+                           ldap_state->domain_dn,
+                           scope,
+                           filter,
+                           attrs,
+                           attrsonly,
+                           &result);
+
+       if (rc != LDAP_SUCCESS) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       *num_domains = 0;
+       if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
+               DEBUG(1, ("talloc failed\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (entry = ldap_first_entry(priv2ld(ldap_state), result);
+            entry != NULL;
+            entry = ldap_next_entry(priv2ld(ldap_state), entry))
+       {
+               char *dom_name, *dom_sid_str;
+               struct trustdom_info *dom_info;
+
+               dom_info = TALLOC_P(*domains, struct trustdom_info);
+               if (dom_info == NULL) {
+                       DEBUG(1, ("talloc failed\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
+                                                          entry,
+                                                          "sambaDomainName",
+                                                          talloc_tos());
+               if (dom_name == NULL) {
+                       DEBUG(1, ("talloc failed\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+               dom_info->name = dom_name;
+
+               dom_sid_str = smbldap_talloc_single_attribute(
+                                       priv2ld(ldap_state), entry, "sambaSID",
+                                       talloc_tos());
+               if (dom_sid_str == NULL) {
+                       DEBUG(1, ("talloc failed\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+               if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
+                       DEBUG(1, ("Error calling string_to_sid on SID %s\n",
+                                 dom_sid_str));
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+
+               ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
+                            domains, num_domains);
+
+               if (*domains == NULL) {
+                       DEBUG(1, ("talloc failed\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
+       return NT_STATUS_OK;
+}
+
+
 /**********************************************************************
  Housekeeping
  *********************************************************************/
 /**********************************************************************
  Housekeeping
  *********************************************************************/
@@ -5336,9 +6087,6 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c
 
        (*pdb_method)->name = "ldapsam";
 
 
        (*pdb_method)->name = "ldapsam";
 
-       (*pdb_method)->setsampwent = ldapsam_setsampwent;
-       (*pdb_method)->endsampwent = ldapsam_endsampwent;
-       (*pdb_method)->getsampwent = ldapsam_getsampwent;
        (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
        (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
        (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
        (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
        (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
        (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
@@ -5362,6 +6110,11 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c
        (*pdb_method)->rid_algorithm = ldapsam_rid_algorithm;
        (*pdb_method)->new_rid = ldapsam_new_rid;
 
        (*pdb_method)->rid_algorithm = ldapsam_rid_algorithm;
        (*pdb_method)->new_rid = ldapsam_new_rid;
 
+       (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
+       (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
+       (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
+       (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
+
        /* TODO: Setup private data and free */
 
        if ( !(ldap_state = TALLOC_ZERO_P(*pdb_method, struct ldapsam_privates)) ) {
        /* TODO: Setup private data and free */
 
        if ( !(ldap_state = TALLOC_ZERO_P(*pdb_method, struct ldapsam_privates)) ) {
@@ -5369,7 +6122,8 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c
                return NT_STATUS_NO_MEMORY;
        }
 
                return NT_STATUS_NO_MEMORY;
        }
 
-       nt_status = smbldap_init(*pdb_method, location, &ldap_state->smbldap_state);
+       nt_status = smbldap_init(*pdb_method, pdb_get_event_context(),
+                                location, &ldap_state->smbldap_state);
 
        if ( !NT_STATUS_IS_OK(nt_status) ) {
                return nt_status;
 
        if ( !NT_STATUS_IS_OK(nt_status) ) {
                return nt_status;
@@ -5396,35 +6150,18 @@ NTSTATUS pdb_init_ldapsam_compat(struct pdb_methods **pdb_method, const char *lo
        struct ldapsam_privates *ldap_state;
        char *uri = talloc_strdup( NULL, location );
 
        struct ldapsam_privates *ldap_state;
        char *uri = talloc_strdup( NULL, location );
 
-#ifdef WITH_LDAP_SAMCONFIG
-       if (!uri) {
-               int ldap_port = lp_ldap_port();
-                       
-               /* remap default port if not using SSL (ie clear or TLS) */
-               if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
-                       ldap_port = 389;
-               }
-
-               uri = talloc_asprintf(NULL, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
-               if (!uri) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               location = uri;
-       }
-#endif
+       trim_char( uri, '\"', '\"' );
+       nt_status = pdb_init_ldapsam_common( pdb_method, uri );
+       if ( uri )
+               TALLOC_FREE( uri );
 
 
-       if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common( pdb_method, uri ))) {
+       if ( !NT_STATUS_IS_OK(nt_status) ) {
                return nt_status;
        }
 
                return nt_status;
        }
 
-       /* the module itself stores a copy of the location so throw this one away */
-
-       if ( uri )
-               TALLOC_FREE( uri );
-
        (*pdb_method)->name = "ldapsam_compat";
 
        (*pdb_method)->name = "ldapsam_compat";
 
-       ldap_state = (*pdb_method)->private_data;
+       ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
        ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
 
        sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
        ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
 
        sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
@@ -5439,17 +6176,23 @@ NTSTATUS pdb_init_ldapsam_compat(struct pdb_methods **pdb_method, const char *lo
 NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
 {
        NTSTATUS nt_status;
 NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
 {
        NTSTATUS nt_status;
-       struct ldapsam_privates *ldap_state;
+       struct ldapsam_privates *ldap_state = NULL;
        uint32 alg_rid_base;
        uint32 alg_rid_base;
-       pstring alg_rid_base_string;
+       char *alg_rid_base_string = NULL;
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        DOM_SID ldap_domain_sid;
        DOM_SID secrets_domain_sid;
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
        DOM_SID ldap_domain_sid;
        DOM_SID secrets_domain_sid;
-       pstring domain_sid_string;
-       char *dn;
+       char *domain_sid_string = NULL;
+       char *dn = NULL;
+       char *uri = talloc_strdup( NULL, location );
+
+       trim_char( uri, '\"', '\"' );
+       nt_status = pdb_init_ldapsam_common(pdb_method, uri);
+       if (uri) {
+               TALLOC_FREE(uri);
+       }
 
 
-       nt_status = pdb_init_ldapsam_common(pdb_method, location);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -5470,7 +6213,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
                        ldapsam_enum_group_memberships;
                (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
                (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
                        ldapsam_enum_group_memberships;
                (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
                (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
-               
+
                if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
                        (*pdb_method)->create_user = ldapsam_create_user;
                        (*pdb_method)->delete_user = ldapsam_delete_user;
                if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
                        (*pdb_method)->create_user = ldapsam_create_user;
                        (*pdb_method)->delete_user = ldapsam_delete_user;
@@ -5482,15 +6225,15 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
                }
        }
 
                }
        }
 
-       ldap_state = (*pdb_method)->private_data;
+       ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
        ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
 
        /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
        ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
 
        /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
-       
+
        nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
        nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
-                                              &result, 
+                                              &result,
                                               ldap_state->domain_name, True);
                                               ldap_state->domain_name, True);
-       
+
        if ( !NT_STATUS_IS_OK(nt_status) ) {
                DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain "
                          "info, nor add one to the domain\n"));
        if ( !NT_STATUS_IS_OK(nt_status) ) {
                DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain "
                          "info, nor add one to the domain\n"));
@@ -5503,7 +6246,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
 
        /* Given that the above might fail, everything below this must be
         * optional */
 
        /* Given that the above might fail, everything below this must be
         * optional */
-       
+
        entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 result);
        if (!entry) {
        entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 result);
        if (!entry) {
@@ -5515,61 +6258,66 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
 
        dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
        if (!dn) {
 
        dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
        if (!dn) {
+               ldap_msgfree(result);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
        ldap_state->domain_dn = smb_xstrdup(dn);
        ldap_memfree(dn);
 
                return NT_STATUS_UNSUCCESSFUL;
        }
 
        ldap_state->domain_dn = smb_xstrdup(dn);
        ldap_memfree(dn);
 
-       if (smbldap_get_single_pstring(
+       domain_sid_string = smbldap_talloc_single_attribute(
                    ldap_state->smbldap_state->ldap_struct,
                    ldap_state->smbldap_state->ldap_struct,
-                   entry, 
+                   entry,
                    get_userattr_key2string(ldap_state->schema_ver,
                    get_userattr_key2string(ldap_state->schema_ver,
-                                           LDAP_ATTR_USER_SID), 
-                   domain_sid_string)) {
-               BOOL found_sid;
+                                           LDAP_ATTR_USER_SID),
+                   talloc_tos());
+
+       if (domain_sid_string) {
+               bool found_sid;
                if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
                        DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
                                  "read as a valid SID\n", domain_sid_string));
                if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
                        DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
                                  "read as a valid SID\n", domain_sid_string));
+                       ldap_msgfree(result);
+                       TALLOC_FREE(domain_sid_string);
                        return NT_STATUS_INVALID_PARAMETER;
                }
                found_sid = secrets_fetch_domain_sid(ldap_state->domain_name,
                                                     &secrets_domain_sid);
                if (!found_sid || !sid_equal(&secrets_domain_sid,
                                             &ldap_domain_sid)) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
                found_sid = secrets_fetch_domain_sid(ldap_state->domain_name,
                                                     &secrets_domain_sid);
                if (!found_sid || !sid_equal(&secrets_domain_sid,
                                             &ldap_domain_sid)) {
-                       fstring new_sid_str, old_sid_str;
                        DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
                                  "%s based on pdb_ldap results %s -> %s\n",
                                  ldap_state->domain_name,
                        DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
                                  "%s based on pdb_ldap results %s -> %s\n",
                                  ldap_state->domain_name,
-                                 sid_to_string(old_sid_str,
-                                               &secrets_domain_sid),
-                                 sid_to_string(new_sid_str,
-                                               &ldap_domain_sid)));
-                       
+                                 sid_string_dbg(&secrets_domain_sid),
+                                 sid_string_dbg(&ldap_domain_sid)));
+
                        /* reset secrets.tdb sid */
                        secrets_store_domain_sid(ldap_state->domain_name,
                                                 &ldap_domain_sid);
                        DEBUG(1, ("New global sam SID: %s\n",
                        /* reset secrets.tdb sid */
                        secrets_store_domain_sid(ldap_state->domain_name,
                                                 &ldap_domain_sid);
                        DEBUG(1, ("New global sam SID: %s\n",
-                                 sid_to_string(new_sid_str,
-                                               get_global_sam_sid())));
+                                 sid_string_dbg(get_global_sam_sid())));
                }
                sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
                }
                sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
+               TALLOC_FREE(domain_sid_string);
        }
 
        }
 
-       if (smbldap_get_single_pstring(
+       alg_rid_base_string = smbldap_talloc_single_attribute(
                    ldap_state->smbldap_state->ldap_struct,
                    ldap_state->smbldap_state->ldap_struct,
-                   entry, 
+                   entry,
                    get_attr_key2string( dominfo_attr_list,
                                         LDAP_ATTR_ALGORITHMIC_RID_BASE ),
                    get_attr_key2string( dominfo_attr_list,
                                         LDAP_ATTR_ALGORITHMIC_RID_BASE ),
-                   alg_rid_base_string)) {
+                   talloc_tos());
+       if (alg_rid_base_string) {
                alg_rid_base = (uint32)atol(alg_rid_base_string);
                if (alg_rid_base != algorithmic_rid_base()) {
                        DEBUG(0, ("The value of 'algorithmic RID base' has "
                                  "changed since the LDAP\n"
                                  "database was initialised.  Aborting. \n"));
                        ldap_msgfree(result);
                alg_rid_base = (uint32)atol(alg_rid_base_string);
                if (alg_rid_base != algorithmic_rid_base()) {
                        DEBUG(0, ("The value of 'algorithmic RID base' has "
                                  "changed since the LDAP\n"
                                  "database was initialised.  Aborting. \n"));
                        ldap_msgfree(result);
+                       TALLOC_FREE(alg_rid_base_string);
                        return NT_STATUS_UNSUCCESSFUL;
                }
                        return NT_STATUS_UNSUCCESSFUL;
                }
+               TALLOC_FREE(alg_rid_base_string);
        }
        ldap_msgfree(result);
 
        }
        ldap_msgfree(result);