Changes from APPLIANCE_HEAD:
[ira/wip.git] / source3 / passdb / pdb_tdb.c
1 /*
2  * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3  * Copyright (C) Andrew Tridgell 1992-1998
4  * Copyright (C) Simo Sorce 2000
5  * Copyright (C) Gerald Carter 2000
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  * 
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  * 
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc., 675
19  * Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include "includes.h"
23
24 #ifdef WITH_TDBPWD
25
26 #define PASSDB_FILE_NAME        "/passdb.tdb"
27 #define RIDDB_FILE_NAME         "/riddb.tdb"
28 #define TDB_FORMAT_STRING       "ddddddfffPPfPPPPffddBBwdwdBdd"
29 #define USERPREFIX              "USER_"
30 #define RIDPREFIX               "RID_"
31
32 extern int              DEBUGLEVEL;
33 extern pstring          samlogon_user;
34 extern BOOL             sam_logon_in_ssb;
35
36
37 struct tdb_enum_info
38 {
39         TDB_CONTEXT     *passwd_tdb;
40         TDB_DATA        key;
41 };
42
43 static struct tdb_enum_info     global_tdb_ent;
44 static SAM_ACCOUNT              global_sam_pass;
45
46 /**********************************************************************
47  Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
48  *********************************************************************/
49 static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, BYTE *buf, 
50                                   uint32 buflen)
51 {
52         static fstring  username,
53                         domain,
54                         nt_username,
55                         dir_drive,
56                         unknown_str,
57                         munged_dial;
58         static pstring  full_name,
59                         home_dir,
60                         logon_script,
61                         profile_path,
62                         acct_desc,
63                         workstations;
64         static BYTE     *lm_pw_ptr,
65                         *nt_pw_ptr,
66                         lm_pw[16],
67                         nt_pw[16];
68         uint32          len = 0;
69         uint32          lmpwlen, ntpwlen, hourslen;
70
71         /* using static memory for strings */
72         /* you set it now or you will delete any fields retrieved by tdb_unpack */
73         pdb_set_mem_ownership(sampass, False);
74
75                                                                         
76         /* unpack the buffer into variables */
77         len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
78                 &sampass->logon_time,
79                 &sampass->logoff_time,
80                 &sampass->kickoff_time,
81                 &sampass->pass_last_set_time,
82                 &sampass->pass_can_change_time,
83                 &sampass->pass_must_change_time,
84                 username,
85                 domain,
86                 nt_username,
87                 full_name,
88                 home_dir,
89                 dir_drive,
90                 logon_script,
91                 profile_path,
92                 acct_desc,
93                 workstations,
94                 unknown_str,
95                 munged_dial,
96                 &sampass->user_rid,
97                 &sampass->group_rid,
98                 &lmpwlen, &lm_pw_ptr,
99                 &ntpwlen, &nt_pw_ptr,
100                 &sampass->acct_ctrl,
101                 &sampass->unknown_3,
102                 &sampass->logon_divs,
103                 &sampass->hours_len,
104                 &hourslen, &sampass->hours,
105                 &sampass->unknown_5,
106                 &sampass->unknown_6);
107                 
108         if (len == -1) 
109                 return False;
110
111         /*
112          * We have to copy the password hashes into static memory
113          * and free the memory allocated by tdb_unpack.  This is because
114          * the sampass->own_memory flag is for all pointer members.
115          * The remaining members are using static memory and so
116          * the password hashes must as well.     --jerry
117          */
118         if (lm_pw_ptr)
119         {
120                 memcpy(lm_pw, lm_pw_ptr, 16);
121                 free (lm_pw_ptr);
122         }
123         if (nt_pw_ptr)
124         {
125                 memcpy(nt_pw, nt_pw_ptr, 16);
126                 free (nt_pw_ptr);
127         }
128         
129         pdb_set_username     (sampass, username);
130         pdb_set_domain       (sampass, domain);
131         pdb_set_nt_username  (sampass, nt_username);
132         pdb_set_fullname     (sampass, full_name);
133         pdb_set_homedir      (sampass, home_dir);
134         pdb_set_dir_drive    (sampass, dir_drive);
135         pdb_set_logon_script (sampass, logon_script);
136         pdb_set_profile_path (sampass, profile_path);
137         pdb_set_acct_desc    (sampass, acct_desc);
138         pdb_set_workstations (sampass, workstations);
139         pdb_set_munged_dial  (sampass, munged_dial);
140         pdb_set_lanman_passwd(sampass, lm_pw);
141         pdb_set_nt_passwd    (sampass, nt_pw);
142         
143         return True;
144 }
145
146 /**********************************************************************
147  Intialize a BYTE buffer from a SAM_ACCOUNT struct
148  *********************************************************************/
149 static uint32 init_buffer_from_sam (BYTE **buf, SAM_ACCOUNT *sampass)
150 {
151         size_t          len, buflen;
152
153         fstring         username,
154                         domain,
155                         nt_username,
156                         dir_drive,
157                         unknown_str,
158                         munged_dial;
159         pstring         full_name,
160                         home_dir,
161                         logon_script,
162                         profile_path,
163                         acct_desc,
164                         workstations;
165         BYTE            lm_pw[16],
166                         nt_pw[16];
167         char            null_pw[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
168
169         /* do we have a valid SAM_ACCOUNT pointer? */
170         if (sampass == NULL)
171                 return -1;
172                 
173         *buf = NULL;
174         buflen = 0;
175
176         fstrcpy(username, sampass->username);
177         fstrcpy(domain,   sampass->domain);
178         fstrcpy(nt_username, sampass->nt_username);
179         fstrcpy(dir_drive, sampass->dir_drive);
180         fstrcpy(unknown_str, sampass->unknown_str);
181         fstrcpy(munged_dial, sampass->munged_dial);
182         
183         pstrcpy(full_name, sampass->full_name);
184         pstrcpy(home_dir, sampass->home_dir);
185         pstrcpy(logon_script, sampass->logon_script);
186         pstrcpy(profile_path, sampass->profile_path);
187         pstrcpy(acct_desc, sampass->acct_desc);
188         pstrcpy(workstations, sampass->workstations);
189         
190         if (sampass->lm_pw)
191                 memcpy(lm_pw, sampass->lm_pw, 16);
192         else
193                 pdb_gethexpwd (null_pw, lm_pw);
194                 
195         if (sampass->nt_pw)
196                 memcpy(nt_pw, sampass->nt_pw, 16);
197         else
198                 pdb_gethexpwd (null_pw, nt_pw);
199                 
200                         
201         /* one time to get the size needed */
202         len = tdb_pack(NULL, 0,  TDB_FORMAT_STRING,
203                 sampass->logon_time,
204                 sampass->logoff_time,
205                 sampass->kickoff_time,
206                 sampass->pass_last_set_time,
207                 sampass->pass_can_change_time,
208                 sampass->pass_must_change_time,
209                 username,
210                 domain,
211                 nt_username,
212                 full_name,
213                 home_dir,
214                 dir_drive,
215                 logon_script,
216                 profile_path,
217                 acct_desc,
218                 workstations,
219                 unknown_str,
220                 munged_dial,
221                 sampass->user_rid,
222                 sampass->group_rid,
223                 16, lm_pw,
224                 16, nt_pw,
225                 sampass->acct_ctrl,
226                 sampass->unknown_3,
227                 sampass->logon_divs,
228                 sampass->hours_len,
229                 MAX_HOURS_LEN, sampass->hours,
230                 sampass->unknown_5,
231                 sampass->unknown_6);
232
233
234         /* malloc the space needed */
235         if ( (*buf=(BYTE*)malloc(len)) == NULL)
236         {
237                 DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
238                 return (-1);
239         }
240         
241         /* now for the real call to tdb_pack() */
242         /* one time to get the size needed */
243         buflen = tdb_pack(*buf, len,  TDB_FORMAT_STRING,
244                 sampass->logon_time,
245                 sampass->logoff_time,
246                 sampass->kickoff_time,
247                 sampass->pass_last_set_time,
248                 sampass->pass_can_change_time,
249                 sampass->pass_must_change_time,
250                 username,
251                 domain,
252                 nt_username,
253                 full_name,
254                 home_dir,
255                 dir_drive,
256                 logon_script,
257                 profile_path,
258                 acct_desc,
259                 workstations,
260                 unknown_str,
261                 munged_dial,
262                 sampass->user_rid,
263                 sampass->group_rid,
264                 16, lm_pw,
265                 16, nt_pw,
266                 sampass->acct_ctrl,
267                 sampass->unknown_3,
268                 sampass->logon_divs,
269                 sampass->hours_len,
270                 MAX_HOURS_LEN, sampass->hours,
271                 sampass->unknown_5,
272                 sampass->unknown_6);
273         
274         
275         /* check to make sure we got it correct */
276         if (buflen != len)
277         {
278                 /* error */
279                 free (*buf);
280                 return (-1);
281         }
282
283         return (buflen);
284 }
285
286 /***************************************************************
287  Open the TDB passwd database for SAM account enumeration.
288 ****************************************************************/
289 BOOL pdb_setsampwent(BOOL update)
290 {
291         pstring         tdbfile;
292         
293         pstrcpy (tdbfile, lp_private_dir());
294         pstrcat (tdbfile, PASSDB_FILE_NAME);
295         
296         /* Open tdb passwd */
297         if (!(global_tdb_ent.passwd_tdb = tdb_open(tdbfile, 0, 0, update ? O_RDWR : O_RDONLY, 0600)))
298         {
299                 DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
300                 if (!(global_tdb_ent.passwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
301                 {
302                         DEBUG(0, ("Unable to create TDB passwd (passdb.tdb) !!!"));
303                         return False;
304                 }
305         }
306         
307         global_tdb_ent.key = tdb_firstkey(global_tdb_ent.passwd_tdb);
308
309         return True;
310 }
311
312 /***************************************************************
313  End enumeration of the TDB passwd list.
314 ****************************************************************/
315 void pdb_endsampwent(void)
316 {
317         if (global_tdb_ent.passwd_tdb)
318         {
319                 tdb_close(global_tdb_ent.passwd_tdb);
320                 global_tdb_ent.passwd_tdb = NULL;
321         }
322         
323         DEBUG(7, ("endtdbpwent: closed password file.\n"));
324 }
325
326
327 /*****************************************************************
328  Get one SAM_ACCOUNT from the TDB (next in line)
329 *****************************************************************/
330 SAM_ACCOUNT* pdb_getsampwent(void)
331 {
332         TDB_DATA        data;
333         struct passwd   *pw;
334         uid_t           uid;
335         gid_t           gid;
336
337         /* do we have an valid interation pointer? */
338         if(global_tdb_ent.passwd_tdb == NULL) 
339         {
340                 DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
341                 return NULL;
342         }
343
344         data = tdb_fetch (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
345         if (!data.dptr)
346         {
347                 DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
348                 return NULL;
349         }
350   
351         /* unpack the buffer */
352         pdb_clear_sam (&global_sam_pass);
353         if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize))
354         {
355                 DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
356                 return NULL;
357         }
358         
359         /* validate the account and fill in UNIX uid and gid.  sys_getpwnam()
360            is used instaed of Get_Pwnam() as we do not need to try case
361            permutations */
362         if ((pw=sys_getpwnam(pdb_get_username(&global_sam_pass))) == NULL)
363         {
364                 DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL.  User does not exist!\n", 
365                           pdb_get_username(&global_sam_pass)));
366                 return NULL;
367         }
368
369         uid = pw->pw_uid;
370         gid = pw->pw_gid;
371         pdb_set_uid (&global_sam_pass, uid);
372         pdb_set_gid (&global_sam_pass, gid);
373
374         /* 21 days from present */
375         pdb_set_pass_must_change_time(&global_sam_pass, time(NULL)+1814400);    
376
377         standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_logon_script(&global_sam_pass));
378         standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_profile_path(&global_sam_pass));
379         standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_homedir(&global_sam_pass));
380
381         /* increment to next in line */
382         global_tdb_ent.key = tdb_nextkey (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
383
384         return (&global_sam_pass);
385 }
386
387 /******************************************************************
388  Lookup a name in the SAM TDB
389 ******************************************************************/
390 SAM_ACCOUNT* pdb_getsampwnam (char *sname)
391 {
392         TDB_CONTEXT     *pwd_tdb;
393         TDB_DATA        data, key;
394         fstring         keystr;
395         struct passwd   *pw;
396         pstring         tdbfile;
397         fstring         name;
398         uid_t           uid;
399         gid_t           gid;
400         
401         fstrcpy (name, sname);
402         strlower (name);
403         pstrcpy (tdbfile, lp_private_dir());
404         pstrcat (tdbfile, PASSDB_FILE_NAME);
405         
406         /* set search key */
407         slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name);
408         key.dptr = keystr;
409         key.dsize = strlen (keystr) + 1;
410
411         /* open the accounts TDB */
412         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDONLY, 0600)))
413         {
414                 DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n"));
415                 return False;
416         }
417
418         /* get the record */
419         data = tdb_fetch (pwd_tdb, key);
420         if (!data.dptr)
421         {
422                 DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
423                 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
424                 tdb_close (pwd_tdb);
425                 return NULL;
426         }
427   
428         /* unpack the buffer */
429         pdb_clear_sam (&global_sam_pass);
430         if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize))
431         {
432                 DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
433                 return NULL;
434         }
435         
436         /* validate the account and fill in UNIX uid and gid.  sys_getpwnam()
437            is used instaed of Get_Pwnam() as we do not need to try case
438            permutations */
439         if ((pw=sys_getpwnam(pdb_get_username(&global_sam_pass))) == NULL)
440         {
441                 DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL.  User does not exist!\n", 
442                           pdb_get_username(&global_sam_pass)));
443                 return NULL;
444         }
445         
446         uid = pw->pw_uid;
447         gid = pw->pw_gid;
448         pdb_set_uid (&global_sam_pass, uid);
449         pdb_set_gid (&global_sam_pass, gid);
450         
451         /* 21 days from present */
452         pdb_set_pass_must_change_time(&global_sam_pass, time(NULL)+1814400);    
453         
454         standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_logon_script(&global_sam_pass));
455         standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_profile_path(&global_sam_pass));
456         standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_homedir(&global_sam_pass));
457
458         /* cleanup */
459         tdb_close (pwd_tdb);
460
461         return (&global_sam_pass);
462 }
463
464 /***************************************************************************
465  Search by uid
466  **************************************************************************/
467 SAM_ACCOUNT* pdb_getsampwuid (uid_t uid)
468 {
469         struct passwd   *pw;
470         fstring         name;
471
472         pw = sys_getpwuid(uid);
473         if (pw == NULL)
474         {
475                 DEBUG(0,("pdb_getsampwuid: getpwuid(%d) return NULL. User does not exist!\n", uid));
476                 return NULL;
477         }
478         fstrcpy (name, pw->pw_name);
479
480         return pdb_getsampwnam (name);
481
482 }
483
484 /***************************************************************************
485  Search by rid
486  **************************************************************************/
487 SAM_ACCOUNT* pdb_getsampwrid (uint32 rid)
488 {
489         TDB_CONTEXT             *pwd_tdb;
490         TDB_DATA                data, key;
491         fstring                 keystr;
492         pstring                 tdbfile;
493         fstring                 name;
494         
495         pstrcpy (tdbfile, lp_private_dir());
496         pstrcat (tdbfile, RIDDB_FILE_NAME);
497         
498         /* set search key */
499         slprintf(keystr, sizeof(keystr), "%s%.8x", RIDPREFIX, rid);
500         key.dptr = keystr;
501         key.dsize = strlen (keystr) + 1;
502
503         /* open the accounts TDB */
504         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDONLY, 0600)))
505         {
506                 DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
507                 return False;
508         }
509
510         /* get the record */
511         data = tdb_fetch (pwd_tdb, key);
512         if (!data.dptr)
513         {
514                 DEBUG(5,("pdb_getsampwrid (TDB): error fetching database.\n"));
515                 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
516                 tdb_close (pwd_tdb);
517                 return NULL;
518         }
519
520         fstrcpy (name, data.dptr);
521         
522         tdb_close (pwd_tdb);
523         
524         return pdb_getsampwnam (name);
525 }
526
527
528 /***************************************************************************
529  Delete a SAM_ACCOUNT
530 ****************************************************************************/
531 BOOL pdb_delete_sam_account(char *sname)
532 {
533         struct passwd  *pwd = NULL;
534         TDB_CONTEXT     *pwd_tdb;
535         TDB_DATA        key, data;
536         fstring         keystr;
537         pstring         tdbfile;
538         uid_t           uid;
539         uint32          rid;
540         fstring         name;
541         
542         fstrcpy (name, sname);
543         strlower (name);
544         
545         pstrcpy (tdbfile, lp_private_dir());
546         pstrcat (tdbfile, PASSDB_FILE_NAME);
547
548         /* open the TDB */
549         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
550         {
551                 DEBUG(0, ("Unable to open TDB passwd!"));
552                 return False;
553         }
554   
555         /* set the search key */
556         slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name);
557         key.dptr = keystr;
558         key.dsize = strlen (keystr) + 1;
559         
560         /* get the record */
561         data = tdb_fetch (pwd_tdb, key);
562         if (!data.dptr)
563         {
564                 DEBUG(5,("pdb_delete_sam_account (TDB): error fetching database.\n"));
565                 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
566                 tdb_close (pwd_tdb);
567                 return False;
568         }
569   
570         /* unpack the buffer */
571         pdb_clear_sam (&global_sam_pass);
572         if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize))
573         {
574                 DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
575                 return False;
576         }
577
578         pwd = sys_getpwnam(global_sam_pass.username);
579         rid = pdb_uid_to_user_rid (uid);
580
581         /* it's outaa here!  8^) */
582         if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
583         {
584                 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
585                 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
586                 tdb_close(pwd_tdb); 
587                 return False;
588         }       
589         tdb_close(pwd_tdb);
590         
591         pstrcpy (tdbfile, lp_private_dir());
592         pstrcat (tdbfile, RIDDB_FILE_NAME);     
593         
594         /* open the RID TDB */
595         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
596         {
597                 DEBUG(0, ("Unable to open TDB rid file!"));
598                 return False;
599         }       
600
601         /* set the search key */
602         slprintf(keystr, sizeof(keystr), "%s%.8x", RIDPREFIX, rid);
603         key.dptr = keystr;
604         key.dsize = strlen (keystr) + 1;
605
606         /* it's outaa here!  8^) */
607         if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
608         {
609                 DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
610                 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
611                 tdb_close(pwd_tdb); 
612                 return False;
613         }
614         
615         tdb_close(pwd_tdb);
616         
617         return True;
618 }
619
620 /***************************************************************************
621  Update the TDB SAM
622 ****************************************************************************/
623 static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
624 {
625         TDB_CONTEXT     *pwd_tdb;
626         TDB_DATA        key, data;
627         BYTE            *buf = NULL;
628         fstring         keystr;
629         pstring         tdbfile;
630         fstring         name;
631         int             newtdb = FALSE;
632         
633         pstrcpy (tdbfile, lp_private_dir());
634         pstrcat (tdbfile, PASSDB_FILE_NAME);
635         
636         if ( (!newpwd->uid) || (!newpwd->gid) )
637                 DEBUG (0,("tdb_update_sam: Storing a SAM_ACCOUNT for [%s] with uid %d and gid %d!\n",
638                         newpwd->username, newpwd->uid, newpwd->gid));
639                 
640         /* if we don't have a RID, then generate one */
641         if (!newpwd->user_rid)
642                 pdb_set_user_rid (newpwd, pdb_uid_to_user_rid (newpwd->uid));
643         if (!newpwd->group_rid)
644                 pdb_set_group_rid (newpwd, pdb_gid_to_group_rid (newpwd->gid));
645     
646         /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
647         if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1)
648         {
649                 DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
650                 return False;
651         }
652         data.dptr = buf;
653
654         fstrcpy (name, pdb_get_username(newpwd));
655         strlower (name);
656         
657         /* setup the USER index key */
658         slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name);
659         key.dptr = keystr;
660         key.dsize = strlen (keystr) + 1;
661
662         /* invalidate the existing TDB iterator if it is open */
663         if (global_tdb_ent.passwd_tdb)
664         {
665                 tdb_close(global_tdb_ent.passwd_tdb);
666                 global_tdb_ent.passwd_tdb = NULL;
667         }
668  
669         /* open the account TDB passwd*/
670         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
671         {
672                 DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
673                 if (flag == TDB_INSERT)
674                 {
675                         DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
676                         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
677                         {
678                                 DEBUG(0, ("Unable to create TDB passwd (passdb.tdb) !!!\n"));
679                                 return False;
680                         }
681                         newtdb = TRUE;
682                 }
683         }
684
685         /* add the account */
686         if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS)
687         {
688                 DEBUG(0, ("Unable to modify TDB passwd!"));
689                 DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
690                 tdb_close (pwd_tdb);
691                 return False;
692         }
693
694         /* cleanup */
695         tdb_close (pwd_tdb);
696         
697         /* setup RID data */
698         data.dsize = sizeof(fstring);
699         data.dptr = name;
700
701         pstrcpy (tdbfile, lp_private_dir());
702         pstrcat (tdbfile, RIDDB_FILE_NAME);
703
704         /* setup the RID index key */
705         slprintf(keystr, sizeof(keystr), "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
706         key.dptr = keystr;
707         key.dsize = strlen (keystr) + 1;
708         
709         /* open the account TDB rid file*/
710         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
711         {
712                 DEBUG(0, ("tdb_update_sam: Unable to open TDB rid database!\n"));
713                 if (newtdb == FALSE)
714                         DEBUG(0, ("WARNING: rid database missing and passdb exist, check references integrity!\n"));
715                 if (flag == TDB_INSERT)
716                 {
717                         DEBUG(0, ("Unable to open TDB rid file, trying create new!\n"));
718                         if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
719                         {
720                                 DEBUG(0, ("Unable to create TDB rid (riddb.tdb) !!!\n"));
721                                 /* return False; */
722                         }
723                 }
724         }
725                 
726         /* add the reference */
727         if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS)
728         {
729                 DEBUG(0, ("Unable to modify TDB rid database!"));
730                 DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
731                 tdb_close (pwd_tdb);
732                 return False;
733         }
734         
735         /* cleanup */
736         tdb_close (pwd_tdb);
737         
738         return (True);
739 }
740
741 /***************************************************************************
742  Modifies an existing SAM_ACCOUNT
743 ****************************************************************************/
744 BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override)
745 {
746         return (tdb_update_sam(newpwd, override, TDB_MODIFY));
747 }
748
749 /***************************************************************************
750  Adds an existing SAM_ACCOUNT
751 ****************************************************************************/
752 BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd)
753 {
754         return (tdb_update_sam(newpwd, True, TDB_INSERT));
755 }
756
757
758 #else
759         /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
760         void samtdb_dummy_function(void) { } /* stop some compilers complaining */
761 #endif /* WITH_TDBPWD */