source: branches/samba-3.0/source/passdb/pdb_tdb.c

Last change on this file was 354, checked in by Herwig Bauernfeind, 16 years ago

Remove superfluos DEBUG() in pdb_tdb.c

File size: 46.5 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * SMB parameters and setup
4 * Copyright (C) Andrew Tridgell 1992-1998
5 * Copyright (C) Simo Sorce 2000-2003
6 * Copyright (C) Gerald Carter 2000-2006
7 * Copyright (C) Jeremy Allison 2001
8 * Copyright (C) Andrew Bartlett 2002
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
10 *
11 * This program is free software; you can redistribute it and/or modify it under
12 * the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 675
23 * Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include "includes.h"
27
28#if 0 /* when made a module use this */
29
30static int tdbsam_debug_level = DBGC_ALL;
31#undef DBGC_CLASS
32#define DBGC_CLASS tdbsam_debug_level
33
34#else
35
36#undef DBGC_CLASS
37#define DBGC_CLASS DBGC_PASSDB
38
39#endif
40
41#define TDBSAM_VERSION 3 /* Most recent TDBSAM version */
42#define TDBSAM_VERSION_STRING "INFO/version"
43#define PASSDB_FILE_NAME "passdb.tdb"
44#define USERPREFIX "USER_"
45#define RIDPREFIX "RID_"
46#define PRIVPREFIX "PRIV_"
47
48struct pwent_list {
49 struct pwent_list *prev, *next;
50 TDB_DATA key;
51};
52static struct pwent_list *tdbsam_pwent_list;
53static BOOL pwent_initialized;
54
55/* GLOBAL TDB SAM CONTEXT */
56
57static TDB_CONTEXT *tdbsam;
58static int ref_count = 0;
59static pstring tdbsam_filename;
60
61/**********************************************************************
62 Marshall/unmarshall struct samu structs.
63 *********************************************************************/
64
65#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
66#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
67#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
68
69/*********************************************************************
70*********************************************************************/
71
72static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buflen)
73{
74
75 /* times are stored as 32bit integer
76 take care on system with 64bit wide time_t
77 --SSS */
78 uint32 logon_time,
79 logoff_time,
80 kickoff_time,
81 pass_last_set_time,
82 pass_can_change_time,
83 pass_must_change_time;
84 char *username = NULL;
85 char *domain = NULL;
86 char *nt_username = NULL;
87 char *dir_drive = NULL;
88 char *unknown_str = NULL;
89 char *munged_dial = NULL;
90 char *fullname = NULL;
91 char *homedir = NULL;
92 char *logon_script = NULL;
93 char *profile_path = NULL;
94 char *acct_desc = NULL;
95 char *workstations = NULL;
96 uint32 username_len, domain_len, nt_username_len,
97 dir_drive_len, unknown_str_len, munged_dial_len,
98 fullname_len, homedir_len, logon_script_len,
99 profile_path_len, acct_desc_len, workstations_len;
100
101 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
102 uint16 acct_ctrl, logon_divs;
103 uint16 bad_password_count, logon_count;
104 uint8 *hours = NULL;
105 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
106 uint32 len = 0;
107 uint32 lm_pw_len, nt_pw_len, hourslen;
108 BOOL ret = True;
109
110 if(sampass == NULL || buf == NULL) {
111 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
112 return False;
113 }
114
115/* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
116
117 /* unpack the buffer into variables */
118 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
119 &logon_time, /* d */
120 &logoff_time, /* d */
121 &kickoff_time, /* d */
122 &pass_last_set_time, /* d */
123 &pass_can_change_time, /* d */
124 &pass_must_change_time, /* d */
125 &username_len, &username, /* B */
126 &domain_len, &domain, /* B */
127 &nt_username_len, &nt_username, /* B */
128 &fullname_len, &fullname, /* B */
129 &homedir_len, &homedir, /* B */
130 &dir_drive_len, &dir_drive, /* B */
131 &logon_script_len, &logon_script, /* B */
132 &profile_path_len, &profile_path, /* B */
133 &acct_desc_len, &acct_desc, /* B */
134 &workstations_len, &workstations, /* B */
135 &unknown_str_len, &unknown_str, /* B */
136 &munged_dial_len, &munged_dial, /* B */
137 &user_rid, /* d */
138 &group_rid, /* d */
139 &lm_pw_len, &lm_pw_ptr, /* B */
140 &nt_pw_len, &nt_pw_ptr, /* B */
141 &acct_ctrl, /* w */
142 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
143 &logon_divs, /* w */
144 &hours_len, /* d */
145 &hourslen, &hours, /* B */
146 &bad_password_count, /* w */
147 &logon_count, /* w */
148 &unknown_6); /* d */
149
150 if (len == (uint32) -1) {
151 ret = False;
152 goto done;
153 }
154
155 pdb_set_logon_time(sampass, logon_time, PDB_SET);
156 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
157 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
158 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
159 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
160 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
161
162 pdb_set_username(sampass, username, PDB_SET);
163 pdb_set_domain(sampass, domain, PDB_SET);
164 pdb_set_nt_username(sampass, nt_username, PDB_SET);
165 pdb_set_fullname(sampass, fullname, PDB_SET);
166
167 if (homedir) {
168 pdb_set_homedir(sampass, homedir, PDB_SET);
169 }
170 else {
171 pdb_set_homedir(sampass,
172 talloc_sub_basic(sampass, username, domain,
173 lp_logon_home()),
174 PDB_DEFAULT);
175 }
176
177 if (dir_drive)
178 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
179 else {
180 pdb_set_dir_drive(sampass,
181 talloc_sub_basic(sampass, username, domain,
182 lp_logon_drive()),
183 PDB_DEFAULT);
184 }
185
186 if (logon_script)
187 pdb_set_logon_script(sampass, logon_script, PDB_SET);
188 else {
189 pdb_set_logon_script(sampass,
190 talloc_sub_basic(sampass, username, domain,
191 lp_logon_script()),
192 PDB_DEFAULT);
193 }
194
195 if (profile_path) {
196 pdb_set_profile_path(sampass, profile_path, PDB_SET);
197 } else {
198 pdb_set_profile_path(sampass,
199 talloc_sub_basic(sampass, username, domain,
200 lp_logon_path()),
201 PDB_DEFAULT);
202 }
203
204 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
205 pdb_set_workstations(sampass, workstations, PDB_SET);
206 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
207
208 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
209 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
210 ret = False;
211 goto done;
212 }
213 }
214
215 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
216 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
217 ret = False;
218 goto done;
219 }
220 }
221
222 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
223 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
224 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
225 pdb_set_hours_len(sampass, hours_len, PDB_SET);
226 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
227 pdb_set_logon_count(sampass, logon_count, PDB_SET);
228 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
229 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
230 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
231 pdb_set_hours(sampass, hours, PDB_SET);
232
233done:
234
235 SAFE_FREE(username);
236 SAFE_FREE(domain);
237 SAFE_FREE(nt_username);
238 SAFE_FREE(fullname);
239 SAFE_FREE(homedir);
240 SAFE_FREE(dir_drive);
241 SAFE_FREE(logon_script);
242 SAFE_FREE(profile_path);
243 SAFE_FREE(acct_desc);
244 SAFE_FREE(workstations);
245 SAFE_FREE(munged_dial);
246 SAFE_FREE(unknown_str);
247 SAFE_FREE(lm_pw_ptr);
248 SAFE_FREE(nt_pw_ptr);
249 SAFE_FREE(hours);
250
251 return ret;
252}
253
254/*********************************************************************
255*********************************************************************/
256
257static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buflen)
258{
259
260 /* times are stored as 32bit integer
261 take care on system with 64bit wide time_t
262 --SSS */
263 uint32 logon_time,
264 logoff_time,
265 kickoff_time,
266 bad_password_time,
267 pass_last_set_time,
268 pass_can_change_time,
269 pass_must_change_time;
270 char *username = NULL;
271 char *domain = NULL;
272 char *nt_username = NULL;
273 char *dir_drive = NULL;
274 char *unknown_str = NULL;
275 char *munged_dial = NULL;
276 char *fullname = NULL;
277 char *homedir = NULL;
278 char *logon_script = NULL;
279 char *profile_path = NULL;
280 char *acct_desc = NULL;
281 char *workstations = NULL;
282 uint32 username_len, domain_len, nt_username_len,
283 dir_drive_len, unknown_str_len, munged_dial_len,
284 fullname_len, homedir_len, logon_script_len,
285 profile_path_len, acct_desc_len, workstations_len;
286
287 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
288 uint16 acct_ctrl, logon_divs;
289 uint16 bad_password_count, logon_count;
290 uint8 *hours = NULL;
291 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
292 uint32 len = 0;
293 uint32 lm_pw_len, nt_pw_len, hourslen;
294 BOOL ret = True;
295
296 if(sampass == NULL || buf == NULL) {
297 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
298 return False;
299 }
300
301/* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
302
303 /* unpack the buffer into variables */
304 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
305 &logon_time, /* d */
306 &logoff_time, /* d */
307 &kickoff_time, /* d */
308 /* Change from V0 is addition of bad_password_time field. */
309 &bad_password_time, /* d */
310 &pass_last_set_time, /* d */
311 &pass_can_change_time, /* d */
312 &pass_must_change_time, /* d */
313 &username_len, &username, /* B */
314 &domain_len, &domain, /* B */
315 &nt_username_len, &nt_username, /* B */
316 &fullname_len, &fullname, /* B */
317 &homedir_len, &homedir, /* B */
318 &dir_drive_len, &dir_drive, /* B */
319 &logon_script_len, &logon_script, /* B */
320 &profile_path_len, &profile_path, /* B */
321 &acct_desc_len, &acct_desc, /* B */
322 &workstations_len, &workstations, /* B */
323 &unknown_str_len, &unknown_str, /* B */
324 &munged_dial_len, &munged_dial, /* B */
325 &user_rid, /* d */
326 &group_rid, /* d */
327 &lm_pw_len, &lm_pw_ptr, /* B */
328 &nt_pw_len, &nt_pw_ptr, /* B */
329 &acct_ctrl, /* w */
330 &remove_me, /* d */
331 &logon_divs, /* w */
332 &hours_len, /* d */
333 &hourslen, &hours, /* B */
334 &bad_password_count, /* w */
335 &logon_count, /* w */
336 &unknown_6); /* d */
337
338 if (len == (uint32) -1) {
339 ret = False;
340 goto done;
341 }
342
343 pdb_set_logon_time(sampass, logon_time, PDB_SET);
344 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
345 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
346
347 /* Change from V0 is addition of bad_password_time field. */
348 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
349 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
350 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
351 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
352
353 pdb_set_username(sampass, username, PDB_SET);
354 pdb_set_domain(sampass, domain, PDB_SET);
355 pdb_set_nt_username(sampass, nt_username, PDB_SET);
356 pdb_set_fullname(sampass, fullname, PDB_SET);
357
358 if (homedir) {
359 pdb_set_homedir(sampass, homedir, PDB_SET);
360 }
361 else {
362 pdb_set_homedir(sampass,
363 talloc_sub_basic(sampass, username, domain,
364 lp_logon_home()),
365 PDB_DEFAULT);
366 }
367
368 if (dir_drive)
369 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
370 else {
371 pdb_set_dir_drive(sampass,
372 talloc_sub_basic(sampass, username, domain,
373 lp_logon_drive()),
374 PDB_DEFAULT);
375 }
376
377 if (logon_script)
378 pdb_set_logon_script(sampass, logon_script, PDB_SET);
379 else {
380 pdb_set_logon_script(sampass,
381 talloc_sub_basic(sampass, username, domain,
382 lp_logon_script()),
383 PDB_DEFAULT);
384 }
385
386 if (profile_path) {
387 pdb_set_profile_path(sampass, profile_path, PDB_SET);
388 } else {
389 pdb_set_profile_path(sampass,
390 talloc_sub_basic(sampass, username, domain,
391 lp_logon_path()),
392 PDB_DEFAULT);
393 }
394
395 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
396 pdb_set_workstations(sampass, workstations, PDB_SET);
397 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
398
399 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
400 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
401 ret = False;
402 goto done;
403 }
404 }
405
406 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
407 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
408 ret = False;
409 goto done;
410 }
411 }
412
413 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
414
415 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
416 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
417 pdb_set_hours_len(sampass, hours_len, PDB_SET);
418 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
419 pdb_set_logon_count(sampass, logon_count, PDB_SET);
420 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
421 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
422 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
423 pdb_set_hours(sampass, hours, PDB_SET);
424
425done:
426
427 SAFE_FREE(username);
428 SAFE_FREE(domain);
429 SAFE_FREE(nt_username);
430 SAFE_FREE(fullname);
431 SAFE_FREE(homedir);
432 SAFE_FREE(dir_drive);
433 SAFE_FREE(logon_script);
434 SAFE_FREE(profile_path);
435 SAFE_FREE(acct_desc);
436 SAFE_FREE(workstations);
437 SAFE_FREE(munged_dial);
438 SAFE_FREE(unknown_str);
439 SAFE_FREE(lm_pw_ptr);
440 SAFE_FREE(nt_pw_ptr);
441 SAFE_FREE(hours);
442
443 return ret;
444}
445
446BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
447{
448
449 /* times are stored as 32bit integer
450 take care on system with 64bit wide time_t
451 --SSS */
452 uint32 logon_time,
453 logoff_time,
454 kickoff_time,
455 bad_password_time,
456 pass_last_set_time,
457 pass_can_change_time,
458 pass_must_change_time;
459 char *username = NULL;
460 char *domain = NULL;
461 char *nt_username = NULL;
462 char *dir_drive = NULL;
463 char *unknown_str = NULL;
464 char *munged_dial = NULL;
465 char *fullname = NULL;
466 char *homedir = NULL;
467 char *logon_script = NULL;
468 char *profile_path = NULL;
469 char *acct_desc = NULL;
470 char *workstations = NULL;
471 uint32 username_len, domain_len, nt_username_len,
472 dir_drive_len, unknown_str_len, munged_dial_len,
473 fullname_len, homedir_len, logon_script_len,
474 profile_path_len, acct_desc_len, workstations_len;
475
476 uint32 user_rid, group_rid, hours_len, unknown_6;
477 uint16 acct_ctrl, logon_divs;
478 uint16 bad_password_count, logon_count;
479 uint8 *hours = NULL;
480 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
481 uint32 len = 0;
482 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
483 uint32 pwHistLen = 0;
484 BOOL ret = True;
485 fstring tmpstring;
486 BOOL expand_explicit = lp_passdb_expand_explicit();
487
488 if(sampass == NULL || buf == NULL) {
489 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
490 return False;
491 }
492
493/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
494
495 /* unpack the buffer into variables */
496 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
497 &logon_time, /* d */
498 &logoff_time, /* d */
499 &kickoff_time, /* d */
500 &bad_password_time, /* d */
501 &pass_last_set_time, /* d */
502 &pass_can_change_time, /* d */
503 &pass_must_change_time, /* d */
504 &username_len, &username, /* B */
505 &domain_len, &domain, /* B */
506 &nt_username_len, &nt_username, /* B */
507 &fullname_len, &fullname, /* B */
508 &homedir_len, &homedir, /* B */
509 &dir_drive_len, &dir_drive, /* B */
510 &logon_script_len, &logon_script, /* B */
511 &profile_path_len, &profile_path, /* B */
512 &acct_desc_len, &acct_desc, /* B */
513 &workstations_len, &workstations, /* B */
514 &unknown_str_len, &unknown_str, /* B */
515 &munged_dial_len, &munged_dial, /* B */
516 &user_rid, /* d */
517 &group_rid, /* d */
518 &lm_pw_len, &lm_pw_ptr, /* B */
519 &nt_pw_len, &nt_pw_ptr, /* B */
520 /* Change from V1 is addition of password history field. */
521 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
522 &acct_ctrl, /* w */
523 /* Also "remove_me" field was removed. */
524 &logon_divs, /* w */
525 &hours_len, /* d */
526 &hourslen, &hours, /* B */
527 &bad_password_count, /* w */
528 &logon_count, /* w */
529 &unknown_6); /* d */
530
531 if (len == (uint32) -1) {
532 ret = False;
533 goto done;
534 }
535
536 pdb_set_logon_time(sampass, logon_time, PDB_SET);
537 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
538 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
539 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
540 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
541 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
542 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
543
544 pdb_set_username(sampass, username, PDB_SET);
545 pdb_set_domain(sampass, domain, PDB_SET);
546 pdb_set_nt_username(sampass, nt_username, PDB_SET);
547 pdb_set_fullname(sampass, fullname, PDB_SET);
548
549 if (homedir) {
550 fstrcpy( tmpstring, homedir );
551 if (expand_explicit) {
552 standard_sub_basic( username, domain, tmpstring,
553 sizeof(tmpstring) );
554 }
555 pdb_set_homedir(sampass, tmpstring, PDB_SET);
556 }
557 else {
558 pdb_set_homedir(sampass,
559 talloc_sub_basic(sampass, username, domain,
560 lp_logon_home()),
561 PDB_DEFAULT);
562 }
563
564 if (dir_drive)
565 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
566 else
567 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
568
569 if (logon_script) {
570 fstrcpy( tmpstring, logon_script );
571 if (expand_explicit) {
572 standard_sub_basic( username, domain, tmpstring,
573 sizeof(tmpstring) );
574 }
575 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
576 }
577 else {
578 pdb_set_logon_script(sampass,
579 talloc_sub_basic(sampass, username, domain,
580 lp_logon_script()),
581 PDB_DEFAULT);
582 }
583
584 if (profile_path) {
585 fstrcpy( tmpstring, profile_path );
586 if (expand_explicit) {
587 standard_sub_basic( username, domain, tmpstring,
588 sizeof(tmpstring) );
589 }
590 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
591 }
592 else {
593 pdb_set_profile_path(sampass,
594 talloc_sub_basic(sampass, username, domain,
595 lp_logon_path()),
596 PDB_DEFAULT);
597 }
598
599 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
600 pdb_set_workstations(sampass, workstations, PDB_SET);
601 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
602
603 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
604 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
605 ret = False;
606 goto done;
607 }
608 }
609
610 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
611 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
612 ret = False;
613 goto done;
614 }
615 }
616
617 /* Change from V1 is addition of password history field. */
618 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
619 if (pwHistLen) {
620 uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN);
621 if (!pw_hist) {
622 ret = False;
623 goto done;
624 }
625 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
626 if (nt_pw_hist_ptr && nt_pw_hist_len) {
627 int i;
628 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
629 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
630 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
631 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
632 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
633 PW_HISTORY_ENTRY_LEN);
634 }
635 }
636 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
637 SAFE_FREE(pw_hist);
638 ret = False;
639 goto done;
640 }
641 SAFE_FREE(pw_hist);
642 } else {
643 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
644 }
645
646 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
647 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
648 pdb_set_hours_len(sampass, hours_len, PDB_SET);
649 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
650 pdb_set_logon_count(sampass, logon_count, PDB_SET);
651 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
652 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
653 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
654 pdb_set_hours(sampass, hours, PDB_SET);
655
656done:
657
658 SAFE_FREE(username);
659 SAFE_FREE(domain);
660 SAFE_FREE(nt_username);
661 SAFE_FREE(fullname);
662 SAFE_FREE(homedir);
663 SAFE_FREE(dir_drive);
664 SAFE_FREE(logon_script);
665 SAFE_FREE(profile_path);
666 SAFE_FREE(acct_desc);
667 SAFE_FREE(workstations);
668 SAFE_FREE(munged_dial);
669 SAFE_FREE(unknown_str);
670 SAFE_FREE(lm_pw_ptr);
671 SAFE_FREE(nt_pw_ptr);
672 SAFE_FREE(nt_pw_hist_ptr);
673 SAFE_FREE(hours);
674
675 return ret;
676}
677
678
679/**********************************************************************
680 Intialize a struct samu struct from a BYTE buffer of size len
681 *********************************************************************/
682
683static BOOL init_sam_from_buffer(struct samu *sampass, uint8 *buf, uint32 buflen)
684{
685 return init_sam_from_buffer_v3(sampass, buf, buflen);
686}
687
688/**********************************************************************
689 Intialize a BYTE buffer from a struct samu struct
690 *********************************************************************/
691
692static uint32 init_buffer_from_sam (uint8 **buf, struct samu *sampass, BOOL size_only)
693{
694 return init_buffer_from_sam_v3(buf, sampass, size_only);
695}
696
697/**********************************************************************
698 Intialize a BYTE buffer from a struct samu struct
699 *********************************************************************/
700
701static BOOL tdbsam_convert(int32 from)
702{
703 const char *vstring = TDBSAM_VERSION_STRING;
704 const char *prefix = USERPREFIX;
705 TDB_DATA data, key, old_key;
706 uint8 *buf = NULL;
707 BOOL ret;
708
709 /* handle a Samba upgrade */
710 tdb_lock_bystring(tdbsam, vstring);
711
712 /* Enumerate all records and convert them */
713 key = tdb_firstkey(tdbsam);
714
715 while (key.dptr) {
716
717 /* skip all non-USER entries (eg. RIDs) */
718 while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) {
719 old_key = key;
720 /* increment to next in line */
721 key = tdb_nextkey(tdbsam, key);
722 SAFE_FREE(old_key.dptr);
723 }
724
725 if (key.dptr) {
726 struct samu *user = NULL;
727
728 /* read from tdbsam */
729 data = tdb_fetch(tdbsam, key);
730 if (!data.dptr) {
731 DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr));
732 return False;
733 }
734
735 /* unpack the buffer from the former format */
736 if ( !(user = samu_new( NULL )) ) {
737 DEBUG(0,("tdbsam_convert: samu_new() failed!\n"));
738 SAFE_FREE( data.dptr );
739 return False;
740 }
741 DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from));
742 switch (from) {
743 case 0:
744 ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize);
745 break;
746 case 1:
747 ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize);
748 break;
749 case 2:
750 ret = init_sam_from_buffer_v2(user, (uint8 *)data.dptr, data.dsize);
751 break;
752 case 3:
753 ret = init_sam_from_buffer_v3(user, (uint8 *)data.dptr, data.dsize);
754 break;
755 default:
756 /* unknown tdbsam version */
757 ret = False;
758 }
759 if (!ret) {
760 DEBUG(0,("tdbsam_convert: Bad struct samu entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
761 SAFE_FREE(data.dptr);
762 TALLOC_FREE(user );
763 return False;
764 }
765
766 /* We're finished with the old data. */
767 SAFE_FREE(data.dptr);
768
769 /* pack from the buffer into the new format */
770
771 DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
772 data.dsize = init_buffer_from_sam (&buf, user, False);
773 TALLOC_FREE(user );
774
775 if ( data.dsize == -1 ) {
776 DEBUG(0,("tdbsam_convert: cannot pack the struct samu into the new format\n"));
777 return False;
778 }
779 data.dptr = (char *)buf;
780
781 /* Store the buffer inside the TDBSAM */
782 if (tdb_store(tdbsam, key, data, TDB_MODIFY) != TDB_SUCCESS) {
783 DEBUG(0,("tdbsam_convert: cannot store the struct samu (key:%s) in new format\n",key.dptr));
784 SAFE_FREE(data.dptr);
785 return False;
786 }
787
788 SAFE_FREE(data.dptr);
789
790 /* increment to next in line */
791 old_key = key;
792 key = tdb_nextkey(tdbsam, key);
793 SAFE_FREE(old_key.dptr);
794 }
795
796 }
797
798
799 /* upgrade finished */
800 tdb_store_int32(tdbsam, vstring, TDBSAM_VERSION);
801 tdb_unlock_bystring(tdbsam, vstring);
802
803 return(True);
804}
805
806/*********************************************************************
807 Open the tdbsam file based on the absolute path specified.
808 Uses a reference count to allow multiple open calls.
809*********************************************************************/
810
811static BOOL tdbsam_open( const char *name )
812{
813 int32 version;
814
815 /* check if we are already open */
816
817 if ( tdbsam ) {
818 ref_count++;
819 DEBUG(8,("tdbsam_open: Incrementing open reference count. Ref count is now %d\n",
820 ref_count));
821 return True;
822 }
823
824 SMB_ASSERT( ref_count == 0 );
825// DEBUG(0, ("tdbsam_open file: %s size: %d \n", name, get_file_size( name ) )); //remove me
826 /* Try to open tdb passwd. Create a new one if necessary */
827
828 if (!(tdbsam = tdb_open_log(name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600))) {
829 DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd [%s]\n", name));
830 return False;
831 }
832
833 /* set the initial reference count - must be done before tdbsam_convert
834 as that calls tdbsam_open()/tdbsam_close(). */
835
836 ref_count = 1;
837
838 /* Check the version */
839 version = tdb_fetch_int32( tdbsam, TDBSAM_VERSION_STRING );
840
841 if (version == -1) {
842 version = 0; /* Version not found, assume version 0 */
843 }
844
845 /* Compare the version */
846 if (version > TDBSAM_VERSION) {
847 /* Version more recent than the latest known */
848 DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
849 tdb_close( tdbsam );
850 ref_count = 0;
851 return False;
852 }
853
854
855 if ( version < TDBSAM_VERSION ) {
856 DEBUG(1, ("tdbsam_open: Converting version %d database to version %d.\n",
857 version, TDBSAM_VERSION));
858
859 if ( !tdbsam_convert(version) ) {
860 DEBUG(0, ("tdbsam_open: Error when trying to convert tdbsam [%s]\n",name));
861 tdb_close(tdbsam);
862 ref_count = 0;
863 return False;
864 }
865
866 DEBUG(3, ("TDBSAM converted successfully.\n"));
867 }
868
869 DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));
870
871 return True;
872}
873
874/****************************************************************************
875 wrapper atound tdb_close() to handle the reference count
876****************************************************************************/
877
878void tdbsam_close( void )
879{
880 ref_count--;
881
882 DEBUG(8,("tdbsam_close: Reference count is now %d.\n", ref_count));
883
884 SMB_ASSERT(ref_count >= 0 );
885/* remove later */
886// DEBUG(0, ("tdbsam_close file: %s size: %d \n", tdbsam_filename, get_file_size( tdbsam_filename ) )); //remove me
887/* -- remove later */
888 if ( ref_count == 0 ) {
889 tdb_close( tdbsam );
890 tdbsam = NULL;
891 }
892
893 return;
894}
895
896/****************************************************************************
897 creates a list of user keys
898****************************************************************************/
899
900static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
901{
902 const char *prefix = USERPREFIX;
903 int prefixlen = strlen (prefix);
904 struct pwent_list *ptr;
905
906 if ( strncmp(key.dptr, prefix, prefixlen) == 0 ) {
907 if ( !(ptr=SMB_MALLOC_P(struct pwent_list)) ) {
908 DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n"));
909
910 /* just return 0 and let the traversal continue */
911 return 0;
912 }
913 ZERO_STRUCTP(ptr);
914
915 /* save a copy of the key */
916
917 ptr->key.dptr = (char *)memdup( key.dptr, key.dsize );
918 if (!ptr->key.dptr) {
919 DEBUG(0,("tdbsam_traverse_setpwent: memdup failed\n"));
920 /* just return 0 and let the traversal continue */
921 SAFE_FREE(ptr);
922 return 0;
923 }
924
925 ptr->key.dsize = key.dsize;
926
927 DLIST_ADD( tdbsam_pwent_list, ptr );
928
929 }
930
931 return 0;
932}
933
934/***************************************************************
935 Open the TDB passwd database for SAM account enumeration.
936 Save a list of user keys for iteration.
937****************************************************************/
938
939static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
940{
941 if ( !tdbsam_open( tdbsam_filename ) ) {
942 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
943 return NT_STATUS_ACCESS_DENIED;
944 }
945
946 tdb_traverse( tdbsam, tdbsam_traverse_setpwent, NULL );
947 pwent_initialized = True;
948
949 return NT_STATUS_OK;
950}
951
952
953/***************************************************************
954 End enumeration of the TDB passwd list.
955****************************************************************/
956
957static void tdbsam_endsampwent(struct pdb_methods *my_methods)
958{
959 struct pwent_list *ptr, *ptr_next;
960
961 /* close the tdb only if we have a valid pwent state */
962
963 if ( pwent_initialized ) {
964 DEBUG(7, ("endtdbpwent: closed sam database.\n"));
965 tdbsam_close();
966 }
967
968 /* clear out any remaining entries in the list */
969
970 for ( ptr=tdbsam_pwent_list; ptr; ptr = ptr_next ) {
971 ptr_next = ptr->next;
972 DLIST_REMOVE( tdbsam_pwent_list, ptr );
973 SAFE_FREE( ptr->key.dptr);
974 SAFE_FREE( ptr );
975 }
976
977 pwent_initialized = False;
978}
979
980/*****************************************************************
981 Get one struct samu from the TDB (next in line)
982*****************************************************************/
983
984static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, struct samu *user)
985{
986 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
987 TDB_DATA data;
988 struct pwent_list *pkey;
989
990 if ( !user ) {
991 DEBUG(0,("tdbsam_getsampwent: struct samu is NULL.\n"));
992 return nt_status;
993 }
994
995 if ( !tdbsam_pwent_list ) {
996 DEBUG(4,("tdbsam_getsampwent: end of list\n"));
997 return nt_status;
998 }
999
1000 /* pull the next entry */
1001
1002 pkey = tdbsam_pwent_list;
1003 DLIST_REMOVE( tdbsam_pwent_list, pkey );
1004
1005 data = tdb_fetch(tdbsam, pkey->key);
1006
1007 SAFE_FREE( pkey->key.dptr);
1008 SAFE_FREE( pkey);
1009
1010 if ( !data.dptr ) {
1011 DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
1012 return nt_status;
1013 }
1014
1015 if ( !init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize) ) {
1016 DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
1017 }
1018
1019 SAFE_FREE( data.dptr );
1020
1021 return NT_STATUS_OK;
1022}
1023
1024/******************************************************************
1025 Lookup a name in the SAM TDB
1026******************************************************************/
1027
1028static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, struct samu *user, const char *sname)
1029{
1030 TDB_DATA data, key;
1031 fstring keystr;
1032 fstring name;
1033
1034 if ( !user ) {
1035 DEBUG(0,("pdb_getsampwnam: struct samu is NULL.\n"));
1036 return NT_STATUS_NO_MEMORY;
1037 }
1038
1039 /* Data is stored in all lower-case */
1040 fstrcpy(name, sname);
1041 strlower_m(name);
1042
1043 /* set search key */
1044 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
1045 key.dptr = keystr;
1046 key.dsize = strlen(keystr) + 1;
1047
1048 /* open the database */
1049
1050 if ( !tdbsam_open( tdbsam_filename ) ) {
1051 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
1052 return NT_STATUS_ACCESS_DENIED;
1053 }
1054
1055 /* get the record */
1056
1057 data = tdb_fetch(tdbsam, key);
1058 if (!data.dptr) {
1059 DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
1060 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
1061 DEBUGADD(5, (" Key: %s\n", keystr));
1062 tdbsam_close();
1063 return NT_STATUS_NO_SUCH_USER;
1064 }
1065
1066 /* unpack the buffer */
1067
1068 if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
1069 DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
1070 SAFE_FREE(data.dptr);
1071 tdbsam_close();
1072 return NT_STATUS_NO_MEMORY;
1073 }
1074
1075 /* success */
1076
1077 SAFE_FREE(data.dptr);
1078 tdbsam_close();
1079
1080 return NT_STATUS_OK;
1081}
1082
1083/***************************************************************************
1084 Search by rid
1085 **************************************************************************/
1086
1087static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, struct samu *user, uint32 rid)
1088{
1089 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1090 TDB_DATA data, key;
1091 fstring keystr;
1092 fstring name;
1093
1094 if ( !user ) {
1095 DEBUG(0,("pdb_getsampwrid: struct samu is NULL.\n"));
1096 return nt_status;
1097 }
1098
1099 /* set search key */
1100
1101 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
1102 key.dptr = keystr;
1103 key.dsize = strlen (keystr) + 1;
1104
1105 /* open the database */
1106
1107 if ( !tdbsam_open( tdbsam_filename ) ) {
1108 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
1109 return NT_STATUS_ACCESS_DENIED;
1110 }
1111
1112 /* get the record */
1113
1114 data = tdb_fetch (tdbsam, key);
1115 if (!data.dptr) {
1116 DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
1117 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
1118 nt_status = NT_STATUS_UNSUCCESSFUL;
1119 goto done;
1120 }
1121
1122 fstrcpy(name, data.dptr);
1123 SAFE_FREE(data.dptr);
1124
1125 nt_status = tdbsam_getsampwnam (my_methods, user, name);
1126
1127 done:
1128 /* cleanup */
1129
1130 tdbsam_close();
1131
1132 return nt_status;
1133}
1134
1135static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
1136{
1137 uint32 rid;
1138
1139 if ( !sid_peek_check_rid(get_global_sam_sid(), sid, &rid) )
1140 return NT_STATUS_UNSUCCESSFUL;
1141
1142 return tdbsam_getsampwrid(my_methods, user, rid);
1143}
1144
1145static BOOL tdb_delete_samacct_only( struct samu *sam_pass )
1146{
1147 TDB_DATA key;
1148 fstring keystr;
1149 fstring name;
1150
1151 fstrcpy(name, pdb_get_username(sam_pass));
1152 strlower_m(name);
1153
1154 /* set the search key */
1155
1156 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
1157 key.dptr = keystr;
1158 key.dsize = strlen (keystr) + 1;
1159
1160 /* it's outaa here! 8^) */
1161
1162 if (tdb_delete(tdbsam, key) != TDB_SUCCESS) {
1163 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
1164 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
1165 return False;
1166 }
1167
1168 return True;
1169}
1170
1171/***************************************************************************
1172 Delete a struct samu records for the username and RID key
1173****************************************************************************/
1174
1175static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, struct samu *sam_pass)
1176{
1177 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1178 TDB_DATA key;
1179 fstring keystr;
1180 uint32 rid;
1181 fstring name;
1182
1183 /* open the database */
1184
1185 if ( !tdbsam_open( tdbsam_filename ) ) {
1186 DEBUG(0,("tdbsam_delete_sam_account: failed to open %s!\n",
1187 tdbsam_filename));
1188 return NT_STATUS_ACCESS_DENIED;
1189 }
1190
1191 fstrcpy(name, pdb_get_username(sam_pass));
1192 strlower_m(name);
1193
1194 /* set the search key */
1195
1196 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
1197 key.dptr = keystr;
1198 key.dsize = strlen (keystr) + 1;
1199
1200 rid = pdb_get_user_rid(sam_pass);
1201
1202 /* it's outaa here! 8^) */
1203
1204 if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
1205 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
1206 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
1207 nt_status = NT_STATUS_UNSUCCESSFUL;
1208 goto done;
1209 }
1210
1211 /* set the search key */
1212
1213 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
1214 key.dptr = keystr;
1215 key.dsize = strlen (keystr) + 1;
1216
1217 /* it's outaa here! 8^) */
1218
1219 if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
1220 DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
1221 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
1222 nt_status = NT_STATUS_UNSUCCESSFUL;
1223 goto done;
1224 }
1225
1226 nt_status = NT_STATUS_OK;
1227
1228 done:
1229 tdbsam_close();
1230
1231 return nt_status;
1232}
1233
1234
1235/***************************************************************************
1236 Update the TDB SAM account record only
1237 Assumes that the tdbsam is already open
1238****************************************************************************/
1239static BOOL tdb_update_samacct_only( struct samu* newpwd, int flag )
1240{
1241 TDB_DATA key, data;
1242 uint8 *buf = NULL;
1243 fstring keystr;
1244 fstring name;
1245 BOOL ret = True;
1246
1247 /* copy the struct samu struct into a BYTE buffer for storage */
1248
1249 if ( (data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1 ) {
1250 DEBUG(0,("tdb_update_sam: ERROR - Unable to copy struct samu info BYTE buffer!\n"));
1251 ret = False;
1252 goto done;
1253 }
1254 data.dptr = (char *)buf;
1255
1256 fstrcpy(name, pdb_get_username(newpwd));
1257 strlower_m(name);
1258
1259 DEBUG(5, ("Storing %saccount %s with RID %d\n",
1260 flag == TDB_INSERT ? "(new) " : "", name,
1261 pdb_get_user_rid(newpwd)));
1262
1263 /* setup the USER index key */
1264 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
1265 key.dptr = keystr;
1266 key.dsize = strlen(keystr) + 1;
1267
1268 /* add the account */
1269
1270 if ( tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS ) {
1271 DEBUG(0, ("Unable to modify passwd TDB!"));
1272 DEBUGADD(0, (" Error: %s", tdb_errorstr(tdbsam)));
1273 DEBUGADD(0, (" occured while storing the main record (%s)\n",
1274 keystr));
1275 ret = False;
1276 goto done;
1277 }
1278
1279done:
1280 /* cleanup */
1281 SAFE_FREE(buf);
1282
1283 return ret;
1284}
1285
1286/***************************************************************************
1287 Update the TDB SAM RID record only
1288 Assumes that the tdbsam is already open
1289****************************************************************************/
1290static BOOL tdb_update_ridrec_only( struct samu* newpwd, int flag )
1291{
1292 TDB_DATA key, data;
1293 fstring keystr;
1294 fstring name;
1295
1296 fstrcpy(name, pdb_get_username(newpwd));
1297 strlower_m(name);
1298
1299 /* setup RID data */
1300 data.dsize = strlen(name) + 1;
1301 data.dptr = name;
1302
1303 /* setup the RID index key */
1304 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
1305 key.dptr = keystr;
1306 key.dsize = strlen (keystr) + 1;
1307
1308 /* add the reference */
1309 if (tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS) {
1310 DEBUG(0, ("Unable to modify TDB passwd !"));
1311 DEBUGADD(0, (" Error: %s\n", tdb_errorstr(tdbsam)));
1312 DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
1313 return False;
1314 }
1315
1316 return True;
1317
1318}
1319
1320/***************************************************************************
1321 Update the TDB SAM
1322****************************************************************************/
1323
1324static BOOL tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd, int flag)
1325{
1326 BOOL result = True;
1327
1328 /* invalidate the existing TDB iterator if it is open */
1329
1330 tdbsam_endsampwent( my_methods );
1331
1332#if 0
1333 if ( !pdb_get_group_rid(newpwd) ) {
1334 DEBUG (0,("tdb_update_sam: Failing to store a struct samu for [%s] "
1335 "without a primary group RID\n", pdb_get_username(newpwd)));
1336 return False;
1337 }
1338#endif
1339
1340 if (!pdb_get_user_rid(newpwd)) {
1341 DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n", pdb_get_username(newpwd)));
1342 return False;
1343 }
1344
1345 /* open the database */
1346
1347 if ( !tdbsam_open( tdbsam_filename ) ) {
1348 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
1349 return False;
1350 }
1351
1352 if ( !tdb_update_samacct_only(newpwd, flag) || !tdb_update_ridrec_only(newpwd, flag)) {
1353 result = False;
1354 }
1355
1356 /* cleanup */
1357
1358 tdbsam_close();
1359
1360 return result;
1361}
1362
1363/***************************************************************************
1364 Modifies an existing struct samu
1365****************************************************************************/
1366
1367static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
1368{
1369 if ( !tdb_update_sam(my_methods, newpwd, TDB_MODIFY) )
1370 return NT_STATUS_UNSUCCESSFUL;
1371
1372 return NT_STATUS_OK;
1373}
1374
1375/***************************************************************************
1376 Adds an existing struct samu
1377****************************************************************************/
1378
1379static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
1380{
1381 if ( !tdb_update_sam(my_methods, newpwd, TDB_INSERT) )
1382 return NT_STATUS_UNSUCCESSFUL;
1383
1384 return NT_STATUS_OK;
1385}
1386
1387/***************************************************************************
1388 Renames a struct samu
1389 - check for the posix user/rename user script
1390 - Add and lock the new user record
1391 - rename the posix user
1392 - rewrite the rid->username record
1393 - delete the old user
1394 - unlock the new user record
1395***************************************************************************/
1396static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
1397 struct samu *old_acct,
1398 const char *newname)
1399{
1400 struct samu *new_acct = NULL;
1401 pstring rename_script;
1402 BOOL interim_account = False;
1403 int rename_ret;
1404 fstring oldname_lower;
1405 fstring newname_lower;
1406
1407 /* can't do anything without an external script */
1408
1409 pstrcpy(rename_script, lp_renameuser_script() );
1410 if ( ! *rename_script ) {
1411 return NT_STATUS_ACCESS_DENIED;
1412 }
1413
1414 /* invalidate the existing TDB iterator if it is open */
1415
1416 tdbsam_endsampwent( my_methods );
1417
1418 if ( !(new_acct = samu_new( NULL )) ) {
1419 return NT_STATUS_NO_MEMORY;
1420 }
1421
1422 if ( !pdb_copy_sam_account(new_acct, old_acct)
1423 || !pdb_set_username(new_acct, newname, PDB_CHANGED))
1424 {
1425 TALLOC_FREE(new_acct );
1426 return NT_STATUS_NO_MEMORY;
1427 }
1428
1429 /* open the database */
1430
1431 if ( !tdbsam_open( tdbsam_filename ) ) {
1432 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
1433 TALLOC_FREE(new_acct );
1434 return NT_STATUS_ACCESS_DENIED;
1435 }
1436
1437 /* add the new account and lock it */
1438
1439 if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) {
1440 goto done;
1441 }
1442
1443 interim_account = True;
1444
1445 if ( tdb_lock_bystring_with_timeout(tdbsam, newname, 30) == -1 ) {
1446 goto done;
1447 }
1448
1449 /* Rename the posix user. Follow the semantics of _samr_create_user()
1450 so that we lower case the posix name but preserve the case in passdb */
1451
1452 fstrcpy( oldname_lower, pdb_get_username(old_acct) );
1453 strlower_m( oldname_lower );
1454
1455 fstrcpy( newname_lower, newname );
1456 strlower_m( newname_lower );
1457
1458 string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring),
1459 True, False, True);
1460 string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring),
1461 True, False, True);
1462 rename_ret = smbrun(rename_script, NULL);
1463
1464 DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
1465
1466 if (rename_ret == 0) {
1467 smb_nscd_flush_user_cache();
1468 }
1469
1470 if (rename_ret) {
1471 goto done;
1472 }
1473
1474 /* rewrite the rid->username record */
1475
1476 if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) {
1477 goto done;
1478 }
1479 interim_account = False;
1480 tdb_unlock_bystring( tdbsam, newname );
1481
1482 tdb_delete_samacct_only( old_acct );
1483
1484 tdbsam_close();
1485
1486 TALLOC_FREE(new_acct );
1487 return NT_STATUS_OK;
1488
1489done:
1490 /* cleanup */
1491 if (interim_account) {
1492 tdb_unlock_bystring(tdbsam, newname);
1493 tdb_delete_samacct_only(new_acct);
1494 }
1495
1496 tdbsam_close();
1497
1498 if (new_acct)
1499 TALLOC_FREE(new_acct);
1500
1501 return NT_STATUS_ACCESS_DENIED;
1502}
1503
1504static BOOL tdbsam_rid_algorithm(struct pdb_methods *methods)
1505{
1506 return False;
1507}
1508
1509/*
1510 * Historically, winbind was responsible for allocating RIDs, so the next RID
1511 * value was stored in winbindd_idmap.tdb. It has been moved to passdb now,
1512 * but for compatibility reasons we still keep the the next RID counter in
1513 * winbindd_idmap.tdb.
1514 */
1515
1516/*****************************************************************************
1517 Initialise idmap database. For now (Dec 2005) this is a copy of the code in
1518 sam/idmap_tdb.c. Maybe at a later stage we can remove that capability from
1519 winbind completely and store the RID counter in passdb.tdb.
1520
1521 Dont' fully initialize with the HWM values, if it's new, we're only
1522 interested in the RID counter.
1523*****************************************************************************/
1524
1525static BOOL init_idmap_tdb(TDB_CONTEXT *tdb)
1526{
1527 int32 version;
1528
1529 if (tdb_lock_bystring(tdb, "IDMAP_VERSION") != 0) {
1530 DEBUG(0, ("Could not lock IDMAP_VERSION\n"));
1531 return False;
1532 }
1533
1534 version = tdb_fetch_int32(tdb, "IDMAP_VERSION");
1535
1536 if (version == -1) {
1537 /* No key found, must be a new db */
1538 if (tdb_store_int32(tdb, "IDMAP_VERSION",
1539 IDMAP_VERSION) != 0) {
1540 DEBUG(0, ("Could not store IDMAP_VERSION\n"));
1541 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
1542 return False;
1543 }
1544 version = IDMAP_VERSION;
1545 }
1546
1547 if (version != IDMAP_VERSION) {
1548 DEBUG(0, ("Expected IDMAP_VERSION=%d, found %d. Please "
1549 "start winbind once\n", IDMAP_VERSION, version));
1550 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
1551 return False;
1552 }
1553
1554 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
1555 return True;
1556}
1557
1558static BOOL tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
1559{
1560 TDB_CONTEXT *tdb;
1561 uint32 rid;
1562 BOOL ret = False;
1563
1564 tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
1565 TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
1566
1567 if (tdb == NULL) {
1568 DEBUG(1, ("Could not open idmap: %s\n", strerror(errno)));
1569 goto done;
1570 }
1571
1572 if (!init_idmap_tdb(tdb)) {
1573 DEBUG(1, ("Could not init idmap\n"));
1574 goto done;
1575 }
1576
1577 rid = BASE_RID; /* Default if not set */
1578
1579 if (!tdb_change_uint32_atomic(tdb, "RID_COUNTER", &rid, 1)) {
1580 DEBUG(3, ("tdbsam_new_rid: Failed to increase RID_COUNTER\n"));
1581 goto done;
1582 }
1583
1584 *prid = rid;
1585 ret = True;
1586
1587 done:
1588 if ((tdb != NULL) && (tdb_close(tdb) != 0)) {
1589 smb_panic("tdb_close(idmap_tdb) failed\n");
1590 }
1591
1592 return ret;
1593}
1594
1595/*********************************************************************
1596 Initialize the tdb sam backend. Setup the dispath table of methods,
1597 open the tdb, etc...
1598*********************************************************************/
1599
1600static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *location)
1601{
1602 NTSTATUS nt_status;
1603 pstring tdbfile;
1604 const char *pfile = location;
1605
1606 if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
1607 return nt_status;
1608 }
1609
1610 (*pdb_method)->name = "tdbsam";
1611
1612 (*pdb_method)->setsampwent = tdbsam_setsampwent;
1613 (*pdb_method)->endsampwent = tdbsam_endsampwent;
1614 (*pdb_method)->getsampwent = tdbsam_getsampwent;
1615 (*pdb_method)->getsampwnam = tdbsam_getsampwnam;
1616 (*pdb_method)->getsampwsid = tdbsam_getsampwsid;
1617 (*pdb_method)->add_sam_account = tdbsam_add_sam_account;
1618 (*pdb_method)->update_sam_account = tdbsam_update_sam_account;
1619 (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
1620 (*pdb_method)->rename_sam_account = tdbsam_rename_sam_account;
1621
1622 (*pdb_method)->rid_algorithm = tdbsam_rid_algorithm;
1623 (*pdb_method)->new_rid = tdbsam_new_rid;
1624
1625 /* save the path for later */
1626
1627 if ( !location ) {
1628 pstr_sprintf( tdbfile, "%s/%s", lp_private_dir(), PASSDB_FILE_NAME );
1629 pfile = tdbfile;
1630 }
1631 pstrcpy( tdbsam_filename, pfile );
1632
1633 /* no private data */
1634
1635 (*pdb_method)->private_data = NULL;
1636 (*pdb_method)->free_private_data = NULL;
1637
1638 return NT_STATUS_OK;
1639}
1640
1641NTSTATUS pdb_tdbsam_init(void)
1642{
1643 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);
1644}
Note: See TracBrowser for help on using the repository browser.