source: trunk/server/source3/passdb/passdb.c@ 421

Last change on this file since 421 was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

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