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