source: vendor/current/source3/passdb/passdb.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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