Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Password and authentication handling
4 : Copyright (C) Andrew Tridgell 1992-2000
5 : Copyright (C) Luke Kenneth Casson Leighton 1996-2000
6 : Copyright (C) Andrew Bartlett 2001-2003
7 : Copyright (C) Gerald Carter 2003
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "auth.h"
25 : #include "../libcli/auth/libcli_auth.h"
26 : #include "passdb.h"
27 : #include "lib/util/memcache.h"
28 :
29 : #undef DBGC_CLASS
30 : #define DBGC_CLASS DBGC_AUTH
31 :
32 : /****************************************************************************
33 : Do a specific test for an smb password being correct, given a smb_password and
34 : the lanman and NT responses.
35 : ****************************************************************************/
36 :
37 494 : static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
38 : const char *username,
39 : uint32_t acct_ctrl,
40 : const DATA_BLOB *challenge,
41 : const uint8_t *lm_pw,
42 : const uint8_t *nt_pw,
43 : const struct auth_usersupplied_info *user_info,
44 : DATA_BLOB *user_sess_key,
45 : DATA_BLOB *lm_sess_key)
46 : {
47 : NTSTATUS status;
48 : struct samr_Password _lm_hash, _nt_hash;
49 494 : struct samr_Password *lm_hash = NULL;
50 494 : struct samr_Password *nt_hash = NULL;
51 :
52 494 : *user_sess_key = data_blob_null;
53 494 : *lm_sess_key = data_blob_null;
54 :
55 494 : if (acct_ctrl & ACB_PWNOTREQ) {
56 0 : if (lp_null_passwords()) {
57 0 : DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username));
58 0 : return NT_STATUS_OK;
59 : } else {
60 0 : DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", username));
61 0 : return NT_STATUS_LOGON_FAILURE;
62 : }
63 : }
64 :
65 494 : if (lm_pw) {
66 44 : memcpy(_lm_hash.hash, lm_pw, sizeof(_lm_hash.hash));
67 44 : lm_hash = &_lm_hash;
68 : }
69 494 : if (nt_pw) {
70 494 : memcpy(_nt_hash.hash, nt_pw, sizeof(_nt_hash.hash));
71 494 : nt_hash = &_nt_hash;
72 : }
73 494 : switch (user_info->password_state) {
74 0 : case AUTH_PASSWORD_HASH:
75 0 : status = hash_password_check(mem_ctx, lp_lanman_auth(),
76 0 : user_info->password.hash.lanman,
77 0 : user_info->password.hash.nt,
78 : username,
79 : lm_hash,
80 : nt_hash);
81 0 : if (NT_STATUS_IS_OK(status)) {
82 0 : if (nt_pw) {
83 0 : *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
84 0 : if (!user_sess_key->data) {
85 0 : status = NT_STATUS_NO_MEMORY;
86 0 : goto done;
87 : }
88 0 : SMBsesskeygen_ntv1(nt_pw, user_sess_key->data);
89 : }
90 : }
91 494 : break;
92 :
93 : /* Eventually we should test plaintext passwords in their own
94 : * function, not assuming the caller has done a
95 : * mapping */
96 494 : case AUTH_PASSWORD_PLAIN:
97 : case AUTH_PASSWORD_RESPONSE:
98 494 : status = ntlm_password_check(mem_ctx, lp_lanman_auth(),
99 494 : lp_ntlm_auth(),
100 494 : user_info->logon_parameters,
101 : challenge,
102 : &user_info->password.response.lanman, &user_info->password.response.nt,
103 : username,
104 494 : user_info->client.account_name,
105 494 : user_info->client.domain_name,
106 : lm_hash,
107 : nt_hash,
108 : user_sess_key, lm_sess_key);
109 494 : break;
110 0 : default:
111 0 : DEBUG(0,("user_info constructed for user '%s' was invalid - password_state=%u invalid.\n", username, user_info->password_state));
112 0 : status = NT_STATUS_INTERNAL_ERROR;
113 : }
114 494 : done:
115 494 : ZERO_STRUCTP(lm_hash);
116 494 : ZERO_STRUCTP(nt_hash);
117 494 : return status;
118 : }
119 :
120 : /****************************************************************************
121 : Check if a user is allowed to logon at this time. Note this is the
122 : servers local time, as logon hours are just specified as a weekly
123 : bitmask.
124 : ****************************************************************************/
125 :
126 456 : static bool logon_hours_ok(struct samu *sampass)
127 : {
128 : /* In logon hours first bit is Sunday from 12AM to 1AM */
129 : const uint8_t *hours;
130 : struct tm *utctime;
131 : time_t lasttime;
132 : const char *asct;
133 : uint8_t bitmask, bitpos;
134 :
135 456 : hours = pdb_get_hours(sampass);
136 456 : if (!hours) {
137 0 : DEBUG(5,("logon_hours_ok: No hours restrictions for user %s\n",pdb_get_username(sampass)));
138 0 : return True;
139 : }
140 :
141 456 : lasttime = time(NULL);
142 456 : utctime = gmtime(&lasttime);
143 456 : if (!utctime) {
144 0 : DEBUG(1, ("logon_hours_ok: failed to get gmtime. Failing logon for user %s\n",
145 : pdb_get_username(sampass) ));
146 0 : return False;
147 : }
148 :
149 : /* find the corresponding byte and bit */
150 456 : bitpos = (utctime->tm_wday * 24 + utctime->tm_hour) % 168;
151 456 : bitmask = 1 << (bitpos % 8);
152 :
153 456 : if (! (hours[bitpos/8] & bitmask)) {
154 0 : struct tm *t = localtime(&lasttime);
155 0 : if (!t) {
156 0 : asct = "INVALID TIME";
157 : } else {
158 0 : asct = asctime(t);
159 0 : if (!asct) {
160 0 : asct = "INVALID TIME";
161 : }
162 : }
163 :
164 0 : DEBUG(1, ("logon_hours_ok: Account for user %s not allowed to "
165 : "logon at this time (%s).\n",
166 : pdb_get_username(sampass), asct ));
167 0 : return False;
168 : }
169 :
170 456 : asct = asctime(utctime);
171 456 : DEBUG(5,("logon_hours_ok: user %s allowed to logon at this time (%s)\n",
172 : pdb_get_username(sampass), asct ? asct : "UNKNOWN TIME" ));
173 :
174 456 : return True;
175 : }
176 :
177 : /****************************************************************************
178 : Do a specific test for a struct samu being valid for this connection
179 : (ie not disabled, expired and the like).
180 : ****************************************************************************/
181 :
182 456 : static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
183 : struct samu *sampass,
184 : const struct auth_usersupplied_info *user_info)
185 : {
186 456 : uint32_t acct_ctrl = pdb_get_acct_ctrl(sampass);
187 : char *workstation_list;
188 : time_t kickoff_time;
189 :
190 456 : DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n",pdb_get_username(sampass)));
191 :
192 : /* Quit if the account was disabled. */
193 456 : if (acct_ctrl & ACB_DISABLED) {
194 0 : DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", pdb_get_username(sampass)));
195 0 : return NT_STATUS_ACCOUNT_DISABLED;
196 : }
197 :
198 : /* Quit if the account was locked out. */
199 456 : if (acct_ctrl & ACB_AUTOLOCK) {
200 0 : DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", pdb_get_username(sampass)));
201 0 : return NT_STATUS_ACCOUNT_LOCKED_OUT;
202 : }
203 :
204 : /* Quit if the account is not allowed to logon at this time. */
205 456 : if (! logon_hours_ok(sampass)) {
206 0 : return NT_STATUS_INVALID_LOGON_HOURS;
207 : }
208 :
209 : /* Test account expire time */
210 :
211 456 : kickoff_time = pdb_get_kickoff_time(sampass);
212 456 : if (kickoff_time != 0 && time(NULL) > kickoff_time) {
213 0 : DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", pdb_get_username(sampass)));
214 0 : DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time));
215 0 : return NT_STATUS_ACCOUNT_EXPIRED;
216 : }
217 :
218 456 : if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP) && !(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) {
219 453 : time_t must_change_time = pdb_get_pass_must_change_time(sampass);
220 453 : time_t last_set_time = pdb_get_pass_last_set_time(sampass);
221 :
222 : /* check for immediate expiry "must change at next logon"
223 : * for a user account. */
224 453 : if (((acct_ctrl & (ACB_WSTRUST|ACB_SVRTRUST)) == 0) && (last_set_time == 0)) {
225 0 : DEBUG(1,("sam_account_ok: Account for user '%s' password must change!\n", pdb_get_username(sampass)));
226 0 : return NT_STATUS_PASSWORD_MUST_CHANGE;
227 : }
228 :
229 : /* check for expired password */
230 453 : if (must_change_time < time(NULL) && must_change_time != 0) {
231 0 : DEBUG(1,("sam_account_ok: Account for user '%s' password expired!\n", pdb_get_username(sampass)));
232 0 : DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", http_timestring(talloc_tos(), must_change_time), (long)must_change_time));
233 0 : return NT_STATUS_PASSWORD_EXPIRED;
234 : }
235 : }
236 :
237 : /* Test workstation. Workstation list is comma separated. */
238 :
239 456 : workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass));
240 456 : if (!workstation_list)
241 0 : return NT_STATUS_NO_MEMORY;
242 :
243 456 : if (*workstation_list) {
244 0 : bool invalid_ws = True;
245 0 : char *tok = NULL;
246 0 : const char *s = workstation_list;
247 0 : char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->workstation_name);
248 :
249 0 : if (machine_name == NULL)
250 0 : return NT_STATUS_NO_MEMORY;
251 :
252 0 : while (next_token_talloc(mem_ctx, &s, &tok, ",")) {
253 0 : DEBUG(10,("sam_account_ok: checking for workstation match %s and %s\n",
254 : tok, user_info->workstation_name));
255 0 : if(strequal(tok, user_info->workstation_name)) {
256 0 : invalid_ws = False;
257 0 : break;
258 : }
259 0 : if (tok[0] == '+') {
260 0 : DEBUG(10,("sam_account_ok: checking for workstation %s in group: %s\n",
261 : machine_name, tok + 1));
262 0 : if (user_in_group(machine_name, tok + 1)) {
263 0 : invalid_ws = False;
264 0 : break;
265 : }
266 : }
267 0 : TALLOC_FREE(tok);
268 : }
269 0 : TALLOC_FREE(tok);
270 0 : TALLOC_FREE(machine_name);
271 :
272 0 : if (invalid_ws)
273 0 : return NT_STATUS_INVALID_WORKSTATION;
274 : }
275 :
276 456 : if (acct_ctrl & ACB_DOMTRUST) {
277 0 : DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", pdb_get_username(sampass)));
278 0 : return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
279 : }
280 :
281 456 : if (acct_ctrl & ACB_SVRTRUST) {
282 0 : if (!(user_info->logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) {
283 0 : DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", pdb_get_username(sampass)));
284 0 : return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
285 : }
286 : }
287 :
288 456 : if (acct_ctrl & ACB_WSTRUST) {
289 3 : if (!(user_info->logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) {
290 0 : DEBUG(2,("sam_account_ok: Wksta trust account %s denied by server\n", pdb_get_username(sampass)));
291 0 : return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
292 : }
293 : }
294 456 : return NT_STATUS_OK;
295 : }
296 :
297 : /**
298 : * Check whether the given password is one of the last two
299 : * password history entries. If so, the bad pwcount should
300 : * not be incremented even though the actual password check
301 : * failed.
302 : */
303 36 : static bool need_to_increment_bad_pw_count(
304 : const DATA_BLOB *challenge,
305 : struct samu* sampass,
306 : const struct auth_usersupplied_info *user_info)
307 : {
308 : uint8_t i;
309 : const uint8_t *pwhistory;
310 : uint32_t pwhistory_len;
311 : uint32_t policy_pwhistory_len;
312 : uint32_t acct_ctrl;
313 : const char *username;
314 36 : TALLOC_CTX *mem_ctx = talloc_stackframe();
315 36 : bool result = true;
316 :
317 36 : pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
318 : &policy_pwhistory_len);
319 36 : if (policy_pwhistory_len == 0) {
320 36 : goto done;
321 : }
322 :
323 0 : pwhistory = pdb_get_pw_history(sampass, &pwhistory_len);
324 0 : if (!pwhistory || pwhistory_len == 0) {
325 0 : goto done;
326 : }
327 :
328 0 : acct_ctrl = pdb_get_acct_ctrl(sampass);
329 0 : username = pdb_get_username(sampass);
330 :
331 0 : for (i=1; i < MIN(MIN(3, policy_pwhistory_len), pwhistory_len); i++) {
332 : const uint8_t *salt;
333 : const uint8_t *nt_pw;
334 : NTSTATUS status;
335 0 : DATA_BLOB user_sess_key = data_blob_null;
336 0 : DATA_BLOB lm_sess_key = data_blob_null;
337 :
338 0 : salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN];
339 0 : nt_pw = salt + PW_HISTORY_SALT_LEN;
340 :
341 0 : if (all_zero(nt_pw, NT_HASH_LEN)) {
342 : /* skip zero password hash */
343 0 : continue;
344 : }
345 :
346 0 : if (!all_zero(salt, PW_HISTORY_SALT_LEN)) {
347 : /* skip nonzero salt (old format entry) */
348 0 : continue;
349 : }
350 :
351 0 : status = sam_password_ok(mem_ctx,
352 : username, acct_ctrl,
353 : challenge,
354 : NULL, nt_pw,
355 : user_info, &user_sess_key, &lm_sess_key);
356 0 : if (NT_STATUS_IS_OK(status)) {
357 0 : result = false;
358 0 : break;
359 : }
360 : }
361 :
362 0 : done:
363 36 : TALLOC_FREE(mem_ctx);
364 36 : return result;
365 : }
366 :
367 : /****************************************************************************
368 : check if a username/password is OK assuming the password is a 24 byte
369 : SMB hash supplied in the user_info structure
370 : return an NT_STATUS constant.
371 : ****************************************************************************/
372 :
373 546 : NTSTATUS check_sam_security(const DATA_BLOB *challenge,
374 : TALLOC_CTX *mem_ctx,
375 : const struct auth_usersupplied_info *user_info,
376 : struct auth_serversupplied_info **server_info)
377 : {
378 546 : struct samu *sampass=NULL;
379 : bool ret;
380 : NTSTATUS nt_status;
381 : NTSTATUS update_login_attempts_status;
382 546 : DATA_BLOB user_sess_key = data_blob_null;
383 546 : DATA_BLOB lm_sess_key = data_blob_null;
384 546 : bool updated_badpw = False;
385 : const char *username;
386 : const uint8_t *nt_pw;
387 : const uint8_t *lm_pw;
388 : uint32_t acct_ctrl;
389 546 : char *mutex_name_by_user = NULL;
390 546 : struct named_mutex *mtx = NULL;
391 :
392 : /* the returned struct gets kept on the server_info, by means
393 : of a steal further down */
394 :
395 546 : sampass = samu_new(mem_ctx);
396 546 : if (sampass == NULL) {
397 0 : return NT_STATUS_NO_MEMORY;
398 : }
399 :
400 : /* get the account information */
401 :
402 546 : become_root();
403 546 : ret = pdb_getsampwnam(sampass, user_info->mapped.account_name);
404 546 : unbecome_root();
405 :
406 546 : if (!ret) {
407 52 : DEBUG(3,("check_sam_security: Couldn't find user '%s' in "
408 : "passdb.\n", user_info->mapped.account_name));
409 52 : TALLOC_FREE(sampass);
410 52 : return NT_STATUS_NO_SUCH_USER;
411 : }
412 :
413 494 : acct_ctrl = pdb_get_acct_ctrl(sampass);
414 494 : username = pdb_get_username(sampass);
415 494 : nt_pw = pdb_get_nt_passwd(sampass);
416 494 : lm_pw = pdb_get_lanman_passwd(sampass);
417 :
418 : /* Quit if the account was locked out. */
419 494 : if (acct_ctrl & ACB_AUTOLOCK) {
420 0 : DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username));
421 0 : TALLOC_FREE(sampass);
422 0 : return NT_STATUS_ACCOUNT_LOCKED_OUT;
423 : }
424 :
425 494 : nt_status = sam_password_ok(mem_ctx,
426 : username, acct_ctrl,
427 : challenge, lm_pw, nt_pw,
428 : user_info, &user_sess_key, &lm_sess_key);
429 :
430 : /*
431 : * We must re-load the sam acount information under a mutex
432 : * lock to ensure we don't miss any concurrent account lockout
433 : * changes.
434 : */
435 :
436 : /* Clear out old sampass info. */
437 494 : TALLOC_FREE(sampass);
438 494 : acct_ctrl = 0;
439 494 : username = NULL;
440 494 : nt_pw = NULL;
441 494 : lm_pw = NULL;
442 :
443 494 : sampass = samu_new(mem_ctx);
444 494 : if (sampass == NULL) {
445 0 : return NT_STATUS_NO_MEMORY;
446 : }
447 :
448 494 : mutex_name_by_user = talloc_asprintf(mem_ctx,
449 : "check_sam_security_mutex_%s",
450 494 : user_info->mapped.account_name);
451 494 : if (mutex_name_by_user == NULL) {
452 0 : nt_status = NT_STATUS_NO_MEMORY;
453 0 : goto done;
454 : }
455 :
456 : /* Grab the named mutex under root with 30 second timeout. */
457 494 : become_root();
458 494 : mtx = grab_named_mutex(mem_ctx, mutex_name_by_user, 30);
459 494 : if (mtx != NULL) {
460 : /* Re-load the account information if we got the mutex. */
461 494 : ret = pdb_getsampwnam(sampass, user_info->mapped.account_name);
462 : }
463 494 : unbecome_root();
464 :
465 : /* Everything from here on until mtx is freed is done under the mutex.*/
466 :
467 494 : if (mtx == NULL) {
468 0 : DBG_ERR("Acquisition of mutex %s failed "
469 : "for user %s\n",
470 : mutex_name_by_user,
471 : user_info->mapped.account_name);
472 0 : nt_status = NT_STATUS_INTERNAL_ERROR;
473 0 : goto done;
474 : }
475 :
476 494 : if (!ret) {
477 : /*
478 : * Re-load of account failed. This could only happen if the
479 : * user was deleted in the meantime.
480 : */
481 0 : DBG_NOTICE("reload of user '%s' in passdb failed.\n",
482 : user_info->mapped.account_name);
483 0 : nt_status = NT_STATUS_NO_SUCH_USER;
484 0 : goto done;
485 : }
486 :
487 : /* Re-load the account control info. */
488 494 : acct_ctrl = pdb_get_acct_ctrl(sampass);
489 494 : username = pdb_get_username(sampass);
490 :
491 : /*
492 : * Check if the account is now locked out - now under the mutex.
493 : * This can happen if the server is under
494 : * a password guess attack and the ACB_AUTOLOCK is set by
495 : * another process.
496 : */
497 494 : if (acct_ctrl & ACB_AUTOLOCK) {
498 0 : DBG_NOTICE("Account for user %s was locked out.\n", username);
499 0 : nt_status = NT_STATUS_ACCOUNT_LOCKED_OUT;
500 0 : goto done;
501 : }
502 :
503 : /* Notify passdb backend of login success/failure. If not
504 : NT_STATUS_OK the backend doesn't like the login */
505 :
506 494 : update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));
507 :
508 494 : if (!NT_STATUS_IS_OK(nt_status)) {
509 38 : bool increment_bad_pw_count = false;
510 :
511 38 : if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) &&
512 36 : (acct_ctrl & ACB_NORMAL) &&
513 36 : NT_STATUS_IS_OK(update_login_attempts_status))
514 : {
515 : increment_bad_pw_count =
516 36 : need_to_increment_bad_pw_count(
517 : challenge, sampass, user_info);
518 : }
519 :
520 38 : if (increment_bad_pw_count) {
521 36 : pdb_increment_bad_password_count(sampass);
522 36 : updated_badpw = True;
523 : } else {
524 2 : pdb_update_bad_password_count(sampass,
525 : &updated_badpw);
526 : }
527 38 : if (updated_badpw){
528 : NTSTATUS status;
529 :
530 36 : become_root();
531 36 : status = pdb_update_sam_account(sampass);
532 36 : unbecome_root();
533 :
534 36 : if (!NT_STATUS_IS_OK(status)) {
535 0 : DEBUG(1, ("Failed to modify entry: %s\n",
536 : nt_errstr(status)));
537 : }
538 : }
539 38 : goto done;
540 : }
541 :
542 : /*
543 : * We must only reset the bad password count if the login was
544 : * successful, including checking account policies
545 : */
546 456 : nt_status = sam_account_ok(mem_ctx, sampass, user_info);
547 456 : if (!NT_STATUS_IS_OK(nt_status)) {
548 0 : goto done;
549 : }
550 :
551 909 : if ((acct_ctrl & ACB_NORMAL) &&
552 453 : (pdb_get_bad_password_count(sampass) > 0)){
553 : NTSTATUS status;
554 :
555 0 : pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
556 0 : pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
557 :
558 0 : become_root();
559 0 : status = pdb_update_sam_account(sampass);
560 0 : unbecome_root();
561 :
562 0 : if (!NT_STATUS_IS_OK(status)) {
563 0 : DEBUG(1, ("Failed to modify entry: %s\n",
564 : nt_errstr(status)));
565 : }
566 : }
567 :
568 456 : become_root();
569 456 : nt_status = make_server_info_sam(mem_ctx, sampass, server_info);
570 456 : unbecome_root();
571 :
572 456 : if (!NT_STATUS_IS_OK(nt_status)) {
573 0 : DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
574 0 : goto done;
575 : }
576 :
577 456 : (*server_info)->session_key =
578 456 : data_blob_talloc(*server_info, user_sess_key.data,
579 : user_sess_key.length);
580 456 : data_blob_free(&user_sess_key);
581 :
582 456 : (*server_info)->lm_session_key =
583 456 : data_blob_talloc(*server_info, lm_sess_key.data,
584 : lm_sess_key.length);
585 456 : data_blob_free(&lm_sess_key);
586 :
587 456 : (*server_info)->nss_token |= user_info->was_mapped;
588 :
589 494 : done:
590 : /*
591 : * Always flush the getpwsid cache or this will grow indefinetly for
592 : * each NTLM auththentication.
593 : */
594 494 : memcache_flush(NULL, PDB_GETPWSID_CACHE);
595 494 : TALLOC_FREE(sampass);
596 494 : data_blob_free(&user_sess_key);
597 494 : data_blob_free(&lm_sess_key);
598 494 : TALLOC_FREE(mutex_name_by_user);
599 494 : TALLOC_FREE(mtx);
600 494 : return nt_status;
601 : }
602 :
603 : /* This helper function for winbindd returns a very similar value to
604 : * what a NETLOGON call would give, without the indirection */
605 1 : NTSTATUS check_sam_security_info3(const DATA_BLOB *challenge,
606 : TALLOC_CTX *mem_ctx,
607 : const struct auth_usersupplied_info *user_info,
608 : struct netr_SamInfo3 **pinfo3)
609 : {
610 1 : struct auth_serversupplied_info *server_info = NULL;
611 : struct netr_SamInfo3 *info3;
612 : NTSTATUS status;
613 1 : TALLOC_CTX *frame = talloc_stackframe();
614 :
615 1 : status = check_sam_security(challenge, talloc_tos(), user_info,
616 : &server_info);
617 1 : if (!NT_STATUS_IS_OK(status)) {
618 0 : DEBUG(10, ("check_sam_security failed: %s\n",
619 : nt_errstr(status)));
620 0 : goto done;
621 : }
622 :
623 1 : info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
624 1 : if (info3 == NULL) {
625 0 : status = NT_STATUS_NO_MEMORY;
626 0 : goto done;
627 : }
628 :
629 1 : status = serverinfo_to_SamInfo3(server_info, info3);
630 1 : if (!NT_STATUS_IS_OK(status)) {
631 0 : DEBUG(10, ("serverinfo_to_SamInfo3 failed: %s\n",
632 : nt_errstr(status)));
633 0 : goto done;
634 : }
635 1 : *pinfo3 = info3;
636 1 : status = NT_STATUS_OK;
637 1 : done:
638 1 : TALLOC_FREE(frame);
639 1 : return status;
640 : }
|