41
#define TDBSAM_VERSION 2 /* Most recent TDBSAM version */
41
#define TDBSAM_VERSION 3 /* Most recent TDBSAM version */
42
42
#define TDBSAM_VERSION_STRING "INFO/version"
43
43
#define PASSDB_FILE_NAME "passdb.tdb"
44
44
#define USERPREFIX "USER_"
45
45
#define RIDPREFIX "RID_"
46
46
#define PRIVPREFIX "PRIV_"
47
#define tdbsamver_t int32
49
struct tdbsam_privates {
50
TDB_CONTEXT *passwd_tdb;
52
/* retrive-once info */
53
const char *tdbsam_location;
56
48
struct pwent_list {
57
49
struct pwent_list *prev, *next;
60
52
static struct pwent_list *tdbsam_pwent_list;
64
* Convert old TDBSAM to the latest version.
65
* @param pdb_tdb A pointer to the opened TDBSAM file which must be converted.
66
* This file must be opened with read/write access.
67
* @param from Current version of the TDBSAM file.
68
* @return True if the conversion has been successful, false otherwise.
71
static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
73
const char * vstring = TDBSAM_VERSION_STRING;
74
SAM_ACCOUNT *user = NULL;
75
const char *prefix = USERPREFIX;
53
static BOOL pwent_initialized;
55
/* GLOBAL TDB SAM CONTEXT */
57
static TDB_CONTEXT *tdbsam;
58
static int ref_count = 0;
59
static pstring tdbsam_filename;
61
/**********************************************************************
62
Marshall/unmarshall struct samu structs.
63
*********************************************************************/
65
#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
66
#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
67
#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
69
/*********************************************************************
70
*********************************************************************/
72
static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buflen)
75
/* times are stored as 32bit integer
76
take care on system with 64bit wide time_t
83
pass_must_change_time;
84
char *username = 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;
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;
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;
105
uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
107
uint32 lm_pw_len, nt_pw_len, hourslen;
110
if(sampass == NULL || buf == NULL) {
111
DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
115
/* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
117
/* unpack the buffer into variables */
118
len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
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 */
139
&lm_pw_len, &lm_pw_ptr, /* B */
140
&nt_pw_len, &nt_pw_ptr, /* B */
142
&remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
145
&hourslen, &hours, /* B */
146
&bad_password_count, /* w */
147
&logon_count, /* w */
150
if (len == (uint32) -1) {
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);
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);
168
pdb_set_homedir(sampass, homedir, PDB_SET);
171
pdb_set_homedir(sampass,
172
talloc_sub_basic(sampass, username, lp_logon_home()),
177
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
179
pdb_set_dir_drive(sampass,
180
talloc_sub_basic(sampass, username, lp_logon_drive()),
185
pdb_set_logon_script(sampass, logon_script, PDB_SET);
187
pdb_set_logon_script(sampass,
188
talloc_sub_basic(sampass, username, lp_logon_script()),
193
pdb_set_profile_path(sampass, profile_path, PDB_SET);
195
pdb_set_profile_path(sampass,
196
talloc_sub_basic(sampass, username, lp_logon_path()),
200
pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
201
pdb_set_workstations(sampass, workstations, PDB_SET);
202
pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
204
if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
205
if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
211
if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
212
if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
218
pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
219
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
220
pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
221
pdb_set_hours_len(sampass, hours_len, PDB_SET);
222
pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
223
pdb_set_logon_count(sampass, logon_count, PDB_SET);
224
pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
225
pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
226
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
227
pdb_set_hours(sampass, hours, PDB_SET);
233
SAFE_FREE(nt_username);
236
SAFE_FREE(dir_drive);
237
SAFE_FREE(logon_script);
238
SAFE_FREE(profile_path);
239
SAFE_FREE(acct_desc);
240
SAFE_FREE(workstations);
241
SAFE_FREE(munged_dial);
242
SAFE_FREE(unknown_str);
243
SAFE_FREE(lm_pw_ptr);
244
SAFE_FREE(nt_pw_ptr);
250
/*********************************************************************
251
*********************************************************************/
253
static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buflen)
256
/* times are stored as 32bit integer
257
take care on system with 64bit wide time_t
264
pass_can_change_time,
265
pass_must_change_time;
266
char *username = NULL;
268
char *nt_username = NULL;
269
char *dir_drive = NULL;
270
char *unknown_str = NULL;
271
char *munged_dial = NULL;
272
char *fullname = NULL;
273
char *homedir = NULL;
274
char *logon_script = NULL;
275
char *profile_path = NULL;
276
char *acct_desc = NULL;
277
char *workstations = NULL;
278
uint32 username_len, domain_len, nt_username_len,
279
dir_drive_len, unknown_str_len, munged_dial_len,
280
fullname_len, homedir_len, logon_script_len,
281
profile_path_len, acct_desc_len, workstations_len;
283
uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
284
uint16 acct_ctrl, logon_divs;
285
uint16 bad_password_count, logon_count;
287
uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
289
uint32 lm_pw_len, nt_pw_len, hourslen;
292
if(sampass == NULL || buf == NULL) {
293
DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
297
/* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
299
/* unpack the buffer into variables */
300
len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
302
&logoff_time, /* d */
303
&kickoff_time, /* d */
304
/* Change from V0 is addition of bad_password_time field. */
305
&bad_password_time, /* d */
306
&pass_last_set_time, /* d */
307
&pass_can_change_time, /* d */
308
&pass_must_change_time, /* d */
309
&username_len, &username, /* B */
310
&domain_len, &domain, /* B */
311
&nt_username_len, &nt_username, /* B */
312
&fullname_len, &fullname, /* B */
313
&homedir_len, &homedir, /* B */
314
&dir_drive_len, &dir_drive, /* B */
315
&logon_script_len, &logon_script, /* B */
316
&profile_path_len, &profile_path, /* B */
317
&acct_desc_len, &acct_desc, /* B */
318
&workstations_len, &workstations, /* B */
319
&unknown_str_len, &unknown_str, /* B */
320
&munged_dial_len, &munged_dial, /* B */
323
&lm_pw_len, &lm_pw_ptr, /* B */
324
&nt_pw_len, &nt_pw_ptr, /* B */
329
&hourslen, &hours, /* B */
330
&bad_password_count, /* w */
331
&logon_count, /* w */
334
if (len == (uint32) -1) {
339
pdb_set_logon_time(sampass, logon_time, PDB_SET);
340
pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
341
pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
343
/* Change from V0 is addition of bad_password_time field. */
344
pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
345
pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
346
pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
347
pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
349
pdb_set_username(sampass, username, PDB_SET);
350
pdb_set_domain(sampass, domain, PDB_SET);
351
pdb_set_nt_username(sampass, nt_username, PDB_SET);
352
pdb_set_fullname(sampass, fullname, PDB_SET);
355
pdb_set_homedir(sampass, homedir, PDB_SET);
358
pdb_set_homedir(sampass,
359
talloc_sub_basic(sampass, username, lp_logon_home()),
364
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
366
pdb_set_dir_drive(sampass,
367
talloc_sub_basic(sampass, username, lp_logon_drive()),
372
pdb_set_logon_script(sampass, logon_script, PDB_SET);
374
pdb_set_logon_script(sampass,
375
talloc_sub_basic(sampass, username, lp_logon_script()),
380
pdb_set_profile_path(sampass, profile_path, PDB_SET);
382
pdb_set_profile_path(sampass,
383
talloc_sub_basic(sampass, username, lp_logon_path()),
387
pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
388
pdb_set_workstations(sampass, workstations, PDB_SET);
389
pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
391
if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
392
if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
398
if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
399
if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
405
pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
407
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
408
pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
409
pdb_set_hours_len(sampass, hours_len, PDB_SET);
410
pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
411
pdb_set_logon_count(sampass, logon_count, PDB_SET);
412
pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
413
pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
414
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
415
pdb_set_hours(sampass, hours, PDB_SET);
421
SAFE_FREE(nt_username);
424
SAFE_FREE(dir_drive);
425
SAFE_FREE(logon_script);
426
SAFE_FREE(profile_path);
427
SAFE_FREE(acct_desc);
428
SAFE_FREE(workstations);
429
SAFE_FREE(munged_dial);
430
SAFE_FREE(unknown_str);
431
SAFE_FREE(lm_pw_ptr);
432
SAFE_FREE(nt_pw_ptr);
438
BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
441
/* times are stored as 32bit integer
442
take care on system with 64bit wide time_t
449
pass_can_change_time,
450
pass_must_change_time;
451
char *username = NULL;
453
char *nt_username = NULL;
454
char *dir_drive = NULL;
455
char *unknown_str = NULL;
456
char *munged_dial = NULL;
457
char *fullname = NULL;
458
char *homedir = NULL;
459
char *logon_script = NULL;
460
char *profile_path = NULL;
461
char *acct_desc = NULL;
462
char *workstations = NULL;
463
uint32 username_len, domain_len, nt_username_len,
464
dir_drive_len, unknown_str_len, munged_dial_len,
465
fullname_len, homedir_len, logon_script_len,
466
profile_path_len, acct_desc_len, workstations_len;
468
uint32 user_rid, group_rid, hours_len, unknown_6;
469
uint16 acct_ctrl, logon_divs;
470
uint16 bad_password_count, logon_count;
472
uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
474
uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
475
uint32 pwHistLen = 0;
478
BOOL expand_explicit = lp_passdb_expand_explicit();
480
if(sampass == NULL || buf == NULL) {
481
DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
485
/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
487
/* unpack the buffer into variables */
488
len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
490
&logoff_time, /* d */
491
&kickoff_time, /* d */
492
&bad_password_time, /* d */
493
&pass_last_set_time, /* d */
494
&pass_can_change_time, /* d */
495
&pass_must_change_time, /* d */
496
&username_len, &username, /* B */
497
&domain_len, &domain, /* B */
498
&nt_username_len, &nt_username, /* B */
499
&fullname_len, &fullname, /* B */
500
&homedir_len, &homedir, /* B */
501
&dir_drive_len, &dir_drive, /* B */
502
&logon_script_len, &logon_script, /* B */
503
&profile_path_len, &profile_path, /* B */
504
&acct_desc_len, &acct_desc, /* B */
505
&workstations_len, &workstations, /* B */
506
&unknown_str_len, &unknown_str, /* B */
507
&munged_dial_len, &munged_dial, /* B */
510
&lm_pw_len, &lm_pw_ptr, /* B */
511
&nt_pw_len, &nt_pw_ptr, /* B */
512
/* Change from V1 is addition of password history field. */
513
&nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
515
/* Also "remove_me" field was removed. */
518
&hourslen, &hours, /* B */
519
&bad_password_count, /* w */
520
&logon_count, /* w */
523
if (len == (uint32) -1) {
528
pdb_set_logon_time(sampass, logon_time, PDB_SET);
529
pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
530
pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
531
pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
532
pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
533
pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
534
pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
536
pdb_set_username(sampass, username, PDB_SET);
537
pdb_set_domain(sampass, domain, PDB_SET);
538
pdb_set_nt_username(sampass, nt_username, PDB_SET);
539
pdb_set_fullname(sampass, fullname, PDB_SET);
542
fstrcpy( tmpstring, homedir );
543
if (expand_explicit) {
544
standard_sub_basic( username, tmpstring,
547
pdb_set_homedir(sampass, tmpstring, PDB_SET);
550
pdb_set_homedir(sampass,
551
talloc_sub_basic(sampass, username, lp_logon_home()),
556
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
558
pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
561
fstrcpy( tmpstring, logon_script );
562
if (expand_explicit) {
563
standard_sub_basic( username, tmpstring,
566
pdb_set_logon_script(sampass, tmpstring, PDB_SET);
569
pdb_set_logon_script(sampass,
570
talloc_sub_basic(sampass, username, lp_logon_script()),
575
fstrcpy( tmpstring, profile_path );
576
if (expand_explicit) {
577
standard_sub_basic( username, tmpstring,
580
pdb_set_profile_path(sampass, tmpstring, PDB_SET);
583
pdb_set_profile_path(sampass,
584
talloc_sub_basic(sampass, username, lp_logon_path()),
588
pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
589
pdb_set_workstations(sampass, workstations, PDB_SET);
590
pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
592
if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
593
if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
599
if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
600
if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
606
/* Change from V1 is addition of password history field. */
607
pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
609
uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
614
memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
615
if (nt_pw_hist_ptr && nt_pw_hist_len) {
617
SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
618
nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
619
for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
620
memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
621
&nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
622
PW_HISTORY_ENTRY_LEN);
625
if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
632
pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
635
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
636
pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
637
pdb_set_hours_len(sampass, hours_len, PDB_SET);
638
pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
639
pdb_set_logon_count(sampass, logon_count, PDB_SET);
640
pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
641
pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
642
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
643
pdb_set_hours(sampass, hours, PDB_SET);
649
SAFE_FREE(nt_username);
652
SAFE_FREE(dir_drive);
653
SAFE_FREE(logon_script);
654
SAFE_FREE(profile_path);
655
SAFE_FREE(acct_desc);
656
SAFE_FREE(workstations);
657
SAFE_FREE(munged_dial);
658
SAFE_FREE(unknown_str);
659
SAFE_FREE(lm_pw_ptr);
660
SAFE_FREE(nt_pw_ptr);
661
SAFE_FREE(nt_pw_hist_ptr);
668
/**********************************************************************
669
Intialize a struct samu struct from a BYTE buffer of size len
670
*********************************************************************/
672
static BOOL init_sam_from_buffer(struct samu *sampass, uint8 *buf, uint32 buflen)
674
return init_sam_from_buffer_v3(sampass, buf, buflen);
677
/**********************************************************************
678
Intialize a BYTE buffer from a struct samu struct
679
*********************************************************************/
681
static uint32 init_buffer_from_sam (uint8 **buf, struct samu *sampass, BOOL size_only)
683
return init_buffer_from_sam_v3(buf, sampass, size_only);
686
/**********************************************************************
687
Intialize a BYTE buffer from a struct samu struct
688
*********************************************************************/
690
static BOOL tdbsam_convert(int32 from)
692
const char *vstring = TDBSAM_VERSION_STRING;
693
const char *prefix = USERPREFIX;
76
694
TDB_DATA data, key, old_key;
77
695
uint8 *buf = NULL;
80
if (pdb_tdb == NULL) {
81
DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n"));
85
698
/* handle a Samba upgrade */
86
tdb_lock_bystring(pdb_tdb, vstring, 0);
699
tdb_lock_bystring(tdbsam, vstring);
88
if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
89
DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n"));
93
701
/* Enumerate all records and convert them */
94
key = tdb_firstkey(pdb_tdb);
702
key = tdb_firstkey(tdbsam);
96
704
while (key.dptr) {
776
1381
- unlock the new user record
777
1382
***************************************************************************/
778
1383
static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
779
SAM_ACCOUNT *old_acct,
1384
struct samu *old_acct,
780
1385
const char *newname)
782
struct tdbsam_privates *tdb_state =
783
(struct tdbsam_privates *)my_methods->private_data;
784
SAM_ACCOUNT *new_acct = NULL;
785
pstring rename_script;
786
TDB_CONTEXT *pwd_tdb = NULL;
787
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
788
BOOL interim_account = False;
790
if (!*(lp_renameuser_script()))
793
if (!pdb_copy_sam_account(old_acct, &new_acct) ||
794
!pdb_set_username(new_acct, newname, PDB_CHANGED))
1387
struct samu *new_acct = NULL;
1388
pstring rename_script;
1389
BOOL interim_account = False;
1391
fstring oldname_lower;
1392
fstring newname_lower;
1394
/* can't do anything without an external script */
1396
pstrcpy(rename_script, lp_renameuser_script() );
1397
if ( ! *rename_script ) {
1398
return NT_STATUS_ACCESS_DENIED;
797
1401
/* invalidate the existing TDB iterator if it is open */
799
if (tdb_state->passwd_tdb) {
800
tdb_close(tdb_state->passwd_tdb);
801
tdb_state->passwd_tdb = NULL;
804
/* open the account TDB passwd */
806
pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
809
DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n",
810
tdb_state->tdbsam_location));
1403
tdbsam_endsampwent( my_methods );
1405
if ( !(new_acct = samu_new( NULL )) ) {
1406
return NT_STATUS_NO_MEMORY;
1409
if ( !pdb_copy_sam_account(new_acct, old_acct)
1410
|| !pdb_set_username(new_acct, newname, PDB_CHANGED))
1412
TALLOC_FREE(new_acct );
1413
return NT_STATUS_NO_MEMORY;
1416
/* open the database */
1418
if ( !tdbsam_open( tdbsam_filename ) ) {
1419
DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
1420
TALLOC_FREE(new_acct );
1421
return NT_STATUS_ACCESS_DENIED;
814
1424
/* add the new account and lock it */
815
if (!tdb_update_samacct_only(pwd_tdb, my_methods, new_acct,
1426
if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) {
818
1430
interim_account = True;
820
if (tdb_lock_bystring(pwd_tdb, newname, 30) == -1) {
824
/* rename the posix user */
825
pstrcpy(rename_script, lp_renameuser_script());
827
if (*rename_script) {
830
pstring_sub(rename_script, "%unew", newname);
831
pstring_sub(rename_script, "%uold",
832
pdb_get_username(old_acct));
833
rename_ret = smbrun(rename_script, NULL);
835
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
1432
if ( tdb_lock_bystring_with_timeout(tdbsam, newname, 30) == -1 ) {
1436
/* Rename the posix user. Follow the semantics of _samr_create_user()
1437
so that we lower case the posix name but preserve the case in passdb */
1439
fstrcpy( oldname_lower, pdb_get_username(old_acct) );
1440
strlower_m( oldname_lower );
1442
fstrcpy( newname_lower, newname );
1443
strlower_m( newname_lower );
1445
string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring),
1447
string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring),
1449
rename_ret = smbrun(rename_script, NULL);
1451
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
1453
if (rename_ret == 0) {
1454
smb_nscd_flush_user_cache();
843
1461
/* rewrite the rid->username record */
844
if (!tdb_update_ridrec_only(pwd_tdb, my_methods, new_acct, TDB_MODIFY))
1463
if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) {
846
1466
interim_account = False;
847
tdb_unlock_bystring(pwd_tdb, newname);
849
tdb_delete_samacct_only(pwd_tdb, my_methods, old_acct);
1467
tdb_unlock_bystring( tdbsam, newname );
1469
tdb_delete_samacct_only( old_acct );
1473
TALLOC_FREE(new_acct );
1474
return NT_STATUS_OK;
856
1478
if (interim_account) {
857
tdb_unlock_bystring(pwd_tdb, newname);
858
tdb_delete_samacct_only(pwd_tdb, my_methods, new_acct);
1479
tdb_unlock_bystring(tdbsam, newname);
1480
tdb_delete_samacct_only(new_acct);
863
pdb_free_sam(&new_acct);
868
static void free_private_data(void **vp)
870
struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp;
871
tdbsam_tdbclose(*tdb_state);
874
/* No need to free any further, as it is talloc()ed */
881
* Init tdbsam backend
883
* @param pdb_context initialised passdb context
884
* @param pdb_method backend methods structure to be filled with function pointers
885
* @param location the backend tdb file location
887
* @return nt_status code
890
static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1486
TALLOC_FREE(new_acct);
1488
return NT_STATUS_ACCESS_DENIED;
1491
static BOOL tdbsam_rid_algorithm(struct pdb_methods *methods)
1497
* Historically, winbind was responsible for allocating RIDs, so the next RID
1498
* value was stored in winbindd_idmap.tdb. It has been moved to passdb now,
1499
* but for compatibility reasons we still keep the the next RID counter in
1500
* winbindd_idmap.tdb.
1503
/*****************************************************************************
1504
Initialise idmap database. For now (Dec 2005) this is a copy of the code in
1505
sam/idmap_tdb.c. Maybe at a later stage we can remove that capability from
1506
winbind completely and store the RID counter in passdb.tdb.
1508
Dont' fully initialize with the HWM values, if it's new, we're only
1509
interested in the RID counter.
1510
*****************************************************************************/
1512
static BOOL init_idmap_tdb(TDB_CONTEXT *tdb)
1516
if (tdb_lock_bystring(tdb, "IDMAP_VERSION") != 0) {
1517
DEBUG(0, ("Could not lock IDMAP_VERSION\n"));
1521
version = tdb_fetch_int32(tdb, "IDMAP_VERSION");
1523
if (version == -1) {
1524
/* No key found, must be a new db */
1525
if (tdb_store_int32(tdb, "IDMAP_VERSION",
1526
IDMAP_VERSION) != 0) {
1527
DEBUG(0, ("Could not store IDMAP_VERSION\n"));
1528
tdb_unlock_bystring(tdb, "IDMAP_VERSION");
1531
version = IDMAP_VERSION;
1534
if (version != IDMAP_VERSION) {
1535
DEBUG(0, ("Expected IDMAP_VERSION=%d, found %d. Please "
1536
"start winbind once\n", IDMAP_VERSION, version));
1537
tdb_unlock_bystring(tdb, "IDMAP_VERSION");
1541
tdb_unlock_bystring(tdb, "IDMAP_VERSION");
1545
static BOOL tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
1551
tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
1552
TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
1555
DEBUG(1, ("Could not open idmap: %s\n", strerror(errno)));
1559
if (!init_idmap_tdb(tdb)) {
1560
DEBUG(1, ("Could not init idmap\n"));
1564
rid = BASE_RID; /* Default if not set */
1566
if (!tdb_change_uint32_atomic(tdb, "RID_COUNTER", &rid, 1)) {
1567
DEBUG(3, ("tdbsam_new_rid: Failed to increase RID_COUNTER\n"));
1575
if ((tdb != NULL) && (tdb_close(tdb) != 0)) {
1576
smb_panic("tdb_close(idmap_tdb) failed\n");
1582
/*********************************************************************
1583
Initialize the tdb sam backend. Setup the dispath table of methods,
1584
open the tdb, etc...
1585
*********************************************************************/
1587
static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *location)
892
1589
NTSTATUS nt_status;
893
struct tdbsam_privates *tdb_state;
1591
const char *pfile = location;
895
if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
1593
if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
896
1594
return nt_status;