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