source: branches/samba-3.5.x/source3/passdb/passdb.c@ 793

Last change on this file since 793 was 429, checked in by Silvan Scherrer, 15 years ago

Samba 3.5.x: trunk update to 3.5.2

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