source: branches/samba-3.3.x/source/passdb/passdb.c@ 271

Last change on this file since 271 was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

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