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 "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
30 #include "../lib/util/util_pw.h"
31 #include "lib/winbind_util.h"
33 #include "../librpc/gen_ndr/ndr_auth.h"
34 #include "../auth/auth_sam_reply.h"
37 #define DBGC_CLASS DBGC_AUTH
39 /****************************************************************************
40 Create a UNIX user on demand.
41 ****************************************************************************/
43 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
45 TALLOC_CTX *ctx = talloc_tos();
49 add_script = talloc_strdup(ctx, lp_adduser_script());
50 if (!add_script || !*add_script) {
53 add_script = talloc_all_string_sub(ctx,
61 add_script = talloc_all_string_sub(ctx,
70 add_script = talloc_all_string_sub(ctx,
78 ret = smbrun(add_script,NULL);
81 ("smb_create_user: Running the command `%s' gave %d\n",
86 /****************************************************************************
87 Create an auth_usersupplied_data structure after appropriate mapping.
88 ****************************************************************************/
90 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
92 const char *client_domain,
93 const char *workstation_name,
94 const struct tsocket_address *remote_address,
97 const struct samr_Password *lm_interactive_pwd,
98 const struct samr_Password *nt_interactive_pwd,
99 const char *plaintext,
100 enum auth_password_state password_state)
105 char *internal_username = NULL;
107 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
108 if (!internal_username) {
109 return NT_STATUS_NO_MEMORY;
112 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
113 client_domain, smb_name, workstation_name));
115 domain = client_domain;
117 /* If you connect to a Windows domain member using a bogus domain name,
118 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
119 * the Windows box is a DC the name will become DOMAIN\user and be
120 * authenticated against AD, if the Windows box is a member server but
121 * not a DC the name will become WORKSTATION\user. A standalone
122 * non-domain member box will also map to WORKSTATION\user.
123 * This also deals with the client passing in a "" domain */
125 if (!is_trusted_domain(domain) &&
126 !strequal(domain, my_sam_name()))
128 if (lp_map_untrusted_to_domain())
129 domain = my_sam_name();
131 domain = get_global_sam_name();
132 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
133 "workstation [%s]\n",
134 client_domain, domain, smb_name, workstation_name));
137 /* We know that the given domain is trusted (and we are allowing them),
138 * it is our global SAM name, or for legacy behavior it is our
139 * primary domain name */
141 result = make_user_info(user_info, smb_name, internal_username,
142 client_domain, domain, workstation_name,
143 remote_address, lm_pwd, nt_pwd,
144 lm_interactive_pwd, nt_interactive_pwd,
145 plaintext, password_state);
146 if (NT_STATUS_IS_OK(result)) {
147 /* We have tried mapping */
148 (*user_info)->mapped_state = True;
149 /* did we actually map the user to a different name? */
150 (*user_info)->was_mapped = was_mapped;
155 /****************************************************************************
156 Create an auth_usersupplied_data, making the DATA_BLOBs here.
157 Decrypt and encrypt the passwords.
158 ****************************************************************************/
160 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
161 const char *smb_name,
162 const char *client_domain,
163 const char *workstation_name,
164 const struct tsocket_address *remote_address,
165 uint32 logon_parameters,
166 const uchar *lm_network_pwd,
168 const uchar *nt_network_pwd,
173 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
174 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
176 status = make_user_info_map(user_info,
177 smb_name, client_domain,
180 lm_pwd_len ? &lm_blob : NULL,
181 nt_pwd_len ? &nt_blob : NULL,
183 AUTH_PASSWORD_RESPONSE);
185 if (NT_STATUS_IS_OK(status)) {
186 (*user_info)->logon_parameters = logon_parameters;
188 ret = NT_STATUS_IS_OK(status) ? True : False;
190 data_blob_free(&lm_blob);
191 data_blob_free(&nt_blob);
195 /****************************************************************************
196 Create an auth_usersupplied_data, making the DATA_BLOBs here.
197 Decrypt and encrypt the passwords.
198 ****************************************************************************/
200 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
201 const char *smb_name,
202 const char *client_domain,
203 const char *workstation_name,
204 const struct tsocket_address *remote_address,
205 uint32 logon_parameters,
207 const uchar lm_interactive_pwd[16],
208 const uchar nt_interactive_pwd[16],
209 const uchar *dc_sess_key)
211 struct samr_Password lm_pwd;
212 struct samr_Password nt_pwd;
213 unsigned char local_lm_response[24];
214 unsigned char local_nt_response[24];
215 unsigned char key[16];
217 memcpy(key, dc_sess_key, 16);
219 if (lm_interactive_pwd)
220 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
222 if (nt_interactive_pwd)
223 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
225 #ifdef DEBUG_PASSWORD
227 dump_data(100, key, sizeof(key));
229 DEBUG(100,("lm owf password:"));
230 dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
232 DEBUG(100,("nt owf password:"));
233 dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
236 if (lm_interactive_pwd)
237 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
239 if (nt_interactive_pwd)
240 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
242 #ifdef DEBUG_PASSWORD
243 DEBUG(100,("decrypt of lm owf password:"));
244 dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
246 DEBUG(100,("decrypt of nt owf password:"));
247 dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
250 if (lm_interactive_pwd)
251 SMBOWFencrypt(lm_pwd.hash, chal,
254 if (nt_interactive_pwd)
255 SMBOWFencrypt(nt_pwd.hash, chal,
258 /* Password info paranoia */
264 DATA_BLOB local_lm_blob;
265 DATA_BLOB local_nt_blob;
267 if (lm_interactive_pwd) {
268 local_lm_blob = data_blob(local_lm_response,
269 sizeof(local_lm_response));
272 if (nt_interactive_pwd) {
273 local_nt_blob = data_blob(local_nt_response,
274 sizeof(local_nt_response));
277 nt_status = make_user_info_map(
279 smb_name, client_domain, workstation_name,
281 lm_interactive_pwd ? &local_lm_blob : NULL,
282 nt_interactive_pwd ? &local_nt_blob : NULL,
283 lm_interactive_pwd ? &lm_pwd : NULL,
284 nt_interactive_pwd ? &nt_pwd : NULL,
285 NULL, AUTH_PASSWORD_HASH);
287 if (NT_STATUS_IS_OK(nt_status)) {
288 (*user_info)->logon_parameters = logon_parameters;
291 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
292 data_blob_free(&local_lm_blob);
293 data_blob_free(&local_nt_blob);
299 /****************************************************************************
300 Create an auth_usersupplied_data structure
301 ****************************************************************************/
303 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
304 const char *smb_name,
305 const char *client_domain,
306 const struct tsocket_address *remote_address,
308 DATA_BLOB plaintext_password)
311 DATA_BLOB local_lm_blob;
312 DATA_BLOB local_nt_blob;
313 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
314 char *plaintext_password_string;
316 * Not encrypted - do so.
319 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
321 if (plaintext_password.data && plaintext_password.length) {
322 unsigned char local_lm_response[24];
324 #ifdef DEBUG_PASSWORD
325 DEBUG(10,("Unencrypted password (len %d):\n",
326 (int)plaintext_password.length));
327 dump_data(100, plaintext_password.data,
328 plaintext_password.length);
331 SMBencrypt( (const char *)plaintext_password.data,
332 (const uchar*)chal, local_lm_response);
333 local_lm_blob = data_blob(local_lm_response, 24);
335 /* We can't do an NT hash here, as the password needs to be
337 local_nt_blob = data_blob_null;
339 local_lm_blob = data_blob_null;
340 local_nt_blob = data_blob_null;
343 plaintext_password_string = talloc_strndup(talloc_tos(),
344 (const char *)plaintext_password.data,
345 plaintext_password.length);
346 if (!plaintext_password_string) {
350 ret = make_user_info_map(
351 user_info, smb_name, client_domain,
352 get_remote_machine_name(),
354 local_lm_blob.data ? &local_lm_blob : NULL,
355 local_nt_blob.data ? &local_nt_blob : NULL,
357 plaintext_password_string,
358 AUTH_PASSWORD_PLAIN);
360 if (plaintext_password_string) {
361 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
362 talloc_free(plaintext_password_string);
365 data_blob_free(&local_lm_blob);
366 return NT_STATUS_IS_OK(ret) ? True : False;
369 /****************************************************************************
370 Create an auth_usersupplied_data structure
371 ****************************************************************************/
373 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
374 const char *smb_name,
375 const char *client_domain,
376 const struct tsocket_address *remote_address,
377 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
379 return make_user_info_map(user_info, smb_name,
381 get_remote_machine_name(),
383 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
384 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
386 AUTH_PASSWORD_RESPONSE);
389 /****************************************************************************
390 Create a guest user_info blob, for anonymous authenticaion.
391 ****************************************************************************/
393 bool make_user_info_guest(const struct tsocket_address *remote_address,
394 struct auth_usersupplied_info **user_info)
398 nt_status = make_user_info(user_info,
406 AUTH_PASSWORD_RESPONSE);
408 return NT_STATUS_IS_OK(nt_status) ? True : False;
411 static NTSTATUS log_nt_token(struct security_token *token)
413 TALLOC_CTX *frame = talloc_stackframe();
418 if ((lp_log_nt_token_command() == NULL) ||
419 (strlen(lp_log_nt_token_command()) == 0)) {
424 group_sidstr = talloc_strdup(frame, "");
425 for (i=1; i<token->num_sids; i++) {
426 group_sidstr = talloc_asprintf(
427 frame, "%s %s", group_sidstr,
428 sid_string_talloc(frame, &token->sids[i]));
431 command = talloc_string_sub(
432 frame, lp_log_nt_token_command(),
433 "%s", sid_string_talloc(frame, &token->sids[0]));
434 command = talloc_string_sub(frame, command, "%t", group_sidstr);
436 if (command == NULL) {
438 return NT_STATUS_NO_MEMORY;
441 DEBUG(8, ("running command: [%s]\n", command));
442 if (smbrun(command, NULL) != 0) {
443 DEBUG(0, ("Could not log NT token\n"));
445 return NT_STATUS_ACCESS_DENIED;
453 * Create the token to use from server_info->info3 and
454 * server_info->sids (the info3/sam groups). Find the unix gids.
457 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
458 const struct auth_serversupplied_info *server_info,
459 DATA_BLOB *session_key,
460 struct auth_session_info **session_info_out)
462 struct security_token *t;
465 struct dom_sid tmp_sid;
466 struct auth_session_info *session_info;
467 struct wbcUnixId *ids;
468 struct auth_user_info_dc *user_info_dc;
469 union netr_Validation val;
471 /* Ensure we can't possible take a code path leading to a
474 return NT_STATUS_LOGON_FAILURE;
477 session_info = make_auth_session_info(mem_ctx);
479 return NT_STATUS_NO_MEMORY;
482 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
483 if (!session_info->unix_token) {
484 TALLOC_FREE(session_info);
485 return NT_STATUS_NO_MEMORY;
488 session_info->unix_token->uid = server_info->utok.uid;
489 session_info->unix_token->gid = server_info->utok.gid;
491 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
492 if (!session_info->unix_info) {
493 TALLOC_FREE(session_info);
494 return NT_STATUS_NO_MEMORY;
497 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
498 if (!session_info->unix_info->unix_name) {
499 TALLOC_FREE(session_info);
500 return NT_STATUS_NO_MEMORY;
503 session_info->unix_info->sanitized_username = talloc_strdup(session_info, server_info->sanitized_username);
504 if (!session_info->unix_info->sanitized_username) {
505 TALLOC_FREE(session_info);
506 return NT_STATUS_NO_MEMORY;
509 session_info->unix_info->guest = server_info->guest;
510 session_info->unix_info->system = server_info->system;
513 data_blob_free(&session_info->session_key);
514 session_info->session_key = data_blob_talloc(session_info,
516 session_key->length);
517 if (!session_info->session_key.data && session_key->length) {
518 return NT_STATUS_NO_MEMORY;
521 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
522 server_info->session_key.length);
525 if (session_info->security_token) {
526 /* Just copy the token, it has already been finalised
527 * (nasty hack to support a cached guest session_info,
528 * and a possible strategy for auth_samba4 to pass in
529 * a finalised session) */
531 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
532 if (!session_info->security_token) {
533 TALLOC_FREE(session_info);
534 return NT_STATUS_NO_MEMORY;
537 session_info->unix_token->ngroups = server_info->utok.ngroups;
538 if (server_info->utok.ngroups != 0) {
539 session_info->unix_token->groups = (gid_t *)talloc_memdup(
540 session_info->unix_token, server_info->utok.groups,
541 sizeof(gid_t)*session_info->unix_token->ngroups);
543 session_info->unix_token->groups = NULL;
546 *session_info_out = session_info;
550 val.sam3 = server_info->info3;
552 /* Convert into something we can build a struct
553 * auth_session_info from. Most of the work here
554 * will be to convert the SIDS, which we will then ignore, but
555 * this is the easier way to handle it */
556 status = make_user_info_dc_netlogon_validation(talloc_tos(), "", 3, &val, &user_info_dc);
557 if (!NT_STATUS_IS_OK(status)) {
558 DEBUG(0, ("conversion of info3 into user_info_dc failed!\n"));
559 TALLOC_FREE(session_info);
563 session_info->info = talloc_move(session_info, &user_info_dc->info);
564 talloc_free(user_info_dc);
567 * If winbind is not around, we can not make much use of the SIDs the
568 * domain controller provided us with. Likewise if the user name was
569 * mapped to some local unix user.
572 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
573 (server_info->nss_token)) {
574 status = create_token_from_username(session_info,
575 server_info->unix_name,
577 &session_info->unix_token->uid,
578 &session_info->unix_token->gid,
579 &session_info->unix_info->unix_name,
580 &session_info->security_token);
583 status = create_local_nt_token_from_info3(session_info,
587 &session_info->security_token);
590 if (!NT_STATUS_IS_OK(status)) {
594 /* Convert the SIDs to gids. */
596 session_info->unix_token->ngroups = 0;
597 session_info->unix_token->groups = NULL;
599 t = session_info->security_token;
601 ids = talloc_array(talloc_tos(), struct wbcUnixId,
604 return NT_STATUS_NO_MEMORY;
607 if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
609 return NT_STATUS_NO_MEMORY;
612 /* Start at index 1, where the groups start. */
614 for (i=1; i<t->num_sids; i++) {
616 if (ids[i].type != WBC_ID_TYPE_GID) {
617 DEBUG(10, ("Could not convert SID %s to gid, "
619 sid_string_dbg(&t->sids[i])));
622 if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
623 &session_info->unix_token->groups,
624 &session_info->unix_token->ngroups)) {
625 return NT_STATUS_NO_MEMORY;
630 * Add the "Unix Group" SID for each gid to catch mapped groups
631 * and their Unix equivalent. This is to solve the backwards
632 * compatibility problem of 'valid users = +ntadmin' where
633 * ntadmin has been paired with "Domain Admins" in the group
634 * mapping table. Otherwise smb.conf would need to be changed
635 * to 'valid user = "Domain Admins"'. --jerry
637 * For consistency we also add the "Unix User" SID,
638 * so that the complete unix token is represented within
642 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
644 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
645 &session_info->security_token->sids,
646 &session_info->security_token->num_sids);
648 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
649 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
650 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
651 &session_info->security_token->sids,
652 &session_info->security_token->num_sids);
655 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
656 debug_unix_user_token(DBGC_AUTH, 10,
657 session_info->unix_token->uid,
658 session_info->unix_token->gid,
659 session_info->unix_token->ngroups,
660 session_info->unix_token->groups);
662 status = log_nt_token(session_info->security_token);
663 if (!NT_STATUS_IS_OK(status)) {
667 *session_info_out = session_info;
671 /***************************************************************************
672 Make (and fill) a server_info struct from a 'struct passwd' by conversion
674 ***************************************************************************/
676 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
681 struct samu *sampass = NULL;
682 char *qualified_name = NULL;
683 TALLOC_CTX *mem_ctx = NULL;
684 struct dom_sid u_sid;
685 enum lsa_SidType type;
686 struct auth_serversupplied_info *result;
689 * The SID returned in server_info->sam_account is based
690 * on our SAM sid even though for a pure UNIX account this should
691 * not be the case as it doesn't really exist in the SAM db.
692 * This causes lookups on "[in]valid users" to fail as they
693 * will lookup this name as a "Unix User" SID to check against
694 * the user token. Fix this by adding the "Unix User"\unix_username
695 * SID to the sid array. The correct fix should probably be
696 * changing the server_info->sam_account user SID to be a
697 * S-1-22 Unix SID, but this might break old configs where
698 * plaintext passwords were used with no SAM backend.
701 mem_ctx = talloc_init("make_server_info_pw_tmp");
703 return NT_STATUS_NO_MEMORY;
706 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
707 unix_users_domain_name(),
709 if (!qualified_name) {
710 TALLOC_FREE(mem_ctx);
711 return NT_STATUS_NO_MEMORY;
714 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
717 TALLOC_FREE(mem_ctx);
718 return NT_STATUS_NO_SUCH_USER;
721 TALLOC_FREE(mem_ctx);
723 if (type != SID_NAME_USER) {
724 return NT_STATUS_NO_SUCH_USER;
727 if ( !(sampass = samu_new( NULL )) ) {
728 return NT_STATUS_NO_MEMORY;
731 status = samu_set_unix( sampass, pwd );
732 if (!NT_STATUS_IS_OK(status)) {
736 /* In pathological cases the above call can set the account
737 * name to the DOMAIN\username form. Reset the account name
738 * using unix_username */
739 pdb_set_username(sampass, unix_username, PDB_SET);
741 /* set the user sid to be the calculated u_sid */
742 pdb_set_user_sid(sampass, &u_sid, PDB_SET);
744 result = make_server_info(NULL);
745 if (result == NULL) {
746 TALLOC_FREE(sampass);
747 return NT_STATUS_NO_MEMORY;
750 status = samu_to_SamInfo3(result, sampass, lp_netbios_name(),
751 &result->info3, &result->extra);
752 TALLOC_FREE(sampass);
753 if (!NT_STATUS_IS_OK(status)) {
754 DEBUG(10, ("Failed to convert samu to info3: %s\n",
760 result->unix_name = talloc_strdup(result, unix_username);
761 result->sanitized_username = sanitize_username(result, unix_username);
763 if ((result->unix_name == NULL)
764 || (result->sanitized_username == NULL)) {
766 return NT_STATUS_NO_MEMORY;
769 result->utok.uid = pwd->pw_uid;
770 result->utok.gid = pwd->pw_gid;
772 *server_info = result;
777 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
778 struct netr_SamInfo3 *info3)
780 const char *guest_account = lp_guestaccount();
781 struct dom_sid domain_sid;
785 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
787 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
788 "account [%s]!\n", guest_account));
789 return NT_STATUS_NO_SUCH_USER;
792 /* Set acount name */
793 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
795 return NT_STATUS_NO_MEMORY;
797 init_lsa_String(&info3->base.account_name, tmp);
799 /* Set domain name */
800 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
802 return NT_STATUS_NO_MEMORY;
804 init_lsa_StringLarge(&info3->base.domain, tmp);
807 sid_copy(&domain_sid, get_global_sam_sid());
809 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
810 if (info3->base.domain_sid == NULL) {
811 return NT_STATUS_NO_MEMORY;
815 info3->base.rid = DOMAIN_RID_GUEST;
818 info3->base.primary_gid = BUILTIN_RID_GUESTS;
824 /***************************************************************************
825 Make (and fill) a user_info struct for a guest login.
826 This *must* succeed for smbd to start. If there is no mapping entry for
827 the guest gid, then create one.
829 The resulting structure is a 'session_info' because
830 create_local_token() has already been called on it. This is quite
831 nasty, as the auth subsystem isn't expect this, but the behaviour is
833 ***************************************************************************/
835 static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
837 static const char zeros[16] = {0};
838 const char *guest_account = lp_guestaccount();
839 const char *domain = lp_netbios_name();
840 struct netr_SamInfo3 info3;
845 tmp_ctx = talloc_stackframe();
846 if (tmp_ctx == NULL) {
847 return NT_STATUS_NO_MEMORY;
852 status = get_guest_info3(tmp_ctx, &info3);
853 if (!NT_STATUS_IS_OK(status)) {
854 DEBUG(0, ("get_guest_info3 failed with %s\n",
859 status = make_server_info_info3(tmp_ctx,
864 if (!NT_STATUS_IS_OK(status)) {
865 DEBUG(0, ("make_server_info_info3 failed with %s\n",
870 (*server_info)->guest = True;
872 /* This should not be done here (we should produce a server
873 * info, and later construct a session info from it), but for
874 * now this does not change the previous behaviours */
875 status = create_local_token(tmp_ctx, *server_info, NULL, session_info);
876 if (!NT_STATUS_IS_OK(status)) {
877 DEBUG(0, ("create_local_token failed: %s\n",
881 talloc_steal(NULL, *session_info);
882 talloc_steal(NULL, *server_info);
884 /* annoying, but the Guest really does have a session key, and it is
886 (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
888 alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string,
889 ". _-$", sizeof(tmp));
890 (*session_info)->unix_info->sanitized_username = talloc_strdup(*session_info, tmp);
892 status = NT_STATUS_OK;
894 TALLOC_FREE(tmp_ctx);
898 /***************************************************************************
899 Make (and fill) a auth_session_info struct for a system user login.
900 This *must* succeed for smbd to start.
901 ***************************************************************************/
903 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
904 struct auth_session_info **session_info)
909 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
911 return NT_STATUS_NO_SUCH_USER;
914 status = make_session_info_from_username(mem_ctx,
919 if (!NT_STATUS_IS_OK(status)) {
923 (*session_info)->unix_info->system = true;
925 status = add_sid_to_array_unique((*session_info)->security_token->sids,
927 &(*session_info)->security_token->sids,
928 &(*session_info)->security_token->num_sids);
929 if (!NT_STATUS_IS_OK(status)) {
930 TALLOC_FREE((*session_info));
937 /****************************************************************************
938 Fake a auth_session_info just from a username (as a
939 session_info structure, with create_local_token() already called on
941 ****************************************************************************/
943 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
944 const char *username,
946 struct auth_session_info **session_info)
948 struct auth_serversupplied_info *result;
952 pwd = Get_Pwnam_alloc(talloc_tos(), username);
954 return NT_STATUS_NO_SUCH_USER;
957 status = make_server_info_pw(&result, pwd->pw_name, pwd);
961 if (!NT_STATUS_IS_OK(status)) {
965 result->nss_token = true;
966 result->guest = is_guest;
968 /* Now turn the server_info into a session_info with the full token etc */
969 status = create_local_token(mem_ctx, result, NULL, session_info);
974 /* This function MUST only used to create the cached server_info for
977 * This is a lossy conversion. Variables known to be lost so far
980 * - nss_token (not needed because the only read doesn't happen
981 * for the GUEST user, as this routine populates ->security_token
983 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
985 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
987 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
988 const struct auth_session_info *src,
989 struct auth_serversupplied_info *server_info)
991 struct auth_serversupplied_info *dst;
993 dst = make_server_info(mem_ctx);
998 /* This element must be provided to convert back to an auth_serversupplied_info */
999 SMB_ASSERT(src->unix_info);
1001 dst->guest = src->unix_info->guest;
1002 dst->system = src->unix_info->system;
1004 /* This element must be provided to convert back to an
1005 * auth_serversupplied_info. This needs to be from hte
1006 * auth_session_info because the group values in particular
1007 * may change during create_local_token() processing */
1008 SMB_ASSERT(src->unix_token);
1009 dst->utok.uid = src->unix_token->uid;
1010 dst->utok.gid = src->unix_token->gid;
1011 dst->utok.ngroups = src->unix_token->ngroups;
1012 if (src->unix_token->ngroups != 0) {
1013 dst->utok.groups = (gid_t *)talloc_memdup(
1014 dst, src->unix_token->groups,
1015 sizeof(gid_t)*dst->utok.ngroups);
1017 dst->utok.groups = NULL;
1020 /* We must have a security_token as otherwise the lossy
1021 * conversion without nss_token would cause create_local_token
1022 * to take the wrong path */
1023 SMB_ASSERT(src->security_token);
1025 dst->security_token = dup_nt_token(dst, src->security_token);
1026 if (!dst->security_token) {
1031 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1032 src->session_key.length);
1034 /* This is OK because this functions is only used for the
1035 * GUEST account, which has all-zero keys for both values */
1036 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1037 src->session_key.length);
1039 dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1045 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1046 if (!dst->unix_name) {
1051 dst->sanitized_username = talloc_strdup(dst, src->unix_info->sanitized_username);
1052 if (!dst->sanitized_username) {
1060 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1061 const struct auth_session_info *src)
1063 struct auth_session_info *dst;
1065 enum ndr_err_code ndr_err;
1067 ndr_err = ndr_push_struct_blob(
1068 &blob, talloc_tos(), src,
1069 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1070 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1071 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1072 "%s\n", ndr_errstr(ndr_err)));
1076 dst = talloc(mem_ctx, struct auth_session_info);
1078 DEBUG(0, ("talloc failed\n"));
1079 TALLOC_FREE(blob.data);
1083 ndr_err = ndr_pull_struct_blob(
1085 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1086 TALLOC_FREE(blob.data);
1088 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1089 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1090 "%s\n", ndr_errstr(ndr_err)));
1099 * Set a new session key. Used in the rpc server where we have to override the
1100 * SMB level session key with SystemLibraryDTC
1103 bool session_info_set_session_key(struct auth_session_info *info,
1104 DATA_BLOB session_key)
1106 TALLOC_FREE(info->session_key.data);
1108 info->session_key = data_blob_talloc(
1109 info, session_key.data, session_key.length);
1111 return (info->session_key.data != NULL);
1114 static struct auth_session_info *guest_info = NULL;
1116 static struct auth_serversupplied_info *guest_server_info = NULL;
1118 bool init_guest_info(void)
1120 if (guest_info != NULL)
1123 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1126 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1127 struct auth_serversupplied_info **server_info)
1129 /* This is trickier than it would appear to need to be because
1130 * we are trying to avoid certain costly operations when the
1131 * structure is converted to a 'auth_session_info' again in
1132 * create_local_token() */
1133 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1134 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1137 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1138 struct auth_session_info **session_info)
1140 *session_info = copy_session_info(mem_ctx, guest_info);
1141 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1144 static struct auth_session_info *system_info = NULL;
1146 NTSTATUS init_system_info(void)
1148 if (system_info != NULL)
1149 return NT_STATUS_OK;
1151 return make_new_session_info_system(NULL, &system_info);
1154 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1155 struct auth_session_info **session_info)
1157 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1158 *session_info = copy_session_info(mem_ctx, system_info);
1159 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1162 const struct auth_session_info *get_session_info_system(void)
1167 bool copy_current_user(struct current_user *dst, struct current_user *src)
1170 struct security_token *nt_token;
1172 groups = (gid_t *)memdup(src->ut.groups,
1173 sizeof(gid_t) * src->ut.ngroups);
1174 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1178 nt_token = dup_nt_token(NULL, src->nt_user_token);
1179 if (nt_token == NULL) {
1184 dst->conn = src->conn;
1185 dst->vuid = src->vuid;
1186 dst->ut.uid = src->ut.uid;
1187 dst->ut.gid = src->ut.gid;
1188 dst->ut.ngroups = src->ut.ngroups;
1189 dst->ut.groups = groups;
1190 dst->nt_user_token = nt_token;
1194 /***************************************************************************
1195 Purely internal function for make_server_info_info3
1196 ***************************************************************************/
1198 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1199 const char *username, char **found_username,
1200 struct passwd **pwd,
1201 bool *username_was_mapped)
1203 char *orig_dom_user = NULL;
1204 char *dom_user = NULL;
1205 char *lower_username = NULL;
1206 char *real_username = NULL;
1207 struct passwd *passwd;
1209 lower_username = talloc_strdup(mem_ctx, username);
1210 if (!lower_username) {
1211 return NT_STATUS_NO_MEMORY;
1213 strlower_m( lower_username );
1215 orig_dom_user = talloc_asprintf(mem_ctx,
1218 *lp_winbind_separator(),
1220 if (!orig_dom_user) {
1221 return NT_STATUS_NO_MEMORY;
1224 /* Get the passwd struct. Try to create the account if necessary. */
1226 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1228 return NT_STATUS_NO_MEMORY;
1231 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
1233 DEBUG(3, ("Failed to find authenticated user %s via "
1234 "getpwnam(), denying access.\n", dom_user));
1235 return NT_STATUS_NO_SUCH_USER;
1238 if (!real_username) {
1239 return NT_STATUS_NO_MEMORY;
1244 /* This is pointless -- there is no suport for differing
1245 unix and windows names. Make sure to always store the
1246 one we actually looked up and succeeded. Have I mentioned
1247 why I hate the 'winbind use default domain' parameter?
1250 *found_username = talloc_strdup( mem_ctx, real_username );
1252 return NT_STATUS_OK;
1255 /****************************************************************************
1256 Wrapper to allow the getpwnam() call to strip the domain name and
1257 try again in case a local UNIX user is already there. Also run through
1258 the username if we fallback to the username only.
1259 ****************************************************************************/
1261 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1262 char **p_save_username, bool create )
1264 struct passwd *pw = NULL;
1266 char *username = NULL;
1268 /* we only save a copy of the username it has been mangled
1269 by winbindd use default domain */
1270 *p_save_username = NULL;
1272 /* don't call map_username() here since it has to be done higher
1273 up the stack so we don't call it multiple times */
1275 username = talloc_strdup(mem_ctx, domuser);
1280 p = strchr_m( username, *lp_winbind_separator() );
1282 /* code for a DOMAIN\user string */
1285 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1287 /* make sure we get the case of the username correct */
1288 /* work around 'winbind use default domain = yes' */
1290 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1293 /* split the domain and username into 2 strings */
1297 *p_save_username = talloc_asprintf(mem_ctx,
1300 *lp_winbind_separator(),
1302 if (!*p_save_username) {
1307 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1314 /* setup for lookup of just the username */
1315 /* remember that p and username are overlapping memory */
1318 username = talloc_strdup(mem_ctx, p);
1324 /* just lookup a plain username */
1326 pw = Get_Pwnam_alloc(mem_ctx, username);
1328 /* Create local user if requested but only if winbindd
1329 is not running. We need to protect against cases
1330 where winbindd is failing and then prematurely
1331 creating users in /etc/passwd */
1333 if ( !pw && create && !winbind_ping() ) {
1334 /* Don't add a machine account. */
1335 if (username[strlen(username)-1] == '$')
1338 _smb_create_user(NULL, username, NULL);
1339 pw = Get_Pwnam_alloc(mem_ctx, username);
1342 /* one last check for a valid passwd struct */
1345 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1350 /***************************************************************************
1351 Make a server_info struct from the info3 returned by a domain logon
1352 ***************************************************************************/
1354 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1355 const char *sent_nt_username,
1357 struct auth_serversupplied_info **server_info,
1358 struct netr_SamInfo3 *info3)
1360 static const char zeros[16] = {0, };
1362 NTSTATUS nt_status = NT_STATUS_OK;
1363 char *found_username = NULL;
1364 const char *nt_domain;
1365 const char *nt_username;
1366 bool username_was_mapped;
1368 struct auth_serversupplied_info *result;
1369 struct dom_sid *group_sid;
1370 struct netr_SamInfo3 *i3;
1373 Here is where we should check the list of
1374 trusted domains, and verify that the SID
1378 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1380 /* If the server didn't give us one, just use the one we sent
1382 nt_username = sent_nt_username;
1385 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1387 /* If the server didn't give us one, just use the one we sent
1392 /* If getpwnam() fails try the add user script (2.2.x behavior).
1394 We use the _unmapped_ username here in an attempt to provide
1395 consistent username mapping behavior between kerberos and NTLM[SSP]
1396 authentication in domain mode security. I.E. Username mapping
1397 should be applied to the fully qualified username
1398 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1399 called map_username() unnecessarily in make_user_info_map() but
1400 that is how the current code is designed. Making the change here
1401 is the least disruptive place. -- jerry */
1403 /* this call will try to create the user if necessary */
1405 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1406 &found_username, &pwd,
1407 &username_was_mapped);
1409 if (!NT_STATUS_IS_OK(nt_status)) {
1413 result = make_server_info(NULL);
1414 if (result == NULL) {
1415 DEBUG(4, ("make_server_info failed!\n"));
1416 return NT_STATUS_NO_MEMORY;
1419 result->unix_name = talloc_strdup(result, found_username);
1421 result->sanitized_username = sanitize_username(result,
1423 if (result->sanitized_username == NULL) {
1424 TALLOC_FREE(result);
1425 return NT_STATUS_NO_MEMORY;
1428 /* copy in the info3 */
1429 result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1430 if (result->info3 == NULL) {
1431 TALLOC_FREE(result);
1432 return NT_STATUS_NO_MEMORY;
1435 /* Fill in the unix info we found on the way */
1436 result->utok.uid = pwd->pw_uid;
1437 result->utok.gid = pwd->pw_gid;
1439 /* We can't just trust that the primary group sid sent us is something
1440 * we can really use. Obtain the useable sid, and store the original
1441 * one as an additional group if it had to be replaced */
1442 nt_status = get_primary_group_sid(mem_ctx, found_username,
1444 if (!NT_STATUS_IS_OK(nt_status)) {
1445 TALLOC_FREE(result);
1449 /* store and check if it is the same we got originally */
1450 sid_peek_rid(group_sid, &i3->base.primary_gid);
1451 if (i3->base.primary_gid != info3->base.primary_gid) {
1452 uint32_t n = i3->base.groups.count;
1453 /* not the same, store the original as an additional group */
1454 i3->base.groups.rids =
1455 talloc_realloc(i3, i3->base.groups.rids,
1456 struct samr_RidWithAttribute, n + 1);
1457 if (i3->base.groups.rids == NULL) {
1458 TALLOC_FREE(result);
1459 return NT_STATUS_NO_MEMORY;
1461 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1462 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1463 i3->base.groups.count = n + 1;
1466 /* ensure we are never given NULL session keys */
1468 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1469 result->session_key = data_blob_null;
1471 result->session_key = data_blob_talloc(
1472 result, info3->base.key.key,
1473 sizeof(info3->base.key.key));
1476 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1477 result->lm_session_key = data_blob_null;
1479 result->lm_session_key = data_blob_talloc(
1480 result, info3->base.LMSessKey.key,
1481 sizeof(info3->base.LMSessKey.key));
1484 result->nss_token |= username_was_mapped;
1486 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1488 *server_info = result;
1490 return NT_STATUS_OK;
1493 /*****************************************************************************
1494 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1495 ******************************************************************************/
1497 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1498 const char *sent_nt_username,
1500 const struct wbcAuthUserInfo *info,
1501 struct auth_serversupplied_info **server_info)
1503 struct netr_SamInfo3 *info3;
1505 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1507 return NT_STATUS_NO_MEMORY;
1510 return make_server_info_info3(mem_ctx,
1511 sent_nt_username, domain,
1512 server_info, info3);
1516 * Verify whether or not given domain is trusted.
1518 * @param domain_name name of the domain to be verified
1519 * @return true if domain is one of the trusted ones or
1520 * false if otherwise
1523 bool is_trusted_domain(const char* dom_name)
1525 struct dom_sid trustdom_sid;
1528 /* no trusted domains for a standalone server */
1530 if ( lp_server_role() == ROLE_STANDALONE )
1533 if (dom_name == NULL || dom_name[0] == '\0') {
1537 if (strequal(dom_name, get_global_sam_name())) {
1541 /* if we are a DC, then check for a direct trust relationships */
1545 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1546 "[%s]\n", dom_name ));
1547 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1555 /* If winbind is around, ask it */
1557 result = wb_is_trusted_domain(dom_name);
1559 if (result == WBC_ERR_SUCCESS) {
1563 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1564 /* winbind could not find the domain */
1568 /* The only other possible result is that winbind is not up
1569 and running. We need to update the trustdom_cache
1572 update_trustdom_cache();
1575 /* now the trustdom cache should be available a DC could still
1576 * have a transitive trust so fall back to the cache of trusted
1577 * domains (like a domain member would use */
1579 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {