/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- my_sam_name
- samu_destroy
- samu_new
- samu_set_unix_internal
- samu_set_unix
- samu_alloc_rid_unix
- pdb_encode_acct_ctrl
- pdb_decode_acct_ctrl
- pdb_sethexpwd
- pdb_gethexpwd
- pdb_sethexhours
- pdb_gethexhours
- algorithmic_rid_base
- algorithmic_pdb_user_rid_to_uid
- max_algorithmic_uid
- algorithmic_pdb_uid_to_user_rid
- pdb_group_rid_to_gid
- max_algorithmic_gid
- algorithmic_pdb_gid_to_group_rid
- rid_is_well_known
- algorithmic_pdb_rid_is_user
- lookup_global_sam_name
- local_password_change
- init_samu_from_buffer_v0
- init_samu_from_buffer_v1
- init_samu_from_buffer_v2
- init_samu_from_buffer_v3
- init_buffer_from_samu_v3
- init_samu_from_buffer_v4
- init_buffer_from_samu_v4
- init_samu_from_buffer
- init_buffer_from_samu
- pdb_copy_sam_account
- pdb_update_bad_password_count
- pdb_update_autolock_flag
- pdb_increment_bad_password_count
- is_dc_trusted_domain_situation
- get_trust_pw_clear
- get_trust_pw_hash
- get_logon_hours_from_pdb
- smb_create_user
1 /*
2 Unix SMB/CIFS implementation.
3 Password and authentication handling
4 Copyright (C) Jeremy Allison 1996-2001
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000-2006
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Simo Sorce 2003
9 Copyright (C) Volker Lendecke 2006
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
29
30 /******************************************************************
31 Get the default domain/netbios name to be used when
32 testing authentication.
33
34 LEGACY: this function provides the legacy domain mapping used with
35 the lp_map_untrusted_to_domain() parameter
36 ******************************************************************/
37
38 const char *my_sam_name(void)
/* [<][>][^][v][top][bottom][index][help] */
39 {
40 /* Standalone servers can only use the local netbios name */
41 if ( lp_server_role() == ROLE_STANDALONE )
42 return global_myname();
43
44 /* Default to the DOMAIN name when not specified */
45 return lp_workgroup();
46 }
47
48 /**********************************************************************
49 ***********************************************************************/
50
51 static int samu_destroy(struct samu *user)
/* [<][>][^][v][top][bottom][index][help] */
52 {
53 data_blob_clear_free( &user->lm_pw );
54 data_blob_clear_free( &user->nt_pw );
55
56 if ( user->plaintext_pw )
57 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
58
59 return 0;
60 }
61
62 /**********************************************************************
63 generate a new struct samuser
64 ***********************************************************************/
65
66 struct samu *samu_new( TALLOC_CTX *ctx )
/* [<][>][^][v][top][bottom][index][help] */
67 {
68 struct samu *user;
69
70 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
71 DEBUG(0,("samuser_new: Talloc failed!\n"));
72 return NULL;
73 }
74
75 talloc_set_destructor( user, samu_destroy );
76
77 /* no initial methods */
78
79 user->methods = NULL;
80
81 /* Don't change these timestamp settings without a good reason.
82 They are important for NT member server compatibility. */
83
84 user->logon_time = (time_t)0;
85 user->pass_last_set_time = (time_t)0;
86 user->pass_can_change_time = (time_t)0;
87 user->logoff_time = get_time_t_max();
88 user->kickoff_time = get_time_t_max();
89 user->pass_must_change_time = get_time_t_max();
90 user->fields_present = 0x00ffffff;
91 user->logon_divs = 168; /* hours per week */
92 user->hours_len = 21; /* 21 times 8 bits = 168 */
93 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
94 user->bad_password_count = 0;
95 user->logon_count = 0;
96 user->unknown_6 = 0x000004ec; /* don't know */
97
98 /* Some parts of samba strlen their pdb_get...() returns,
99 so this keeps the interface unchanged for now. */
100
101 user->username = "";
102 user->domain = "";
103 user->nt_username = "";
104 user->full_name = "";
105 user->home_dir = "";
106 user->logon_script = "";
107 user->profile_path = "";
108 user->acct_desc = "";
109 user->workstations = "";
110 user->comment = "";
111 user->munged_dial = "";
112
113 user->plaintext_pw = NULL;
114
115 /* Unless we know otherwise have a Account Control Bit
116 value of 'normal user'. This helps User Manager, which
117 asks for a filtered list of users. */
118
119 user->acct_ctrl = ACB_NORMAL;
120
121 return user;
122 }
123
124 /*********************************************************************
125 Initialize a struct samu from a struct passwd including the user
126 and group SIDs. The *user structure is filled out with the Unix
127 attributes and a user SID.
128 *********************************************************************/
129
130 static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, bool create)
/* [<][>][^][v][top][bottom][index][help] */
131 {
132 const char *guest_account = lp_guestaccount();
133 const char *domain = global_myname();
134 uint32 urid;
135
136 if ( !pwd ) {
137 return NT_STATUS_NO_SUCH_USER;
138 }
139
140 /* Basic properties based upon the Unix account information */
141
142 pdb_set_username(user, pwd->pw_name, PDB_SET);
143 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
144 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
145 #if 0
146 /* This can lead to a primary group of S-1-22-2-XX which
147 will be rejected by other parts of the Samba code.
148 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
149 --jerry */
150
151 gid_to_sid(&group_sid, pwd->pw_gid);
152 pdb_set_group_sid(user, &group_sid, PDB_SET);
153 #endif
154
155 /* save the password structure for later use */
156
157 user->unix_pw = tcopy_passwd( user, pwd );
158
159 /* Special case for the guest account which must have a RID of 501 */
160
161 if ( strequal( pwd->pw_name, guest_account ) ) {
162 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
163 return NT_STATUS_NO_SUCH_USER;
164 }
165 return NT_STATUS_OK;
166 }
167
168 /* Non-guest accounts...Check for a workstation or user account */
169
170 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
171 /* workstation */
172
173 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
174 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
175 pwd->pw_name));
176 return NT_STATUS_INVALID_COMPUTER_NAME;
177 }
178 }
179 else {
180 /* user */
181
182 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
183 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
184 pwd->pw_name));
185 return NT_STATUS_INVALID_ACCOUNT_NAME;
186 }
187
188 /* set some basic attributes */
189
190 pdb_set_profile_path(user, talloc_sub_specified(user,
191 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
192 PDB_DEFAULT);
193 pdb_set_homedir(user, talloc_sub_specified(user,
194 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
195 PDB_DEFAULT);
196 pdb_set_dir_drive(user, talloc_sub_specified(user,
197 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
198 PDB_DEFAULT);
199 pdb_set_logon_script(user, talloc_sub_specified(user,
200 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
201 PDB_DEFAULT);
202 }
203
204 /* Now deal with the user SID. If we have a backend that can generate
205 RIDs, then do so. But sometimes the caller just wanted a structure
206 initialized and will fill in these fields later (such as from a
207 netr_SamInfo3 structure) */
208
209 if ( create && !pdb_rid_algorithm() ) {
210 uint32 user_rid;
211 DOM_SID user_sid;
212
213 if ( !pdb_new_rid( &user_rid ) ) {
214 DEBUG(3, ("Could not allocate a new RID\n"));
215 return NT_STATUS_ACCESS_DENIED;
216 }
217
218 sid_copy( &user_sid, get_global_sam_sid() );
219 sid_append_rid( &user_sid, user_rid );
220
221 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
222 DEBUG(3, ("pdb_set_user_sid failed\n"));
223 return NT_STATUS_INTERNAL_ERROR;
224 }
225
226 return NT_STATUS_OK;
227 }
228
229 /* generate a SID for the user with the RID algorithm */
230
231 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
232
233 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
234 return NT_STATUS_INTERNAL_ERROR;
235 }
236
237 return NT_STATUS_OK;
238 }
239
240 /********************************************************************
241 Set the Unix user attributes
242 ********************************************************************/
243
244 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
/* [<][>][^][v][top][bottom][index][help] */
245 {
246 return samu_set_unix_internal( user, pwd, False );
247 }
248
249 NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
/* [<][>][^][v][top][bottom][index][help] */
250 {
251 return samu_set_unix_internal( user, pwd, True );
252 }
253
254 /**********************************************************
255 Encode the account control bits into a string.
256 length = length of string to encode into (including terminating
257 null). length *MUST BE MORE THAN 2* !
258 **********************************************************/
259
260 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
/* [<][>][^][v][top][bottom][index][help] */
261 {
262 fstring acct_str;
263 char *result;
264
265 size_t i = 0;
266
267 SMB_ASSERT(length <= sizeof(acct_str));
268
269 acct_str[i++] = '[';
270
271 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
272 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
273 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
274 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
275 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
276 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
277 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
278 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
279 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
280 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
281 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
282
283 for ( ; i < length - 2 ; i++ )
284 acct_str[i] = ' ';
285
286 i = length - 2;
287 acct_str[i++] = ']';
288 acct_str[i++] = '\0';
289
290 result = talloc_strdup(talloc_tos(), acct_str);
291 SMB_ASSERT(result != NULL);
292 return result;
293 }
294
295 /**********************************************************
296 Decode the account control bits from a string.
297 **********************************************************/
298
299 uint32_t pdb_decode_acct_ctrl(const char *p)
/* [<][>][^][v][top][bottom][index][help] */
300 {
301 uint32_t acct_ctrl = 0;
302 bool finished = false;
303
304 /*
305 * Check if the account type bits have been encoded after the
306 * NT password (in the form [NDHTUWSLXI]).
307 */
308
309 if (*p != '[')
310 return 0;
311
312 for (p++; *p && !finished; p++) {
313 switch (*p) {
314 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
315 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
316 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
317 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
318 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
319 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
320 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
321 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
322 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
323 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
324 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
325 case ' ': { break; }
326 case ':':
327 case '\n':
328 case '\0':
329 case ']':
330 default: { finished = true; }
331 }
332 }
333
334 return acct_ctrl;
335 }
336
337 /*************************************************************
338 Routine to set 32 hex password characters from a 16 byte array.
339 **************************************************************/
340
341 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32 acct_ctrl)
/* [<][>][^][v][top][bottom][index][help] */
342 {
343 if (pwd != NULL) {
344 int i;
345 for (i = 0; i < 16; i++)
346 slprintf(&p[i*2], 3, "%02X", pwd[i]);
347 } else {
348 if (acct_ctrl & ACB_PWNOTREQ)
349 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
350 else
351 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
352 }
353 }
354
355 /*************************************************************
356 Routine to get the 32 hex characters and turn them
357 into a 16 byte array.
358 **************************************************************/
359
360 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
/* [<][>][^][v][top][bottom][index][help] */
361 {
362 int i;
363 unsigned char lonybble, hinybble;
364 const char *hexchars = "0123456789ABCDEF";
365 char *p1, *p2;
366
367 if (!p)
368 return false;
369
370 for (i = 0; i < 32; i += 2) {
371 hinybble = toupper_ascii(p[i]);
372 lonybble = toupper_ascii(p[i + 1]);
373
374 p1 = strchr(hexchars, hinybble);
375 p2 = strchr(hexchars, lonybble);
376
377 if (!p1 || !p2)
378 return false;
379
380 hinybble = PTR_DIFF(p1, hexchars);
381 lonybble = PTR_DIFF(p2, hexchars);
382
383 pwd[i / 2] = (hinybble << 4) | lonybble;
384 }
385 return true;
386 }
387
388 /*************************************************************
389 Routine to set 42 hex hours characters from a 21 byte array.
390 **************************************************************/
391
392 void pdb_sethexhours(char *p, const unsigned char *hours)
/* [<][>][^][v][top][bottom][index][help] */
393 {
394 if (hours != NULL) {
395 int i;
396 for (i = 0; i < 21; i++) {
397 slprintf(&p[i*2], 3, "%02X", hours[i]);
398 }
399 } else {
400 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
401 }
402 }
403
404 /*************************************************************
405 Routine to get the 42 hex characters and turn them
406 into a 21 byte array.
407 **************************************************************/
408
409 bool pdb_gethexhours(const char *p, unsigned char *hours)
/* [<][>][^][v][top][bottom][index][help] */
410 {
411 int i;
412 unsigned char lonybble, hinybble;
413 const char *hexchars = "0123456789ABCDEF";
414 char *p1, *p2;
415
416 if (!p) {
417 return (False);
418 }
419
420 for (i = 0; i < 42; i += 2) {
421 hinybble = toupper_ascii(p[i]);
422 lonybble = toupper_ascii(p[i + 1]);
423
424 p1 = strchr(hexchars, hinybble);
425 p2 = strchr(hexchars, lonybble);
426
427 if (!p1 || !p2) {
428 return (False);
429 }
430
431 hinybble = PTR_DIFF(p1, hexchars);
432 lonybble = PTR_DIFF(p2, hexchars);
433
434 hours[i / 2] = (hinybble << 4) | lonybble;
435 }
436 return (True);
437 }
438
439 /********************************************************************
440 ********************************************************************/
441
442 int algorithmic_rid_base(void)
/* [<][>][^][v][top][bottom][index][help] */
443 {
444 int rid_offset;
445
446 rid_offset = lp_algorithmic_rid_base();
447
448 if (rid_offset < BASE_RID) {
449 /* Try to prevent admin foot-shooting, we can't put algorithmic
450 rids below 1000, that's the 'well known RIDs' on NT */
451 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
452 rid_offset = BASE_RID;
453 }
454 if (rid_offset & 1) {
455 DEBUG(0, ("algorithmic rid base must be even\n"));
456 rid_offset += 1;
457 }
458 return rid_offset;
459 }
460
461 /*******************************************************************
462 Converts NT user RID to a UNIX uid.
463 ********************************************************************/
464
465 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
/* [<][>][^][v][top][bottom][index][help] */
466 {
467 int rid_offset = algorithmic_rid_base();
468 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
469 }
470
471 uid_t max_algorithmic_uid(void)
/* [<][>][^][v][top][bottom][index][help] */
472 {
473 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
474 }
475
476 /*******************************************************************
477 converts UNIX uid to an NT User RID.
478 ********************************************************************/
479
480 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
/* [<][>][^][v][top][bottom][index][help] */
481 {
482 int rid_offset = algorithmic_rid_base();
483 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
484 }
485
486 /*******************************************************************
487 Converts NT group RID to a UNIX gid.
488 ********************************************************************/
489
490 gid_t pdb_group_rid_to_gid(uint32 group_rid)
/* [<][>][^][v][top][bottom][index][help] */
491 {
492 int rid_offset = algorithmic_rid_base();
493 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
494 }
495
496 gid_t max_algorithmic_gid(void)
/* [<][>][^][v][top][bottom][index][help] */
497 {
498 return pdb_group_rid_to_gid(0xffffffff);
499 }
500
501 /*******************************************************************
502 converts NT Group RID to a UNIX uid.
503
504 warning: you must not call that function only
505 you must do a call to the group mapping first.
506 there is not anymore a direct link between the gid and the rid.
507 ********************************************************************/
508
509 uint32 algorithmic_pdb_gid_to_group_rid(gid_t gid)
/* [<][>][^][v][top][bottom][index][help] */
510 {
511 int rid_offset = algorithmic_rid_base();
512 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
513 }
514
515 /*******************************************************************
516 Decides if a RID is a well known RID.
517 ********************************************************************/
518
519 static bool rid_is_well_known(uint32 rid)
/* [<][>][^][v][top][bottom][index][help] */
520 {
521 /* Not using rid_offset here, because this is the actual
522 NT fixed value (1000) */
523
524 return (rid < BASE_RID);
525 }
526
527 /*******************************************************************
528 Decides if a RID is a user or group RID.
529 ********************************************************************/
530
531 bool algorithmic_pdb_rid_is_user(uint32 rid)
/* [<][>][^][v][top][bottom][index][help] */
532 {
533 if ( rid_is_well_known(rid) ) {
534 /*
535 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
536 * and DOMAIN_USER_RID_GUEST.
537 */
538 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
539 return True;
540 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
541 return True;
542 }
543 return False;
544 }
545
546 /*******************************************************************
547 Convert a name into a SID. Used in the lookup name rpc.
548 ********************************************************************/
549
550 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
/* [<][>][^][v][top][bottom][index][help] */
551 enum lsa_SidType *type)
552 {
553 GROUP_MAP map;
554 bool ret;
555
556 /* Windows treats "MACHINE\None" as a special name for
557 rid 513 on non-DCs. You cannot create a user or group
558 name "None" on Windows. You will get an error that
559 the group already exists. */
560
561 if ( strequal( name, "None" ) ) {
562 *rid = DOMAIN_GROUP_RID_USERS;
563 *type = SID_NAME_DOM_GRP;
564
565 return True;
566 }
567
568 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
569 * correctly in the case where foo also exists as a user. If the flag
570 * is set, don't look for users at all. */
571
572 if ((flags & LOOKUP_NAME_GROUP) == 0) {
573 struct samu *sam_account = NULL;
574 DOM_SID user_sid;
575
576 if ( !(sam_account = samu_new( NULL )) ) {
577 return False;
578 }
579
580 become_root();
581 ret = pdb_getsampwnam(sam_account, name);
582 unbecome_root();
583
584 if (ret) {
585 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
586 }
587
588 TALLOC_FREE(sam_account);
589
590 if (ret) {
591 if (!sid_check_is_in_our_domain(&user_sid)) {
592 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
593 name, sid_string_dbg(&user_sid)));
594 return False;
595 }
596
597 sid_peek_rid(&user_sid, rid);
598 *type = SID_NAME_USER;
599 return True;
600 }
601 }
602
603 /*
604 * Maybe it is a group ?
605 */
606
607 become_root();
608 ret = pdb_getgrnam(&map, name);
609 unbecome_root();
610
611 if (!ret) {
612 return False;
613 }
614
615 /* BUILTIN groups are looked up elsewhere */
616 if (!sid_check_is_in_our_domain(&map.sid)) {
617 DEBUG(10, ("Found group %s (%s) not in our domain -- "
618 "ignoring.", name, sid_string_dbg(&map.sid)));
619 return False;
620 }
621
622 /* yes it's a mapped group */
623 sid_peek_rid(&map.sid, rid);
624 *type = map.sid_name_use;
625 return True;
626 }
627
628 /*************************************************************
629 Change a password entry in the local passdb backend.
630
631 Assumptions:
632 - always called as root
633 - ignores the account type except when adding a new account
634 - will create/delete the unix account if the relative
635 add/delete user script is configured
636
637 *************************************************************/
638
639 NTSTATUS local_password_change(const char *user_name,
/* [<][>][^][v][top][bottom][index][help] */
640 int local_flags,
641 const char *new_passwd,
642 char **pp_err_str,
643 char **pp_msg_str)
644 {
645 TALLOC_CTX *tosctx;
646 struct samu *sam_pass;
647 uint32_t acb;
648 uint32_t rid;
649 NTSTATUS result;
650 bool user_exists;
651 int ret = -1;
652
653 *pp_err_str = NULL;
654 *pp_msg_str = NULL;
655
656 tosctx = talloc_tos();
657 if (!tosctx) {
658 return NT_STATUS_NO_MEMORY;
659 }
660
661 sam_pass = samu_new(tosctx);
662 if (!sam_pass) {
663 result = NT_STATUS_NO_MEMORY;
664 goto done;
665 }
666
667 /* Get the smb passwd entry for this user */
668 user_exists = pdb_getsampwnam(sam_pass, user_name);
669
670 /* Check delete first, we don't need to do anything else if we
671 * are going to delete the acocunt */
672 if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
673
674 result = pdb_delete_user(tosctx, sam_pass);
675 if (!NT_STATUS_IS_OK(result)) {
676 ret = asprintf(pp_err_str,
677 "Failed to delete entry for user %s.\n",
678 user_name);
679 if (ret < 0) {
680 *pp_err_str = NULL;
681 }
682 result = NT_STATUS_UNSUCCESSFUL;
683 } else {
684 ret = asprintf(pp_msg_str,
685 "Deleted user %s.\n",
686 user_name);
687 if (ret < 0) {
688 *pp_msg_str = NULL;
689 }
690 }
691 goto done;
692 }
693
694 if (user_exists && (local_flags & LOCAL_ADD_USER)) {
695 /* the entry already existed */
696 local_flags &= ~LOCAL_ADD_USER;
697 }
698
699 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
700 ret = asprintf(pp_err_str,
701 "Failed to find entry for user %s.\n",
702 user_name);
703 if (ret < 0) {
704 *pp_err_str = NULL;
705 }
706 result = NT_STATUS_NO_SUCH_USER;
707 goto done;
708 }
709
710 /* First thing add the new user if we are required to do so */
711 if (local_flags & LOCAL_ADD_USER) {
712
713 if (local_flags & LOCAL_TRUST_ACCOUNT) {
714 acb = ACB_WSTRUST;
715 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
716 acb = ACB_DOMTRUST;
717 } else {
718 acb = ACB_NORMAL;
719 }
720
721 result = pdb_create_user(tosctx, user_name, acb, &rid);
722 if (!NT_STATUS_IS_OK(result)) {
723 ret = asprintf(pp_err_str,
724 "Failed to add entry for user %s.\n",
725 user_name);
726 if (ret < 0) {
727 *pp_err_str = NULL;
728 }
729 result = NT_STATUS_UNSUCCESSFUL;
730 goto done;
731 }
732
733 sam_pass = samu_new(tosctx);
734 if (!sam_pass) {
735 result = NT_STATUS_NO_MEMORY;
736 goto done;
737 }
738
739 /* Now get back the smb passwd entry for this new user */
740 user_exists = pdb_getsampwnam(sam_pass, user_name);
741 if (!user_exists) {
742 ret = asprintf(pp_err_str,
743 "Failed to add entry for user %s.\n",
744 user_name);
745 if (ret < 0) {
746 *pp_err_str = NULL;
747 }
748 result = NT_STATUS_UNSUCCESSFUL;
749 goto done;
750 }
751 }
752
753 acb = pdb_get_acct_ctrl(sam_pass);
754
755 /*
756 * We are root - just write the new password
757 * and the valid last change time.
758 */
759 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
760 acb |= ACB_PWNOTREQ;
761 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
762 ret = asprintf(pp_err_str,
763 "Failed to set 'no password required' "
764 "flag for user %s.\n", user_name);
765 if (ret < 0) {
766 *pp_err_str = NULL;
767 }
768 result = NT_STATUS_UNSUCCESSFUL;
769 goto done;
770 }
771 }
772
773 if (local_flags & LOCAL_SET_PASSWORD) {
774 /*
775 * If we're dealing with setting a completely empty user account
776 * ie. One with a password of 'XXXX', but not set disabled (like
777 * an account created from scratch) then if the old password was
778 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
779 * We remove that as we're giving this user their first password
780 * and the decision hasn't really been made to disable them (ie.
781 * don't create them disabled). JRA.
782 */
783 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
784 (acb & ACB_DISABLED)) {
785 acb &= (~ACB_DISABLED);
786 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
787 ret = asprintf(pp_err_str,
788 "Failed to unset 'disabled' "
789 "flag for user %s.\n",
790 user_name);
791 if (ret < 0) {
792 *pp_err_str = NULL;
793 }
794 result = NT_STATUS_UNSUCCESSFUL;
795 goto done;
796 }
797 }
798
799 acb &= (~ACB_PWNOTREQ);
800 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
801 ret = asprintf(pp_err_str,
802 "Failed to unset 'no password required'"
803 " flag for user %s.\n", user_name);
804 if (ret < 0) {
805 *pp_err_str = NULL;
806 }
807 result = NT_STATUS_UNSUCCESSFUL;
808 goto done;
809 }
810
811 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
812 ret = asprintf(pp_err_str,
813 "Failed to set password for "
814 "user %s.\n", user_name);
815 if (ret < 0) {
816 *pp_err_str = NULL;
817 }
818 result = NT_STATUS_UNSUCCESSFUL;
819 goto done;
820 }
821 }
822
823 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
824 acb |= ACB_DISABLED;
825 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
826 ret = asprintf(pp_err_str,
827 "Failed to set 'disabled' flag for "
828 "user %s.\n", user_name);
829 if (ret < 0) {
830 *pp_err_str = NULL;
831 }
832 result = NT_STATUS_UNSUCCESSFUL;
833 goto done;
834 }
835 }
836
837 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
838 acb &= (~ACB_DISABLED);
839 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
840 ret = asprintf(pp_err_str,
841 "Failed to unset 'disabled' flag for "
842 "user %s.\n", user_name);
843 if (ret < 0) {
844 *pp_err_str = NULL;
845 }
846 result = NT_STATUS_UNSUCCESSFUL;
847 goto done;
848 }
849 }
850
851 /* now commit changes if any */
852 result = pdb_update_sam_account(sam_pass);
853 if (!NT_STATUS_IS_OK(result)) {
854 ret = asprintf(pp_err_str,
855 "Failed to modify entry for user %s.\n",
856 user_name);
857 if (ret < 0) {
858 *pp_err_str = NULL;
859 }
860 goto done;
861 }
862
863 if (local_flags & LOCAL_ADD_USER) {
864 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
865 } else if (local_flags & LOCAL_DISABLE_USER) {
866 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
867 } else if (local_flags & LOCAL_ENABLE_USER) {
868 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
869 } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
870 ret = asprintf(pp_msg_str,
871 "User %s password set to none.\n", user_name);
872 }
873
874 if (ret < 0) {
875 *pp_msg_str = NULL;
876 }
877
878 result = NT_STATUS_OK;
879
880 done:
881 TALLOC_FREE(sam_pass);
882 return result;
883 }
884
885 /**********************************************************************
886 Marshall/unmarshall struct samu structs.
887 *********************************************************************/
888
889 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
890 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
891 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
892 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
893 /* nothing changed between V3 and V4 */
894
895 /*********************************************************************
896 *********************************************************************/
897
898 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buflen)
/* [<][>][^][v][top][bottom][index][help] */
899 {
900
901 /* times are stored as 32bit integer
902 take care on system with 64bit wide time_t
903 --SSS */
904 uint32 logon_time,
905 logoff_time,
906 kickoff_time,
907 pass_last_set_time,
908 pass_can_change_time,
909 pass_must_change_time;
910 char *username = NULL;
911 char *domain = NULL;
912 char *nt_username = NULL;
913 char *dir_drive = NULL;
914 char *unknown_str = NULL;
915 char *munged_dial = NULL;
916 char *fullname = NULL;
917 char *homedir = NULL;
918 char *logon_script = NULL;
919 char *profile_path = NULL;
920 char *acct_desc = NULL;
921 char *workstations = NULL;
922 uint32 username_len, domain_len, nt_username_len,
923 dir_drive_len, unknown_str_len, munged_dial_len,
924 fullname_len, homedir_len, logon_script_len,
925 profile_path_len, acct_desc_len, workstations_len;
926
927 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
928 uint16 acct_ctrl, logon_divs;
929 uint16 bad_password_count, logon_count;
930 uint8 *hours = NULL;
931 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
932 uint32 len = 0;
933 uint32 lm_pw_len, nt_pw_len, hourslen;
934 bool ret = True;
935
936 if(sampass == NULL || buf == NULL) {
937 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
938 return False;
939 }
940
941 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
942
943 /* unpack the buffer into variables */
944 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
945 &logon_time, /* d */
946 &logoff_time, /* d */
947 &kickoff_time, /* d */
948 &pass_last_set_time, /* d */
949 &pass_can_change_time, /* d */
950 &pass_must_change_time, /* d */
951 &username_len, &username, /* B */
952 &domain_len, &domain, /* B */
953 &nt_username_len, &nt_username, /* B */
954 &fullname_len, &fullname, /* B */
955 &homedir_len, &homedir, /* B */
956 &dir_drive_len, &dir_drive, /* B */
957 &logon_script_len, &logon_script, /* B */
958 &profile_path_len, &profile_path, /* B */
959 &acct_desc_len, &acct_desc, /* B */
960 &workstations_len, &workstations, /* B */
961 &unknown_str_len, &unknown_str, /* B */
962 &munged_dial_len, &munged_dial, /* B */
963 &user_rid, /* d */
964 &group_rid, /* d */
965 &lm_pw_len, &lm_pw_ptr, /* B */
966 &nt_pw_len, &nt_pw_ptr, /* B */
967 &acct_ctrl, /* w */
968 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
969 &logon_divs, /* w */
970 &hours_len, /* d */
971 &hourslen, &hours, /* B */
972 &bad_password_count, /* w */
973 &logon_count, /* w */
974 &unknown_6); /* d */
975
976 if (len == (uint32) -1) {
977 ret = False;
978 goto done;
979 }
980
981 pdb_set_logon_time(sampass, logon_time, PDB_SET);
982 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
983 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
984 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
985 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
986 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
987
988 pdb_set_username(sampass, username, PDB_SET);
989 pdb_set_domain(sampass, domain, PDB_SET);
990 pdb_set_nt_username(sampass, nt_username, PDB_SET);
991 pdb_set_fullname(sampass, fullname, PDB_SET);
992
993 if (homedir) {
994 pdb_set_homedir(sampass, homedir, PDB_SET);
995 }
996 else {
997 pdb_set_homedir(sampass,
998 talloc_sub_basic(sampass, username, domain,
999 lp_logon_home()),
1000 PDB_DEFAULT);
1001 }
1002
1003 if (dir_drive)
1004 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1005 else {
1006 pdb_set_dir_drive(sampass,
1007 talloc_sub_basic(sampass, username, domain,
1008 lp_logon_drive()),
1009 PDB_DEFAULT);
1010 }
1011
1012 if (logon_script)
1013 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1014 else {
1015 pdb_set_logon_script(sampass,
1016 talloc_sub_basic(sampass, username, domain,
1017 lp_logon_script()),
1018 PDB_DEFAULT);
1019 }
1020
1021 if (profile_path) {
1022 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1023 } else {
1024 pdb_set_profile_path(sampass,
1025 talloc_sub_basic(sampass, username, domain,
1026 lp_logon_path()),
1027 PDB_DEFAULT);
1028 }
1029
1030 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1031 pdb_set_workstations(sampass, workstations, PDB_SET);
1032 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1033
1034 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1035 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1036 ret = False;
1037 goto done;
1038 }
1039 }
1040
1041 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1042 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1043 ret = False;
1044 goto done;
1045 }
1046 }
1047
1048 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1049 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1050 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1051 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1052 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1053 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1054 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1055 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1056 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1057 pdb_set_hours(sampass, hours, PDB_SET);
1058
1059 done:
1060
1061 SAFE_FREE(username);
1062 SAFE_FREE(domain);
1063 SAFE_FREE(nt_username);
1064 SAFE_FREE(fullname);
1065 SAFE_FREE(homedir);
1066 SAFE_FREE(dir_drive);
1067 SAFE_FREE(logon_script);
1068 SAFE_FREE(profile_path);
1069 SAFE_FREE(acct_desc);
1070 SAFE_FREE(workstations);
1071 SAFE_FREE(munged_dial);
1072 SAFE_FREE(unknown_str);
1073 SAFE_FREE(lm_pw_ptr);
1074 SAFE_FREE(nt_pw_ptr);
1075 SAFE_FREE(hours);
1076
1077 return ret;
1078 }
1079
1080 /*********************************************************************
1081 *********************************************************************/
1082
1083 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buflen)
/* [<][>][^][v][top][bottom][index][help] */
1084 {
1085
1086 /* times are stored as 32bit integer
1087 take care on system with 64bit wide time_t
1088 --SSS */
1089 uint32 logon_time,
1090 logoff_time,
1091 kickoff_time,
1092 bad_password_time,
1093 pass_last_set_time,
1094 pass_can_change_time,
1095 pass_must_change_time;
1096 char *username = NULL;
1097 char *domain = NULL;
1098 char *nt_username = NULL;
1099 char *dir_drive = NULL;
1100 char *unknown_str = NULL;
1101 char *munged_dial = NULL;
1102 char *fullname = NULL;
1103 char *homedir = NULL;
1104 char *logon_script = NULL;
1105 char *profile_path = NULL;
1106 char *acct_desc = NULL;
1107 char *workstations = NULL;
1108 uint32 username_len, domain_len, nt_username_len,
1109 dir_drive_len, unknown_str_len, munged_dial_len,
1110 fullname_len, homedir_len, logon_script_len,
1111 profile_path_len, acct_desc_len, workstations_len;
1112
1113 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1114 uint16 acct_ctrl, logon_divs;
1115 uint16 bad_password_count, logon_count;
1116 uint8 *hours = NULL;
1117 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1118 uint32 len = 0;
1119 uint32 lm_pw_len, nt_pw_len, hourslen;
1120 bool ret = True;
1121
1122 if(sampass == NULL || buf == NULL) {
1123 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1124 return False;
1125 }
1126
1127 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1128
1129 /* unpack the buffer into variables */
1130 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1131 &logon_time, /* d */
1132 &logoff_time, /* d */
1133 &kickoff_time, /* d */
1134 /* Change from V0 is addition of bad_password_time field. */
1135 &bad_password_time, /* d */
1136 &pass_last_set_time, /* d */
1137 &pass_can_change_time, /* d */
1138 &pass_must_change_time, /* d */
1139 &username_len, &username, /* B */
1140 &domain_len, &domain, /* B */
1141 &nt_username_len, &nt_username, /* B */
1142 &fullname_len, &fullname, /* B */
1143 &homedir_len, &homedir, /* B */
1144 &dir_drive_len, &dir_drive, /* B */
1145 &logon_script_len, &logon_script, /* B */
1146 &profile_path_len, &profile_path, /* B */
1147 &acct_desc_len, &acct_desc, /* B */
1148 &workstations_len, &workstations, /* B */
1149 &unknown_str_len, &unknown_str, /* B */
1150 &munged_dial_len, &munged_dial, /* B */
1151 &user_rid, /* d */
1152 &group_rid, /* d */
1153 &lm_pw_len, &lm_pw_ptr, /* B */
1154 &nt_pw_len, &nt_pw_ptr, /* B */
1155 &acct_ctrl, /* w */
1156 &remove_me, /* d */
1157 &logon_divs, /* w */
1158 &hours_len, /* d */
1159 &hourslen, &hours, /* B */
1160 &bad_password_count, /* w */
1161 &logon_count, /* w */
1162 &unknown_6); /* d */
1163
1164 if (len == (uint32) -1) {
1165 ret = False;
1166 goto done;
1167 }
1168
1169 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1170 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1171 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1172
1173 /* Change from V0 is addition of bad_password_time field. */
1174 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1175 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1176 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1177 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1178
1179 pdb_set_username(sampass, username, PDB_SET);
1180 pdb_set_domain(sampass, domain, PDB_SET);
1181 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1182 pdb_set_fullname(sampass, fullname, PDB_SET);
1183
1184 if (homedir) {
1185 pdb_set_homedir(sampass, homedir, PDB_SET);
1186 }
1187 else {
1188 pdb_set_homedir(sampass,
1189 talloc_sub_basic(sampass, username, domain,
1190 lp_logon_home()),
1191 PDB_DEFAULT);
1192 }
1193
1194 if (dir_drive)
1195 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1196 else {
1197 pdb_set_dir_drive(sampass,
1198 talloc_sub_basic(sampass, username, domain,
1199 lp_logon_drive()),
1200 PDB_DEFAULT);
1201 }
1202
1203 if (logon_script)
1204 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1205 else {
1206 pdb_set_logon_script(sampass,
1207 talloc_sub_basic(sampass, username, domain,
1208 lp_logon_script()),
1209 PDB_DEFAULT);
1210 }
1211
1212 if (profile_path) {
1213 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1214 } else {
1215 pdb_set_profile_path(sampass,
1216 talloc_sub_basic(sampass, username, domain,
1217 lp_logon_path()),
1218 PDB_DEFAULT);
1219 }
1220
1221 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1222 pdb_set_workstations(sampass, workstations, PDB_SET);
1223 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1224
1225 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1226 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1227 ret = False;
1228 goto done;
1229 }
1230 }
1231
1232 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1233 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1234 ret = False;
1235 goto done;
1236 }
1237 }
1238
1239 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1240
1241 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1242 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1243 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1244 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1245 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1246 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1247 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1248 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1249 pdb_set_hours(sampass, hours, PDB_SET);
1250
1251 done:
1252
1253 SAFE_FREE(username);
1254 SAFE_FREE(domain);
1255 SAFE_FREE(nt_username);
1256 SAFE_FREE(fullname);
1257 SAFE_FREE(homedir);
1258 SAFE_FREE(dir_drive);
1259 SAFE_FREE(logon_script);
1260 SAFE_FREE(profile_path);
1261 SAFE_FREE(acct_desc);
1262 SAFE_FREE(workstations);
1263 SAFE_FREE(munged_dial);
1264 SAFE_FREE(unknown_str);
1265 SAFE_FREE(lm_pw_ptr);
1266 SAFE_FREE(nt_pw_ptr);
1267 SAFE_FREE(hours);
1268
1269 return ret;
1270 }
1271
1272 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
/* [<][>][^][v][top][bottom][index][help] */
1273 {
1274
1275 /* times are stored as 32bit integer
1276 take care on system with 64bit wide time_t
1277 --SSS */
1278 uint32 logon_time,
1279 logoff_time,
1280 kickoff_time,
1281 bad_password_time,
1282 pass_last_set_time,
1283 pass_can_change_time,
1284 pass_must_change_time;
1285 char *username = NULL;
1286 char *domain = NULL;
1287 char *nt_username = NULL;
1288 char *dir_drive = NULL;
1289 char *unknown_str = NULL;
1290 char *munged_dial = NULL;
1291 char *fullname = NULL;
1292 char *homedir = NULL;
1293 char *logon_script = NULL;
1294 char *profile_path = NULL;
1295 char *acct_desc = NULL;
1296 char *workstations = NULL;
1297 uint32 username_len, domain_len, nt_username_len,
1298 dir_drive_len, unknown_str_len, munged_dial_len,
1299 fullname_len, homedir_len, logon_script_len,
1300 profile_path_len, acct_desc_len, workstations_len;
1301
1302 uint32 user_rid, group_rid, hours_len, unknown_6;
1303 uint16 acct_ctrl, logon_divs;
1304 uint16 bad_password_count, logon_count;
1305 uint8 *hours = NULL;
1306 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1307 uint32 len = 0;
1308 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1309 uint32 pwHistLen = 0;
1310 bool ret = True;
1311 fstring tmp_string;
1312 bool expand_explicit = lp_passdb_expand_explicit();
1313
1314 if(sampass == NULL || buf == NULL) {
1315 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1316 return False;
1317 }
1318
1319 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1320
1321 /* unpack the buffer into variables */
1322 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1323 &logon_time, /* d */
1324 &logoff_time, /* d */
1325 &kickoff_time, /* d */
1326 &bad_password_time, /* d */
1327 &pass_last_set_time, /* d */
1328 &pass_can_change_time, /* d */
1329 &pass_must_change_time, /* d */
1330 &username_len, &username, /* B */
1331 &domain_len, &domain, /* B */
1332 &nt_username_len, &nt_username, /* B */
1333 &fullname_len, &fullname, /* B */
1334 &homedir_len, &homedir, /* B */
1335 &dir_drive_len, &dir_drive, /* B */
1336 &logon_script_len, &logon_script, /* B */
1337 &profile_path_len, &profile_path, /* B */
1338 &acct_desc_len, &acct_desc, /* B */
1339 &workstations_len, &workstations, /* B */
1340 &unknown_str_len, &unknown_str, /* B */
1341 &munged_dial_len, &munged_dial, /* B */
1342 &user_rid, /* d */
1343 &group_rid, /* d */
1344 &lm_pw_len, &lm_pw_ptr, /* B */
1345 &nt_pw_len, &nt_pw_ptr, /* B */
1346 /* Change from V1 is addition of password history field. */
1347 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1348 &acct_ctrl, /* w */
1349 /* Also "remove_me" field was removed. */
1350 &logon_divs, /* w */
1351 &hours_len, /* d */
1352 &hourslen, &hours, /* B */
1353 &bad_password_count, /* w */
1354 &logon_count, /* w */
1355 &unknown_6); /* d */
1356
1357 if (len == (uint32) -1) {
1358 ret = False;
1359 goto done;
1360 }
1361
1362 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1363 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1364 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1365 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1366 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1367 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1368 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1369
1370 pdb_set_username(sampass, username, PDB_SET);
1371 pdb_set_domain(sampass, domain, PDB_SET);
1372 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1373 pdb_set_fullname(sampass, fullname, PDB_SET);
1374
1375 if (homedir) {
1376 fstrcpy( tmp_string, homedir );
1377 if (expand_explicit) {
1378 standard_sub_basic( username, domain, tmp_string,
1379 sizeof(tmp_string) );
1380 }
1381 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1382 }
1383 else {
1384 pdb_set_homedir(sampass,
1385 talloc_sub_basic(sampass, username, domain,
1386 lp_logon_home()),
1387 PDB_DEFAULT);
1388 }
1389
1390 if (dir_drive)
1391 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1392 else
1393 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1394
1395 if (logon_script) {
1396 fstrcpy( tmp_string, logon_script );
1397 if (expand_explicit) {
1398 standard_sub_basic( username, domain, tmp_string,
1399 sizeof(tmp_string) );
1400 }
1401 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1402 }
1403 else {
1404 pdb_set_logon_script(sampass,
1405 talloc_sub_basic(sampass, username, domain,
1406 lp_logon_script()),
1407 PDB_DEFAULT);
1408 }
1409
1410 if (profile_path) {
1411 fstrcpy( tmp_string, profile_path );
1412 if (expand_explicit) {
1413 standard_sub_basic( username, domain, tmp_string,
1414 sizeof(tmp_string) );
1415 }
1416 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1417 }
1418 else {
1419 pdb_set_profile_path(sampass,
1420 talloc_sub_basic(sampass, username, domain,
1421 lp_logon_path()),
1422 PDB_DEFAULT);
1423 }
1424
1425 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1426 pdb_set_workstations(sampass, workstations, PDB_SET);
1427 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1428
1429 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1430 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1431 ret = False;
1432 goto done;
1433 }
1434 }
1435
1436 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1437 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1438 ret = False;
1439 goto done;
1440 }
1441 }
1442
1443 /* Change from V1 is addition of password history field. */
1444 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1445 if (pwHistLen) {
1446 uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN);
1447 if (!pw_hist) {
1448 ret = False;
1449 goto done;
1450 }
1451 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1452 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1453 int i;
1454 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1455 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1456 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1457 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1458 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1459 PW_HISTORY_ENTRY_LEN);
1460 }
1461 }
1462 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1463 SAFE_FREE(pw_hist);
1464 ret = False;
1465 goto done;
1466 }
1467 SAFE_FREE(pw_hist);
1468 } else {
1469 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1470 }
1471
1472 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1473 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1474 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1475 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1476 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1477 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1478 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1479 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1480 pdb_set_hours(sampass, hours, PDB_SET);
1481
1482 done:
1483
1484 SAFE_FREE(username);
1485 SAFE_FREE(domain);
1486 SAFE_FREE(nt_username);
1487 SAFE_FREE(fullname);
1488 SAFE_FREE(homedir);
1489 SAFE_FREE(dir_drive);
1490 SAFE_FREE(logon_script);
1491 SAFE_FREE(profile_path);
1492 SAFE_FREE(acct_desc);
1493 SAFE_FREE(workstations);
1494 SAFE_FREE(munged_dial);
1495 SAFE_FREE(unknown_str);
1496 SAFE_FREE(lm_pw_ptr);
1497 SAFE_FREE(nt_pw_ptr);
1498 SAFE_FREE(nt_pw_hist_ptr);
1499 SAFE_FREE(hours);
1500
1501 return ret;
1502 }
1503
1504 /*********************************************************************
1505 *********************************************************************/
1506
1507 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
/* [<][>][^][v][top][bottom][index][help] */
1508 {
1509
1510 /* times are stored as 32bit integer
1511 take care on system with 64bit wide time_t
1512 --SSS */
1513 uint32 logon_time,
1514 logoff_time,
1515 kickoff_time,
1516 bad_password_time,
1517 pass_last_set_time,
1518 pass_can_change_time,
1519 pass_must_change_time;
1520 char *username = NULL;
1521 char *domain = NULL;
1522 char *nt_username = NULL;
1523 char *dir_drive = NULL;
1524 char *unknown_str = NULL;
1525 char *munged_dial = NULL;
1526 char *fullname = NULL;
1527 char *homedir = NULL;
1528 char *logon_script = NULL;
1529 char *profile_path = NULL;
1530 char *acct_desc = NULL;
1531 char *workstations = NULL;
1532 uint32 username_len, domain_len, nt_username_len,
1533 dir_drive_len, unknown_str_len, munged_dial_len,
1534 fullname_len, homedir_len, logon_script_len,
1535 profile_path_len, acct_desc_len, workstations_len;
1536
1537 uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1538 uint16 logon_divs;
1539 uint16 bad_password_count, logon_count;
1540 uint8 *hours = NULL;
1541 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1542 uint32 len = 0;
1543 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1544 uint32 pwHistLen = 0;
1545 bool ret = True;
1546 fstring tmp_string;
1547 bool expand_explicit = lp_passdb_expand_explicit();
1548
1549 if(sampass == NULL || buf == NULL) {
1550 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1551 return False;
1552 }
1553
1554 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1555
1556 /* unpack the buffer into variables */
1557 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1558 &logon_time, /* d */
1559 &logoff_time, /* d */
1560 &kickoff_time, /* d */
1561 &bad_password_time, /* d */
1562 &pass_last_set_time, /* d */
1563 &pass_can_change_time, /* d */
1564 &pass_must_change_time, /* d */
1565 &username_len, &username, /* B */
1566 &domain_len, &domain, /* B */
1567 &nt_username_len, &nt_username, /* B */
1568 &fullname_len, &fullname, /* B */
1569 &homedir_len, &homedir, /* B */
1570 &dir_drive_len, &dir_drive, /* B */
1571 &logon_script_len, &logon_script, /* B */
1572 &profile_path_len, &profile_path, /* B */
1573 &acct_desc_len, &acct_desc, /* B */
1574 &workstations_len, &workstations, /* B */
1575 &unknown_str_len, &unknown_str, /* B */
1576 &munged_dial_len, &munged_dial, /* B */
1577 &user_rid, /* d */
1578 &group_rid, /* d */
1579 &lm_pw_len, &lm_pw_ptr, /* B */
1580 &nt_pw_len, &nt_pw_ptr, /* B */
1581 /* Change from V1 is addition of password history field. */
1582 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1583 /* Change from V2 is the uint32 acb_mask */
1584 &acct_ctrl, /* d */
1585 /* Also "remove_me" field was removed. */
1586 &logon_divs, /* w */
1587 &hours_len, /* d */
1588 &hourslen, &hours, /* B */
1589 &bad_password_count, /* w */
1590 &logon_count, /* w */
1591 &unknown_6); /* d */
1592
1593 if (len == (uint32) -1) {
1594 ret = False;
1595 goto done;
1596 }
1597
1598 pdb_set_logon_time(sampass, convert_uint32_to_time_t(logon_time), PDB_SET);
1599 pdb_set_logoff_time(sampass, convert_uint32_to_time_t(logoff_time), PDB_SET);
1600 pdb_set_kickoff_time(sampass, convert_uint32_to_time_t(kickoff_time), PDB_SET);
1601 pdb_set_bad_password_time(sampass, convert_uint32_to_time_t(bad_password_time), PDB_SET);
1602 pdb_set_pass_can_change_time(sampass, convert_uint32_to_time_t(pass_can_change_time), PDB_SET);
1603 pdb_set_pass_must_change_time(sampass, convert_uint32_to_time_t(pass_must_change_time), PDB_SET);
1604 pdb_set_pass_last_set_time(sampass, convert_uint32_to_time_t(pass_last_set_time), PDB_SET);
1605
1606 pdb_set_username(sampass, username, PDB_SET);
1607 pdb_set_domain(sampass, domain, PDB_SET);
1608 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1609 pdb_set_fullname(sampass, fullname, PDB_SET);
1610
1611 if (homedir) {
1612 fstrcpy( tmp_string, homedir );
1613 if (expand_explicit) {
1614 standard_sub_basic( username, domain, tmp_string,
1615 sizeof(tmp_string) );
1616 }
1617 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1618 }
1619 else {
1620 pdb_set_homedir(sampass,
1621 talloc_sub_basic(sampass, username, domain,
1622 lp_logon_home()),
1623 PDB_DEFAULT);
1624 }
1625
1626 if (dir_drive)
1627 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1628 else
1629 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1630
1631 if (logon_script) {
1632 fstrcpy( tmp_string, logon_script );
1633 if (expand_explicit) {
1634 standard_sub_basic( username, domain, tmp_string,
1635 sizeof(tmp_string) );
1636 }
1637 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1638 }
1639 else {
1640 pdb_set_logon_script(sampass,
1641 talloc_sub_basic(sampass, username, domain,
1642 lp_logon_script()),
1643 PDB_DEFAULT);
1644 }
1645
1646 if (profile_path) {
1647 fstrcpy( tmp_string, profile_path );
1648 if (expand_explicit) {
1649 standard_sub_basic( username, domain, tmp_string,
1650 sizeof(tmp_string) );
1651 }
1652 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1653 }
1654 else {
1655 pdb_set_profile_path(sampass,
1656 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1657 PDB_DEFAULT);
1658 }
1659
1660 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1661 pdb_set_workstations(sampass, workstations, PDB_SET);
1662 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1663
1664 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1665 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1666 ret = False;
1667 goto done;
1668 }
1669 }
1670
1671 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1672 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1673 ret = False;
1674 goto done;
1675 }
1676 }
1677
1678 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1679 if (pwHistLen) {
1680 uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1681 if (!pw_hist) {
1682 ret = False;
1683 goto done;
1684 }
1685 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1686 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1687 int i;
1688 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1689 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1690 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1691 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1692 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1693 PW_HISTORY_ENTRY_LEN);
1694 }
1695 }
1696 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1697 SAFE_FREE(pw_hist);
1698 ret = False;
1699 goto done;
1700 }
1701 SAFE_FREE(pw_hist);
1702 } else {
1703 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1704 }
1705
1706 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1707 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1708 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1709 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1710 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1711 /* Change from V2 is the uint32 acct_ctrl */
1712 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1713 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1714 pdb_set_hours(sampass, hours, PDB_SET);
1715
1716 done:
1717
1718 SAFE_FREE(username);
1719 SAFE_FREE(domain);
1720 SAFE_FREE(nt_username);
1721 SAFE_FREE(fullname);
1722 SAFE_FREE(homedir);
1723 SAFE_FREE(dir_drive);
1724 SAFE_FREE(logon_script);
1725 SAFE_FREE(profile_path);
1726 SAFE_FREE(acct_desc);
1727 SAFE_FREE(workstations);
1728 SAFE_FREE(munged_dial);
1729 SAFE_FREE(unknown_str);
1730 SAFE_FREE(lm_pw_ptr);
1731 SAFE_FREE(nt_pw_ptr);
1732 SAFE_FREE(nt_pw_hist_ptr);
1733 SAFE_FREE(hours);
1734
1735 return ret;
1736 }
1737
1738 /*********************************************************************
1739 *********************************************************************/
1740
1741 static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool size_only)
/* [<][>][^][v][top][bottom][index][help] */
1742 {
1743 size_t len, buflen;
1744
1745 /* times are stored as 32bit integer
1746 take care on system with 64bit wide time_t
1747 --SSS */
1748 uint32 logon_time,
1749 logoff_time,
1750 kickoff_time,
1751 bad_password_time,
1752 pass_last_set_time,
1753 pass_can_change_time,
1754 pass_must_change_time;
1755
1756 uint32 user_rid, group_rid;
1757
1758 const char *username;
1759 const char *domain;
1760 const char *nt_username;
1761 const char *dir_drive;
1762 const char *unknown_str;
1763 const char *munged_dial;
1764 const char *fullname;
1765 const char *homedir;
1766 const char *logon_script;
1767 const char *profile_path;
1768 const char *acct_desc;
1769 const char *workstations;
1770 uint32 username_len, domain_len, nt_username_len,
1771 dir_drive_len, unknown_str_len, munged_dial_len,
1772 fullname_len, homedir_len, logon_script_len,
1773 profile_path_len, acct_desc_len, workstations_len;
1774
1775 const uint8 *lm_pw;
1776 const uint8 *nt_pw;
1777 const uint8 *nt_pw_hist;
1778 uint32 lm_pw_len = 16;
1779 uint32 nt_pw_len = 16;
1780 uint32 nt_pw_hist_len;
1781 uint32 pwHistLen = 0;
1782
1783 *buf = NULL;
1784 buflen = 0;
1785
1786 logon_time = convert_time_t_to_uint32(pdb_get_logon_time(sampass));
1787 logoff_time = convert_time_t_to_uint32(pdb_get_logoff_time(sampass));
1788 kickoff_time = convert_time_t_to_uint32(pdb_get_kickoff_time(sampass));
1789 bad_password_time = convert_time_t_to_uint32(pdb_get_bad_password_time(sampass));
1790 pass_can_change_time = convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass));
1791 pass_must_change_time = convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass));
1792 pass_last_set_time = convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass));
1793
1794 user_rid = pdb_get_user_rid(sampass);
1795 group_rid = pdb_get_group_rid(sampass);
1796
1797 username = pdb_get_username(sampass);
1798 if (username) {
1799 username_len = strlen(username) +1;
1800 } else {
1801 username_len = 0;
1802 }
1803
1804 domain = pdb_get_domain(sampass);
1805 if (domain) {
1806 domain_len = strlen(domain) +1;
1807 } else {
1808 domain_len = 0;
1809 }
1810
1811 nt_username = pdb_get_nt_username(sampass);
1812 if (nt_username) {
1813 nt_username_len = strlen(nt_username) +1;
1814 } else {
1815 nt_username_len = 0;
1816 }
1817
1818 fullname = pdb_get_fullname(sampass);
1819 if (fullname) {
1820 fullname_len = strlen(fullname) +1;
1821 } else {
1822 fullname_len = 0;
1823 }
1824
1825 /*
1826 * Only updates fields which have been set (not defaults from smb.conf)
1827 */
1828
1829 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1830 dir_drive = pdb_get_dir_drive(sampass);
1831 } else {
1832 dir_drive = NULL;
1833 }
1834 if (dir_drive) {
1835 dir_drive_len = strlen(dir_drive) +1;
1836 } else {
1837 dir_drive_len = 0;
1838 }
1839
1840 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1841 homedir = pdb_get_homedir(sampass);
1842 } else {
1843 homedir = NULL;
1844 }
1845 if (homedir) {
1846 homedir_len = strlen(homedir) +1;
1847 } else {
1848 homedir_len = 0;
1849 }
1850
1851 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1852 logon_script = pdb_get_logon_script(sampass);
1853 } else {
1854 logon_script = NULL;
1855 }
1856 if (logon_script) {
1857 logon_script_len = strlen(logon_script) +1;
1858 } else {
1859 logon_script_len = 0;
1860 }
1861
1862 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1863 profile_path = pdb_get_profile_path(sampass);
1864 } else {
1865 profile_path = NULL;
1866 }
1867 if (profile_path) {
1868 profile_path_len = strlen(profile_path) +1;
1869 } else {
1870 profile_path_len = 0;
1871 }
1872
1873 lm_pw = pdb_get_lanman_passwd(sampass);
1874 if (!lm_pw) {
1875 lm_pw_len = 0;
1876 }
1877
1878 nt_pw = pdb_get_nt_passwd(sampass);
1879 if (!nt_pw) {
1880 nt_pw_len = 0;
1881 }
1882
1883 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1884 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1885 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1886 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1887 } else {
1888 nt_pw_hist_len = 0;
1889 }
1890
1891 acct_desc = pdb_get_acct_desc(sampass);
1892 if (acct_desc) {
1893 acct_desc_len = strlen(acct_desc) +1;
1894 } else {
1895 acct_desc_len = 0;
1896 }
1897
1898 workstations = pdb_get_workstations(sampass);
1899 if (workstations) {
1900 workstations_len = strlen(workstations) +1;
1901 } else {
1902 workstations_len = 0;
1903 }
1904
1905 unknown_str = NULL;
1906 unknown_str_len = 0;
1907
1908 munged_dial = pdb_get_munged_dial(sampass);
1909 if (munged_dial) {
1910 munged_dial_len = strlen(munged_dial) +1;
1911 } else {
1912 munged_dial_len = 0;
1913 }
1914
1915 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1916
1917 /* one time to get the size needed */
1918 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3,
1919 logon_time, /* d */
1920 logoff_time, /* d */
1921 kickoff_time, /* d */
1922 bad_password_time, /* d */
1923 pass_last_set_time, /* d */
1924 pass_can_change_time, /* d */
1925 pass_must_change_time, /* d */
1926 username_len, username, /* B */
1927 domain_len, domain, /* B */
1928 nt_username_len, nt_username, /* B */
1929 fullname_len, fullname, /* B */
1930 homedir_len, homedir, /* B */
1931 dir_drive_len, dir_drive, /* B */
1932 logon_script_len, logon_script, /* B */
1933 profile_path_len, profile_path, /* B */
1934 acct_desc_len, acct_desc, /* B */
1935 workstations_len, workstations, /* B */
1936 unknown_str_len, unknown_str, /* B */
1937 munged_dial_len, munged_dial, /* B */
1938 user_rid, /* d */
1939 group_rid, /* d */
1940 lm_pw_len, lm_pw, /* B */
1941 nt_pw_len, nt_pw, /* B */
1942 nt_pw_hist_len, nt_pw_hist, /* B */
1943 pdb_get_acct_ctrl(sampass), /* d */
1944 pdb_get_logon_divs(sampass), /* w */
1945 pdb_get_hours_len(sampass), /* d */
1946 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1947 pdb_get_bad_password_count(sampass), /* w */
1948 pdb_get_logon_count(sampass), /* w */
1949 pdb_get_unknown_6(sampass)); /* d */
1950
1951 if (size_only) {
1952 return buflen;
1953 }
1954
1955 /* malloc the space needed */
1956 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
1957 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1958 return (-1);
1959 }
1960
1961 /* now for the real call to tdb_pack() */
1962 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
1963 logon_time, /* d */
1964 logoff_time, /* d */
1965 kickoff_time, /* d */
1966 bad_password_time, /* d */
1967 pass_last_set_time, /* d */
1968 pass_can_change_time, /* d */
1969 pass_must_change_time, /* d */
1970 username_len, username, /* B */
1971 domain_len, domain, /* B */
1972 nt_username_len, nt_username, /* B */
1973 fullname_len, fullname, /* B */
1974 homedir_len, homedir, /* B */
1975 dir_drive_len, dir_drive, /* B */
1976 logon_script_len, logon_script, /* B */
1977 profile_path_len, profile_path, /* B */
1978 acct_desc_len, acct_desc, /* B */
1979 workstations_len, workstations, /* B */
1980 unknown_str_len, unknown_str, /* B */
1981 munged_dial_len, munged_dial, /* B */
1982 user_rid, /* d */
1983 group_rid, /* d */
1984 lm_pw_len, lm_pw, /* B */
1985 nt_pw_len, nt_pw, /* B */
1986 nt_pw_hist_len, nt_pw_hist, /* B */
1987 pdb_get_acct_ctrl(sampass), /* d */
1988 pdb_get_logon_divs(sampass), /* w */
1989 pdb_get_hours_len(sampass), /* d */
1990 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1991 pdb_get_bad_password_count(sampass), /* w */
1992 pdb_get_logon_count(sampass), /* w */
1993 pdb_get_unknown_6(sampass)); /* d */
1994
1995 /* check to make sure we got it correct */
1996 if (buflen != len) {
1997 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1998 (unsigned long)buflen, (unsigned long)len));
1999 /* error */
2000 SAFE_FREE (*buf);
2001 return (-1);
2002 }
2003
2004 return (buflen);
2005 }
2006
2007 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8 *buf, uint32 buflen)
/* [<][>][^][v][top][bottom][index][help] */
2008 {
2009 /* nothing changed between V3 and V4 */
2010 return init_samu_from_buffer_v3(sampass, buf, buflen);
2011 }
2012
2013 static uint32 init_buffer_from_samu_v4(uint8 **buf, struct samu *sampass, bool size_only)
/* [<][>][^][v][top][bottom][index][help] */
2014 {
2015 /* nothing changed between V3 and V4 */
2016 return init_buffer_from_samu_v3(buf, sampass, size_only);
2017 }
2018
2019 /**********************************************************************
2020 Intialize a struct samu struct from a BYTE buffer of size len
2021 *********************************************************************/
2022
2023 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
/* [<][>][^][v][top][bottom][index][help] */
2024 uint8 *buf, uint32 buflen)
2025 {
2026 switch (level) {
2027 case SAMU_BUFFER_V0:
2028 return init_samu_from_buffer_v0(sampass, buf, buflen);
2029 case SAMU_BUFFER_V1:
2030 return init_samu_from_buffer_v1(sampass, buf, buflen);
2031 case SAMU_BUFFER_V2:
2032 return init_samu_from_buffer_v2(sampass, buf, buflen);
2033 case SAMU_BUFFER_V3:
2034 return init_samu_from_buffer_v3(sampass, buf, buflen);
2035 case SAMU_BUFFER_V4:
2036 return init_samu_from_buffer_v4(sampass, buf, buflen);
2037 }
2038
2039 return false;
2040 }
2041
2042 /**********************************************************************
2043 Intialize a BYTE buffer from a struct samu struct
2044 *********************************************************************/
2045
2046 uint32 init_buffer_from_samu (uint8 **buf, struct samu *sampass, bool size_only)
/* [<][>][^][v][top][bottom][index][help] */
2047 {
2048 return init_buffer_from_samu_v4(buf, sampass, size_only);
2049 }
2050
2051 /*********************************************************************
2052 *********************************************************************/
2053
2054 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
/* [<][>][^][v][top][bottom][index][help] */
2055 {
2056 uint8 *buf = NULL;
2057 int len;
2058
2059 len = init_buffer_from_samu(&buf, src, False);
2060 if (len == -1 || !buf) {
2061 SAFE_FREE(buf);
2062 return False;
2063 }
2064
2065 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2066 free(buf);
2067 return False;
2068 }
2069
2070 dst->methods = src->methods;
2071
2072 if ( src->unix_pw ) {
2073 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2074 if (!dst->unix_pw) {
2075 free(buf);
2076 return False;
2077 }
2078 }
2079
2080 free(buf);
2081 return True;
2082 }
2083
2084 /*********************************************************************
2085 Update the bad password count checking the AP_RESET_COUNT_TIME
2086 *********************************************************************/
2087
2088 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
/* [<][>][^][v][top][bottom][index][help] */
2089 {
2090 time_t LastBadPassword;
2091 uint16 BadPasswordCount;
2092 uint32 resettime;
2093 bool res;
2094
2095 BadPasswordCount = pdb_get_bad_password_count(sampass);
2096 if (!BadPasswordCount) {
2097 DEBUG(9, ("No bad password attempts.\n"));
2098 return True;
2099 }
2100
2101 become_root();
2102 res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime);
2103 unbecome_root();
2104
2105 if (!res) {
2106 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2107 return False;
2108 }
2109
2110 /* First, check if there is a reset time to compare */
2111 if ((resettime == (uint32) -1) || (resettime == 0)) {
2112 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2113 return True;
2114 }
2115
2116 LastBadPassword = pdb_get_bad_password_time(sampass);
2117 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2118 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2119 if (time(NULL) > (LastBadPassword + convert_uint32_to_time_t(resettime)*60)){
2120 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2121 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2122 if (updated) {
2123 *updated = True;
2124 }
2125 }
2126
2127 return True;
2128 }
2129
2130 /*********************************************************************
2131 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2132 *********************************************************************/
2133
2134 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
/* [<][>][^][v][top][bottom][index][help] */
2135 {
2136 uint32 duration;
2137 time_t LastBadPassword;
2138 bool res;
2139
2140 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2141 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2142 pdb_get_username(sampass)));
2143 return True;
2144 }
2145
2146 become_root();
2147 res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration);
2148 unbecome_root();
2149
2150 if (!res) {
2151 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2152 return False;
2153 }
2154
2155 /* First, check if there is a duration to compare */
2156 if ((duration == (uint32) -1) || (duration == 0)) {
2157 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2158 return True;
2159 }
2160
2161 LastBadPassword = pdb_get_bad_password_time(sampass);
2162 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2163 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2164
2165 if (LastBadPassword == (time_t)0) {
2166 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2167 "administratively locked out with no bad password "
2168 "time. Leaving locked out.\n",
2169 pdb_get_username(sampass) ));
2170 return True;
2171 }
2172
2173 if ((time(NULL) > (LastBadPassword + convert_uint32_to_time_t(duration) * 60))) {
2174 pdb_set_acct_ctrl(sampass,
2175 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2176 PDB_CHANGED);
2177 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2178 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2179 if (updated) {
2180 *updated = True;
2181 }
2182 }
2183
2184 return True;
2185 }
2186
2187 /*********************************************************************
2188 Increment the bad_password_count
2189 *********************************************************************/
2190
2191 bool pdb_increment_bad_password_count(struct samu *sampass)
/* [<][>][^][v][top][bottom][index][help] */
2192 {
2193 uint32 account_policy_lockout;
2194 bool autolock_updated = False, badpw_updated = False;
2195 bool ret;
2196
2197 /* Retrieve the account lockout policy */
2198 become_root();
2199 ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2200 unbecome_root();
2201 if ( !ret ) {
2202 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2203 return False;
2204 }
2205
2206 /* If there is no policy, we don't need to continue checking */
2207 if (!account_policy_lockout) {
2208 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2209 return True;
2210 }
2211
2212 /* Check if the autolock needs to be cleared */
2213 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2214 return False;
2215
2216 /* Check if the badpw count needs to be reset */
2217 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2218 return False;
2219
2220 /*
2221 Ok, now we can assume that any resetting that needs to be
2222 done has been done, and just get on with incrementing
2223 and autolocking if necessary
2224 */
2225
2226 pdb_set_bad_password_count(sampass,
2227 pdb_get_bad_password_count(sampass)+1,
2228 PDB_CHANGED);
2229 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2230
2231
2232 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2233 return True;
2234
2235 if (!pdb_set_acct_ctrl(sampass,
2236 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2237 PDB_CHANGED)) {
2238 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2239 return False;
2240 }
2241
2242 return True;
2243 }
2244
2245 bool is_dc_trusted_domain_situation(const char *domain_name)
/* [<][>][^][v][top][bottom][index][help] */
2246 {
2247 return IS_DC && !strequal(domain_name, lp_workgroup());
2248 }
2249
2250 /*******************************************************************
2251 Wrapper around retrieving the clear text trust account password.
2252 appropriate account name is stored in account_name.
2253 Caller must free password, but not account_name.
2254 *******************************************************************/
2255
2256 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
/* [<][>][^][v][top][bottom][index][help] */
2257 const char **account_name, uint32 *channel)
2258 {
2259 char *pwd;
2260 time_t last_set_time;
2261
2262 /* if we are a DC and this is not our domain, then lookup an account
2263 * for the domain trust */
2264
2265 if (is_dc_trusted_domain_situation(domain)) {
2266 if (!lp_allow_trusted_domains()) {
2267 return false;
2268 }
2269
2270 if (!pdb_get_trusteddom_pw(domain, ret_pwd, NULL,
2271 &last_set_time))
2272 {
2273 DEBUG(0, ("get_trust_pw: could not fetch trust "
2274 "account password for trusted domain %s\n",
2275 domain));
2276 return false;
2277 }
2278
2279 if (channel != NULL) {
2280 *channel = SEC_CHAN_DOMAIN;
2281 }
2282
2283 if (account_name != NULL) {
2284 *account_name = lp_workgroup();
2285 }
2286
2287 return true;
2288 }
2289
2290 /*
2291 * Since we can only be member of one single domain, we are now
2292 * in a member situation:
2293 *
2294 * - Either we are a DC (selfjoined) and the domain is our
2295 * own domain.
2296 * - Or we are on a member and the domain is our own or some
2297 * other (potentially trusted) domain.
2298 *
2299 * In both cases, we can only get the machine account password
2300 * for our own domain to connect to our own dc. (For a member,
2301 * request to trusted domains are performed through our dc.)
2302 *
2303 * So we simply use our own domain name to retrieve the
2304 * machine account passowrd and ignore the request domain here.
2305 */
2306
2307 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2308
2309 if (pwd != NULL) {
2310 *ret_pwd = pwd;
2311 if (account_name != NULL) {
2312 *account_name = global_myname();
2313 }
2314
2315 return true;
2316 }
2317
2318 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2319 "account password for domain %s\n", domain));
2320 return false;
2321 }
2322
2323 /*******************************************************************
2324 Wrapper around retrieving the trust account password.
2325 appropriate account name is stored in account_name.
2326 *******************************************************************/
2327
2328 bool get_trust_pw_hash(const char *domain, uint8 ret_pwd[16],
/* [<][>][^][v][top][bottom][index][help] */
2329 const char **account_name, uint32 *channel)
2330 {
2331 char *pwd = NULL;
2332 time_t last_set_time;
2333
2334 if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
2335 E_md4hash(pwd, ret_pwd);
2336 SAFE_FREE(pwd);
2337 return true;
2338 } else if (is_dc_trusted_domain_situation(domain)) {
2339 return false;
2340 }
2341
2342 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2343
2344 if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
2345 &last_set_time,
2346 channel))
2347 {
2348 if (account_name != NULL) {
2349 *account_name = global_myname();
2350 }
2351
2352 return true;
2353 }
2354
2355 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2356 "password for domain %s\n", domain));
2357 return False;
2358 }
2359
2360 struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
2361 struct samu *pw)
2362 {
2363 struct samr_LogonHours hours;
2364 const int units_per_week = 168;
2365
2366 ZERO_STRUCT(hours);
2367 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2368 if (!hours.bits) {
2369 return hours;
2370 }
2371
2372 hours.units_per_week = units_per_week;
2373 memset(hours.bits, 0xFF, units_per_week);
2374
2375 if (pdb_get_hours(pw)) {
2376 memcpy(hours.bits, pdb_get_hours(pw),
2377 MIN(pdb_get_hours_len(pw), units_per_week));
2378 }
2379
2380 return hours;
2381 }
2382
2383 /****************************************************************
2384 ****************************************************************/
2385
2386 NTSTATUS smb_create_user(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
2387 uint32_t acct_flags,
2388 const char *account,
2389 struct passwd **passwd_p)
2390 {
2391 struct passwd *passwd;
2392 char *add_script = NULL;
2393
2394 passwd = Get_Pwnam_alloc(mem_ctx, account);
2395 if (passwd) {
2396 *passwd_p = passwd;
2397 return NT_STATUS_OK;
2398 }
2399
2400 /* Create appropriate user */
2401 if (acct_flags & ACB_NORMAL) {
2402 add_script = talloc_strdup(mem_ctx, lp_adduser_script());
2403 } else if ( (acct_flags & ACB_WSTRUST) ||
2404 (acct_flags & ACB_SVRTRUST) ||
2405 (acct_flags & ACB_DOMTRUST) ) {
2406 add_script = talloc_strdup(mem_ctx, lp_addmachine_script());
2407 } else {
2408 DEBUG(1, ("Unknown user type: %s\n",
2409 pdb_encode_acct_ctrl(acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN)));
2410 return NT_STATUS_UNSUCCESSFUL;
2411 }
2412
2413 if (!add_script) {
2414 return NT_STATUS_NO_MEMORY;
2415 }
2416
2417 if (*add_script) {
2418 int add_ret;
2419 add_script = talloc_all_string_sub(mem_ctx, add_script,
2420 "%u", account);
2421 if (!add_script) {
2422 return NT_STATUS_NO_MEMORY;
2423 }
2424 add_ret = smbrun(add_script, NULL);
2425 DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' "
2426 "gave %d\n", add_script, add_ret));
2427 if (add_ret == 0) {
2428 smb_nscd_flush_user_cache();
2429 }
2430 }
2431
2432 /* try and find the possible unix account again */
2433 passwd = Get_Pwnam_alloc(mem_ctx, account);
2434 if (!passwd) {
2435 return NT_STATUS_NO_SUCH_USER;
2436 }
2437
2438 *passwd_p = passwd;
2439
2440 return NT_STATUS_OK;
2441 }