r4925: Migrate Account Policies to passdb (esp. replicating ldapsam).
[vlendec/samba-autobuild/.git] / source3 / passdb / pdb_ldap.c
1 /* 
2    Unix SMB/CIFS implementation.
3    LDAP protocol helper functions for SAMBA
4    Copyright (C) Jean François Micouleau        1998
5    Copyright (C) Gerald Carter                  2001-2003
6    Copyright (C) Shahms King                    2001
7    Copyright (C) Andrew Bartlett                2002-2003
8    Copyright (C) Stefan (metze) Metzmacher      2002-2003
9     
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23    
24 */
25
26 /* TODO:
27 *  persistent connections: if using NSS LDAP, many connections are made
28 *      however, using only one within Samba would be nice
29 *  
30 *  Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
31 *
32 *  Other LDAP based login attributes: accountExpires, etc.
33 *  (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
34 *  structures don't have fields for some of these attributes)
35 *
36 *  SSL is done, but can't get the certificate based authentication to work
37 *  against on my test platform (Linux 2.4, OpenLDAP 2.x)
38 */
39
40 /* NOTE: this will NOT work against an Active Directory server
41 *  due to the fact that the two password fields cannot be retrieved
42 *  from a server; recommend using security = domain in this situation
43 *  and/or winbind
44 */
45
46 #include "includes.h"
47
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_PASSDB
50
51 #include <lber.h>
52 #include <ldap.h>
53
54 /*
55  * Work around versions of the LDAP client libs that don't have the OIDs
56  * defined, or have them defined under the old name.  
57  * This functionality is really a factor of the server, not the client 
58  *
59  */
60
61 #if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
62 #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
63 #elif !defined(LDAP_EXOP_MODIFY_PASSWD)
64 #define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
65 #endif
66
67 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
68 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
69 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
70 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID        ((ber_tag_t) 0x80U)
71 #endif
72
73 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
74 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
75 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
76 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW       ((ber_tag_t) 0x82U)
77 #endif
78
79
80 #ifndef SAM_ACCOUNT
81 #define SAM_ACCOUNT struct sam_passwd
82 #endif
83
84 #include "smbldap.h"
85
86 struct ldapsam_privates {
87         struct smbldap_state *smbldap_state;
88
89         /* Former statics */
90         LDAPMessage *result;
91         LDAPMessage *entry;
92         int index;
93         
94         const char *domain_name;
95         DOM_SID domain_sid;
96         
97         /* configuration items */
98         int schema_ver;
99 };
100
101 /**********************************************************************
102  Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
103  **********************************************************************/
104  
105 static void private_data_free_fn(void **result) 
106 {
107         ldap_msgfree(*result);
108         *result = NULL;
109 }
110
111 /**********************************************************************
112  Get the attribute name given a user schame version.
113  **********************************************************************/
114  
115 static const char* get_userattr_key2string( int schema_ver, int key )
116 {
117         switch ( schema_ver ) {
118                 case SCHEMAVER_SAMBAACCOUNT:
119                         return get_attr_key2string( attrib_map_v22, key );
120                         
121                 case SCHEMAVER_SAMBASAMACCOUNT:
122                         return get_attr_key2string( attrib_map_v30, key );
123                         
124                 default:
125                         DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
126                         break;
127         }
128         return NULL;
129 }
130
131 /**********************************************************************
132  Return the list of attribute names given a user schema version.
133 **********************************************************************/
134
135 static char** get_userattr_list( int schema_ver )
136 {
137         switch ( schema_ver ) {
138                 case SCHEMAVER_SAMBAACCOUNT:
139                         return get_attr_list( attrib_map_v22 );
140                         
141                 case SCHEMAVER_SAMBASAMACCOUNT:
142                         return get_attr_list( attrib_map_v30 );
143                 default:
144                         DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
145                         break;
146         }
147         
148         return NULL;
149 }
150
151 /**************************************************************************
152  Return the list of attribute names to delete given a user schema version.
153 **************************************************************************/
154
155 static char** get_userattr_delete_list( int schema_ver )
156 {
157         switch ( schema_ver ) {
158                 case SCHEMAVER_SAMBAACCOUNT:
159                         return get_attr_list( attrib_map_to_delete_v22 );
160                         
161                 case SCHEMAVER_SAMBASAMACCOUNT:
162                         return get_attr_list( attrib_map_to_delete_v30 );
163                 default:
164                         DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
165                         break;
166         }
167         
168         return NULL;
169 }
170
171
172 /*******************************************************************
173  Generate the LDAP search filter for the objectclass based on the 
174  version of the schema we are using.
175 ******************************************************************/
176
177 static const char* get_objclass_filter( int schema_ver )
178 {
179         static fstring objclass_filter;
180         
181         switch( schema_ver ) {
182                 case SCHEMAVER_SAMBAACCOUNT:
183                         fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
184                         break;
185                 case SCHEMAVER_SAMBASAMACCOUNT:
186                         fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
187                         break;
188                 default:
189                         DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
190                         break;
191         }
192         
193         return objclass_filter; 
194 }
195
196 /*******************************************************************
197  Run the search by name.
198 ******************************************************************/
199
200 static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state, 
201                                           const char *user,
202                                           LDAPMessage ** result, char **attr)
203 {
204         pstring filter;
205         char *escape_user = escape_ldap_string_alloc(user);
206
207         if (!escape_user) {
208                 return LDAP_NO_MEMORY;
209         }
210
211         /*
212          * in the filter expression, replace %u with the real name
213          * so in ldap filter, %u MUST exist :-)
214          */
215         pstr_sprintf(filter, "(&%s%s)", lp_ldap_filter(), 
216                 get_objclass_filter(ldap_state->schema_ver));
217
218         /* 
219          * have to use this here because $ is filtered out
220            * in pstring_sub
221          */
222         
223
224         all_string_sub(filter, "%u", escape_user, sizeof(pstring));
225         SAFE_FREE(escape_user);
226
227         return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
228 }
229
230 /*******************************************************************
231  Run the search by rid.
232 ******************************************************************/
233
234 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state, 
235                                          uint32 rid, LDAPMessage ** result, 
236                                          char **attr)
237 {
238         pstring filter;
239         int rc;
240
241         pstr_sprintf(filter, "(&(rid=%i)%s)", rid, 
242                 get_objclass_filter(ldap_state->schema_ver));
243         
244         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
245         
246         return rc;
247 }
248
249 /*******************************************************************
250  Run the search by SID.
251 ******************************************************************/
252
253 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state, 
254                                          const DOM_SID *sid, LDAPMessage ** result, 
255                                          char **attr)
256 {
257         pstring filter;
258         int rc;
259         fstring sid_string;
260
261         pstr_sprintf(filter, "(&(%s=%s)%s)", 
262                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
263                 sid_to_string(sid_string, sid), 
264                 get_objclass_filter(ldap_state->schema_ver));
265                 
266         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
267         
268         return rc;
269 }
270
271 /*******************************************************************
272  Delete complete object or objectclass and attrs from
273  object found in search_result depending on lp_ldap_delete_dn
274 ******************************************************************/
275
276 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
277                                      LDAPMessage *result,
278                                      const char *objectclass,
279                                      char **attrs)
280 {
281         int rc;
282         LDAPMessage *entry = NULL;
283         LDAPMod **mods = NULL;
284         char *name, *dn;
285         BerElement *ptr = NULL;
286
287         rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
288
289         if (rc != 1) {
290                 DEBUG(0, ("ldapsam_delete_entry: Entry must exist exactly once!\n"));
291                 return NT_STATUS_UNSUCCESSFUL;
292         }
293
294         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
295         dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
296         if (!dn) {
297                 return NT_STATUS_UNSUCCESSFUL;
298         }
299
300         if (lp_ldap_delete_dn()) {
301                 NTSTATUS ret = NT_STATUS_OK;
302                 rc = smbldap_delete(ldap_state->smbldap_state, dn);
303
304                 if (rc != LDAP_SUCCESS) {
305                         DEBUG(0, ("ldapsam_delete_entry: Could not delete object %s\n", dn));
306                         ret = NT_STATUS_UNSUCCESSFUL;
307                 }
308                 SAFE_FREE(dn);
309                 return ret;
310         }
311
312         /* Ok, delete only the SAM attributes */
313         
314         for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
315              name != NULL;
316              name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr)) {
317                 char **attrib;
318
319                 /* We are only allowed to delete the attributes that
320                    really exist. */
321
322                 for (attrib = attrs; *attrib != NULL; attrib++) {
323                         /* Don't delete LDAP_ATTR_MOD_TIMESTAMP attribute. */
324                         if (strequal(*attrib, get_userattr_key2string(ldap_state->schema_ver,
325                                                 LDAP_ATTR_MOD_TIMESTAMP))) {
326                                 continue;
327                         }
328                         if (strequal(*attrib, name)) {
329                                 DEBUG(10, ("ldapsam_delete_entry: deleting "
330                                            "attribute %s\n", name));
331                                 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
332                                                 NULL);
333                         }
334                 }
335
336                 ldap_memfree(name);
337         }
338         
339         if (ptr != NULL) {
340                 ber_free(ptr, 0);
341         }
342         
343         smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
344
345         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
346         ldap_mods_free(mods, True);
347
348         if (rc != LDAP_SUCCESS) {
349                 char *ld_error = NULL;
350                 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
351                                 &ld_error);
352                 
353                 DEBUG(0, ("ldapsam_delete_entry: Could not delete attributes for %s, error: %s (%s)\n",
354                           dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
355                 SAFE_FREE(ld_error);
356                 SAFE_FREE(dn);
357                 return NT_STATUS_UNSUCCESSFUL;
358         }
359
360         SAFE_FREE(dn);
361         return NT_STATUS_OK;
362 }
363                   
364 /* New Interface is being implemented here */
365
366 #if 0   /* JERRY - not uesed anymore */
367
368 /**********************************************************************
369 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
370 *********************************************************************/
371 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, 
372                                 SAM_ACCOUNT * sampass,
373                                 LDAPMessage * entry,
374                                 gid_t *gid)
375 {
376         pstring  homedir;
377         pstring  temp;
378         char **ldap_values;
379         char **values;
380
381         if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
382                 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
383                 return False;
384         }
385
386         for (values=ldap_values;*values;values++) {
387                 if (strequal(*values, LDAP_OBJ_POSIXACCOUNT )) {
388                         break;
389                 }
390         }
391         
392         if (!*values) { /*end of array, no posixAccount */
393                 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
394                 ldap_value_free(ldap_values);
395                 return False;
396         }
397         ldap_value_free(ldap_values);
398
399         if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
400                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) ) 
401         {
402                 return False;
403         }
404         
405         if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
406                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
407         {
408                 return False;
409         }
410         
411         *gid = (gid_t)atol(temp);
412
413         pdb_set_unix_homedir(sampass, homedir, PDB_SET);
414         
415         DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
416         
417         return True;
418 }
419
420 #endif
421
422 static time_t ldapsam_get_entry_timestamp(
423         struct ldapsam_privates *ldap_state,
424         LDAPMessage * entry)
425 {
426         pstring temp;   
427         struct tm tm;
428
429         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
430                         get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
431                         temp))
432                 return (time_t) 0;
433
434         strptime(temp, "%Y%m%d%H%M%SZ", &tm);
435         tzset();
436         return timegm(&tm);
437 }
438
439 /**********************************************************************
440  Initialize SAM_ACCOUNT from an LDAP query.
441  (Based on init_sam_from_buffer in pdb_tdb.c)
442 *********************************************************************/
443
444 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, 
445                                 SAM_ACCOUNT * sampass,
446                                 LDAPMessage * entry)
447 {
448         time_t  logon_time,
449                         logoff_time,
450                         kickoff_time,
451                         pass_last_set_time, 
452                         pass_can_change_time, 
453                         pass_must_change_time,
454                         ldap_entry_time,
455                         bad_password_time;
456         pstring         username, 
457                         domain,
458                         nt_username,
459                         fullname,
460                         homedir,
461                         dir_drive,
462                         logon_script,
463                         profile_path,
464                         acct_desc,
465                         workstations;
466         char            munged_dial[2048];
467         uint32          user_rid; 
468         uint8           smblmpwd[LM_HASH_LEN],
469                         smbntpwd[NT_HASH_LEN];
470         uint16          acct_ctrl = 0, 
471                         logon_divs;
472         uint16          bad_password_count = 0, 
473                         logon_count = 0;
474         uint32 hours_len;
475         uint8           hours[MAX_HOURS_LEN];
476         pstring temp;
477         LOGIN_CACHE     *cache_entry = NULL;
478         int pwHistLen;
479         pstring         tmpstring;
480
481         /*
482          * do a little initialization
483          */
484         username[0]     = '\0';
485         domain[0]       = '\0';
486         nt_username[0]  = '\0';
487         fullname[0]     = '\0';
488         homedir[0]      = '\0';
489         dir_drive[0]    = '\0';
490         logon_script[0] = '\0';
491         profile_path[0] = '\0';
492         acct_desc[0]    = '\0';
493         munged_dial[0]  = '\0';
494         workstations[0] = '\0';
495          
496
497         if (sampass == NULL || ldap_state == NULL || entry == NULL) {
498                 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
499                 return False;
500         }
501
502         if (ldap_state->smbldap_state->ldap_struct == NULL) {
503                 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
504                 return False;
505         }
506         
507         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
508                 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
509                 return False;
510         }
511
512         DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
513
514         pstrcpy(nt_username, username);
515
516         pstrcpy(domain, ldap_state->domain_name);
517         
518         pdb_set_username(sampass, username, PDB_SET);
519
520         pdb_set_domain(sampass, domain, PDB_DEFAULT);
521         pdb_set_nt_username(sampass, nt_username, PDB_SET);
522
523         /* deal with different attributes between the schema first */
524         
525         if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
526                 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
527                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
528                         pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
529                 }
530                 
531                 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
532                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp)) {
533                         pdb_set_group_sid_from_string(sampass, temp, PDB_SET);                  
534                 } else {
535                         pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
536                 }
537         } else {
538                 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
539                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
540                         user_rid = (uint32)atol(temp);
541                         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
542                 }
543                 
544                 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
545                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp)) {
546                         pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
547                 } else {
548                         uint32 group_rid;
549                         
550                         group_rid = (uint32)atol(temp);
551                         
552                         /* for some reason, we often have 0 as a primary group RID.
553                            Make sure that we treat this just as a 'default' value */
554                            
555                         if ( group_rid > 0 )
556                                 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
557                         else
558                                 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
559                 }
560         }
561
562         if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
563                 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n", 
564                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
565                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
566                         username));
567                 return False;
568         }
569
570         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
571                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) {
572                 /* leave as default */
573         } else {
574                 pass_last_set_time = (time_t) atol(temp);
575                 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
576         }
577
578         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
579                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) {
580                 /* leave as default */
581         } else {
582                 logon_time = (time_t) atol(temp);
583                 pdb_set_logon_time(sampass, logon_time, PDB_SET);
584         }
585
586         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
587                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) {
588                 /* leave as default */
589         } else {
590                 logoff_time = (time_t) atol(temp);
591                 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
592         }
593
594         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
595                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) {
596                 /* leave as default */
597         } else {
598                 kickoff_time = (time_t) atol(temp);
599                 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
600         }
601
602         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
603                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) {
604                 /* leave as default */
605         } else {
606                 pass_can_change_time = (time_t) atol(temp);
607                 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
608         }
609
610         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
611                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) {    
612                 /* leave as default */
613         } else {
614                 pass_must_change_time = (time_t) atol(temp);
615                 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
616         }
617
618         /* recommend that 'gecos' and 'displayName' should refer to the same
619          * attribute OID.  userFullName depreciated, only used by Samba
620          * primary rules of LDAP: don't make a new attribute when one is already defined
621          * that fits your needs; using cn then displayName rather than 'userFullName'
622          */
623
624         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
625                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) {
626                 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
627                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) {
628                         /* leave as default */
629                 } else {
630                         pdb_set_fullname(sampass, fullname, PDB_SET);
631                 }
632         } else {
633                 pdb_set_fullname(sampass, fullname, PDB_SET);
634         }
635
636         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
637                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive)) 
638         {
639                 pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
640         } else {
641                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
642         }
643
644         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
645                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir)) 
646         {
647                 pdb_set_homedir( sampass, 
648                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
649                         PDB_DEFAULT );
650         } else {
651                 pstrcpy( tmpstring, homedir );
652                 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
653                 pdb_set_homedir(sampass, tmpstring, PDB_SET);
654         }
655
656         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
657                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script)) 
658         {
659                 pdb_set_logon_script( sampass, 
660                         talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()), 
661                         PDB_DEFAULT );
662         } else {
663                 pstrcpy( tmpstring, logon_script );
664                 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
665                 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
666         }
667
668         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
669                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path)) 
670         {
671                 pdb_set_profile_path( sampass, 
672                         talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()),
673                         PDB_DEFAULT );
674         } else {
675                 pstrcpy( tmpstring, profile_path );
676                 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
677                 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
678         }
679
680         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
681                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc)) 
682         {
683                 /* leave as default */
684         } else {
685                 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
686         }
687
688         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
689                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) {
690                 /* leave as default */;
691         } else {
692                 pdb_set_workstations(sampass, workstations, PDB_SET);
693         }
694
695         if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, 
696                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial, sizeof(munged_dial))) {
697                 /* leave as default */;
698         } else {
699                 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
700         }
701         
702         /* FIXME: hours stuff should be cleaner */
703         
704         logon_divs = 168;
705         hours_len = 21;
706         memset(hours, 0xff, hours_len);
707
708         if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, 
709                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
710                 /* leave as default */
711         } else {
712                 pdb_gethexpwd(temp, smblmpwd);
713                 memset((char *)temp, '\0', strlen(temp)+1);
714                 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
715                         return False;
716                 ZERO_STRUCT(smblmpwd);
717         }
718
719         if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
720                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
721                 /* leave as default */
722         } else {
723                 pdb_gethexpwd(temp, smbntpwd);
724                 memset((char *)temp, '\0', strlen(temp)+1);
725                 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
726                         return False;
727                 ZERO_STRUCT(smbntpwd);
728         }
729
730         pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
731         if (pwHistLen > 0){
732                 uint8 *pwhist = NULL;
733                 int i;
734
735                 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
736                 pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
737
738                 if ((pwhist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN)) == NULL){
739                         DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
740                         return False;
741                 }
742                 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
743
744                 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, 
745                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), temp)) {
746                         /* leave as default - zeros */
747                 } else {
748                         BOOL hex_failed = False;
749                         for (i = 0; i < pwHistLen; i++){
750                                 /* Get the 16 byte salt. */
751                                 if (!pdb_gethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
752                                         hex_failed = True;
753                                         break;
754                                 }
755                                 /* Get the 16 byte MD5 hash of salt+passwd. */
756                                 if (!pdb_gethexpwd(&temp[(i*64)+32],
757                                                 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN])) {
758                                         hex_failed = True;
759                                         break;
760                                 }
761                         }
762                         if (hex_failed) {
763                                 DEBUG(0,("init_sam_from_ldap: Failed to get password history for user %s\n",
764                                         username));
765                                 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
766                         }
767                 }
768                 if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
769                         SAFE_FREE(pwhist);
770                         return False;
771                 }
772                 SAFE_FREE(pwhist);
773         }
774
775         if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
776                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
777                 acct_ctrl |= ACB_NORMAL;
778         } else {
779                 acct_ctrl = pdb_decode_acct_ctrl(temp);
780
781                 if (acct_ctrl == 0)
782                         acct_ctrl |= ACB_NORMAL;
783
784                 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
785         }
786
787         pdb_set_hours_len(sampass, hours_len, PDB_SET);
788         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
789
790         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
791                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
792                         /* leave as default */
793         } else {
794                 bad_password_count = (uint32) atol(temp);
795                 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
796         }
797
798         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
799                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) {
800                 /* leave as default */
801         } else {
802                 bad_password_time = (time_t) atol(temp);
803                 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
804         }
805
806
807         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
808                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) {
809                         /* leave as default */
810         } else {
811                 logon_count = (uint32) atol(temp);
812                 pdb_set_logon_count(sampass, logon_count, PDB_SET);
813         }
814
815         /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
816
817         if(!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
818                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS), temp)) {
819                         /* leave as default */
820         } else {
821                 pdb_gethexhours(temp, hours);
822                 memset((char *)temp, '\0', strlen(temp) +1);
823                 pdb_set_hours(sampass, hours, PDB_SET);
824                 ZERO_STRUCT(hours);
825         }
826
827         /* check the timestamp of the cache vs ldap entry */
828         if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state, 
829                                                             entry)))
830                 return True;
831
832         /* see if we have newer updates */
833         if (!(cache_entry = login_cache_read(sampass))) {
834                 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
835                            (unsigned int)pdb_get_bad_password_count(sampass),
836                            (unsigned int)pdb_get_bad_password_time(sampass)));
837                 return True;
838         }
839
840         DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n", 
841                   (unsigned int)ldap_entry_time, (unsigned int)cache_entry->entry_timestamp, 
842                   (unsigned int)cache_entry->bad_password_time));
843
844         if (ldap_entry_time > cache_entry->entry_timestamp) {
845                 /* cache is older than directory , so
846                    we need to delete the entry but allow the 
847                    fields to be written out */
848                 login_cache_delentry(sampass);
849         } else {
850                 /* read cache in */
851                 pdb_set_acct_ctrl(sampass, 
852                                   pdb_get_acct_ctrl(sampass) | 
853                                   (cache_entry->acct_ctrl & ACB_AUTOLOCK),
854                                   PDB_SET);
855                 pdb_set_bad_password_count(sampass, 
856                                            cache_entry->bad_password_count, 
857                                            PDB_SET);
858                 pdb_set_bad_password_time(sampass, 
859                                           cache_entry->bad_password_time, 
860                                           PDB_SET);
861         }
862
863         SAFE_FREE(cache_entry);
864         return True;
865 }
866
867 /**********************************************************************
868  Initialize the ldap db from a SAM_ACCOUNT. Called on update.
869  (Based on init_buffer_from_sam in pdb_tdb.c)
870 *********************************************************************/
871
872 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, 
873                                 LDAPMessage *existing,
874                                 LDAPMod *** mods, SAM_ACCOUNT * sampass,
875                                 BOOL (*need_update)(const SAM_ACCOUNT *,
876                                                     enum pdb_elements))
877 {
878         pstring temp;
879         uint32 rid;
880
881         if (mods == NULL || sampass == NULL) {
882                 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
883                 return False;
884         }
885
886         *mods = NULL;
887
888         /* 
889          * took out adding "objectclass: sambaAccount"
890          * do this on a per-mod basis
891          */
892         if (need_update(sampass, PDB_USERNAME))
893                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, 
894                               "uid", pdb_get_username(sampass));
895
896         DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
897
898         /* only update the RID if we actually need to */
899         if (need_update(sampass, PDB_USERSID)) {
900                 fstring sid_string;
901                 fstring dom_sid_string;
902                 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
903                 
904                 switch ( ldap_state->schema_ver ) {
905                         case SCHEMAVER_SAMBAACCOUNT:
906                                 if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
907                                         DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n", 
908                                                 sid_to_string(sid_string, user_sid), 
909                                                 sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
910                                         return False;
911                                 }
912                                 slprintf(temp, sizeof(temp) - 1, "%i", rid);
913                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
914                                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), 
915                                         temp);
916                                 break;
917                                 
918                         case SCHEMAVER_SAMBASAMACCOUNT:
919                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
920                                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), 
921                                         sid_to_string(sid_string, user_sid));                                 
922                                 break;
923                                 
924                         default:
925                                 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
926                                 break;
927                 }               
928         }
929
930         /* we don't need to store the primary group RID - so leaving it
931            'free' to hang off the unix primary group makes life easier */
932
933         if (need_update(sampass, PDB_GROUPSID)) {
934                 fstring sid_string;
935                 fstring dom_sid_string;
936                 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
937                 
938                 switch ( ldap_state->schema_ver ) {
939                         case SCHEMAVER_SAMBAACCOUNT:
940                                 if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
941                                         DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
942                                                 sid_to_string(sid_string, group_sid),
943                                                 sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
944                                         return False;
945                                 }
946
947                                 slprintf(temp, sizeof(temp) - 1, "%i", rid);
948                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
949                                         get_userattr_key2string(ldap_state->schema_ver, 
950                                         LDAP_ATTR_PRIMARY_GROUP_RID), temp);
951                                 break;
952                                 
953                         case SCHEMAVER_SAMBASAMACCOUNT:
954                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
955                                         get_userattr_key2string(ldap_state->schema_ver, 
956                                         LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
957                                 break;
958                                 
959                         default:
960                                 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
961                                 break;
962                 }
963                 
964         }
965         
966         /* displayName, cn, and gecos should all be the same
967          *  most easily accomplished by giving them the same OID
968          *  gecos isn't set here b/c it should be handled by the 
969          *  add-user script
970          *  We change displayName only and fall back to cn if
971          *  it does not exist.
972          */
973
974         if (need_update(sampass, PDB_FULLNAME))
975                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
976                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), 
977                         pdb_get_fullname(sampass));
978
979         if (need_update(sampass, PDB_ACCTDESC))
980                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
981                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), 
982                         pdb_get_acct_desc(sampass));
983
984         if (need_update(sampass, PDB_WORKSTATIONS))
985                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
986                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), 
987                         pdb_get_workstations(sampass));
988         
989         if (need_update(sampass, PDB_MUNGEDDIAL))
990                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
991                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), 
992                         pdb_get_munged_dial(sampass));
993         
994         if (need_update(sampass, PDB_SMBHOME))
995                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
996                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), 
997                         pdb_get_homedir(sampass));
998                         
999         if (need_update(sampass, PDB_DRIVE))
1000                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1001                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), 
1002                         pdb_get_dir_drive(sampass));
1003
1004         if (need_update(sampass, PDB_LOGONSCRIPT))
1005                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1006                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), 
1007                         pdb_get_logon_script(sampass));
1008
1009         if (need_update(sampass, PDB_PROFILE))
1010                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1011                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), 
1012                         pdb_get_profile_path(sampass));
1013
1014         slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1015         if (need_update(sampass, PDB_LOGONTIME))
1016                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1017                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
1018
1019         slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1020         if (need_update(sampass, PDB_LOGOFFTIME))
1021                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1022                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
1023
1024         slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1025         if (need_update(sampass, PDB_KICKOFFTIME))
1026                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1027                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
1028
1029         slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
1030         if (need_update(sampass, PDB_CANCHANGETIME))
1031                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1032                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
1033
1034         slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1035         if (need_update(sampass, PDB_MUSTCHANGETIME))
1036                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1037                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
1038
1039
1040         if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
1041                         || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1042
1043                 if (need_update(sampass, PDB_LMPASSWD)) {
1044                         const uchar *lm_pw =  pdb_get_lanman_passwd(sampass);
1045                         if (lm_pw) {
1046                                 pdb_sethexpwd(temp, lm_pw,
1047                                               pdb_get_acct_ctrl(sampass));
1048                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1049                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), 
1050                                                  temp);
1051                         } else {
1052                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1053                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), 
1054                                                  NULL);
1055                         }
1056                 }
1057                 if (need_update(sampass, PDB_NTPASSWD)) {
1058                         const uchar *nt_pw =  pdb_get_nt_passwd(sampass);
1059                         if (nt_pw) {
1060                                 pdb_sethexpwd(temp, nt_pw,
1061                                               pdb_get_acct_ctrl(sampass));
1062                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1063                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), 
1064                                                  temp);
1065                         } else {
1066                                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1067                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), 
1068                                                  NULL);
1069                         }
1070                 }
1071
1072                 if (need_update(sampass, PDB_PWHISTORY)) {
1073                         int pwHistLen = 0;
1074                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1075                         if (pwHistLen == 0) {
1076                                 /* Remove any password history from the LDAP store. */
1077                                 memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1078                                 temp[64] = '\0';
1079                         } else {
1080                                 int i, currHistLen = 0;
1081                                 const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
1082                                 if (pwhist != NULL) {
1083                                         /* We can only store (sizeof(pstring)-1)/64 password history entries. */
1084                                         pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
1085                                         for (i=0; i< pwHistLen && i < currHistLen; i++) {
1086                                                 /* Store the salt. */
1087                                                 pdb_sethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
1088                                                 /* Followed by the md5 hash of salt + md4 hash */
1089                                                 pdb_sethexpwd(&temp[(i*64)+32],
1090                                                         &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
1091                                                 DEBUG(100, ("temp=%s\n", temp));
1092                                         }
1093                                 } 
1094                         }
1095                         smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1096                                          get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), 
1097                                          temp);
1098                 }
1099
1100                 if (need_update(sampass, PDB_PASSLASTSET)) {
1101                         slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1102                         smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1103                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), 
1104                                 temp);
1105                 }
1106         }
1107
1108         if (need_update(sampass, PDB_HOURS)) {
1109                 const char *hours = pdb_get_hours(sampass);
1110                 if (hours) {
1111                         pdb_sethexhours(temp, hours);
1112                         smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
1113                                 existing,
1114                                 mods,
1115                                 get_userattr_key2string(ldap_state->schema_ver,
1116                                                 LDAP_ATTR_LOGON_HOURS),
1117                                 temp);
1118                 }
1119         }
1120
1121         if (need_update(sampass, PDB_ACCTCTRL))
1122                 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1123                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), 
1124                         pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
1125
1126         /* password lockout cache: 
1127            - If we are now autolocking or clearing, we write to ldap
1128            - If we are clearing, we delete the cache entry
1129            - If the count is > 0, we update the cache
1130
1131            This even means when autolocking, we cache, just in case the
1132            update doesn't work, and we have to cache the autolock flag */
1133
1134         if (need_update(sampass, PDB_BAD_PASSWORD_COUNT))  /* &&
1135             need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1136                 uint16 badcount = pdb_get_bad_password_count(sampass);
1137                 time_t badtime = pdb_get_bad_password_time(sampass);
1138                 uint32 pol;
1139                 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
1140
1141                 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1142                         (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
1143
1144                 if ((badcount >= pol) || (badcount == 0)) {
1145                         DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1146                                 (unsigned int)badcount, (unsigned int)badtime));
1147                         slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount);
1148                         smbldap_make_mod(
1149                                 ldap_state->smbldap_state->ldap_struct,
1150                                 existing, mods, 
1151                                 get_userattr_key2string(
1152                                         ldap_state->schema_ver, 
1153                                         LDAP_ATTR_BAD_PASSWORD_COUNT),
1154                                 temp);
1155
1156                         slprintf (temp, sizeof (temp) - 1, "%li", badtime);
1157                         smbldap_make_mod(
1158                                 ldap_state->smbldap_state->ldap_struct, 
1159                                 existing, mods,
1160                                 get_userattr_key2string(
1161                                         ldap_state->schema_ver, 
1162                                         LDAP_ATTR_BAD_PASSWORD_TIME), 
1163                                 temp);
1164                 }
1165                 if (badcount == 0) {
1166                         DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
1167                         login_cache_delentry(sampass);
1168                 } else {
1169                         LOGIN_CACHE cache_entry;
1170
1171                         cache_entry.entry_timestamp = time(NULL);
1172                         cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
1173                         cache_entry.bad_password_count = badcount;
1174                         cache_entry.bad_password_time = badtime;
1175
1176                         DEBUG(7, ("Updating bad password count and time in login cache\n"));
1177                         login_cache_write(sampass, cache_entry);
1178                 }
1179         }
1180
1181         return True;
1182 }
1183
1184 /**********************************************************************
1185  Connect to LDAP server for password enumeration.
1186 *********************************************************************/
1187
1188 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
1189 {
1190         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1191         int rc;
1192         pstring filter, suffix;
1193         char **attr_list;
1194         BOOL machine_mask = False, user_mask = False;
1195
1196         pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(), 
1197                 get_objclass_filter(ldap_state->schema_ver));
1198         all_string_sub(filter, "%u", "*", sizeof(pstring));
1199
1200         machine_mask    = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
1201         user_mask       = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
1202
1203         if (machine_mask) {
1204                 pstrcpy(suffix, lp_ldap_machine_suffix());
1205         } else if (user_mask) {
1206                 pstrcpy(suffix, lp_ldap_user_suffix());
1207         } else {
1208                 pstrcpy(suffix, lp_ldap_suffix());
1209         }
1210
1211         DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n", 
1212                 acb_mask, suffix));
1213
1214         attr_list = get_userattr_list(ldap_state->schema_ver);
1215         rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, 
1216                             attr_list, 0, &ldap_state->result);
1217         free_attr_list( attr_list );
1218
1219         if (rc != LDAP_SUCCESS) {
1220                 DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
1221                 DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
1222                 ldap_msgfree(ldap_state->result);
1223                 ldap_state->result = NULL;
1224                 return NT_STATUS_UNSUCCESSFUL;
1225         }
1226
1227         DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
1228                 ldap_count_entries(ldap_state->smbldap_state->ldap_struct, 
1229                 ldap_state->result), suffix));
1230
1231         ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
1232                                  ldap_state->result);
1233         ldap_state->index = 0;
1234
1235         return NT_STATUS_OK;
1236 }
1237
1238 /**********************************************************************
1239  End enumeration of the LDAP password list.
1240 *********************************************************************/
1241
1242 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1243 {
1244         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1245         if (ldap_state->result) {
1246                 ldap_msgfree(ldap_state->result);
1247                 ldap_state->result = NULL;
1248         }
1249 }
1250
1251 /**********************************************************************
1252 Get the next entry in the LDAP password database.
1253 *********************************************************************/
1254
1255 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1256 {
1257         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1258         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1259         BOOL bret = False;
1260
1261         while (!bret) {
1262                 if (!ldap_state->entry)
1263                         return ret;
1264                 
1265                 ldap_state->index++;
1266                 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1267                 
1268                 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
1269                                             ldap_state->entry); 
1270         }
1271
1272         return NT_STATUS_OK;
1273 }
1274
1275 static void append_attr(char ***attr_list, const char *new_attr)
1276 {
1277         int i;
1278
1279         if (new_attr == NULL) {
1280                 return;
1281         }
1282
1283         for (i=0; (*attr_list)[i] != NULL; i++) {
1284                 ;
1285         }
1286
1287         (*attr_list) = SMB_REALLOC_ARRAY((*attr_list), char *,  i+2);
1288         SMB_ASSERT((*attr_list) != NULL);
1289         (*attr_list)[i] = SMB_STRDUP(new_attr);
1290         (*attr_list)[i+1] = NULL;
1291 }
1292
1293 /**********************************************************************
1294 Get SAM_ACCOUNT entry from LDAP by username.
1295 *********************************************************************/
1296
1297 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1298 {
1299         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1300         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1301         LDAPMessage *result = NULL;
1302         LDAPMessage *entry = NULL;
1303         int count;
1304         char ** attr_list;
1305         int rc;
1306         
1307         attr_list = get_userattr_list( ldap_state->schema_ver );
1308         append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
1309         rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
1310         free_attr_list( attr_list );
1311
1312         if ( rc != LDAP_SUCCESS ) 
1313                 return NT_STATUS_NO_SUCH_USER;
1314         
1315         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1316         
1317         if (count < 1) {
1318                 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1319                 ldap_msgfree(result);
1320                 return NT_STATUS_NO_SUCH_USER;
1321         } else if (count > 1) {
1322                 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1323                 ldap_msgfree(result);
1324                 return NT_STATUS_NO_SUCH_USER;
1325         }
1326
1327         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1328         if (entry) {
1329                 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1330                         DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1331                         ldap_msgfree(result);
1332                         return NT_STATUS_NO_SUCH_USER;
1333                 }
1334                 pdb_set_backend_private_data(user, result, 
1335                                              private_data_free_fn, 
1336                                              my_methods, PDB_CHANGED);
1337                 ret = NT_STATUS_OK;
1338         } else {
1339                 ldap_msgfree(result);
1340         }
1341         return ret;
1342 }
1343
1344 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state, 
1345                                    const DOM_SID *sid, LDAPMessage **result) 
1346 {
1347         int rc = -1;
1348         char ** attr_list;
1349         uint32 rid;
1350
1351         switch ( ldap_state->schema_ver ) {
1352                 case SCHEMAVER_SAMBASAMACCOUNT:
1353                         attr_list = get_userattr_list(ldap_state->schema_ver);
1354                         append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
1355                         rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list);
1356                         free_attr_list( attr_list );
1357
1358                         if ( rc != LDAP_SUCCESS ) 
1359                                 return rc;
1360                         break;
1361                         
1362                 case SCHEMAVER_SAMBAACCOUNT:
1363                         if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
1364                                 return rc;
1365                         }
1366                 
1367                         attr_list = get_userattr_list(ldap_state->schema_ver);
1368                         rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
1369                         free_attr_list( attr_list );
1370
1371                         if ( rc != LDAP_SUCCESS ) 
1372                                 return rc;
1373                         break;
1374         }
1375         return rc;
1376 }
1377
1378 /**********************************************************************
1379  Get SAM_ACCOUNT entry from LDAP by SID.
1380 *********************************************************************/
1381
1382 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1383 {
1384         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1385         LDAPMessage *result = NULL;
1386         LDAPMessage *entry = NULL;
1387         int count;
1388         int rc;
1389         fstring sid_string;
1390
1391         rc = ldapsam_get_ldap_user_by_sid(ldap_state, 
1392                                           sid, &result); 
1393         if (rc != LDAP_SUCCESS)
1394                 return NT_STATUS_NO_SUCH_USER;
1395
1396         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1397         
1398         if (count < 1) {
1399                 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
1400                        count));
1401                 ldap_msgfree(result);
1402                 return NT_STATUS_NO_SUCH_USER;
1403         }  else if (count > 1) {
1404                 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
1405                        count));
1406                 ldap_msgfree(result);
1407                 return NT_STATUS_NO_SUCH_USER;
1408         }
1409
1410         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1411         if (!entry) {
1412                 ldap_msgfree(result);
1413                 return NT_STATUS_NO_SUCH_USER;
1414         }
1415
1416         if (!init_sam_from_ldap(ldap_state, user, entry)) {
1417                 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1418                 ldap_msgfree(result);
1419                 return NT_STATUS_NO_SUCH_USER;
1420         }
1421
1422         pdb_set_backend_private_data(user, result, 
1423                                      private_data_free_fn, 
1424                                      my_methods, PDB_CHANGED);
1425         return NT_STATUS_OK;
1426 }       
1427
1428 static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state)
1429 {
1430         return smbldap_has_extension(ldap_state, LDAP_EXOP_MODIFY_PASSWD);
1431 }
1432
1433 /********************************************************************
1434  Do the actual modification - also change a plaintext passord if 
1435  it it set.
1436 **********************************************************************/
1437
1438 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, 
1439                                      SAM_ACCOUNT *newpwd, char *dn,
1440                                      LDAPMod **mods, int ldap_op, 
1441                                      BOOL (*need_update)(const SAM_ACCOUNT *, enum pdb_elements))
1442 {
1443         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1444         int rc;
1445         
1446         if (!my_methods || !newpwd || !dn) {
1447                 return NT_STATUS_INVALID_PARAMETER;
1448         }
1449         
1450         if (!mods) {
1451                 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1452                 /* may be password change below however */
1453         } else {
1454                 switch(ldap_op) {
1455                         case LDAP_MOD_ADD: 
1456                                 smbldap_set_mod(&mods, LDAP_MOD_ADD, 
1457                                                 "objectclass", 
1458                                                 LDAP_OBJ_ACCOUNT);
1459                                 rc = smbldap_add(ldap_state->smbldap_state, 
1460                                                  dn, mods);
1461                                 break;
1462                         case LDAP_MOD_REPLACE: 
1463                                 rc = smbldap_modify(ldap_state->smbldap_state, 
1464                                                     dn ,mods);
1465                                 break;
1466                         default:        
1467                                 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n", 
1468                                          ldap_op));
1469                                 return NT_STATUS_INVALID_PARAMETER;
1470                 }
1471                 
1472                 if (rc!=LDAP_SUCCESS) {
1473                         char *ld_error = NULL;
1474                         ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1475                                         &ld_error);
1476                         DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
1477                                ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1478                                dn, ldap_err2string(rc),
1479                                ld_error?ld_error:"unknown"));
1480                         SAFE_FREE(ld_error);
1481                         return NT_STATUS_UNSUCCESSFUL;
1482                 }  
1483         }
1484         
1485         if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1486                         (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1487                         need_update(newpwd, PDB_PLAINTEXT_PW) &&
1488                         (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1489                 BerElement *ber;
1490                 struct berval *bv;
1491                 char *retoid;
1492                 struct berval *retdata;
1493                 char *utf8_password;
1494                 char *utf8_dn;
1495
1496                 if (!ldapsam_can_pwchange_exop(ldap_state->smbldap_state)) {
1497                         DEBUG(2, ("ldap password change requested, but LDAP "
1498                                   "server does not support it -- ignoring\n"));
1499                         return NT_STATUS_OK;
1500                 }
1501
1502                 if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
1503                         return NT_STATUS_NO_MEMORY;
1504                 }
1505
1506                 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
1507                         return NT_STATUS_NO_MEMORY;
1508                 }
1509
1510                 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1511                         DEBUG(0,("ber_alloc_t returns NULL\n"));
1512                         SAFE_FREE(utf8_password);
1513                         return NT_STATUS_UNSUCCESSFUL;
1514                 }
1515
1516                 ber_printf (ber, "{");
1517                 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
1518                 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
1519                 ber_printf (ber, "N}");
1520
1521                 if ((rc = ber_flatten (ber, &bv))<0) {
1522                         DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1523                         ber_free(ber,1);
1524                         SAFE_FREE(utf8_dn);
1525                         SAFE_FREE(utf8_password);
1526                         return NT_STATUS_UNSUCCESSFUL;
1527                 }
1528                 
1529                 SAFE_FREE(utf8_dn);
1530                 SAFE_FREE(utf8_password);
1531                 ber_free(ber, 1);
1532
1533                 if ((rc = smbldap_extended_operation(ldap_state->smbldap_state, 
1534                                                      LDAP_EXOP_MODIFY_PASSWD,
1535                                                      bv, NULL, NULL, &retoid, 
1536                                                      &retdata)) != LDAP_SUCCESS) {
1537                         char *ld_error = NULL;
1538
1539                         if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
1540                                 DEBUG(3, ("Could not set userPassword "
1541                                           "attribute due to an objectClass "
1542                                           "violation -- ignoring\n"));
1543                                 ber_bvfree(bv);
1544                                 return NT_STATUS_OK;
1545                         }
1546
1547                         ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1548                                         &ld_error);
1549                         DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1550                                 pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1551                         SAFE_FREE(ld_error);
1552                         ber_bvfree(bv);
1553                         return NT_STATUS_UNSUCCESSFUL;
1554                 } else {
1555                         DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1556 #ifdef DEBUG_PASSWORD
1557                         DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1558 #endif    
1559                         ber_bvfree(retdata);
1560                         ber_memfree(retoid);
1561                 }
1562                 ber_bvfree(bv);
1563         }
1564         return NT_STATUS_OK;
1565 }
1566
1567 /**********************************************************************
1568  Delete entry from LDAP for username.
1569 *********************************************************************/
1570
1571 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1572 {
1573         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1574         const char *sname;
1575         int rc;
1576         LDAPMessage *result = NULL;
1577         NTSTATUS ret;
1578         char **attr_list;
1579         fstring objclass;
1580
1581         if (!sam_acct) {
1582                 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1583                 return NT_STATUS_INVALID_PARAMETER;
1584         }
1585
1586         sname = pdb_get_username(sam_acct);
1587
1588         DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname));
1589
1590         attr_list= get_userattr_delete_list( ldap_state->schema_ver );
1591         rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
1592
1593         if (rc != LDAP_SUCCESS)  {
1594                 free_attr_list( attr_list );
1595                 return NT_STATUS_NO_SUCH_USER;
1596         }
1597         
1598         switch ( ldap_state->schema_ver ) {
1599                 case SCHEMAVER_SAMBASAMACCOUNT:
1600                         fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
1601                         break;
1602                         
1603                 case SCHEMAVER_SAMBAACCOUNT:
1604                         fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
1605                         break;
1606                 default:
1607                         fstrcpy( objclass, "UNKNOWN" );
1608                         DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
1609                                 break;
1610         }
1611
1612         ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
1613         ldap_msgfree(result);
1614         free_attr_list( attr_list );
1615
1616         return ret;
1617 }
1618
1619 /**********************************************************************
1620  Helper function to determine for update_sam_account whether
1621  we need LDAP modification.
1622 *********************************************************************/
1623
1624 static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
1625                                enum pdb_elements element)
1626 {
1627         return IS_SAM_CHANGED(sampass, element);
1628 }
1629
1630 /**********************************************************************
1631  Update SAM_ACCOUNT.
1632 *********************************************************************/
1633
1634 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1635 {
1636         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1637         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1638         int rc = 0;
1639         char *dn;
1640         LDAPMessage *result = NULL;
1641         LDAPMessage *entry = NULL;
1642         LDAPMod **mods = NULL;
1643         char **attr_list;
1644
1645         result = pdb_get_backend_private_data(newpwd, my_methods);
1646         if (!result) {
1647                 attr_list = get_userattr_list(ldap_state->schema_ver);
1648                 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1649                 free_attr_list( attr_list );
1650                 if (rc != LDAP_SUCCESS) {
1651                         return NT_STATUS_UNSUCCESSFUL;
1652                 }
1653                 pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED);
1654         }
1655
1656         if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
1657                 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1658                 return NT_STATUS_UNSUCCESSFUL;
1659         }
1660
1661         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1662         dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
1663         if (!dn) {
1664                 return NT_STATUS_UNSUCCESSFUL;
1665         }
1666
1667         DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1668
1669         if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1670                                 element_is_changed)) {
1671                 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1672                 SAFE_FREE(dn);
1673                 if (mods != NULL)
1674                         ldap_mods_free(mods,True);
1675                 return NT_STATUS_UNSUCCESSFUL;
1676         }
1677         
1678         if (mods == NULL) {
1679                 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1680                          pdb_get_username(newpwd)));
1681                 SAFE_FREE(dn);
1682                 return NT_STATUS_OK;
1683         }
1684         
1685         ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
1686         ldap_mods_free(mods,True);
1687         SAFE_FREE(dn);
1688
1689         if (!NT_STATUS_IS_OK(ret)) {
1690                 char *ld_error = NULL;
1691                 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1692                                 &ld_error);
1693                 DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
1694                          pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
1695                 SAFE_FREE(ld_error);
1696                 return ret;
1697         }
1698
1699         DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
1700                   pdb_get_username(newpwd)));
1701         return NT_STATUS_OK;
1702 }
1703
1704 /**********************************************************************
1705  Helper function to determine for update_sam_account whether
1706  we need LDAP modification.
1707  *********************************************************************/
1708
1709 static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
1710                                       enum pdb_elements element)
1711 {
1712         return (IS_SAM_SET(sampass, element) ||
1713                 IS_SAM_CHANGED(sampass, element));
1714 }
1715
1716 /**********************************************************************
1717  Add SAM_ACCOUNT to LDAP.
1718 *********************************************************************/
1719
1720 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1721 {
1722         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1723         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1724         int rc;
1725         LDAPMessage     *result = NULL;
1726         LDAPMessage     *entry  = NULL;
1727         pstring         dn;
1728         LDAPMod         **mods = NULL;
1729         int             ldap_op = LDAP_MOD_REPLACE;
1730         uint32          num_result;
1731         char            **attr_list;
1732         char            *escape_user;
1733         const char      *username = pdb_get_username(newpwd);
1734         const DOM_SID   *sid = pdb_get_user_sid(newpwd);
1735         pstring         filter;
1736         fstring         sid_string;
1737
1738         if (!username || !*username) {
1739                 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
1740                 return NT_STATUS_INVALID_PARAMETER;
1741         }
1742
1743         /* free this list after the second search or in case we exit on failure */
1744         attr_list = get_userattr_list(ldap_state->schema_ver);
1745
1746         rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
1747
1748         if (rc != LDAP_SUCCESS) {
1749                 free_attr_list( attr_list );
1750                 return NT_STATUS_UNSUCCESSFUL;
1751         }
1752
1753         if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1754                 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n", 
1755                          username));
1756                 ldap_msgfree(result);
1757                 free_attr_list( attr_list );
1758                 return NT_STATUS_UNSUCCESSFUL;
1759         }
1760         ldap_msgfree(result);
1761         result = NULL;
1762
1763         if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
1764                 rc = ldapsam_get_ldap_user_by_sid(ldap_state, 
1765                                                   sid, &result); 
1766                 if (rc == LDAP_SUCCESS) {
1767                         if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1768                                 DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n", 
1769                                          sid_to_string(sid_string, sid)));
1770                                 free_attr_list( attr_list );
1771                                 ldap_msgfree(result);
1772                                 return NT_STATUS_UNSUCCESSFUL;
1773                         }
1774                         ldap_msgfree(result);
1775                 }
1776         }
1777
1778         /* does the entry already exist but without a samba attributes?
1779            we need to return the samba attributes here */
1780            
1781         escape_user = escape_ldap_string_alloc( username );
1782         pstrcpy( filter, lp_ldap_filter() );
1783         all_string_sub( filter, "%u", escape_user, sizeof(filter) );
1784         SAFE_FREE( escape_user );
1785
1786         rc = smbldap_search_suffix(ldap_state->smbldap_state, 
1787                                    filter, attr_list, &result);
1788         if ( rc != LDAP_SUCCESS ) {
1789                 free_attr_list( attr_list );
1790                 return NT_STATUS_UNSUCCESSFUL;
1791         }
1792
1793         num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1794         
1795         if (num_result > 1) {
1796                 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1797                 free_attr_list( attr_list );
1798                 ldap_msgfree(result);
1799                 return NT_STATUS_UNSUCCESSFUL;
1800         }
1801         
1802         /* Check if we need to update an existing entry */
1803         if (num_result == 1) {
1804                 char *tmp;
1805                 
1806                 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1807                 ldap_op = LDAP_MOD_REPLACE;
1808                 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
1809                 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
1810                 if (!tmp) {
1811                         free_attr_list( attr_list );
1812                         ldap_msgfree(result);
1813                         return NT_STATUS_UNSUCCESSFUL;
1814                 }
1815                 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1816                 SAFE_FREE(tmp);
1817
1818         } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
1819
1820                 /* There might be a SID for this account already - say an idmap entry */
1821
1822                 pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))", 
1823                          get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1824                          sid_to_string(sid_string, sid),
1825                          LDAP_OBJ_IDMAP_ENTRY,
1826                          LDAP_OBJ_SID_ENTRY);
1827                 
1828                 /* free old result before doing a new search */
1829                 if (result != NULL) {
1830                         ldap_msgfree(result);
1831                         result = NULL;
1832                 }
1833                 rc = smbldap_search_suffix(ldap_state->smbldap_state, 
1834                                            filter, attr_list, &result);
1835                         
1836                 if ( rc != LDAP_SUCCESS ) {
1837                         free_attr_list( attr_list );
1838                         return NT_STATUS_UNSUCCESSFUL;
1839                 }
1840                 
1841                 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1842                 
1843                 if (num_result > 1) {
1844                         DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1845                         free_attr_list( attr_list );
1846                         ldap_msgfree(result);
1847                         return NT_STATUS_UNSUCCESSFUL;
1848                 }
1849                 
1850                 /* Check if we need to update an existing entry */
1851                 if (num_result == 1) {
1852                         char *tmp;
1853                         
1854                         DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1855                         ldap_op = LDAP_MOD_REPLACE;
1856                         entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
1857                         tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
1858                         if (!tmp) {
1859                                 free_attr_list( attr_list );
1860                                 ldap_msgfree(result);
1861                                 return NT_STATUS_UNSUCCESSFUL;
1862                         }
1863                         slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1864                         SAFE_FREE(tmp);
1865                 }
1866         }
1867         
1868         free_attr_list( attr_list );
1869
1870         if (num_result == 0) {
1871                 /* Check if we need to add an entry */
1872                 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
1873                 ldap_op = LDAP_MOD_ADD;
1874                 if (username[strlen(username)-1] == '$') {
1875                         slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1876                 } else {
1877                         slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1878                 }
1879         }
1880
1881         if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1882                                 element_is_set_or_changed)) {
1883                 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1884                 ldap_msgfree(result);
1885                 if (mods != NULL)
1886                         ldap_mods_free(mods,True);
1887                 return NT_STATUS_UNSUCCESSFUL;          
1888         }
1889         
1890         ldap_msgfree(result);
1891
1892         if (mods == NULL) {
1893                 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
1894                 return NT_STATUS_UNSUCCESSFUL;
1895         }
1896         switch ( ldap_state->schema_ver ) {
1897                 case SCHEMAVER_SAMBAACCOUNT:
1898                         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
1899                         break;
1900                 case SCHEMAVER_SAMBASAMACCOUNT:
1901                         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
1902                         break;
1903                 default:
1904                         DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
1905                         break;
1906         }
1907
1908         ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
1909         if (!NT_STATUS_IS_OK(ret)) {
1910                 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
1911                          pdb_get_username(newpwd),dn));
1912                 ldap_mods_free(mods, True);
1913                 return ret;
1914         }
1915
1916         DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
1917         ldap_mods_free(mods, True);
1918         
1919         return NT_STATUS_OK;
1920 }
1921
1922 /**********************************************************************
1923  *********************************************************************/
1924
1925 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
1926                                      const char *filter,
1927                                      LDAPMessage ** result)
1928 {
1929         int scope = LDAP_SCOPE_SUBTREE;
1930         int rc;
1931         char **attr_list;
1932
1933         attr_list = get_attr_list(groupmap_attr_list);
1934         rc = smbldap_search(ldap_state->smbldap_state, 
1935                             lp_ldap_group_suffix (), scope,
1936                             filter, attr_list, 0, result);
1937         free_attr_list( attr_list );
1938
1939         if (rc != LDAP_SUCCESS) {
1940                 char *ld_error = NULL;
1941                 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1942                                 &ld_error);
1943                 DEBUG(0, ("ldapsam_search_one_group: "
1944                           "Problem during the LDAP search: LDAP error: %s (%s)\n",
1945                           ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
1946                 DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1947                           lp_ldap_group_suffix(), filter));
1948                 SAFE_FREE(ld_error);
1949         }
1950
1951         return rc;
1952 }
1953
1954 /**********************************************************************
1955  *********************************************************************/
1956
1957 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
1958                                  GROUP_MAP *map, LDAPMessage *entry)
1959 {
1960         pstring temp;
1961
1962         if (ldap_state == NULL || map == NULL || entry == NULL ||
1963                         ldap_state->smbldap_state->ldap_struct == NULL) {
1964                 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
1965                 return False;
1966         }
1967
1968         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
1969                         get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) {
1970                 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n", 
1971                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
1972                 return False;
1973         }
1974         DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
1975
1976         map->gid = (gid_t)atol(temp);
1977
1978         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
1979                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) {
1980                 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1981                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
1982                 return False;
1983         }
1984         
1985         if (!string_to_sid(&map->sid, temp)) {
1986                 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
1987                 return False;
1988         }
1989
1990         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
1991                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) {
1992                 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1993                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
1994                 return False;
1995         }
1996         map->sid_name_use = (enum SID_NAME_USE)atol(temp);
1997
1998         if ((map->sid_name_use < SID_NAME_USER) ||
1999                         (map->sid_name_use > SID_NAME_UNKNOWN)) {
2000                 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
2001                 return False;
2002         }
2003
2004         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
2005                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) {
2006                 temp[0] = '\0';
2007                 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
2008                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp)) 
2009                 {
2010                         DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2011 for gidNumber(%lu)\n",(unsigned long)map->gid));
2012                         return False;
2013                 }
2014         }
2015         fstrcpy(map->nt_name, temp);
2016
2017         if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
2018                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) {
2019                 temp[0] = '\0';
2020         }
2021         fstrcpy(map->comment, temp);
2022
2023         return True;
2024 }
2025
2026 /**********************************************************************
2027  *********************************************************************/
2028
2029 static BOOL init_ldap_from_group(LDAP *ldap_struct,
2030                                  LDAPMessage *existing,
2031                                  LDAPMod ***mods,
2032                                  const GROUP_MAP *map)
2033 {
2034         pstring tmp;
2035
2036         if (mods == NULL || map == NULL) {
2037                 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2038                 return False;
2039         }
2040
2041         *mods = NULL;
2042
2043         sid_to_string(tmp, &map->sid);
2044
2045         smbldap_make_mod(ldap_struct, existing, mods, 
2046                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
2047         pstr_sprintf(tmp, "%i", map->sid_name_use);
2048         smbldap_make_mod(ldap_struct, existing, mods, 
2049                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
2050
2051         smbldap_make_mod(ldap_struct, existing, mods, 
2052                 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
2053         smbldap_make_mod(ldap_struct, existing, mods, 
2054                 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
2055
2056         return True;
2057 }
2058
2059 /**********************************************************************
2060  *********************************************************************/
2061
2062 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2063                                  const char *filter,
2064                                  GROUP_MAP *map)
2065 {
2066         struct ldapsam_privates *ldap_state =
2067                 (struct ldapsam_privates *)methods->private_data;
2068         LDAPMessage *result = NULL;
2069         LDAPMessage *entry = NULL;
2070         int count;
2071
2072         if (ldapsam_search_one_group(ldap_state, filter, &result)
2073             != LDAP_SUCCESS) {
2074                 return NT_STATUS_NO_SUCH_GROUP;
2075         }
2076
2077         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2078
2079         if (count < 1) {
2080                 DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
2081                 ldap_msgfree(result);
2082                 return NT_STATUS_NO_SUCH_GROUP;
2083         }
2084
2085         if (count > 1) {
2086                 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
2087                           filter, count));
2088                 ldap_msgfree(result);
2089                 return NT_STATUS_NO_SUCH_GROUP;
2090         }
2091
2092         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2093
2094         if (!entry) {
2095                 ldap_msgfree(result);
2096                 return NT_STATUS_UNSUCCESSFUL;
2097         }
2098
2099         if (!init_group_from_ldap(ldap_state, map, entry)) {
2100                 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
2101                           filter));
2102                 ldap_msgfree(result);
2103                 return NT_STATUS_NO_SUCH_GROUP;
2104         }
2105
2106         ldap_msgfree(result);
2107         return NT_STATUS_OK;
2108 }
2109
2110 /**********************************************************************
2111  *********************************************************************/
2112
2113 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2114                                  DOM_SID sid)
2115 {
2116         pstring filter;
2117
2118         pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
2119                 LDAP_OBJ_GROUPMAP, 
2120                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2121                 sid_string_static(&sid));
2122
2123         return ldapsam_getgroup(methods, filter, map);
2124 }
2125
2126 /**********************************************************************
2127  *********************************************************************/
2128
2129 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2130                                  gid_t gid)
2131 {
2132         pstring filter;
2133
2134         pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
2135                 LDAP_OBJ_GROUPMAP,
2136                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2137                 (unsigned long)gid);
2138
2139         return ldapsam_getgroup(methods, filter, map);
2140 }
2141
2142 /**********************************************************************
2143  *********************************************************************/
2144
2145 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2146                                  const char *name)
2147 {
2148         pstring filter;
2149         char *escape_name = escape_ldap_string_alloc(name);
2150
2151         if (!escape_name) {
2152                 return NT_STATUS_NO_MEMORY;
2153         }
2154
2155         pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2156                 LDAP_OBJ_GROUPMAP,
2157                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
2158                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
2159
2160         SAFE_FREE(escape_name);
2161
2162         return ldapsam_getgroup(methods, filter, map);
2163 }
2164
2165 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2166                                                const char *username,
2167                                                gid_t primary_gid,
2168                                                DOM_SID **sids, gid_t **gids,
2169                                                int *num_groups)
2170 {
2171         struct ldapsam_privates *ldap_state =
2172                 (struct ldapsam_privates *)methods->private_data;
2173         struct smbldap_state *conn = ldap_state->smbldap_state;
2174         pstring filter;
2175         char *attrs[] = { "gidNumber", "sambaSID", NULL };
2176         char *escape_name;
2177         int rc;
2178         LDAPMessage *msg = NULL;
2179         LDAPMessage *entry;
2180         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2181         int num_sids, num_gids;
2182         extern DOM_SID global_sid_NULL;
2183
2184         if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
2185                 return pdb_default_enum_group_memberships(methods, username,
2186                                                           primary_gid, sids,
2187                                                           gids, num_groups);
2188
2189         *sids = NULL;
2190         num_sids = 0;
2191
2192         escape_name = escape_ldap_string_alloc(username);
2193
2194         if (escape_name == NULL)
2195                 return NT_STATUS_NO_MEMORY;
2196
2197         pstr_sprintf(filter, "(&(objectClass=posixGroup)"
2198                      "(|(memberUid=%s)(gidNumber=%d)))",
2199                      username, primary_gid);
2200
2201         rc = smbldap_search(conn, lp_ldap_group_suffix(),
2202                             LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg);
2203
2204         if (rc != LDAP_SUCCESS)
2205                 goto done;
2206
2207         num_gids = 0;
2208         *gids = NULL;
2209
2210         num_sids = 0;
2211         *sids = NULL;
2212
2213         /* We need to add the primary group as the first gid/sid */
2214
2215         add_gid_to_array_unique(primary_gid, gids, &num_gids);
2216
2217         /* This sid will be replaced later */
2218
2219         add_sid_to_array_unique(&global_sid_NULL, sids, &num_sids);
2220
2221         for (entry = ldap_first_entry(conn->ldap_struct, msg);
2222              entry != NULL;
2223              entry = ldap_next_entry(conn->ldap_struct, entry))
2224         {
2225                 fstring str;
2226                 DOM_SID sid;
2227                 gid_t gid;
2228                 char *end;
2229
2230                 if (!smbldap_get_single_attribute(conn->ldap_struct,
2231                                                   entry, "sambaSID",
2232                                                   str, sizeof(str)-1))
2233                         continue;
2234
2235                 if (!string_to_sid(&sid, str))
2236                         goto done;
2237
2238                 if (!smbldap_get_single_attribute(conn->ldap_struct,
2239                                                   entry, "gidNumber",
2240                                                   str, sizeof(str)-1))
2241                         continue;
2242
2243                 gid = strtoul(str, &end, 10);
2244
2245                 if (PTR_DIFF(end, str) != strlen(str))
2246                         goto done;
2247
2248                 if (gid == primary_gid) {
2249                         sid_copy(&(*sids)[0], &sid);
2250                 } else {
2251                         add_gid_to_array_unique(gid, gids, &num_gids);
2252                         add_sid_to_array_unique(&sid, sids, &num_sids);
2253                 }
2254         }
2255
2256         if (sid_compare(&global_sid_NULL, &(*sids)[0]) == 0) {
2257                 DEBUG(3, ("primary group of [%s] not found\n", username));
2258                 goto done;
2259         }
2260
2261         *num_groups = num_sids;
2262
2263         result = NT_STATUS_OK;
2264
2265  done:
2266
2267         SAFE_FREE(escape_name);
2268         if (msg != NULL)
2269                 ldap_msgfree(msg);
2270
2271         return result;
2272 }
2273
2274 /**********************************************************************
2275  *********************************************************************/
2276
2277 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
2278                                            gid_t gid,
2279                                            LDAPMessage **result)
2280 {
2281         pstring filter;
2282
2283         pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))", 
2284                 LDAP_OBJ_POSIXGROUP, LDAP_OBJ_IDMAP_ENTRY,
2285                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2286                 (unsigned long)gid);
2287
2288         return ldapsam_search_one_group(ldap_state, filter, result);
2289 }
2290
2291 /**********************************************************************
2292  *********************************************************************/
2293
2294 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2295                                                 GROUP_MAP *map)
2296 {
2297         struct ldapsam_privates *ldap_state =
2298                 (struct ldapsam_privates *)methods->private_data;
2299         LDAPMessage *result = NULL;
2300         LDAPMod **mods = NULL;
2301         int count;
2302
2303         char *tmp;
2304         pstring dn;
2305         LDAPMessage *entry;
2306
2307         GROUP_MAP dummy;
2308
2309         int rc;
2310
2311         if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
2312                                              map->gid))) {
2313                 DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map->gid));
2314                 return NT_STATUS_UNSUCCESSFUL;
2315         }
2316
2317         rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2318         if (rc != LDAP_SUCCESS) {
2319                 ldap_msgfree(result);
2320                 return NT_STATUS_UNSUCCESSFUL;
2321         }
2322
2323         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2324
2325         if ( count == 0 ) {
2326                 /* There's no posixGroup account, let's try to find an
2327                  * appropriate idmap entry for aliases */
2328
2329                 pstring suffix;
2330                 pstring filter;
2331                 char **attr_list;
2332
2333                 ldap_msgfree(result);
2334
2335                 pstrcpy( suffix, lp_ldap_idmap_suffix() );
2336                 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%u))",
2337                              LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_GIDNUMBER,
2338                              map->gid);
2339                 
2340                 attr_list = get_attr_list( sidmap_attr_list );
2341                 rc = smbldap_search(ldap_state->smbldap_state, suffix,
2342                                     LDAP_SCOPE_SUBTREE, filter, attr_list,
2343                                     0, &result);
2344
2345                 free_attr_list(attr_list);
2346
2347                 if (rc != LDAP_SUCCESS) {
2348                         DEBUG(3,("Failure looking up entry (%s)\n",
2349                                  ldap_err2string(rc) ));
2350                         ldap_msgfree(result);
2351                         return NT_STATUS_UNSUCCESSFUL;
2352                 }
2353         }
2354                            
2355         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2356         if ( count == 0 ) {
2357                 ldap_msgfree(result);
2358                 return NT_STATUS_UNSUCCESSFUL;
2359         }
2360
2361         if (count > 1) {
2362                 DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
2363                           (unsigned long)map->gid));
2364                 ldap_msgfree(result);
2365                 return NT_STATUS_UNSUCCESSFUL;
2366         }
2367
2368         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2369         tmp = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2370         if (!tmp) {
2371                 ldap_msgfree(result);
2372                 return NT_STATUS_UNSUCCESSFUL;
2373         }
2374         pstrcpy(dn, tmp);
2375         SAFE_FREE(tmp);
2376
2377         if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
2378                                   result, &mods, map)) {
2379                 DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
2380                 ldap_mods_free(mods, True);
2381                 ldap_msgfree(result);
2382                 return NT_STATUS_UNSUCCESSFUL;
2383         }
2384
2385         ldap_msgfree(result);
2386
2387         if (mods == NULL) {
2388                 DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
2389                 return NT_STATUS_UNSUCCESSFUL;
2390         }
2391
2392         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
2393
2394         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2395         ldap_mods_free(mods, True);
2396
2397         if (rc != LDAP_SUCCESS) {
2398                 char *ld_error = NULL;
2399                 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2400                                 &ld_error);
2401                 DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid, 
2402                           ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
2403                 SAFE_FREE(ld_error);
2404                 return NT_STATUS_UNSUCCESSFUL;
2405         }
2406
2407         DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
2408         return NT_STATUS_OK;
2409 }
2410
2411 /**********************************************************************
2412  *********************************************************************/
2413
2414 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2415                                                    GROUP_MAP *map)
2416 {
2417         struct ldapsam_privates *ldap_state =
2418                 (struct ldapsam_privates *)methods->private_data;
2419         int rc;
2420         char *dn = NULL;
2421         LDAPMessage *result = NULL;
2422         LDAPMessage *entry = NULL;
2423         LDAPMod **mods = NULL;
2424
2425         rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2426
2427         if (rc != LDAP_SUCCESS) {
2428                 return NT_STATUS_UNSUCCESSFUL;
2429         }
2430
2431         if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
2432                 DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
2433                 ldap_msgfree(result);
2434                 return NT_STATUS_UNSUCCESSFUL;
2435         }
2436
2437         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2438
2439         if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
2440                                   result, &mods, map)) {
2441                 DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
2442                 ldap_msgfree(result);
2443                 if (mods != NULL)
2444                         ldap_mods_free(mods,True);
2445                 return NT_STATUS_UNSUCCESSFUL;
2446         }
2447
2448         if (mods == NULL) {
2449                 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
2450                 ldap_msgfree(result);
2451                 return NT_STATUS_OK;
2452         }
2453
2454         dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2455         if (!dn) {
2456                 ldap_msgfree(result);
2457                 return NT_STATUS_UNSUCCESSFUL;
2458         }
2459         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2460         SAFE_FREE(dn);
2461
2462         ldap_mods_free(mods, True);
2463         ldap_msgfree(result);
2464
2465         if (rc != LDAP_SUCCESS) {
2466                 char *ld_error = NULL;
2467                 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2468                                 &ld_error);
2469                 DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid, 
2470                           ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
2471                 SAFE_FREE(ld_error);
2472                 return NT_STATUS_UNSUCCESSFUL;
2473         }
2474
2475         DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
2476         return NT_STATUS_OK;
2477 }
2478
2479 /**********************************************************************
2480  *********************************************************************/
2481
2482 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2483                                                    DOM_SID sid)
2484 {
2485         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
2486         pstring sidstring, filter;
2487         LDAPMessage *result = NULL;
2488         int rc;
2489         NTSTATUS ret;
2490         char **attr_list;
2491
2492         sid_to_string(sidstring, &sid);
2493         
2494         pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", 
2495                 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
2496
2497         rc = ldapsam_search_one_group(ldap_state, filter, &result);
2498
2499         if (rc != LDAP_SUCCESS) {
2500                 return NT_STATUS_NO_SUCH_GROUP;
2501         }
2502
2503         attr_list = get_attr_list( groupmap_attr_list_to_delete );
2504         ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
2505         free_attr_list ( attr_list );
2506
2507         ldap_msgfree(result);
2508
2509         return ret;
2510 }
2511
2512 /**********************************************************************
2513  *********************************************************************/
2514
2515 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
2516 {
2517         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2518         fstring filter;
2519         int rc;
2520         char **attr_list;
2521
2522         pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
2523         attr_list = get_attr_list( groupmap_attr_list );
2524         rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
2525                             LDAP_SCOPE_SUBTREE, filter,
2526                             attr_list, 0, &ldap_state->result);
2527         free_attr_list( attr_list );
2528
2529         if (rc != LDAP_SUCCESS) {
2530                 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc)));
2531                 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
2532                 ldap_msgfree(ldap_state->result);
2533                 ldap_state->result = NULL;
2534                 return NT_STATUS_UNSUCCESSFUL;
2535         }
2536
2537         DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
2538                   ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2539                                      ldap_state->result)));
2540
2541         ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
2542         ldap_state->index = 0;
2543
2544         return NT_STATUS_OK;
2545 }
2546
2547 /**********************************************************************
2548  *********************************************************************/
2549
2550 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
2551 {
2552         ldapsam_endsampwent(my_methods);
2553 }
2554
2555 /**********************************************************************
2556  *********************************************************************/
2557
2558 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
2559                                     GROUP_MAP *map)
2560 {
2561         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2562         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2563         BOOL bret = False;
2564
2565         while (!bret) {
2566                 if (!ldap_state->entry)
2567                         return ret;
2568                 
2569                 ldap_state->index++;
2570                 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
2571                 
2572                 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
2573                                             ldap_state->entry); 
2574         }
2575
2576         return NT_STATUS_OK;
2577 }
2578
2579 /**********************************************************************
2580  *********************************************************************/
2581
2582 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
2583                                            enum SID_NAME_USE sid_name_use,
2584                                            GROUP_MAP **rmap, int *num_entries,
2585                                            BOOL unix_only)
2586 {
2587         GROUP_MAP map;
2588         GROUP_MAP *mapt;
2589         int entries = 0;
2590
2591         *num_entries = 0;
2592         *rmap = NULL;
2593
2594         if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
2595                 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
2596                 return NT_STATUS_ACCESS_DENIED;
2597         }
2598
2599         while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
2600                 if (sid_name_use != SID_NAME_UNKNOWN &&
2601                     sid_name_use != map.sid_name_use) {
2602                         DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
2603                         continue;
2604                 }
2605                 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
2606                         DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map.nt_name));
2607                         continue;
2608                 }
2609
2610                 mapt=SMB_REALLOC_ARRAY((*rmap), GROUP_MAP, entries+1);
2611                 if (!mapt) {
2612                         DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
2613                         SAFE_FREE(*rmap);
2614                         return NT_STATUS_UNSUCCESSFUL;
2615                 }
2616                 else
2617                         (*rmap) = mapt;
2618
2619                 mapt[entries] = map;
2620
2621                 entries += 1;
2622
2623         }
2624         ldapsam_endsamgrent(methods);
2625
2626         *num_entries = entries;
2627
2628         return NT_STATUS_OK;
2629 }
2630
2631 static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
2632                                         const DOM_SID *alias,
2633                                         const DOM_SID *member,
2634                                         int modop)
2635 {
2636         struct ldapsam_privates *ldap_state =
2637                 (struct ldapsam_privates *)methods->private_data;
2638         char *dn;
2639         LDAPMessage *result = NULL;
2640         LDAPMessage *entry = NULL;
2641         int count;
2642         LDAPMod **mods = NULL;
2643         int rc;
2644
2645         pstring filter;
2646
2647         pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
2648                      LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
2649                      get_attr_key2string(groupmap_attr_list,
2650                                          LDAP_ATTR_GROUP_SID),
2651                      sid_string_static(alias));
2652
2653         if (ldapsam_search_one_group(ldap_state, filter,
2654                                      &result) != LDAP_SUCCESS)
2655                 return NT_STATUS_NO_SUCH_ALIAS;
2656
2657         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2658                                    result);
2659
2660         if (count < 1) {
2661                 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
2662                 ldap_msgfree(result);
2663                 return NT_STATUS_NO_SUCH_ALIAS;
2664         }
2665
2666         if (count > 1) {
2667                 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for filter %s: "
2668                           "count=%d\n", filter, count));
2669                 ldap_msgfree(result);
2670                 return NT_STATUS_NO_SUCH_ALIAS;
2671         }
2672
2673         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
2674                                  result);
2675
2676         if (!entry) {
2677                 ldap_msgfree(result);
2678                 return NT_STATUS_UNSUCCESSFUL;
2679         }
2680
2681         dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2682         if (!dn) {
2683                 ldap_msgfree(result);
2684                 return NT_STATUS_UNSUCCESSFUL;
2685         }
2686
2687         smbldap_set_mod(&mods, modop,
2688                         get_attr_key2string(groupmap_attr_list,
2689                                             LDAP_ATTR_SID_LIST),
2690                         sid_string_static(member));
2691
2692         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2693
2694         ldap_mods_free(mods, True);
2695         ldap_msgfree(result);
2696
2697         if (rc != LDAP_SUCCESS) {
2698                 char *ld_error = NULL;
2699                 ldap_get_option(ldap_state->smbldap_state->ldap_struct,
2700                                 LDAP_OPT_ERROR_STRING,&ld_error);
2701                 
2702                 DEBUG(0, ("ldapsam_modify_aliasmem: Could not modify alias "
2703                           "for %s, error: %s (%s)\n", dn, ldap_err2string(rc),
2704                           ld_error?ld_error:"unknown"));
2705                 SAFE_FREE(ld_error);
2706                 SAFE_FREE(dn);
2707                 return NT_STATUS_UNSUCCESSFUL;
2708         }
2709
2710         SAFE_FREE(dn);
2711
2712         return NT_STATUS_OK;
2713 }
2714
2715 static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
2716                                      const DOM_SID *alias,
2717                                      const DOM_SID *member)
2718 {
2719         return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
2720 }
2721
2722 static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
2723                                      const DOM_SID *alias,
2724                                      const DOM_SID *member)
2725 {
2726         return ldapsam_modify_aliasmem(methods, alias, member,
2727                                        LDAP_MOD_DELETE);
2728 }
2729
2730 static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
2731                                       const DOM_SID *alias, DOM_SID **members,
2732                                       int *num_members)
2733 {
2734         struct ldapsam_privates *ldap_state =
2735                 (struct ldapsam_privates *)methods->private_data;
2736         LDAPMessage *result = NULL;
2737         LDAPMessage *entry = NULL;
2738         int count;
2739         char **values;
2740         int i;
2741         pstring filter;
2742
2743         *members = NULL;
2744         *num_members = 0;
2745
2746         pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
2747                      LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
2748                      get_attr_key2string(groupmap_attr_list,
2749                                          LDAP_ATTR_GROUP_SID),
2750                      sid_string_static(alias));
2751
2752         if (ldapsam_search_one_group(ldap_state, filter,
2753                                      &result) != LDAP_SUCCESS)
2754                 return NT_STATUS_NO_SUCH_ALIAS;
2755
2756         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2757                                    result);
2758
2759         if (count < 1) {
2760                 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
2761                 ldap_msgfree(result);
2762                 return NT_STATUS_NO_SUCH_ALIAS;
2763         }
2764
2765         if (count > 1) {
2766                 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for filter %s: "
2767                           "count=%d\n", filter, count));
2768                 ldap_msgfree(result);
2769                 return NT_STATUS_NO_SUCH_ALIAS;
2770         }
2771
2772         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
2773                                  result);
2774
2775         if (!entry) {
2776                 ldap_msgfree(result);
2777                 return NT_STATUS_UNSUCCESSFUL;
2778         }
2779
2780         values = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
2781                                  entry,
2782                                  get_attr_key2string(groupmap_attr_list,
2783                                                      LDAP_ATTR_SID_LIST));
2784
2785         if (values == NULL) {
2786                 ldap_msgfree(result);
2787                 return NT_STATUS_OK;
2788         }
2789
2790         count = ldap_count_values(values);
2791
2792         for (i=0; i<count; i++) {
2793                 DOM_SID member;
2794
2795                 if (!string_to_sid(&member, values[i]))
2796                         continue;
2797
2798                 add_sid_to_array(&member, members, num_members);
2799         }
2800
2801         ldap_value_free(values);
2802         ldap_msgfree(result);
2803
2804         return NT_STATUS_OK;
2805 }
2806
2807 static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
2808                                           const DOM_SID *members,
2809                                           int num_members,
2810                                           DOM_SID **aliases, int *num_aliases)
2811 {
2812         struct ldapsam_privates *ldap_state =
2813                 (struct ldapsam_privates *)methods->private_data;
2814         LDAP *ldap_struct;
2815
2816         char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
2817
2818         LDAPMessage *result = NULL;
2819         LDAPMessage *entry = NULL;
2820         int i;
2821         int rc;
2822         char *filter;
2823         TALLOC_CTX *mem_ctx;
2824
2825         mem_ctx = talloc_init("ldapsam_alias_memberships");
2826
2827         if (mem_ctx == NULL)
2828                 return NT_STATUS_NO_MEMORY;
2829
2830         /* This query could be further optimized by adding a
2831            (&(sambaSID=<domain-sid>*)) so that only those aliases that are
2832            asked for in the getuseraliases are returned. */        
2833
2834         filter = talloc_asprintf(mem_ctx,
2835                                  "(&(|(objectclass=%s)(objectclass=%s))(|",
2836                                  LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY);
2837
2838         for (i=0; i<num_members; i++)
2839                 filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
2840                                          filter,
2841                                          sid_string_static(&members[i]));
2842
2843         filter = talloc_asprintf(mem_ctx, "%s))", filter);
2844
2845         rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
2846                             LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2847
2848         talloc_destroy(mem_ctx);
2849
2850         if (rc != LDAP_SUCCESS)
2851                 return NT_STATUS_UNSUCCESSFUL;
2852
2853         *aliases = NULL;
2854         *num_aliases = 0;
2855
2856         ldap_struct = ldap_state->smbldap_state->ldap_struct;
2857
2858         for (entry = ldap_first_entry(ldap_struct, result);
2859              entry != NULL;
2860              entry = ldap_next_entry(ldap_struct, entry))
2861         {
2862                 fstring sid_str;
2863                 DOM_SID sid;
2864
2865                 if (!smbldap_get_single_attribute(ldap_struct, entry,
2866                                                   LDAP_ATTRIBUTE_SID,
2867                                                   sid_str,
2868                                                   sizeof(sid_str)-1))
2869                         continue;
2870
2871                 if (!string_to_sid(&sid, sid_str))
2872                         continue;
2873
2874                 add_sid_to_array_unique(&sid, aliases, num_aliases);
2875         }
2876
2877         ldap_msgfree(result);
2878         return NT_STATUS_OK;
2879 }
2880
2881 static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int policy_index, int *value)
2882 {
2883         NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
2884         LDAPMessage *result = NULL;
2885         LDAPMessage *entry = NULL;
2886         int count;
2887         int rc;
2888         pstring filter, base;
2889         char **vals;
2890         const char *policy_string = NULL;
2891         int tmp_val;
2892         BOOL found_tdb = False;
2893
2894         struct ldapsam_privates *ldap_state =
2895                 (struct ldapsam_privates *)methods->private_data;
2896
2897         char *attrs[] = {
2898                 (char *)get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_NAME), 
2899                 (char *)get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_VAL), 
2900                 NULL 
2901         };
2902
2903         if (cache_account_policy_get(policy_index, value)) {
2904                 DEBUG(11,("ldapsam_get_account_policy: got valid value from cache\n"));
2905                 return NT_STATUS_OK;
2906         }
2907
2908         policy_string = decode_account_policy_name(policy_index);
2909         if (!policy_string) {
2910                 DEBUG(0,("ldapsam_get_account_policy: invalid policy index: %d\n", policy_index));
2911                 return ntstatus;
2912         }
2913
2914         pstr_sprintf(filter, "(&(objectclass=%s)(%s=%s))",
2915                      LDAP_OBJ_ACCOUNT_POLICY, 
2916                      get_attr_key2string(acctpol_attr_list,
2917                                          LDAP_ATTR_ACCOUNT_POLICY_NAME), policy_string);
2918
2919         pstr_sprintf(base, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
2920                 get_global_sam_name(), lp_ldap_suffix());
2921
2922 search:         
2923         rc = smbldap_search(ldap_state->smbldap_state, base,
2924                             LDAP_SCOPE_ONE, filter, attrs, 0, &result);
2925
2926         if (rc != LDAP_SUCCESS) 
2927                 return ntstatus;
2928
2929         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2930                                    result);
2931
2932         /* handle deleted ldap-entries (migrate on the fly, use a default as last resort) - gd */
2933         if (count < 1 && !found_tdb) {
2934
2935                 found_tdb = False;
2936
2937                 DEBUG(3,("ldapsam_get_account_policy: no entry for that policy in ldap found\n"));
2938
2939                 if (!account_policy_get(policy_index, &tmp_val)) {
2940                         DEBUG(10,("ldapsam_get_account_policy: failed to get account_policy from tdb\n"));
2941                         found_tdb = True;
2942                 }
2943
2944                 if (!found_tdb && !account_policy_get_default(policy_index, &tmp_val)) {
2945                         ldap_msgfree(result);
2946                         return ntstatus;
2947                 }
2948
2949                 if (!pdb_set_account_policy(policy_index, tmp_val)) {
2950                         DEBUG(1,("ldapsam_get_account_policy: failed to set account_policy\n"));
2951                         ldap_msgfree(result);
2952                         return ntstatus;
2953                 }
2954
2955                 DEBUG(3,("ldapsam_get_account_policy: set account policy value based on %s value.\n", 
2956                         found_tdb ? "tdb":"default"));
2957
2958                 ldap_msgfree(result);
2959                 goto search;
2960         }
2961
2962         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2963
2964         if (!entry) {
2965                 ldap_msgfree(result);
2966                 return NT_STATUS_UNSUCCESSFUL;
2967         }
2968
2969         vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, 
2970                 get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_VAL));
2971
2972         if (vals == NULL) 
2973                 goto out;
2974
2975         *value = (uint32)atol(vals[0]);
2976
2977         if (!cache_account_policy_set(policy_index, *value)) {
2978                 DEBUG(0,("ldapsam_get_account_policy: failed to update local tdb as a cache\n"));
2979                 return ntstatus;
2980         }
2981
2982         ntstatus = NT_STATUS_OK;
2983
2984 out:
2985         ldap_value_free(vals);
2986         ldap_msgfree(result);
2987
2988         return ntstatus;
2989 }
2990
2991 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int policy_index, int value)
2992 {
2993         NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
2994         LDAPMessage *result = NULL;
2995         LDAPMessage *entry = NULL;
2996         int count;
2997         int rc;
2998         pstring filter, base, dn;
2999         int modop;
3000         LDAPMod **mods = NULL;
3001         fstring value_string;
3002         char *old_dn = NULL;
3003         const char *policy_string = NULL;
3004         const char *policy_description = NULL;
3005
3006         struct ldapsam_privates *ldap_state =
3007                 (struct ldapsam_privates *)methods->private_data;
3008
3009         char *attrs[] = {
3010                 (char *)get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_NAME), 
3011                 (char *)get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_VAL), 
3012                 NULL 
3013         };
3014
3015         policy_string = decode_account_policy_name(policy_index);
3016         if (!policy_string) {
3017                 DEBUG(0,("ldapsam_set_account_policy: invalid policy\n"));
3018                 return ntstatus;
3019         }
3020
3021         policy_description = account_policy_get_comment(policy_index);
3022         if (!policy_description) {
3023                 DEBUG(0,("ldapsam_set_account_policy: no description for policy found\n"));
3024                 return ntstatus;
3025         }
3026
3027         pstr_sprintf(filter, "(&(objectclass=%s)(%s=%s))",
3028                      LDAP_OBJ_ACCOUNT_POLICY, 
3029                      get_attr_key2string(acctpol_attr_list,
3030                                          LDAP_ATTR_ACCOUNT_POLICY_NAME), policy_string);
3031
3032         pstr_sprintf(base, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
3033                 get_global_sam_name(), lp_ldap_suffix());
3034                 
3035         rc = smbldap_search(ldap_state->smbldap_state, base,
3036                             LDAP_SCOPE_ONE, filter, attrs, 0, &result);
3037
3038         if (rc != LDAP_SUCCESS) 
3039                 return ntstatus;
3040
3041         count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
3042
3043         slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3044
3045         if (count == 1) {
3046
3047                 modop = LDAP_MOD_REPLACE;
3048
3049                 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
3050
3051                 if (!entry) {
3052                         ldap_msgfree(result);
3053                         return NT_STATUS_UNSUCCESSFUL;
3054                 }
3055
3056                 old_dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
3057                 if (!old_dn) {
3058                         ldap_msgfree(result);
3059                         return ntstatus;
3060                 }
3061
3062                 smbldap_set_mod(&mods, modop,
3063                         get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_VAL), 
3064                         value_string);
3065
3066                 rc = smbldap_modify(ldap_state->smbldap_state, old_dn, mods);
3067
3068         } else {
3069
3070                 modop = LDAP_MOD_ADD;
3071
3072                 pstr_sprintf(dn, "%s=%s,%s=%s,%s",
3073                         get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_NAME), policy_string,
3074                         get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), get_global_sam_name(),
3075                         lp_ldap_suffix());
3076
3077                 smbldap_set_mod( &mods, modop, "objectClass", LDAP_OBJ_ACCOUNT_POLICY );
3078
3079                 smbldap_make_mod( ldap_state->smbldap_state->ldap_struct, entry, &mods, 
3080                         get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_NAME), 
3081                         policy_string);
3082
3083                 smbldap_make_mod( ldap_state->smbldap_state->ldap_struct, entry, &mods, 
3084                         get_attr_key2string(acctpol_attr_list, LDAP_ATTR_ACCOUNT_POLICY_VAL), 
3085                         value_string);
3086
3087                 smbldap_make_mod( ldap_state->smbldap_state->ldap_struct, entry, &mods, 
3088                         "description", 
3089                         policy_description);
3090
3091                 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
3092         }
3093
3094         ldap_mods_free(mods, True);
3095         ldap_msgfree(result);
3096
3097         if (rc != LDAP_SUCCESS) {
3098                 char *ld_error = NULL;
3099                 ldap_get_option(ldap_state->smbldap_state->ldap_struct,
3100                                 LDAP_OPT_ERROR_STRING,&ld_error);
3101                 
3102                 DEBUG(0, ("ldapsam_set_account_policy: Could not set account policy "
3103                           "for %s, error: %s (%s)\n", dn, ldap_err2string(rc),
3104                           ld_error?ld_error:"unknown"));
3105                 SAFE_FREE(ld_error);
3106                 SAFE_FREE(old_dn);
3107                 return ntstatus;
3108         }
3109
3110         SAFE_FREE(old_dn);
3111
3112         if (!cache_account_policy_set(policy_index, value)) {
3113                 DEBUG(0,("ldapsam_set_account_policy: failed to update local tdb cache\n"));
3114                 return ntstatus;
3115         }
3116
3117         return NT_STATUS_OK;
3118 }
3119
3120 /**********************************************************************
3121  Housekeeping
3122  *********************************************************************/
3123
3124 static void free_private_data(void **vp) 
3125 {
3126         struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
3127
3128         smbldap_free_struct(&(*ldap_state)->smbldap_state);
3129
3130         if ((*ldap_state)->result != NULL) {
3131                 ldap_msgfree((*ldap_state)->result);
3132                 (*ldap_state)->result = NULL;
3133         }
3134
3135         *ldap_state = NULL;
3136
3137         /* No need to free any further, as it is talloc()ed */
3138 }
3139
3140 /**********************************************************************
3141  Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
3142  *********************************************************************/
3143
3144 static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, 
3145                                         const char *location)
3146 {
3147         NTSTATUS nt_status;
3148         struct ldapsam_privates *ldap_state;
3149
3150         if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
3151                 return nt_status;
3152         }
3153
3154         (*pdb_method)->name = "ldapsam";
3155
3156         (*pdb_method)->setsampwent = ldapsam_setsampwent;
3157         (*pdb_method)->endsampwent = ldapsam_endsampwent;
3158         (*pdb_method)->getsampwent = ldapsam_getsampwent;
3159         (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
3160         (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
3161         (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
3162         (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
3163         (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
3164
3165         (*pdb_method)->getgrsid = ldapsam_getgrsid;
3166         (*pdb_method)->getgrgid = ldapsam_getgrgid;
3167         (*pdb_method)->getgrnam = ldapsam_getgrnam;
3168         (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
3169         (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
3170         (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
3171         (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
3172         (*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
3173
3174         (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
3175         (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
3176
3177         /* TODO: Setup private data and free */
3178
3179         ldap_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct ldapsam_privates);
3180         if (!ldap_state) {
3181                 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
3182                 return NT_STATUS_NO_MEMORY;
3183         }
3184
3185         if (!NT_STATUS_IS_OK(nt_status = 
3186                              smbldap_init(pdb_context->mem_ctx, location, 
3187                                           &ldap_state->smbldap_state)));
3188
3189         ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
3190         if (!ldap_state->domain_name) {
3191                 return NT_STATUS_NO_MEMORY;
3192         }
3193
3194         (*pdb_method)->private_data = ldap_state;
3195
3196         (*pdb_method)->free_private_data = free_private_data;
3197
3198         return NT_STATUS_OK;
3199 }
3200
3201 /**********************************************************************
3202  Initialise the 'compat' mode for pdb_ldap
3203  *********************************************************************/
3204
3205 static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
3206 {
3207         NTSTATUS nt_status;
3208         struct ldapsam_privates *ldap_state;
3209
3210 #ifdef WITH_LDAP_SAMCONFIG
3211         if (!location) {
3212                 int ldap_port = lp_ldap_port();
3213                         
3214                 /* remap default port if not using SSL (ie clear or TLS) */
3215                 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
3216                         ldap_port = 389;
3217                 }
3218
3219                 location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
3220                 if (!location) {
3221                         return NT_STATUS_NO_MEMORY;
3222                 }
3223         }
3224 #endif
3225
3226         if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
3227                 return nt_status;
3228         }
3229
3230         (*pdb_method)->name = "ldapsam_compat";
3231
3232         ldap_state = (*pdb_method)->private_data;
3233         ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
3234
3235         sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
3236
3237         return NT_STATUS_OK;
3238 }
3239
3240 /**********************************************************************
3241  Initialise the normal mode for pdb_ldap
3242  *********************************************************************/
3243
3244 static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
3245 {
3246         NTSTATUS nt_status;
3247         struct ldapsam_privates *ldap_state;
3248         uint32 alg_rid_base;
3249         pstring alg_rid_base_string;
3250         LDAPMessage *result = NULL;
3251         LDAPMessage *entry = NULL;
3252         DOM_SID ldap_domain_sid;
3253         DOM_SID secrets_domain_sid;
3254         pstring domain_sid_string;
3255
3256         if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
3257                 return nt_status;
3258         }
3259
3260         (*pdb_method)->name = "ldapsam";
3261
3262         (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
3263         (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
3264         (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
3265         (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
3266
3267         ldap_state = (*pdb_method)->private_data;
3268         ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
3269
3270         /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
3271         
3272         nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result, 
3273                                                ldap_state->domain_name, True);
3274         
3275         if ( !NT_STATUS_IS_OK(nt_status) ) {
3276                 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
3277                 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
3278 and will risk BDCs having inconsistant SIDs\n"));
3279                 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
3280                 return NT_STATUS_OK;
3281         }
3282
3283         /* Given that the above might fail, everything below this must be optional */
3284         
3285         entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
3286         if (!entry) {
3287                 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
3288                 ldap_msgfree(result);
3289                 return NT_STATUS_UNSUCCESSFUL;
3290         }
3291
3292         if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
3293                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), 
3294                                  domain_sid_string)) {
3295                 BOOL found_sid;
3296                 if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
3297                         DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string));
3298                         return NT_STATUS_INVALID_PARAMETER;
3299                 }
3300                 found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid);
3301                 if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) {
3302                         fstring new_sid_str, old_sid_str;
3303                         DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n",
3304                                   ldap_state->domain_name, 
3305                                   sid_to_string(old_sid_str, &secrets_domain_sid),
3306                                   sid_to_string(new_sid_str, &ldap_domain_sid)));
3307                         
3308                         /* reset secrets.tdb sid */
3309                         secrets_store_domain_sid(ldap_state->domain_name, &ldap_domain_sid);
3310                         DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str, get_global_sam_sid())));
3311                 }
3312                 sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
3313         }
3314
3315         if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, 
3316                                  get_attr_key2string( dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE ),
3317                                  alg_rid_base_string)) {
3318                 alg_rid_base = (uint32)atol(alg_rid_base_string);
3319                 if (alg_rid_base != algorithmic_rid_base()) {
3320                         DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
3321                                   "database was initialised.  Aborting. \n"));
3322                         ldap_msgfree(result);
3323                         return NT_STATUS_UNSUCCESSFUL;
3324                 }
3325         }
3326         ldap_msgfree(result);
3327
3328         return NT_STATUS_OK;
3329 }
3330
3331 NTSTATUS pdb_ldap_init(void)
3332 {
3333         NTSTATUS nt_status;
3334         if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
3335                 return nt_status;
3336
3337         if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
3338                 return nt_status;
3339
3340         return NT_STATUS_OK;
3341 }