2 Unix SMB/CIFS implementation.
3 Password and authentication handling
4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004
5 Copyright (C) Gerald Carter 2003
6 Copyright (C) Stefan Metzmacher 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "system/time.h"
25 #include "auth/auth.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "libcli/security/proto.h"
29 #include "libcli/ldap/ldap.h"
30 #include "librpc/gen_ndr/ndr_security.h"
32 static const char *user_attrs[] = {
33 /* requried for the krb5 kdc*/
37 "servicePrincipalName",
38 "msDS-KeyVersionNumber",
52 /* check 'allowed workstations' */
55 /* required for server_info, not access control: */
70 static const char *domain_ref_attrs[] = {"nETBIOSName", "nCName",
71 "dnsRoot", "objectClass", NULL};
73 /****************************************************************************
74 Do a specific test for an smb password being correct, given a smb_password and
75 the lanman and NT responses.
76 ****************************************************************************/
77 static NTSTATUS authsam_password_ok(struct auth_context *auth_context,
80 const struct samr_Password *lm_pwd,
81 const struct samr_Password *nt_pwd,
82 const struct auth_usersupplied_info *user_info,
83 DATA_BLOB *user_sess_key,
84 DATA_BLOB *lm_sess_key)
88 if (acct_flags & ACB_PWNOTREQ) {
89 if (lp_null_passwords()) {
90 DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n",
91 user_info->mapped.account_name));
94 DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n",
95 user_info->mapped.account_name));
96 return NT_STATUS_LOGON_FAILURE;
100 switch (user_info->password_state) {
101 case AUTH_PASSWORD_PLAIN:
103 const struct auth_usersupplied_info *user_info_temp;
104 status = encrypt_user_info(mem_ctx, auth_context,
106 user_info, &user_info_temp);
107 if (!NT_STATUS_IS_OK(status)) {
108 DEBUG(1, ("Failed to convert plaintext password to password HASH: %s\n", nt_errstr(status)));
111 user_info = user_info_temp;
115 case AUTH_PASSWORD_HASH:
116 *lm_sess_key = data_blob(NULL, 0);
117 *user_sess_key = data_blob(NULL, 0);
118 status = hash_password_check(mem_ctx,
119 user_info->password.hash.lanman,
120 user_info->password.hash.nt,
121 user_info->mapped.account_name,
123 NT_STATUS_NOT_OK_RETURN(status);
126 case AUTH_PASSWORD_RESPONSE:
127 status = ntlm_password_check(mem_ctx, user_info->logon_parameters,
128 &auth_context->challenge.data,
129 &user_info->password.response.lanman,
130 &user_info->password.response.nt,
131 user_info->mapped.account_name,
132 user_info->client.account_name,
133 user_info->client.domain_name,
135 user_sess_key, lm_sess_key);
136 NT_STATUS_NOT_OK_RETURN(status);
140 if (user_sess_key && user_sess_key->data) {
141 talloc_steal(auth_context, user_sess_key->data);
143 if (lm_sess_key && lm_sess_key->data) {
144 talloc_steal(auth_context, lm_sess_key->data);
151 /****************************************************************************
152 Do a specific test for a SAM_ACCOUNT being vaild for this connection
153 (ie not disabled, expired and the like).
154 ****************************************************************************/
155 NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
156 struct ldb_context *sam_ctx,
157 uint32_t logon_parameters,
158 struct ldb_message *msg,
159 struct ldb_message *msg_domain_ref,
160 const char *logon_workstation,
161 const char *name_for_logs)
164 const char *workstation_list;
166 NTTIME must_change_time;
167 NTTIME last_set_time;
169 struct ldb_dn *domain_dn = samdb_result_dn(mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx));
172 DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
174 acct_flags = samdb_result_acct_flags(msg, "userAccountControl");
176 acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
177 must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx,
179 last_set_time = samdb_result_nttime(msg, "pwdLastSet", 0);
181 workstation_list = samdb_result_string(msg, "userWorkstations", NULL);
183 /* Quit if the account was disabled. */
184 if (acct_flags & ACB_DISABLED) {
185 DEBUG(1,("authsam_account_ok: Account for user '%s' was disabled.\n", name_for_logs));
186 return NT_STATUS_ACCOUNT_DISABLED;
189 /* Quit if the account was locked out. */
190 if (acct_flags & ACB_AUTOLOCK) {
191 DEBUG(1,("authsam_account_ok: Account for user %s was locked out.\n", name_for_logs));
192 return NT_STATUS_ACCOUNT_LOCKED_OUT;
195 /* Test account expire time */
196 unix_to_nt_time(&now, time(NULL));
197 if (now > acct_expiry) {
198 DEBUG(1,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs));
199 DEBUG(3,("authsam_account_ok: Account expired at '%s'.\n",
200 nt_time_string(mem_ctx, acct_expiry)));
201 return NT_STATUS_ACCOUNT_EXPIRED;
204 if (!(acct_flags & ACB_PWNOEXP)) {
205 /* check for immediate expiry "must change at next logon" */
206 if (must_change_time == 0 && last_set_time != 0) {
207 DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n",
209 return NT_STATUS_PASSWORD_MUST_CHANGE;
212 /* check for expired password */
213 if ((must_change_time != 0) && (must_change_time < now)) {
214 DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n",
216 DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n",
217 nt_time_string(mem_ctx, must_change_time)));
218 return NT_STATUS_PASSWORD_EXPIRED;
222 /* Test workstation. Workstation list is comma separated. */
223 if (logon_workstation && workstation_list && *workstation_list) {
224 BOOL invalid_ws = True;
226 const char **workstations = str_list_make(mem_ctx, workstation_list, ",");
228 for (i = 0; workstations && workstations[i]; i++) {
229 DEBUG(10,("sam_account_ok: checking for workstation match '%s' and '%s'\n",
230 workstations[i], logon_workstation));
232 if (strequal(workstations[i], logon_workstation)) {
238 talloc_free(workstations);
241 return NT_STATUS_INVALID_WORKSTATION;
245 if (acct_flags & ACB_DOMTRUST) {
246 DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", name_for_logs));
247 return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
250 if (!(logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) {
251 if (acct_flags & ACB_SVRTRUST) {
252 DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", name_for_logs));
253 return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
256 if (!(logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) {
257 if (acct_flags & ACB_WSTRUST) {
258 DEBUG(4,("sam_account_ok: Wksta trust account %s denied by server\n", name_for_logs));
259 return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
266 /****************************************************************************
267 Look for the specified user in the sam, return ldb result structures
268 ****************************************************************************/
270 static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
271 const char *account_name,
272 const char *domain_name,
273 struct ldb_message ***ret_msgs,
274 struct ldb_message ***ret_msgs_domain_ref)
276 struct ldb_message **msgs_tmp;
277 struct ldb_message **msgs;
278 struct ldb_message **msgs_domain_ref;
283 const struct ldb_dn *domain_dn = NULL;
286 char *escaped_domain = ldb_binary_encode_string(mem_ctx, domain_name);
287 /* find the domain's DN */
288 ret_domain = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_domain_ref, domain_ref_attrs,
289 "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
290 escaped_domain, escaped_domain);
291 if (ret_domain == -1) {
292 return NT_STATUS_INTERNAL_DB_CORRUPTION;
295 if (ret_domain == 0) {
296 DEBUG(3,("sam_search_user: Couldn't find domain [%s] in samdb.\n",
298 return NT_STATUS_NO_SUCH_USER;
301 if (ret_domain > 1) {
302 DEBUG(0,("Found %d records matching domain [%s]\n",
303 ret_domain, domain_name));
304 return NT_STATUS_INTERNAL_DB_CORRUPTION;
307 domain_dn = samdb_result_dn(mem_ctx, msgs_domain_ref[0], "nCName", NULL);
310 /* pull the user attributes */
311 ret = gendb_search(sam_ctx, mem_ctx, domain_dn, &msgs, user_attrs,
312 "(&(sAMAccountName=%s)(objectclass=user))",
313 ldb_binary_encode_string(mem_ctx, account_name));
315 return NT_STATUS_INTERNAL_DB_CORRUPTION;
319 DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb.\n",
321 return NT_STATUS_NO_SUCH_USER;
325 DEBUG(0,("Found %d records matching user [%s]\n", ret, account_name));
326 return NT_STATUS_INTERNAL_DB_CORRUPTION;
330 struct dom_sid *domain_sid;
332 domain_sid = samdb_result_sid_prefix(mem_ctx, msgs[0], "objectSid");
334 return NT_STATUS_INTERNAL_DB_CORRUPTION;
337 /* find the domain's DN */
338 ret = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_tmp, NULL,
339 "(&(objectSid=%s)(objectclass=domain))",
340 ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
342 return NT_STATUS_INTERNAL_DB_CORRUPTION;
346 DEBUG(3,("check_sam_security: Couldn't find domain_sid [%s] in passdb file.\n",
347 dom_sid_string(mem_ctx, domain_sid)));
348 return NT_STATUS_NO_SUCH_USER;
352 DEBUG(0,("Found %d records matching domain_sid [%s]\n",
353 ret, dom_sid_string(mem_ctx, domain_sid)));
354 return NT_STATUS_INTERNAL_DB_CORRUPTION;
357 ret_domain = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_domain_ref, domain_ref_attrs,
358 "(nCName=%s)", ldb_dn_linearize(msgs_tmp, msgs_tmp[0]->dn));
360 if (ret_domain == -1) {
361 return NT_STATUS_INTERNAL_DB_CORRUPTION;
364 if (ret_domain == 0) {
365 DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n",
366 ldb_dn_linearize(msgs_tmp, msgs_tmp[0]->dn)));
367 return NT_STATUS_NO_SUCH_USER;
370 if (ret_domain > 1) {
371 DEBUG(0,("Found %d records matching domain [%s]\n",
372 ret_domain, ldb_dn_linearize(msgs_tmp, msgs_tmp[0]->dn)));
373 return NT_STATUS_INTERNAL_DB_CORRUPTION;
379 *ret_msgs_domain_ref = msgs_domain_ref;
384 static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
385 TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
386 struct ldb_message **msgs,
387 struct ldb_message **msgs_domain_ref,
388 const struct auth_usersupplied_info *user_info,
389 DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key)
391 struct samr_Password *lm_pwd, *nt_pwd;
393 uint16_t acct_flags = samdb_result_acct_flags(msgs[0], "userAccountControl");
395 /* Quit if the account was locked out. */
396 if (acct_flags & ACB_AUTOLOCK) {
397 DEBUG(3,("check_sam_security: Account for user %s was locked out.\n",
398 user_info->mapped.account_name));
399 return NT_STATUS_ACCOUNT_LOCKED_OUT;
402 /* You can only do an interactive login to normal accounts */
403 if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
404 if (!(acct_flags & ACB_NORMAL)) {
405 return NT_STATUS_NO_SUCH_USER;
409 nt_status = samdb_result_passwords(mem_ctx, msgs[0], &lm_pwd, &nt_pwd);
410 NT_STATUS_NOT_OK_RETURN(nt_status);
412 nt_status = authsam_password_ok(auth_context, mem_ctx,
413 acct_flags, lm_pwd, nt_pwd,
414 user_info, user_sess_key, lm_sess_key);
415 NT_STATUS_NOT_OK_RETURN(nt_status);
417 nt_status = authsam_account_ok(mem_ctx, sam_ctx,
418 user_info->logon_parameters,
421 user_info->workstation_name,
422 user_info->mapped.account_name);
427 NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
428 struct ldb_message *msg,
429 struct ldb_message *msg_domain_ref,
430 DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
431 struct auth_serversupplied_info **_server_info)
433 struct auth_serversupplied_info *server_info;
434 struct ldb_message **group_msgs;
436 const char *group_attrs[3] = { "sAMAccountType", "objectSid", NULL };
437 /* find list of sids */
438 struct dom_sid **groupSIDs = NULL;
439 struct dom_sid *account_sid;
440 struct dom_sid *primary_group_sid;
442 struct ldb_dn *ncname;
445 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
447 group_ret = gendb_search(sam_ctx,
448 tmp_ctx, NULL, &group_msgs, group_attrs,
449 "(&(member=%s)(sAMAccountType=*))",
450 ldb_dn_linearize(tmp_ctx, msg->dn));
451 if (group_ret == -1) {
452 talloc_free(tmp_ctx);
453 return NT_STATUS_INTERNAL_DB_CORRUPTION;
456 server_info = talloc(mem_ctx, struct auth_serversupplied_info);
457 NT_STATUS_HAVE_NO_MEMORY(server_info);
460 groupSIDs = talloc_array(server_info, struct dom_sid *, group_ret);
461 NT_STATUS_HAVE_NO_MEMORY(groupSIDs);
464 /* Need to unroll some nested groups, but not aliases */
465 for (i = 0; i < group_ret; i++) {
466 groupSIDs[i] = samdb_result_dom_sid(groupSIDs,
467 group_msgs[i], "objectSid");
468 NT_STATUS_HAVE_NO_MEMORY(groupSIDs[i]);
471 talloc_free(tmp_ctx);
473 account_sid = samdb_result_dom_sid(server_info, msg, "objectSid");
474 NT_STATUS_HAVE_NO_MEMORY(account_sid);
476 primary_group_sid = dom_sid_dup(server_info, account_sid);
477 NT_STATUS_HAVE_NO_MEMORY(primary_group_sid);
479 rid = samdb_result_uint(msg, "primaryGroupID", ~0);
482 primary_group_sid = groupSIDs[0];
484 primary_group_sid = NULL;
487 primary_group_sid->sub_auths[primary_group_sid->num_auths-1] = rid;
490 server_info->account_sid = account_sid;
491 server_info->primary_group_sid = primary_group_sid;
493 server_info->n_domain_groups = group_ret;
494 server_info->domain_groups = groupSIDs;
496 server_info->account_name = talloc_steal(server_info, samdb_result_string(msg, "sAMAccountName", NULL));
498 server_info->domain_name = talloc_steal(server_info, samdb_result_string(msg_domain_ref, "nETBIOSName", NULL));
500 str = samdb_result_string(msg, "displayName", "");
501 server_info->full_name = talloc_strdup(server_info, str);
502 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
504 str = samdb_result_string(msg, "scriptPath", "");
505 server_info->logon_script = talloc_strdup(server_info, str);
506 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
508 str = samdb_result_string(msg, "profilePath", "");
509 server_info->profile_path = talloc_strdup(server_info, str);
510 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
512 str = samdb_result_string(msg, "homeDirectory", "");
513 server_info->home_directory = talloc_strdup(server_info, str);
514 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
516 str = samdb_result_string(msg, "homeDrive", "");
517 server_info->home_drive = talloc_strdup(server_info, str);
518 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
520 server_info->logon_server = talloc_strdup(server_info, lp_netbios_name());
521 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
523 server_info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
524 server_info->last_logoff = samdb_result_nttime(msg, "lastLogoff", 0);
525 server_info->acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
526 server_info->last_password_change = samdb_result_nttime(msg, "pwdLastSet", 0);
528 ncname = samdb_result_dn(mem_ctx, msg_domain_ref, "nCName", NULL);
530 return NT_STATUS_INTERNAL_DB_CORRUPTION;
532 server_info->allow_password_change
533 = samdb_result_allow_password_change(sam_ctx, mem_ctx,
534 ncname, msg, "pwdLastSet");
535 server_info->force_password_change
536 = samdb_result_force_password_change(sam_ctx, mem_ctx,
539 server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);
540 server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount", 0);
542 server_info->acct_flags = samdb_result_acct_flags(msg, "userAccountControl");
544 server_info->user_session_key = user_sess_key;
545 server_info->lm_session_key = lm_sess_key;
547 server_info->authenticated = True;
549 *_server_info = server_info;
554 NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
555 TALLOC_CTX *mem_ctx, const char *principal,
556 struct ldb_message ***msgs,
557 struct ldb_message ***msgs_domain_ref)
559 struct ldb_dn *user_dn, *domain_dn;
561 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
565 return NT_STATUS_NO_MEMORY;
568 nt_status = crack_user_principal_name(sam_ctx, tmp_ctx, principal, &user_dn, &domain_dn);
569 if (!NT_STATUS_IS_OK(nt_status)) {
570 talloc_free(tmp_ctx);
574 /* grab domain info from the reference */
575 ret = gendb_search(sam_ctx, tmp_ctx, NULL, msgs_domain_ref, domain_ref_attrs,
576 "(ncName=%s)", ldb_dn_linearize(tmp_ctx, domain_dn));
579 talloc_free(tmp_ctx);
580 return NT_STATUS_INTERNAL_DB_CORRUPTION;
583 /* pull the user attributes */
584 ret = gendb_search_dn(sam_ctx, tmp_ctx,
585 user_dn, msgs, user_attrs);
587 talloc_free(tmp_ctx);
588 return NT_STATUS_INTERNAL_DB_CORRUPTION;
590 talloc_steal(mem_ctx, *msgs);
591 talloc_steal(mem_ctx, *msgs_domain_ref);
592 talloc_free(tmp_ctx);
597 /* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
598 NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, const char *principal,
599 struct auth_serversupplied_info **server_info)
602 DATA_BLOB user_sess_key = data_blob(NULL, 0);
603 DATA_BLOB lm_sess_key = data_blob(NULL, 0);
605 struct ldb_message **msgs;
606 struct ldb_message **msgs_domain_ref;
607 struct ldb_context *sam_ctx;
609 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
611 return NT_STATUS_NO_MEMORY;
614 sam_ctx = samdb_connect(tmp_ctx, system_session(tmp_ctx));
615 if (sam_ctx == NULL) {
616 talloc_free(tmp_ctx);
617 return NT_STATUS_INVALID_SYSTEM_SERVICE;
620 nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal,
621 &msgs, &msgs_domain_ref);
622 if (!NT_STATUS_IS_OK(nt_status)) {
626 nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, msgs[0], msgs_domain_ref[0],
627 user_sess_key, lm_sess_key,
629 if (NT_STATUS_IS_OK(nt_status)) {
630 talloc_steal(mem_ctx, *server_info);
632 talloc_free(tmp_ctx);
636 static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx,
639 const struct auth_usersupplied_info *user_info,
640 struct auth_serversupplied_info **server_info)
643 const char *account_name = user_info->mapped.account_name;
644 struct ldb_message **msgs;
645 struct ldb_message **domain_ref_msgs;
646 struct ldb_context *sam_ctx;
647 DATA_BLOB user_sess_key, lm_sess_key;
650 if (!account_name || !*account_name) {
652 return NT_STATUS_NOT_IMPLEMENTED;
655 tmp_ctx = talloc_new(mem_ctx);
657 return NT_STATUS_NO_MEMORY;
660 sam_ctx = samdb_connect(tmp_ctx, system_session(mem_ctx));
661 if (sam_ctx == NULL) {
662 talloc_free(tmp_ctx);
663 return NT_STATUS_INVALID_SYSTEM_SERVICE;
666 nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain, &msgs, &domain_ref_msgs);
667 if (!NT_STATUS_IS_OK(nt_status)) {
668 talloc_free(tmp_ctx);
672 nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, msgs, domain_ref_msgs, user_info,
673 &user_sess_key, &lm_sess_key);
674 if (!NT_STATUS_IS_OK(nt_status)) {
675 talloc_free(tmp_ctx);
679 nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, msgs[0], domain_ref_msgs[0],
680 user_sess_key, lm_sess_key,
682 if (!NT_STATUS_IS_OK(nt_status)) {
683 talloc_free(tmp_ctx);
687 talloc_steal(mem_ctx, *server_info);
688 talloc_free(tmp_ctx);
693 static NTSTATUS authsam_ignoredomain_check_password(struct auth_method_context *ctx,
695 const struct auth_usersupplied_info *user_info,
696 struct auth_serversupplied_info **server_info)
698 return authsam_check_password_internals(ctx, mem_ctx, NULL, user_info, server_info);
701 /****************************************************************************
702 Check SAM security (above) but with a few extra checks.
703 ****************************************************************************/
704 static NTSTATUS authsam_check_password(struct auth_method_context *ctx,
706 const struct auth_usersupplied_info *user_info,
707 struct auth_serversupplied_info **server_info)
710 BOOL is_local_name, is_my_domain;
712 is_local_name = is_myname(user_info->mapped.domain_name);
713 is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
715 /* check whether or not we service this domain/workgroup name */
716 switch (lp_server_role()) {
717 case ROLE_STANDALONE:
718 domain = lp_netbios_name();
720 case ROLE_DOMAIN_MEMBER:
721 if (!is_local_name) {
722 DEBUG(6,("authsam_check_password: %s is not one of my local names (%s)\n",
723 user_info->mapped.domain_name, (lp_server_role() == ROLE_DOMAIN_MEMBER
724 ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
725 return NT_STATUS_NOT_IMPLEMENTED;
727 domain = lp_netbios_name();
729 case ROLE_DOMAIN_PDC:
730 case ROLE_DOMAIN_BDC:
731 if (!is_local_name && !is_my_domain) {
732 DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n",
733 user_info->mapped.domain_name));
734 return NT_STATUS_NOT_IMPLEMENTED;
736 domain = lp_workgroup();
739 DEBUG(6,("authsam_check_password: lp_server_role() has an undefined value\n"));
740 return NT_STATUS_NOT_IMPLEMENTED;
743 return authsam_check_password_internals(ctx, mem_ctx, domain, user_info, server_info);
746 static const struct auth_operations sam_ignoredomain_ops = {
747 .name = "sam_ignoredomain",
748 .get_challenge = auth_get_challenge_not_implemented,
749 .check_password = authsam_ignoredomain_check_password
752 static const struct auth_operations sam_ops = {
754 .get_challenge = auth_get_challenge_not_implemented,
755 .check_password = authsam_check_password
758 NTSTATUS auth_sam_init(void)
762 ret = auth_register(&sam_ops);
763 if (!NT_STATUS_IS_OK(ret)) {
764 DEBUG(0,("Failed to register 'sam' auth backend!\n"));
768 ret = auth_register(&sam_ignoredomain_ops);
769 if (!NT_STATUS_IS_OK(ret)) {
770 DEBUG(0,("Failed to register 'sam_ignoredomain' auth backend!\n"));