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