Large commit which restructures the local password storage API.
[ira/wip.git] / source / 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  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  * 
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc., 675
18  * Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "includes.h"
22
23 #ifdef WITH_TDBPWD
24
25 #define lp_tdb_passwd_file lp_smb_passwd_file
26 #define tdb_writelock(ptr)
27 #define tdb_writeunlock(ptr)
28
29 extern int DEBUGLEVEL;
30 extern pstring samlogon_user;
31 extern BOOL sam_logon_in_ssb;
32
33 #if 0   /* GWC */
34 struct tdb_sam_entry
35 {
36         time_t logon_time;            /* logon time */
37         time_t logoff_time;           /* logoff time */
38         time_t kickoff_time;          /* kickoff time */
39         time_t pass_last_set_time;    /* password last set time */
40         time_t pass_can_change_time;  /* password can change time */
41         time_t pass_must_change_time; /* password must change time */
42
43         uid_t smb_userid;       /* this is actually the unix uid_t */
44         gid_t smb_grpid;        /* this is actually the unix gid_t */
45         uint32 user_rid;      /* Primary User ID */
46         uint32 group_rid;     /* Primary Group ID */
47
48         char smb_passwd[33]; /* Null if no password */
49         char smb_nt_passwd[33]; /* Null if no password */
50
51         uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
52         uint32 unknown_3; /* 0x00ff ffff */
53
54         uint16 logon_divs; /* 168 - number of hours in a week */
55         uint32 hours_len; /* normally 21 bytes */
56         uint8 hours[MAX_HOURS_LEN];
57
58         uint32 unknown_5; /* 0x0002 0000 */
59         uint32 unknown_6; /* 0x0000 04ec */
60         
61         /* relative pointers to dynamically allocated strings[] */
62         int smb_name_offset;     /* username string */
63         int full_name_offset;    /* user's full name string */
64         int home_dir_offset;     /* home directory string */
65         int dir_drive_offset;    /* home directory drive string */
66         int logon_script_offset; /* logon script string */
67         int profile_path_offset; /* profile path string */
68         int acct_desc_offset;  /* user description string */
69         int workstations_offset; /* login from workstations string */
70         int unknown_str_offset; /* don't know what this is, yet. */
71         int munged_dial_offset; /* munged path name and dial-back tel number */
72
73         /* how to correctly declare this ?*/
74         char strings[1]; 
75 };
76
77 #endif
78
79 struct tdb_enum_info
80 {
81         TDB_CONTEXT *passwd_tdb;
82         TDB_DATA key;
83 };
84
85 static struct tdb_enum_info tdb_ent;
86
87 /***************************************************************
88  Start to enumerate the TDB passwd list. Returns a void pointer
89  to ensure no modification outside this module.
90 ****************************************************************/
91
92 static void *startsamtdbpwent(BOOL update)
93 {
94         /* Open tdb passwd */
95         if (!(tdb_ent.passwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, update ? O_RDWR : O_RDONLY, 0600)))
96         {
97                 DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
98                 if (!(tdb_ent.passwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
99                 {
100                         DEBUG(0, ("Unable to creat TDB passwd (smbpasswd.tdb) !!!"));
101                         return NULL;
102                 }
103                 return &tdb_ent;
104         }
105         
106         tdb_ent.key = tdb_firstkey(tdb_ent.passwd_tdb);
107         return &tdb_ent;
108 }
109
110 /***************************************************************
111  End enumeration of the TDB passwd list.
112 ****************************************************************/
113
114 static void endsamtdbpwent(void *vp)
115 {
116   struct tdb_enum_info *p_ent = (struct tdb_enum_info *)vp;
117
118   tdb_close(p_ent->passwd_tdb);
119   DEBUG(7, ("endtdbpwent: closed password file.\n"));
120 }
121
122 static struct sam_passwd *getsamtdb21pwent(void *vp)
123 {
124   static struct sam_passwd sam_entry;
125   static struct tdb_sam_entry *tdb_entry;
126   struct tdb_enum_info *p_ent = (struct tdb_enum_info *)vp;
127   TDB_DATA data;
128
129   if(p_ent == NULL) {
130     DEBUG(0,("gettdbpwent: Bad TDB Context pointer.\n"));
131     return NULL;
132   }
133
134   data = tdb_fetch (p_ent->passwd_tdb, p_ent->key);
135   if (!data.dptr)
136   {
137     DEBUG(5,("gettdbpwent: database entry not found.\n"));
138     return NULL;
139   }
140   
141   tdb_entry = (struct tdb_sam_entry *)(data.dptr);
142
143   sam_entry.logon_time = tdb_entry->logon_time;
144   sam_entry.logoff_time = tdb_entry->logoff_time;
145   sam_entry.kickoff_time = tdb_entry->kickoff_time;
146   sam_entry.pass_last_set_time = tdb_entry->pass_last_set_time;
147   sam_entry.pass_can_change_time = tdb_entry->pass_can_change_time;
148   sam_entry.pass_must_change_time = tdb_entry->pass_must_change_time;
149   sam_entry.smb_name = tdb_entry->strings + tdb_entry->smb_name_offset;
150   sam_entry.full_name = tdb_entry->strings + tdb_entry->full_name_offset;
151   sam_entry.home_dir = tdb_entry->strings + tdb_entry->home_dir_offset;
152   sam_entry.dir_drive = tdb_entry->strings + tdb_entry->dir_drive_offset;
153   sam_entry.logon_script = tdb_entry->strings + tdb_entry->logon_script_offset;
154   sam_entry.profile_path = tdb_entry->strings + tdb_entry->profile_path_offset;
155   sam_entry.acct_desc = tdb_entry->strings + tdb_entry->acct_desc_offset;
156   sam_entry.workstations = tdb_entry->strings + tdb_entry->workstations_offset;
157   sam_entry.unknown_str = tdb_entry->strings + tdb_entry->unknown_str_offset;
158   sam_entry.munged_dial = tdb_entry->strings + tdb_entry->munged_dial_offset;
159   sam_entry.smb_userid = tdb_entry->smb_userid;
160   sam_entry.smb_grpid = tdb_entry->smb_grpid;
161   sam_entry.user_rid = tdb_entry->user_rid;
162   sam_entry.group_rid = tdb_entry->group_rid;
163   sam_entry.smb_passwd = tdb_entry->smb_passwd;
164   sam_entry.smb_nt_passwd = tdb_entry->smb_nt_passwd;
165   sam_entry.acct_ctrl = tdb_entry->acct_ctrl;
166   sam_entry.unknown_3 = tdb_entry->unknown_3;
167   sam_entry.logon_divs = tdb_entry->logon_divs;
168   sam_entry.hours_len = tdb_entry->hours_len;
169   memcpy (sam_entry.hours, tdb_entry->hours, MAX_HOURS_LEN);
170   sam_entry.unknown_5 = tdb_entry->unknown_5;
171   sam_entry.unknown_6 = tdb_entry->unknown_6;
172
173   p_ent->key = tdb_nextkey (p_ent->passwd_tdb, p_ent->key);
174
175   return &sam_entry;
176 }
177
178 static BOOL del_samtdbpwd_entry(const char *name)
179 {
180   TDB_CONTEXT *pwd_tdb;
181   TDB_DATA key;
182   fstring keystr;
183
184   if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600)))
185   {
186      DEBUG(0, ("Unable to open TDB passwd!"));
187      return False;
188   }
189   
190   slprintf(keystr, sizeof(keystr), "USER_%s", name);
191   key.dptr = keystr;
192   key.dsize = strlen (keystr) + 1;
193   if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
194   {
195         DEBUG(5, ("Error deleting entry from tdb database!\n"));
196         DEBUGADD(5, (" Error: %s\n", tdb_error(pwd_tdb)));
197         tdb_close(pwd_tdb); 
198         return False;
199   }
200   tdb_close(pwd_tdb);
201   return True;
202 }
203
204 static BOOL mod_samtdb21pwd_entry(struct sam_passwd* newpwd, BOOL override)
205 {
206   TDB_CONTEXT *pwd_tdb;
207   TDB_DATA key;
208   TDB_DATA data;
209   struct tdb_sam_entry *tdb_entry;
210   fstring keystr;
211   
212   int smb_name_len = (newpwd->smb_name) ? (strlen (newpwd->smb_name) + 1) : 0;
213   int full_name_len = (newpwd->full_name) ? (strlen (newpwd->full_name) + 1) : 0;
214   int home_dir_len = (newpwd->home_dir) ? (strlen (newpwd->home_dir) + 1) : 0;
215   int dir_drive_len = (newpwd->dir_drive) ? (strlen (newpwd->dir_drive) + 1) : 0;
216   int logon_script_len = (newpwd->logon_script) ? (strlen (newpwd->logon_script) + 1) : 0;
217   int profile_path_len = (newpwd->profile_path) ? (strlen (newpwd->profile_path) + 1) : 0;
218   int acct_desc_len = (newpwd->acct_desc) ? (strlen (newpwd->acct_desc) + 1) : 0;
219   int workstations_len = (newpwd->workstations) ? (strlen (newpwd->workstations) + 1) : 0;
220   int unknown_str_len = (newpwd->unknown_str) ? (strlen (newpwd->unknown_str) + 1) : 0;
221   int munged_dial_len = (newpwd->munged_dial) ? (strlen (newpwd->munged_dial) + 1) : 0;
222   
223   if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600)))
224   {
225      DEBUG(0, ("Unable to open TDB passwd!"));
226      return False;
227   }
228
229   data.dsize = sizeof (struct tdb_sam_entry) +
230                                 smb_name_len +
231                                 full_name_len +
232                                 home_dir_len +
233                                 dir_drive_len +
234                                 logon_script_len +
235                                 profile_path_len +
236                                 acct_desc_len +
237                                 workstations_len +
238                                 unknown_str_len +
239                                 munged_dial_len;
240
241   tdb_entry = malloc (data.dsize);
242   data.dptr = tdb_entry;
243   memset (data.dptr, 0, data.dsize);
244
245   tdb_entry->logon_time = newpwd->logon_time;
246   tdb_entry->logoff_time = newpwd->logoff_time;
247   tdb_entry->kickoff_time = newpwd->kickoff_time;
248   tdb_entry->pass_last_set_time = newpwd->pass_last_set_time;
249   tdb_entry->pass_can_change_time = newpwd->pass_can_change_time;
250   tdb_entry->pass_must_change_time = newpwd->pass_must_change_time;
251   tdb_entry->smb_userid = newpwd->smb_userid;
252   tdb_entry->smb_grpid = newpwd->smb_grpid;
253   tdb_entry->user_rid = newpwd->user_rid;
254   tdb_entry->group_rid = newpwd->group_rid;
255   memcpy (tdb_entry->smb_passwd, newpwd->smb_passwd, strlen (newpwd->smb_passwd) + 1);
256   memcpy (tdb_entry->smb_nt_passwd, newpwd->smb_nt_passwd, strlen (newpwd->smb_nt_passwd) + 1);
257   tdb_entry->acct_ctrl = newpwd->acct_ctrl;
258   tdb_entry->unknown_3 = newpwd->unknown_3;
259   tdb_entry->logon_divs = newpwd->logon_divs;
260   tdb_entry->hours_len = newpwd->hours_len;
261   memcpy (tdb_entry->hours, newpwd->hours, MAX_HOURS_LEN);
262   tdb_entry->unknown_5 = newpwd->unknown_5;
263   tdb_entry->unknown_6 = newpwd->unknown_6;
264   tdb_entry->smb_name_offset = 0;
265   tdb_entry->full_name_offset = smb_name_len;
266   tdb_entry->home_dir_offset = tdb_entry->full_name_offset + full_name_len;
267   tdb_entry->dir_drive_offset = tdb_entry->home_dir_offset + home_dir_len;
268   tdb_entry->logon_script_offset = tdb_entry->dir_drive_offset + dir_drive_len;
269   tdb_entry->profile_path_offset = tdb_entry->logon_script_offset + logon_script_len;
270   tdb_entry->acct_desc_offset = tdb_entry->profile_path_offset + profile_path_len;
271   tdb_entry->workstations_offset = tdb_entry->acct_desc_offset + acct_desc_len;
272   tdb_entry->unknown_str_offset = tdb_entry->workstations_offset  + workstations_len;
273   tdb_entry->munged_dial_offset = tdb_entry->unknown_str_offset + unknown_str_len;
274   if (newpwd->smb_name)
275     memcpy (tdb_entry->strings + tdb_entry->smb_name_offset, newpwd->smb_name, smb_name_len);
276   if (newpwd->full_name)
277     memcpy (tdb_entry->strings + tdb_entry->full_name_offset, newpwd->full_name, full_name_len);
278   if (newpwd->home_dir)
279     memcpy (tdb_entry->strings + tdb_entry->home_dir_offset, newpwd->home_dir, home_dir_len);
280   if (newpwd->dir_drive)
281     memcpy (tdb_entry->strings + tdb_entry->dir_drive_offset, newpwd->dir_drive, dir_drive_len);
282   if (newpwd->logon_script)
283     memcpy (tdb_entry->strings + tdb_entry->logon_script_offset, newpwd->logon_script, logon_script_len);
284   if (newpwd->profile_path)
285     memcpy (tdb_entry->strings + tdb_entry->profile_path_offset, newpwd->profile_path, profile_path_len);
286   if (newpwd->acct_desc)
287     memcpy (tdb_entry->strings + tdb_entry->acct_desc_offset, newpwd->acct_desc, acct_desc_len);
288   if (newpwd->workstations)
289     memcpy (tdb_entry->strings + tdb_entry->workstations_offset, newpwd->workstations, workstations_len);
290   if (newpwd->unknown_str)
291     memcpy (tdb_entry->strings + tdb_entry->unknown_str_offset, newpwd->unknown_str, unknown_str_len);
292   if (newpwd->munged_dial)
293     memcpy (tdb_entry->strings + tdb_entry->munged_dial_offset, newpwd->munged_dial, munged_dial_len);
294  
295   slprintf(keystr, sizeof(keystr), "USER_%s", newpwd->smb_name);
296   key.dptr = keystr;
297   key.dsize = strlen (keystr) + 1;
298   
299   tdb_writelock (pwd_tdb);
300   if (tdb_store (pwd_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS)
301   {
302       DEBUG(0, ("Unable to modify TDB passwd!"));
303       DEBUGADD(0, (" Error: %s\n", tdb_error (pwd_tdb)));
304       tdb_writeunlock (pwd_tdb);
305       tdb_close (pwd_tdb);
306       return False;
307   }
308   
309   tdb_writeunlock (pwd_tdb);
310   tdb_close (pwd_tdb);
311   return True;
312 }
313
314 static BOOL add_samtdb21pwd_entry(struct sam_passwd *newpwd)
315 {
316   TDB_CONTEXT *pwd_tdb;
317   TDB_DATA key;
318   TDB_DATA data;
319   struct tdb_sam_entry *tdb_entry;
320   fstring keystr;
321   
322   int smb_name_len = (newpwd->smb_name) ? (strlen (newpwd->smb_name) + 1) : 1;
323   int full_name_len = (newpwd->full_name) ? (strlen (newpwd->full_name) + 1) : 1;
324   int home_dir_len = (newpwd->home_dir) ? (strlen (newpwd->home_dir) + 1) : 1;
325   int dir_drive_len = (newpwd->dir_drive) ? (strlen (newpwd->dir_drive) + 1) : 1;
326   int logon_script_len = (newpwd->logon_script) ? (strlen (newpwd->logon_script) + 1) : 1;
327   int profile_path_len = (newpwd->profile_path) ? (strlen (newpwd->profile_path) + 1) : 1;
328   int acct_desc_len = (newpwd->acct_desc) ? (strlen (newpwd->acct_desc) + 1) : 1;
329   int workstations_len = (newpwd->workstations) ? (strlen (newpwd->workstations) + 1) : 1;
330   int unknown_str_len = (newpwd->unknown_str) ? (strlen (newpwd->unknown_str) + 1) : 1;
331   int munged_dial_len = (newpwd->munged_dial) ? (strlen (newpwd->munged_dial) + 1) : 1;
332   
333   if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600)))
334   {
335      DEBUG(0, ("Unable to open TDB passwd!"));
336      return False;
337   }
338
339   data.dsize = sizeof (struct tdb_sam_entry) +
340                                 smb_name_len +
341                                 full_name_len +
342                                 home_dir_len +
343                                 dir_drive_len +
344                                 logon_script_len +
345                                 profile_path_len +
346                                 acct_desc_len +
347                                 workstations_len +
348                                 unknown_str_len +
349                                 munged_dial_len;
350
351   tdb_entry = malloc (data.dsize);
352   data.dptr = tdb_entry;
353   memset (data.dptr, 0, data.dsize);
354
355   tdb_entry->logon_time = newpwd->logon_time;
356   tdb_entry->logoff_time = newpwd->logoff_time;
357   tdb_entry->kickoff_time = newpwd->kickoff_time;
358   tdb_entry->pass_last_set_time = newpwd->pass_last_set_time;
359   tdb_entry->pass_can_change_time = newpwd->pass_can_change_time;
360   tdb_entry->pass_must_change_time = newpwd->pass_must_change_time;
361   tdb_entry->smb_userid = newpwd->smb_userid;
362   tdb_entry->smb_grpid = newpwd->smb_grpid;
363   tdb_entry->user_rid = newpwd->user_rid;
364   tdb_entry->group_rid = newpwd->group_rid;
365   memcpy (tdb_entry->smb_passwd, newpwd->smb_passwd, strlen (newpwd->smb_passwd) + 1);
366   memcpy (tdb_entry->smb_nt_passwd, newpwd->smb_nt_passwd, strlen (newpwd->smb_nt_passwd) + 1);
367   tdb_entry->acct_ctrl = newpwd->acct_ctrl;
368   tdb_entry->unknown_3 = newpwd->unknown_3;
369   tdb_entry->logon_divs = newpwd->logon_divs;
370   tdb_entry->hours_len = newpwd->hours_len;
371   memcpy (tdb_entry->hours, newpwd->hours, MAX_HOURS_LEN);
372   tdb_entry->unknown_5 = newpwd->unknown_5;
373   tdb_entry->unknown_6 = newpwd->unknown_6;
374   tdb_entry->smb_name_offset = 0;
375   tdb_entry->full_name_offset = smb_name_len;
376   tdb_entry->home_dir_offset = tdb_entry->full_name_offset + full_name_len;
377   tdb_entry->dir_drive_offset = tdb_entry->home_dir_offset + home_dir_len;
378   tdb_entry->logon_script_offset = tdb_entry->dir_drive_offset + dir_drive_len;
379   tdb_entry->profile_path_offset = tdb_entry->logon_script_offset + logon_script_len;
380   tdb_entry->acct_desc_offset = tdb_entry->profile_path_offset + profile_path_len;
381   tdb_entry->workstations_offset = tdb_entry->acct_desc_offset + acct_desc_len;
382   tdb_entry->unknown_str_offset = tdb_entry->workstations_offset  + workstations_len;
383   tdb_entry->munged_dial_offset = tdb_entry->unknown_str_offset + unknown_str_len;
384   if (newpwd->smb_name)
385     memcpy (tdb_entry->strings + tdb_entry->smb_name_offset, newpwd->smb_name, smb_name_len);
386   if (newpwd->full_name)
387     memcpy (tdb_entry->strings + tdb_entry->full_name_offset, newpwd->full_name, full_name_len);
388   if (newpwd->home_dir)
389     memcpy (tdb_entry->strings + tdb_entry->home_dir_offset, newpwd->home_dir, home_dir_len);
390   if (newpwd->dir_drive)
391     memcpy (tdb_entry->strings + tdb_entry->dir_drive_offset, newpwd->dir_drive, dir_drive_len);
392   if (newpwd->logon_script)
393     memcpy (tdb_entry->strings + tdb_entry->logon_script_offset, newpwd->logon_script, logon_script_len);
394   if (newpwd->profile_path)
395     memcpy (tdb_entry->strings + tdb_entry->profile_path_offset, newpwd->profile_path, profile_path_len);
396   if (newpwd->acct_desc)
397     memcpy (tdb_entry->strings + tdb_entry->acct_desc_offset, newpwd->acct_desc, acct_desc_len);
398   if (newpwd->workstations)
399     memcpy (tdb_entry->strings + tdb_entry->workstations_offset, newpwd->workstations, workstations_len);
400   if (newpwd->unknown_str)
401     memcpy (tdb_entry->strings + tdb_entry->unknown_str_offset, newpwd->unknown_str, unknown_str_len);
402   if (newpwd->munged_dial)
403     memcpy (tdb_entry->strings + tdb_entry->munged_dial_offset, newpwd->munged_dial, munged_dial_len);
404   
405   slprintf(keystr, sizeof(keystr), "USER_%s", newpwd->smb_name);
406   key.dptr = keystr;
407   key.dsize = strlen (keystr) + 1;
408   
409   tdb_writelock (pwd_tdb);
410   if (tdb_store (pwd_tdb, key, data, TDB_INSERT) != TDB_SUCCESS)
411   {
412       DEBUG(0, ("Unable to modify TDB passwd!"));
413       DEBUGADD(0, (" Error: %s\n", tdb_error (pwd_tdb)));
414       tdb_writeunlock (pwd_tdb);
415       tdb_close (pwd_tdb);
416       return False;
417   }
418
419   tdb_writeunlock (pwd_tdb);
420   tdb_close (pwd_tdb);
421   return True;
422 }
423
424 static struct sam_passwd *iterate_getsamtdb21pwrid(uint32 user_rid)
425 {
426         struct sam_passwd *pwd = NULL;
427         void *fp = NULL;
428
429         DEBUG(10, ("search by smb_userid: %x\n", (int)user_rid));
430
431         /* Open the smb password database - not for update. */
432         fp = startsamtdbpwent(False);
433
434         if (fp == NULL)
435         {
436                 DEBUG(0, ("unable to open smb password database.\n"));
437                 return NULL;
438         }
439
440         while ((pwd = getsamtdb21pwent(fp)) != NULL && pwd->user_rid != user_rid);
441
442         if (pwd != NULL)
443         {
444                 DEBUG(10, ("found by user_rid: %x\n", (int)user_rid));
445         }
446
447         endsamtdbpwent(fp);
448         return pwd;
449 }
450
451 static struct sam_passwd *getsamtdb21pwnam(char *name)
452 {
453   static struct sam_passwd sam_entry;
454   static struct tdb_sam_entry *tdb_entry;
455   TDB_CONTEXT *pwd_tdb;
456   TDB_DATA data;
457   TDB_DATA key;
458   fstring keystr;
459
460   if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDONLY, 0600)))
461   {
462      DEBUG(0, ("Unable to open TDB passwd!"));
463      return False;
464   }
465
466   slprintf(keystr, sizeof(keystr), "USER_%s", name);
467   key.dptr = keystr;
468   key.dsize = strlen (keystr) + 1;
469
470   data = tdb_fetch (pwd_tdb, key);
471   if (!data.dptr)
472   {
473     DEBUG(5,("getsamtdbpwent: error fetching database.\n"));
474     DEBUGADD(5, (" Error: %s\n", tdb_error(pwd_tdb)));
475     tdb_close (pwd_tdb);
476     return NULL;
477   }
478   
479   tdb_entry = (struct tdb_sam_entry *)(data.dptr);
480
481   sam_entry.logon_time = tdb_entry->logon_time;
482   sam_entry.logoff_time = tdb_entry->logoff_time;
483   sam_entry.kickoff_time = tdb_entry->kickoff_time;
484   sam_entry.pass_last_set_time = tdb_entry->pass_last_set_time;
485   sam_entry.pass_can_change_time = tdb_entry->pass_can_change_time;
486   sam_entry.pass_must_change_time = tdb_entry->pass_must_change_time;
487   sam_entry.smb_name = tdb_entry->strings + tdb_entry->smb_name_offset;
488   sam_entry.full_name = tdb_entry->strings + tdb_entry->full_name_offset;
489   sam_entry.home_dir = tdb_entry->strings + tdb_entry->home_dir_offset;
490   sam_entry.dir_drive = tdb_entry->strings + tdb_entry->dir_drive_offset;
491   sam_entry.logon_script = tdb_entry->strings + tdb_entry->logon_script_offset;
492   sam_entry.profile_path = tdb_entry->strings + tdb_entry->profile_path_offset;
493   sam_entry.acct_desc = tdb_entry->strings + tdb_entry->acct_desc_offset;
494   sam_entry.workstations = tdb_entry->strings + tdb_entry->workstations_offset;
495   sam_entry.unknown_str = tdb_entry->strings + tdb_entry->unknown_str_offset;
496   sam_entry.munged_dial = tdb_entry->strings + tdb_entry->munged_dial_offset;
497   sam_entry.smb_userid = tdb_entry->smb_userid;
498   sam_entry.smb_grpid = tdb_entry->smb_grpid;
499   sam_entry.user_rid = tdb_entry->user_rid;
500   sam_entry.group_rid = tdb_entry->group_rid;
501   sam_entry.smb_passwd = tdb_entry->smb_passwd;
502   sam_entry.smb_nt_passwd = tdb_entry->smb_nt_passwd;
503   sam_entry.acct_ctrl = tdb_entry->acct_ctrl;
504   sam_entry.unknown_3 = tdb_entry->unknown_3;
505   sam_entry.logon_divs = tdb_entry->logon_divs;
506   sam_entry.hours_len = tdb_entry->hours_len;
507   memcpy (sam_entry.hours, tdb_entry->hours, MAX_HOURS_LEN);
508   sam_entry.unknown_5 = tdb_entry->unknown_5;
509   sam_entry.unknown_6 = tdb_entry->unknown_6;
510
511   tdb_close (pwd_tdb);
512   return &sam_entry;
513 }
514
515 static SMB_BIG_UINT getsamtdbpwpos(void *vp)
516 {
517         return (SMB_BIG_UINT)0;
518 }
519
520 static BOOL setsamtdbpwpos(void *vp, SMB_BIG_UINT tok)
521 {
522         return False;
523 }
524
525 static struct smb_passwd *getsamtdbpwent(void *vp)
526 {
527         return pdb_sam_to_smb(getsamtdb21pwent(vp));
528 }
529
530 static BOOL add_samtdbpwd_entry(struct smb_passwd *newpwd)
531 {
532         return add_samtdb21pwd_entry(pdb_smb_to_sam(newpwd));
533 }
534
535 static BOOL mod_samtdbpwd_entry(struct smb_passwd* pwd, BOOL override)
536 {
537         return mod_samtdb21pwd_entry(pdb_smb_to_sam(pwd), override);
538 }
539
540 static struct sam_disp_info *getsamtdbdispnam(char *name)
541 {
542         return pdb_sam_to_dispinfo(getsam21pwnam(name));
543 }
544
545 static struct sam_disp_info *getsamtdbdisprid(uint32 rid)
546 {
547         return pdb_sam_to_dispinfo(getsam21pwrid(rid));
548 }
549
550 static struct sam_disp_info *getsamtdbdispent(void *vp)
551 {
552         return pdb_sam_to_dispinfo(getsam21pwent(vp));
553 }
554
555 static struct smb_passwd *iterate_getsamtdbpwrid(uint32 user_rid)
556 {
557         return pdb_sam_to_smb(iterate_getsamtdb21pwrid(user_rid));
558 }
559
560 static struct smb_passwd *getsamtdbpwnam(char *name)
561 {
562         return pdb_sam_to_smb(getsamtdb21pwnam(name));
563 }
564
565 static struct passdb_ops tdb_ops = {
566         startsamtdbpwent,
567         endsamtdbpwent,
568         getsamtdbpwpos,
569         setsamtdbpwpos,
570         getsamtdbpwnam,
571         iterate_getsmbpwuid,          /* In passdb.c */
572         iterate_getsamtdbpwrid,
573         getsamtdbpwent,
574         add_samtdbpwd_entry,
575         mod_samtdbpwd_entry,
576         del_samtdbpwd_entry,
577         getsamtdb21pwent,
578         getsamtdb21pwnam,
579
580         /* TODO change get username from uid and then use
581            getsamtdb21pwnam */
582         iterate_getsam21pwuid,
583
584         iterate_getsamtdb21pwrid, 
585         add_samtdb21pwd_entry,
586         mod_samtdb21pwd_entry,
587         getsamtdbdispnam,
588         getsamtdbdisprid,
589         getsamtdbdispent
590 };
591
592 struct passdb_ops *tdb_initialize_password_db(void)
593 {    
594   return &tdb_ops;
595 }
596
597 #else
598         /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
599         void samtdb_dummy_function(void) { } /* stop some compilers complaining */
600 #endif /* WITH_TDBPWD */