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

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

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