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