2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001-2011
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
8 Copyright (C) Volker Lendecke 2006-2008
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "lib/util_unixsids.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../lib/crypto/arcfour.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/util_pw.h"
32 #include "lib/winbind_util.h"
34 #include "../librpc/gen_ndr/ndr_auth.h"
35 #include "../auth/auth_sam_reply.h"
36 #include "../librpc/gen_ndr/idmap.h"
37 #include "lib/param/loadparm.h"
38 #include "../lib/tsocket/tsocket.h"
39 #include "rpc_client/util_netlogon.h"
42 #define DBGC_CLASS DBGC_AUTH
44 /****************************************************************************
45 Create a UNIX user on demand.
46 ****************************************************************************/
48 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
50 TALLOC_CTX *ctx = talloc_tos();
54 add_script = lp_add_user_script(ctx);
55 if (!add_script || !*add_script) {
58 add_script = talloc_all_string_sub(ctx,
66 add_script = talloc_all_string_sub(ctx,
75 add_script = talloc_all_string_sub(ctx,
83 ret = smbrun(add_script, NULL, NULL);
86 ("smb_create_user: Running the command `%s' gave %d\n",
91 /****************************************************************************
92 Create an auth_usersupplied_data structure after appropriate mapping.
93 ****************************************************************************/
95 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
96 struct auth_usersupplied_info **user_info,
98 const char *client_domain,
99 const char *workstation_name,
100 const struct tsocket_address *remote_address,
101 const struct tsocket_address *local_address,
102 const char *service_description,
103 const DATA_BLOB *lm_pwd,
104 const DATA_BLOB *nt_pwd,
105 const struct samr_Password *lm_interactive_pwd,
106 const struct samr_Password *nt_interactive_pwd,
107 const char *plaintext,
108 enum auth_password_state password_state)
113 char *internal_username = NULL;
115 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
116 if (!internal_username) {
117 return NT_STATUS_NO_MEMORY;
120 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
121 client_domain, smb_name, workstation_name));
124 * We let the auth stack canonicalize, username
127 domain = client_domain;
129 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
130 client_domain, domain, workstation_name,
131 remote_address, local_address,
132 service_description, lm_pwd, nt_pwd,
133 lm_interactive_pwd, nt_interactive_pwd,
134 plaintext, password_state);
135 if (NT_STATUS_IS_OK(result)) {
136 /* We have tried mapping */
137 (*user_info)->mapped_state = true;
138 /* did we actually map the user to a different name? */
139 (*user_info)->was_mapped = was_mapped;
144 /****************************************************************************
145 Create an auth_usersupplied_data, making the DATA_BLOBs here.
146 Decrypt and encrypt the passwords.
147 ****************************************************************************/
149 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
150 struct auth_usersupplied_info **user_info,
151 const char *smb_name,
152 const char *client_domain,
153 const char *workstation_name,
154 const struct tsocket_address *remote_address,
155 const struct tsocket_address *local_address,
156 uint32_t logon_parameters,
157 const uchar *lm_network_pwd,
159 const uchar *nt_network_pwd,
164 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
165 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
167 status = make_user_info_map(mem_ctx, user_info,
168 smb_name, client_domain,
173 lm_pwd_len ? &lm_blob : NULL,
174 nt_pwd_len ? &nt_blob : NULL,
176 AUTH_PASSWORD_RESPONSE);
178 if (NT_STATUS_IS_OK(status)) {
179 (*user_info)->logon_parameters = logon_parameters;
181 ret = NT_STATUS_IS_OK(status) ? true : false;
183 data_blob_free(&lm_blob);
184 data_blob_free(&nt_blob);
188 /****************************************************************************
189 Create an auth_usersupplied_data, making the DATA_BLOBs here.
190 Decrypt and encrypt the passwords.
191 ****************************************************************************/
193 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
194 struct auth_usersupplied_info **user_info,
195 const char *smb_name,
196 const char *client_domain,
197 const char *workstation_name,
198 const struct tsocket_address *remote_address,
199 const struct tsocket_address *local_address,
200 uint32_t logon_parameters,
202 const uchar lm_interactive_pwd[16],
203 const uchar nt_interactive_pwd[16])
205 struct samr_Password lm_pwd;
206 struct samr_Password nt_pwd;
207 unsigned char local_lm_response[24];
208 unsigned char local_nt_response[24];
210 if (lm_interactive_pwd)
211 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
213 if (nt_interactive_pwd)
214 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
216 if (lm_interactive_pwd)
217 SMBOWFencrypt(lm_pwd.hash, chal,
220 if (nt_interactive_pwd)
221 SMBOWFencrypt(nt_pwd.hash, chal,
227 DATA_BLOB local_lm_blob = data_blob_null;
228 DATA_BLOB local_nt_blob = data_blob_null;
230 if (lm_interactive_pwd) {
231 local_lm_blob = data_blob(local_lm_response,
232 sizeof(local_lm_response));
235 if (nt_interactive_pwd) {
236 local_nt_blob = data_blob(local_nt_response,
237 sizeof(local_nt_response));
240 nt_status = make_user_info_map(
243 smb_name, client_domain, workstation_name,
247 lm_interactive_pwd ? &local_lm_blob : NULL,
248 nt_interactive_pwd ? &local_nt_blob : NULL,
249 lm_interactive_pwd ? &lm_pwd : NULL,
250 nt_interactive_pwd ? &nt_pwd : NULL,
251 NULL, AUTH_PASSWORD_HASH);
253 if (NT_STATUS_IS_OK(nt_status)) {
254 (*user_info)->logon_parameters = logon_parameters;
257 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
258 data_blob_free(&local_lm_blob);
259 data_blob_free(&local_nt_blob);
265 /****************************************************************************
266 Create an auth_usersupplied_data structure
267 ****************************************************************************/
269 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
270 struct auth_usersupplied_info **user_info,
271 const char *smb_name,
272 const char *client_domain,
273 const struct tsocket_address *remote_address,
274 const struct tsocket_address *local_address,
275 const char *service_description,
276 const uint8_t chal[8],
277 DATA_BLOB plaintext_password)
280 DATA_BLOB local_lm_blob;
281 DATA_BLOB local_nt_blob;
282 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
283 char *plaintext_password_string;
285 * Not encrypted - do so.
288 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
290 if (plaintext_password.data && plaintext_password.length) {
291 unsigned char local_lm_response[24];
293 #ifdef DEBUG_PASSWORD
294 DEBUG(10,("Unencrypted password (len %d):\n",
295 (int)plaintext_password.length));
296 dump_data(100, plaintext_password.data,
297 plaintext_password.length);
300 SMBencrypt( (const char *)plaintext_password.data,
301 (const uchar*)chal, local_lm_response);
302 local_lm_blob = data_blob(local_lm_response, 24);
304 /* We can't do an NT hash here, as the password needs to be
306 local_nt_blob = data_blob_null;
308 local_lm_blob = data_blob_null;
309 local_nt_blob = data_blob_null;
312 plaintext_password_string = talloc_strndup(talloc_tos(),
313 (const char *)plaintext_password.data,
314 plaintext_password.length);
315 if (!plaintext_password_string) {
319 ret = make_user_info(mem_ctx,
320 user_info, smb_name, smb_name, client_domain, client_domain,
321 get_remote_machine_name(),
325 local_lm_blob.data ? &local_lm_blob : NULL,
326 local_nt_blob.data ? &local_nt_blob : NULL,
328 plaintext_password_string,
329 AUTH_PASSWORD_PLAIN);
331 if (plaintext_password_string) {
332 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
333 talloc_free(plaintext_password_string);
336 data_blob_free(&local_lm_blob);
337 return NT_STATUS_IS_OK(ret) ? true : false;
340 /****************************************************************************
341 Create an auth_usersupplied_data structure
342 ****************************************************************************/
344 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
345 struct auth_usersupplied_info **user_info,
346 const char *smb_name,
347 const char *client_domain,
348 const struct tsocket_address *remote_address,
349 const struct tsocket_address *local_address,
350 const char *service_description,
351 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
353 bool allow_raw = lp_raw_ntlmv2_auth();
355 if (!allow_raw && nt_resp.length >= 48) {
357 * NTLMv2_RESPONSE has at least 48 bytes
358 * and should only be supported via NTLMSSP.
360 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
361 "user [%s\\%s] from[%s]\n",
362 client_domain, smb_name,
363 tsocket_address_string(remote_address, mem_ctx)));
364 return NT_STATUS_INVALID_PARAMETER;
367 return make_user_info(mem_ctx,
368 user_info, smb_name, smb_name,
369 client_domain, client_domain,
370 get_remote_machine_name(),
374 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
375 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
377 AUTH_PASSWORD_RESPONSE);
380 /****************************************************************************
381 Create a guest user_info blob, for anonymous authentication.
382 ****************************************************************************/
384 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
385 const struct tsocket_address *remote_address,
386 const struct tsocket_address *local_address,
387 const char *service_description,
388 struct auth_usersupplied_info **user_info)
392 nt_status = make_user_info(mem_ctx,
403 AUTH_PASSWORD_RESPONSE);
405 return NT_STATUS_IS_OK(nt_status) ? true : false;
408 static NTSTATUS log_nt_token(struct security_token *token)
410 TALLOC_CTX *frame = talloc_stackframe();
415 if ((lp_log_nt_token_command(frame) == NULL) ||
416 (strlen(lp_log_nt_token_command(frame)) == 0)) {
421 group_sidstr = talloc_strdup(frame, "");
422 for (i=1; i<token->num_sids; i++) {
423 group_sidstr = talloc_asprintf(
424 frame, "%s %s", group_sidstr,
425 sid_string_talloc(frame, &token->sids[i]));
428 command = talloc_string_sub(
429 frame, lp_log_nt_token_command(frame),
430 "%s", sid_string_talloc(frame, &token->sids[0]));
431 command = talloc_string_sub(frame, command, "%t", group_sidstr);
433 if (command == NULL) {
435 return NT_STATUS_NO_MEMORY;
438 DEBUG(8, ("running command: [%s]\n", command));
439 if (smbrun(command, NULL, NULL) != 0) {
440 DEBUG(0, ("Could not log NT token\n"));
442 return NT_STATUS_ACCESS_DENIED;
450 * Create the token to use from server_info->info3 and
451 * server_info->sids (the info3/sam groups). Find the unix gids.
454 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
455 const struct auth_serversupplied_info *server_info,
456 DATA_BLOB *session_key,
457 const char *smb_username, /* for ->sanitized_username, for %U subs */
458 struct auth_session_info **session_info_out)
460 struct security_token *t;
463 struct dom_sid tmp_sid;
464 struct auth_session_info *session_info;
468 /* Ensure we can't possible take a code path leading to a
471 return NT_STATUS_LOGON_FAILURE;
474 session_info = talloc_zero(mem_ctx, struct auth_session_info);
476 return NT_STATUS_NO_MEMORY;
479 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
480 if (!session_info->unix_token) {
481 TALLOC_FREE(session_info);
482 return NT_STATUS_NO_MEMORY;
485 session_info->unix_token->uid = server_info->utok.uid;
486 session_info->unix_token->gid = server_info->utok.gid;
488 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
489 if (!session_info->unix_info) {
490 TALLOC_FREE(session_info);
491 return NT_STATUS_NO_MEMORY;
494 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
495 if (!session_info->unix_info->unix_name) {
496 TALLOC_FREE(session_info);
497 return NT_STATUS_NO_MEMORY;
500 /* This is a potentially untrusted username for use in %U */
501 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
502 session_info->unix_info->sanitized_username =
503 talloc_strdup(session_info->unix_info, tmp);
506 data_blob_free(&session_info->session_key);
507 session_info->session_key = data_blob_talloc(session_info,
509 session_key->length);
510 if (!session_info->session_key.data && session_key->length) {
511 return NT_STATUS_NO_MEMORY;
514 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
515 server_info->session_key.length);
518 /* We need to populate session_info->info with the information found in server_info->info3 */
519 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
520 server_info->guest == false,
521 &session_info->info);
522 if (!NT_STATUS_IS_OK(status)) {
523 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
524 TALLOC_FREE(session_info);
528 if (server_info->security_token) {
529 /* Just copy the token, it has already been finalised
530 * (nasty hack to support a cached guest/system session_info
533 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
534 if (!session_info->security_token) {
535 TALLOC_FREE(session_info);
536 return NT_STATUS_NO_MEMORY;
539 session_info->unix_token->ngroups = server_info->utok.ngroups;
540 if (server_info->utok.ngroups != 0) {
541 session_info->unix_token->groups = (gid_t *)talloc_memdup(
542 session_info->unix_token, server_info->utok.groups,
543 sizeof(gid_t)*session_info->unix_token->ngroups);
545 session_info->unix_token->groups = NULL;
548 *session_info_out = session_info;
553 * If winbind is not around, we can not make much use of the SIDs the
554 * domain controller provided us with. Likewise if the user name was
555 * mapped to some local unix user.
558 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
559 (server_info->nss_token)) {
560 char *found_username = NULL;
561 status = create_token_from_username(session_info,
562 server_info->unix_name,
564 &session_info->unix_token->uid,
565 &session_info->unix_token->gid,
567 &session_info->security_token);
568 if (NT_STATUS_IS_OK(status)) {
569 session_info->unix_info->unix_name = found_username;
572 status = create_local_nt_token_from_info3(session_info,
576 &session_info->security_token);
579 if (!NT_STATUS_IS_OK(status)) {
583 /* Convert the SIDs to gids. */
585 session_info->unix_token->ngroups = 0;
586 session_info->unix_token->groups = NULL;
588 t = session_info->security_token;
590 ids = talloc_array(talloc_tos(), struct unixid,
593 return NT_STATUS_NO_MEMORY;
596 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
598 return NT_STATUS_NO_MEMORY;
601 for (i=0; i<t->num_sids; i++) {
603 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
607 if (ids[i].type != ID_TYPE_GID &&
608 ids[i].type != ID_TYPE_BOTH) {
609 DEBUG(10, ("Could not convert SID %s to gid, "
611 sid_string_dbg(&t->sids[i])));
614 if (!add_gid_to_array_unique(session_info->unix_token,
616 &session_info->unix_token->groups,
617 &session_info->unix_token->ngroups)) {
618 return NT_STATUS_NO_MEMORY;
623 * Add the "Unix Group" SID for each gid to catch mapped groups
624 * and their Unix equivalent. This is to solve the backwards
625 * compatibility problem of 'valid users = +ntadmin' where
626 * ntadmin has been paired with "Domain Admins" in the group
627 * mapping table. Otherwise smb.conf would need to be changed
628 * to 'valid user = "Domain Admins"'. --jerry
630 * For consistency we also add the "Unix User" SID,
631 * so that the complete unix token is represented within
635 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
637 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
638 &session_info->security_token->sids,
639 &session_info->security_token->num_sids);
641 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
642 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
643 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
644 &session_info->security_token->sids,
645 &session_info->security_token->num_sids);
648 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
649 debug_unix_user_token(DBGC_AUTH, 10,
650 session_info->unix_token->uid,
651 session_info->unix_token->gid,
652 session_info->unix_token->ngroups,
653 session_info->unix_token->groups);
655 status = log_nt_token(session_info->security_token);
656 if (!NT_STATUS_IS_OK(status)) {
660 *session_info_out = session_info;
664 /***************************************************************************
665 Make (and fill) a server_info struct from a 'struct passwd' by conversion
667 ***************************************************************************/
669 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
670 const char *unix_username,
671 const struct passwd *pwd,
672 struct auth_serversupplied_info **server_info)
675 TALLOC_CTX *tmp_ctx = NULL;
676 struct auth_serversupplied_info *result;
678 tmp_ctx = talloc_stackframe();
679 if (tmp_ctx == NULL) {
680 return NT_STATUS_NO_MEMORY;
683 result = make_server_info(tmp_ctx);
684 if (result == NULL) {
685 status = NT_STATUS_NO_MEMORY;
689 status = passwd_to_SamInfo3(result,
694 if (!NT_STATUS_IS_OK(status)) {
698 result->unix_name = talloc_strdup(result, unix_username);
699 if (result->unix_name == NULL) {
700 status = NT_STATUS_NO_MEMORY;
704 result->utok.uid = pwd->pw_uid;
705 result->utok.gid = pwd->pw_gid;
707 *server_info = talloc_steal(mem_ctx, result);
708 status = NT_STATUS_OK;
710 talloc_free(tmp_ctx);
715 static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
716 struct netr_SamInfo3 *info3)
720 /* Set account name */
721 init_lsa_String(&info3->base.account_name, "SYSTEM");
723 /* Set domain name */
724 init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");
727 status = dom_sid_split_rid(mem_ctx, &global_sid_System,
728 &info3->base.domain_sid,
730 if (!NT_STATUS_IS_OK(status)) {
734 /* Primary gid is the same */
735 info3->base.primary_gid = info3->base.rid;
740 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
741 struct netr_SamInfo3 *info3)
743 const char *guest_account = lp_guest_account();
744 struct dom_sid domain_sid;
748 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
750 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
751 "account [%s]!\n", guest_account));
752 return NT_STATUS_NO_SUCH_USER;
755 /* Set account name */
756 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
758 return NT_STATUS_NO_MEMORY;
760 init_lsa_String(&info3->base.account_name, tmp);
762 /* Set domain name */
763 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
765 return NT_STATUS_NO_MEMORY;
767 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
770 sid_copy(&domain_sid, get_global_sam_sid());
772 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
773 if (info3->base.domain_sid == NULL) {
774 return NT_STATUS_NO_MEMORY;
778 info3->base.rid = DOMAIN_RID_GUEST;
781 info3->base.primary_gid = DOMAIN_RID_GUESTS;
784 info3->base.user_flags = NETLOGON_GUEST;
790 /***************************************************************************
791 Make (and fill) a user_info struct for a guest login.
792 This *must* succeed for smbd to start. If there is no mapping entry for
793 the guest gid, then create one.
795 The resulting structure is a 'session_info' because
796 create_local_token() has already been called on it. This is quite
797 nasty, as the auth subsystem isn't expect this, but the behavior is
799 ***************************************************************************/
801 static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
803 const char *guest_account = lp_guest_account();
804 const char *domain = lp_netbios_name();
805 struct netr_SamInfo3 info3;
809 tmp_ctx = talloc_stackframe();
810 if (tmp_ctx == NULL) {
811 return NT_STATUS_NO_MEMORY;
816 status = get_guest_info3(tmp_ctx, &info3);
817 if (!NT_STATUS_IS_OK(status)) {
818 DEBUG(0, ("get_guest_info3 failed with %s\n",
823 status = make_server_info_info3(tmp_ctx,
828 if (!NT_STATUS_IS_OK(status)) {
829 DEBUG(0, ("make_server_info_info3 failed with %s\n",
834 (*server_info)->guest = true;
836 /* This should not be done here (we should produce a server
837 * info, and later construct a session info from it), but for
838 * now this does not change the previous behavior */
839 status = create_local_token(tmp_ctx, *server_info, NULL,
840 (*server_info)->info3->base.account_name.string,
842 if (!NT_STATUS_IS_OK(status)) {
843 DEBUG(0, ("create_local_token failed: %s\n",
847 talloc_steal(NULL, *session_info);
848 talloc_steal(NULL, *server_info);
850 /* annoying, but the Guest really does have a session key, and it is
852 (*session_info)->session_key = data_blob_talloc_zero(NULL, 16);
854 status = NT_STATUS_OK;
856 TALLOC_FREE(tmp_ctx);
860 /***************************************************************************
861 Make (and fill) a auth_session_info struct for a system user login.
862 This *must* succeed for smbd to start.
863 ***************************************************************************/
865 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
866 struct auth_session_info **session_info)
869 struct auth_serversupplied_info *server_info;
872 tmp_ctx = talloc_stackframe();
873 if (tmp_ctx == NULL) {
874 return NT_STATUS_NO_MEMORY;
877 server_info = make_server_info(tmp_ctx);
879 status = NT_STATUS_NO_MEMORY;
880 DEBUG(0, ("failed making server_info\n"));
884 server_info->info3 = talloc_zero(server_info, struct netr_SamInfo3);
885 if (!server_info->info3) {
886 status = NT_STATUS_NO_MEMORY;
887 DEBUG(0, ("talloc failed setting info3\n"));
891 status = get_system_info3(server_info, server_info->info3);
892 if (!NT_STATUS_IS_OK(status)) {
893 DEBUG(0, ("Failed creating system info3 with %s\n",
898 server_info->utok.uid = sec_initial_uid();
899 server_info->utok.gid = sec_initial_gid();
900 server_info->unix_name = talloc_asprintf(server_info,
901 "NT AUTHORITY%cSYSTEM",
902 *lp_winbind_separator());
904 if (!server_info->unix_name) {
905 status = NT_STATUS_NO_MEMORY;
906 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
910 server_info->security_token = talloc_zero(server_info, struct security_token);
911 if (!server_info->security_token) {
912 status = NT_STATUS_NO_MEMORY;
913 DEBUG(0, ("talloc failed setting security token\n"));
917 status = add_sid_to_array_unique(server_info->security_token->sids,
919 &server_info->security_token->sids,
920 &server_info->security_token->num_sids);
921 if (!NT_STATUS_IS_OK(status)) {
925 /* SYSTEM has all privilages */
926 server_info->security_token->privilege_mask = ~0;
928 /* Now turn the server_info into a session_info with the full token etc */
929 status = create_local_token(mem_ctx, server_info, NULL, "SYSTEM", session_info);
930 talloc_free(server_info);
932 if (!NT_STATUS_IS_OK(status)) {
933 DEBUG(0, ("create_local_token failed: %s\n",
938 talloc_steal(mem_ctx, *session_info);
941 TALLOC_FREE(tmp_ctx);
945 /****************************************************************************
946 Fake a auth_session_info just from a username (as a
947 session_info structure, with create_local_token() already called on
949 ****************************************************************************/
951 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
952 const char *username,
954 struct auth_session_info **session_info)
958 struct auth_serversupplied_info *result;
961 tmp_ctx = talloc_stackframe();
962 if (tmp_ctx == NULL) {
963 return NT_STATUS_NO_MEMORY;
966 pwd = Get_Pwnam_alloc(tmp_ctx, username);
968 status = NT_STATUS_NO_SUCH_USER;
972 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
973 if (!NT_STATUS_IS_OK(status)) {
977 result->nss_token = true;
978 result->guest = is_guest;
980 /* Now turn the server_info into a session_info with the full token etc */
981 status = create_local_token(mem_ctx,
988 talloc_free(tmp_ctx);
993 /* This function MUST only used to create the cached server_info for
996 * This is a lossy conversion. Variables known to be lost so far
999 * - nss_token (not needed because the only read doesn't happen
1000 * for the GUEST user, as this routine populates ->security_token
1002 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1004 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1006 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1007 const struct auth_session_info *src,
1008 struct auth_serversupplied_info *server_info)
1010 struct auth_serversupplied_info *dst;
1012 dst = make_server_info(mem_ctx);
1017 /* This element must be provided to convert back to an auth_serversupplied_info */
1018 SMB_ASSERT(src->unix_info);
1021 dst->system = false;
1023 /* This element must be provided to convert back to an
1024 * auth_serversupplied_info. This needs to be from the
1025 * auth_session_info because the group values in particular
1026 * may change during create_local_token() processing */
1027 SMB_ASSERT(src->unix_token);
1028 dst->utok.uid = src->unix_token->uid;
1029 dst->utok.gid = src->unix_token->gid;
1030 dst->utok.ngroups = src->unix_token->ngroups;
1031 if (src->unix_token->ngroups != 0) {
1032 dst->utok.groups = (gid_t *)talloc_memdup(
1033 dst, src->unix_token->groups,
1034 sizeof(gid_t)*dst->utok.ngroups);
1036 dst->utok.groups = NULL;
1039 /* We must have a security_token as otherwise the lossy
1040 * conversion without nss_token would cause create_local_token
1041 * to take the wrong path */
1042 SMB_ASSERT(src->security_token);
1044 dst->security_token = dup_nt_token(dst, src->security_token);
1045 if (!dst->security_token) {
1050 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1051 src->session_key.length);
1053 /* This is OK because this functions is only used for the
1054 * GUEST account, which has all-zero keys for both values */
1055 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1056 src->session_key.length);
1058 dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1064 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1065 if (!dst->unix_name) {
1073 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1074 const struct auth_session_info *src)
1076 struct auth_session_info *dst;
1078 enum ndr_err_code ndr_err;
1080 ndr_err = ndr_push_struct_blob(
1081 &blob, talloc_tos(), src,
1082 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1083 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1084 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1085 "%s\n", ndr_errstr(ndr_err)));
1089 dst = talloc(mem_ctx, struct auth_session_info);
1091 DEBUG(0, ("talloc failed\n"));
1092 TALLOC_FREE(blob.data);
1096 ndr_err = ndr_pull_struct_blob(
1098 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1099 TALLOC_FREE(blob.data);
1101 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1102 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1103 "%s\n", ndr_errstr(ndr_err)));
1112 * Set a new session key. Used in the rpc server where we have to override the
1113 * SMB level session key with SystemLibraryDTC
1116 bool session_info_set_session_key(struct auth_session_info *info,
1117 DATA_BLOB session_key)
1119 TALLOC_FREE(info->session_key.data);
1121 info->session_key = data_blob_talloc(
1122 info, session_key.data, session_key.length);
1124 return (info->session_key.data != NULL);
1127 static struct auth_session_info *guest_info = NULL;
1129 static struct auth_serversupplied_info *guest_server_info = NULL;
1131 bool init_guest_info(void)
1133 if (guest_info != NULL)
1136 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1139 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1140 struct auth_serversupplied_info **server_info)
1142 /* This is trickier than it would appear to need to be because
1143 * we are trying to avoid certain costly operations when the
1144 * structure is converted to a 'auth_session_info' again in
1145 * create_local_token() */
1146 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1147 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1150 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1151 struct auth_session_info **session_info)
1153 *session_info = copy_session_info(mem_ctx, guest_info);
1154 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1157 static struct auth_session_info *system_info = NULL;
1159 NTSTATUS init_system_session_info(void)
1161 if (system_info != NULL)
1162 return NT_STATUS_OK;
1164 return make_new_session_info_system(NULL, &system_info);
1167 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1168 struct auth_session_info **session_info)
1170 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1171 *session_info = copy_session_info(mem_ctx, system_info);
1172 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1175 const struct auth_session_info *get_session_info_system(void)
1180 /***************************************************************************
1181 Purely internal function for make_server_info_info3
1182 ***************************************************************************/
1184 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1185 const char *username, char **found_username,
1186 struct passwd **pwd,
1187 bool *username_was_mapped)
1189 char *orig_dom_user = NULL;
1190 char *dom_user = NULL;
1191 char *lower_username = NULL;
1192 char *real_username = NULL;
1193 struct passwd *passwd;
1195 lower_username = talloc_strdup(mem_ctx, username);
1196 if (!lower_username) {
1197 return NT_STATUS_NO_MEMORY;
1199 if (!strlower_m( lower_username )) {
1200 return NT_STATUS_INVALID_PARAMETER;
1203 orig_dom_user = talloc_asprintf(mem_ctx,
1206 *lp_winbind_separator(),
1208 if (!orig_dom_user) {
1209 return NT_STATUS_NO_MEMORY;
1212 /* Get the passwd struct. Try to create the account if necessary. */
1214 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1216 return NT_STATUS_NO_MEMORY;
1219 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1221 DEBUG(3, ("Failed to find authenticated user %s via "
1222 "getpwnam(), denying access.\n", dom_user));
1223 return NT_STATUS_NO_SUCH_USER;
1226 if (!real_username) {
1227 return NT_STATUS_NO_MEMORY;
1232 /* This is pointless -- there is no support for differing
1233 unix and windows names. Make sure to always store the
1234 one we actually looked up and succeeded. Have I mentioned
1235 why I hate the 'winbind use default domain' parameter?
1238 *found_username = talloc_strdup( mem_ctx, real_username );
1240 return NT_STATUS_OK;
1243 /****************************************************************************
1244 Wrapper to allow the getpwnam() call to strip the domain name and
1245 try again in case a local UNIX user is already there. Also run through
1246 the username if we fallback to the username only.
1247 ****************************************************************************/
1249 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1250 char **p_save_username, bool create )
1252 struct passwd *pw = NULL;
1254 char *username = NULL;
1256 /* we only save a copy of the username it has been mangled
1257 by winbindd use default domain */
1258 *p_save_username = NULL;
1260 /* don't call map_username() here since it has to be done higher
1261 up the stack so we don't call it multiple times */
1263 username = talloc_strdup(mem_ctx, domuser);
1268 p = strchr_m( username, *lp_winbind_separator() );
1270 /* code for a DOMAIN\user string */
1273 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1275 /* make sure we get the case of the username correct */
1276 /* work around 'winbind use default domain = yes' */
1278 if ( lp_winbind_use_default_domain() &&
1279 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1282 /* split the domain and username into 2 strings */
1286 *p_save_username = talloc_asprintf(mem_ctx,
1289 *lp_winbind_separator(),
1291 if (!*p_save_username) {
1296 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1303 /* setup for lookup of just the username */
1304 /* remember that p and username are overlapping memory */
1307 username = talloc_strdup(mem_ctx, p);
1313 /* just lookup a plain username */
1315 pw = Get_Pwnam_alloc(mem_ctx, username);
1317 /* Create local user if requested but only if winbindd
1318 is not running. We need to protect against cases
1319 where winbindd is failing and then prematurely
1320 creating users in /etc/passwd */
1322 if ( !pw && create && !winbind_ping() ) {
1323 /* Don't add a machine account. */
1324 if (username[strlen(username)-1] == '$')
1327 _smb_create_user(NULL, username, NULL);
1328 pw = Get_Pwnam_alloc(mem_ctx, username);
1331 /* one last check for a valid passwd struct */
1334 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1339 /***************************************************************************
1340 Make a server_info struct from the info3 returned by a domain logon
1341 ***************************************************************************/
1343 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1344 const char *sent_nt_username,
1346 struct auth_serversupplied_info **server_info,
1347 const struct netr_SamInfo3 *info3)
1349 NTSTATUS nt_status = NT_STATUS_OK;
1350 char *found_username = NULL;
1351 const char *nt_domain;
1352 const char *nt_username;
1353 struct dom_sid user_sid;
1354 struct dom_sid group_sid;
1355 bool username_was_mapped;
1357 struct auth_serversupplied_info *result;
1358 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1361 Here is where we should check the list of
1362 trusted domains, and verify that the SID
1366 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1367 nt_status = NT_STATUS_INVALID_PARAMETER;
1371 if (!sid_compose(&group_sid, info3->base.domain_sid,
1372 info3->base.primary_gid)) {
1373 nt_status = NT_STATUS_INVALID_PARAMETER;
1377 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
1379 /* If the server didn't give us one, just use the one we sent
1381 nt_username = sent_nt_username;
1384 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1386 /* If the server didn't give us one, just use the one we sent
1391 /* If getpwnam() fails try the add user script (2.2.x behavior).
1393 We use the _unmapped_ username here in an attempt to provide
1394 consistent username mapping behavior between kerberos and NTLM[SSP]
1395 authentication in domain mode security. I.E. Username mapping
1396 should be applied to the fully qualified username
1397 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1398 called map_username() unnecessarily in make_user_info_map() but
1399 that is how the current code is designed. Making the change here
1400 is the least disruptive place. -- jerry */
1402 /* this call will try to create the user if necessary */
1404 nt_status = check_account(tmp_ctx,
1409 &username_was_mapped);
1411 if (!NT_STATUS_IS_OK(nt_status)) {
1412 /* Handle 'map to guest = Bad Uid */
1413 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
1414 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
1415 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
1416 DBG_NOTICE("Try to map %s to guest account",
1418 nt_status = make_server_info_guest(tmp_ctx, &result);
1419 if (NT_STATUS_IS_OK(nt_status)) {
1420 *server_info = talloc_move(mem_ctx, &result);
1426 result = make_server_info(tmp_ctx);
1427 if (result == NULL) {
1428 DEBUG(4, ("make_server_info failed!\n"));
1429 nt_status = NT_STATUS_NO_MEMORY;
1433 result->unix_name = talloc_strdup(result, found_username);
1435 /* copy in the info3 */
1436 result->info3 = copy_netr_SamInfo3(result, info3);
1437 if (result->info3 == NULL) {
1438 nt_status = NT_STATUS_NO_MEMORY;
1442 /* Fill in the unix info we found on the way */
1444 result->utok.uid = pwd->pw_uid;
1445 result->utok.gid = pwd->pw_gid;
1447 /* ensure we are never given NULL session keys */
1449 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
1450 result->session_key = data_blob_null;
1452 result->session_key = data_blob_talloc(
1453 result, info3->base.key.key,
1454 sizeof(info3->base.key.key));
1457 if (all_zero(info3->base.LMSessKey.key,
1458 sizeof(info3->base.LMSessKey.key))) {
1459 result->lm_session_key = data_blob_null;
1461 result->lm_session_key = data_blob_talloc(
1462 result, info3->base.LMSessKey.key,
1463 sizeof(info3->base.LMSessKey.key));
1466 result->nss_token |= username_was_mapped;
1468 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1470 *server_info = talloc_move(mem_ctx, &result);
1472 nt_status = NT_STATUS_OK;
1474 talloc_free(tmp_ctx);
1479 /*****************************************************************************
1480 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1481 ******************************************************************************/
1483 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1484 const char *sent_nt_username,
1486 const struct wbcAuthUserInfo *info,
1487 struct auth_serversupplied_info **server_info)
1489 struct netr_SamInfo3 info3;
1490 struct netr_SamInfo6 *info6;
1492 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
1494 return NT_STATUS_NO_MEMORY;
1497 info3.base = info6->base;
1498 info3.sidcount = info6->sidcount;
1499 info3.sids = info6->sids;
1501 return make_server_info_info3(mem_ctx,
1502 sent_nt_username, domain,
1503 server_info, &info3);
1507 * Verify whether or not given domain is trusted.
1509 * This should only be used on a DC.
1511 * @param domain_name name of the domain to be verified
1512 * @return true if domain is one of the trusted ones or
1513 * false if otherwise
1516 bool is_trusted_domain(const char* dom_name)
1524 if (dom_name == NULL || dom_name[0] == '\0') {
1528 if (strequal(dom_name, get_global_sam_name())) {
1533 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1534 "[%s]\n", dom_name ));
1535 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1544 on a logon error possibly map the error to success if "map to guest"
1547 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1551 struct auth_serversupplied_info **server_info)
1553 user = user ? user : "";
1554 domain = domain ? domain : "";
1556 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1557 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
1558 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
1559 DEBUG(3,("No such user %s [%s] - using guest account\n",
1561 return make_server_info_guest(mem_ctx, server_info);
1563 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1564 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
1565 DEBUG(3,("Registered username %s for guest access\n",
1567 return make_server_info_guest(mem_ctx, server_info);
1575 Extract session key from a session info and return it in a blob
1576 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1578 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1579 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1581 Note that returned session_key is referencing the original key, it is supposed to be
1582 short-lived. If original session_info->session_key is gone, the reference will be broken.
1584 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
1587 if (session_key == NULL || session_info == NULL) {
1588 return NT_STATUS_INVALID_PARAMETER;
1591 if (session_info->session_key.length == 0) {
1592 return NT_STATUS_NO_USER_SESSION_KEY;
1595 *session_key = session_info->session_key;
1596 if (intent == KEY_USE_16BYTES) {
1597 session_key->length = MIN(session_info->session_key.length, 16);
1599 return NT_STATUS_OK;