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
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"
35 #define DBGC_CLASS DBGC_AUTH
37 /****************************************************************************
38 Create a UNIX user on demand.
39 ****************************************************************************/
41 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
43 TALLOC_CTX *ctx = talloc_tos();
47 add_script = talloc_strdup(ctx, lp_adduser_script());
48 if (!add_script || !*add_script) {
51 add_script = talloc_all_string_sub(ctx,
59 add_script = talloc_all_string_sub(ctx,
68 add_script = talloc_all_string_sub(ctx,
76 ret = smbrun(add_script,NULL);
79 ("smb_create_user: Running the command `%s' gave %d\n",
84 /****************************************************************************
85 Create an auth_usersupplied_data structure after appropriate mapping.
86 ****************************************************************************/
88 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
90 const char *client_domain,
91 const char *workstation_name,
92 const struct tsocket_address *remote_address,
95 const struct samr_Password *lm_interactive_pwd,
96 const struct samr_Password *nt_interactive_pwd,
97 const char *plaintext,
98 enum auth_password_state password_state)
103 char *internal_username = NULL;
105 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
106 if (!internal_username) {
107 return NT_STATUS_NO_MEMORY;
110 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
111 client_domain, smb_name, workstation_name));
113 domain = client_domain;
115 /* If you connect to a Windows domain member using a bogus domain name,
116 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
117 * the Windows box is a DC the name will become DOMAIN\user and be
118 * authenticated against AD, if the Windows box is a member server but
119 * not a DC the name will become WORKSTATION\user. A standalone
120 * non-domain member box will also map to WORKSTATION\user.
121 * This also deals with the client passing in a "" domain */
123 if (!is_trusted_domain(domain) &&
124 !strequal(domain, my_sam_name()))
126 if (lp_map_untrusted_to_domain())
127 domain = my_sam_name();
129 domain = get_global_sam_name();
130 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
131 "workstation [%s]\n",
132 client_domain, domain, smb_name, workstation_name));
135 /* We know that the given domain is trusted (and we are allowing them),
136 * it is our global SAM name, or for legacy behavior it is our
137 * primary domain name */
139 result = make_user_info(user_info, smb_name, internal_username,
140 client_domain, domain, workstation_name,
141 remote_address, lm_pwd, nt_pwd,
142 lm_interactive_pwd, nt_interactive_pwd,
143 plaintext, password_state);
144 if (NT_STATUS_IS_OK(result)) {
145 /* We have tried mapping */
146 (*user_info)->mapped_state = True;
147 /* did we actually map the user to a different name? */
148 (*user_info)->was_mapped = was_mapped;
153 /****************************************************************************
154 Create an auth_usersupplied_data, making the DATA_BLOBs here.
155 Decrypt and encrypt the passwords.
156 ****************************************************************************/
158 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
159 const char *smb_name,
160 const char *client_domain,
161 const char *workstation_name,
162 const struct tsocket_address *remote_address,
163 uint32 logon_parameters,
164 const uchar *lm_network_pwd,
166 const uchar *nt_network_pwd,
171 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
172 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
174 status = make_user_info_map(user_info,
175 smb_name, client_domain,
178 lm_pwd_len ? &lm_blob : NULL,
179 nt_pwd_len ? &nt_blob : NULL,
181 AUTH_PASSWORD_RESPONSE);
183 if (NT_STATUS_IS_OK(status)) {
184 (*user_info)->logon_parameters = logon_parameters;
186 ret = NT_STATUS_IS_OK(status) ? True : False;
188 data_blob_free(&lm_blob);
189 data_blob_free(&nt_blob);
193 /****************************************************************************
194 Create an auth_usersupplied_data, making the DATA_BLOBs here.
195 Decrypt and encrypt the passwords.
196 ****************************************************************************/
198 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
199 const char *smb_name,
200 const char *client_domain,
201 const char *workstation_name,
202 const struct tsocket_address *remote_address,
203 uint32 logon_parameters,
205 const uchar lm_interactive_pwd[16],
206 const uchar nt_interactive_pwd[16],
207 const uchar *dc_sess_key)
209 struct samr_Password lm_pwd;
210 struct samr_Password nt_pwd;
211 unsigned char local_lm_response[24];
212 unsigned char local_nt_response[24];
213 unsigned char key[16];
215 memcpy(key, dc_sess_key, 16);
217 if (lm_interactive_pwd)
218 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
220 if (nt_interactive_pwd)
221 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
223 #ifdef DEBUG_PASSWORD
225 dump_data(100, key, sizeof(key));
227 DEBUG(100,("lm owf password:"));
228 dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
230 DEBUG(100,("nt owf password:"));
231 dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
234 if (lm_interactive_pwd)
235 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
237 if (nt_interactive_pwd)
238 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
240 #ifdef DEBUG_PASSWORD
241 DEBUG(100,("decrypt of lm owf password:"));
242 dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
244 DEBUG(100,("decrypt of nt owf password:"));
245 dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
248 if (lm_interactive_pwd)
249 SMBOWFencrypt(lm_pwd.hash, chal,
252 if (nt_interactive_pwd)
253 SMBOWFencrypt(nt_pwd.hash, chal,
256 /* Password info paranoia */
262 DATA_BLOB local_lm_blob;
263 DATA_BLOB local_nt_blob;
265 if (lm_interactive_pwd) {
266 local_lm_blob = data_blob(local_lm_response,
267 sizeof(local_lm_response));
270 if (nt_interactive_pwd) {
271 local_nt_blob = data_blob(local_nt_response,
272 sizeof(local_nt_response));
275 nt_status = make_user_info_map(
277 smb_name, client_domain, workstation_name,
279 lm_interactive_pwd ? &local_lm_blob : NULL,
280 nt_interactive_pwd ? &local_nt_blob : NULL,
281 lm_interactive_pwd ? &lm_pwd : NULL,
282 nt_interactive_pwd ? &nt_pwd : NULL,
283 NULL, AUTH_PASSWORD_HASH);
285 if (NT_STATUS_IS_OK(nt_status)) {
286 (*user_info)->logon_parameters = logon_parameters;
289 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
290 data_blob_free(&local_lm_blob);
291 data_blob_free(&local_nt_blob);
297 /****************************************************************************
298 Create an auth_usersupplied_data structure
299 ****************************************************************************/
301 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
302 const char *smb_name,
303 const char *client_domain,
304 const struct tsocket_address *remote_address,
306 DATA_BLOB plaintext_password)
309 DATA_BLOB local_lm_blob;
310 DATA_BLOB local_nt_blob;
311 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
312 char *plaintext_password_string;
314 * Not encrypted - do so.
317 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
319 if (plaintext_password.data && plaintext_password.length) {
320 unsigned char local_lm_response[24];
322 #ifdef DEBUG_PASSWORD
323 DEBUG(10,("Unencrypted password (len %d):\n",
324 (int)plaintext_password.length));
325 dump_data(100, plaintext_password.data,
326 plaintext_password.length);
329 SMBencrypt( (const char *)plaintext_password.data,
330 (const uchar*)chal, local_lm_response);
331 local_lm_blob = data_blob(local_lm_response, 24);
333 /* We can't do an NT hash here, as the password needs to be
335 local_nt_blob = data_blob_null;
337 local_lm_blob = data_blob_null;
338 local_nt_blob = data_blob_null;
341 plaintext_password_string = talloc_strndup(talloc_tos(),
342 (const char *)plaintext_password.data,
343 plaintext_password.length);
344 if (!plaintext_password_string) {
348 ret = make_user_info_map(
349 user_info, smb_name, client_domain,
350 get_remote_machine_name(),
352 local_lm_blob.data ? &local_lm_blob : NULL,
353 local_nt_blob.data ? &local_nt_blob : NULL,
355 plaintext_password_string,
356 AUTH_PASSWORD_PLAIN);
358 if (plaintext_password_string) {
359 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
360 talloc_free(plaintext_password_string);
363 data_blob_free(&local_lm_blob);
364 return NT_STATUS_IS_OK(ret) ? True : False;
367 /****************************************************************************
368 Create an auth_usersupplied_data structure
369 ****************************************************************************/
371 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
372 const char *smb_name,
373 const char *client_domain,
374 const struct tsocket_address *remote_address,
375 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
377 return make_user_info_map(user_info, smb_name,
379 get_remote_machine_name(),
381 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
382 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
384 AUTH_PASSWORD_RESPONSE);
387 /****************************************************************************
388 Create a guest user_info blob, for anonymous authenticaion.
389 ****************************************************************************/
391 bool make_user_info_guest(const struct tsocket_address *remote_address,
392 struct auth_usersupplied_info **user_info)
396 nt_status = make_user_info(user_info,
404 AUTH_PASSWORD_RESPONSE);
406 return NT_STATUS_IS_OK(nt_status) ? True : False;
409 static NTSTATUS log_nt_token(struct security_token *token)
411 TALLOC_CTX *frame = talloc_stackframe();
416 if ((lp_log_nt_token_command() == NULL) ||
417 (strlen(lp_log_nt_token_command()) == 0)) {
422 group_sidstr = talloc_strdup(frame, "");
423 for (i=1; i<token->num_sids; i++) {
424 group_sidstr = talloc_asprintf(
425 frame, "%s %s", group_sidstr,
426 sid_string_talloc(frame, &token->sids[i]));
429 command = talloc_string_sub(
430 frame, lp_log_nt_token_command(),
431 "%s", sid_string_talloc(frame, &token->sids[0]));
432 command = talloc_string_sub(frame, command, "%t", group_sidstr);
434 if (command == NULL) {
436 return NT_STATUS_NO_MEMORY;
439 DEBUG(8, ("running command: [%s]\n", command));
440 if (smbrun(command, NULL) != 0) {
441 DEBUG(0, ("Could not log NT token\n"));
443 return NT_STATUS_ACCESS_DENIED;
451 * Create the token to use from server_info->info3 and
452 * server_info->sids (the info3/sam groups). Find the unix gids.
455 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
456 const struct auth_serversupplied_info *server_info,
457 DATA_BLOB *session_key,
458 struct auth_serversupplied_info **session_info_out)
460 struct security_token *t;
463 struct dom_sid tmp_sid;
464 struct auth_serversupplied_info *session_info;
465 struct wbcUnixId *ids;
467 /* Ensure we can't possible take a code path leading to a
470 return NT_STATUS_LOGON_FAILURE;
473 session_info = copy_serverinfo(mem_ctx, server_info);
476 return NT_STATUS_NO_MEMORY;
480 data_blob_free(&session_info->session_key);
481 session_info->session_key = data_blob_talloc(session_info,
483 session_key->length);
484 if (!session_info->session_key.data && session_key->length) {
485 return NT_STATUS_NO_MEMORY;
489 if (session_info->security_token) {
490 /* Just copy the token, it has already been finalised
491 * (nasty hack to support a cached guest session_info,
492 * and a possible strategy for auth_samba4 to pass in
493 * a finalised session) */
494 *session_info_out = session_info;
499 * If winbind is not around, we can not make much use of the SIDs the
500 * domain controller provided us with. Likewise if the user name was
501 * mapped to some local unix user.
504 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
505 (server_info->nss_token)) {
506 status = create_token_from_username(session_info,
507 session_info->unix_name,
509 &session_info->utok.uid,
510 &session_info->utok.gid,
511 &session_info->unix_name,
512 &session_info->security_token);
515 status = create_local_nt_token_from_info3(session_info,
518 &session_info->extra,
519 &session_info->security_token);
522 if (!NT_STATUS_IS_OK(status)) {
526 /* Convert the SIDs to gids. */
528 session_info->utok.ngroups = 0;
529 session_info->utok.groups = NULL;
531 t = session_info->security_token;
533 ids = talloc_array(talloc_tos(), struct wbcUnixId,
536 return NT_STATUS_NO_MEMORY;
539 if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
541 return NT_STATUS_NO_MEMORY;
544 /* Start at index 1, where the groups start. */
546 for (i=1; i<t->num_sids; i++) {
548 if (ids[i].type != WBC_ID_TYPE_GID) {
549 DEBUG(10, ("Could not convert SID %s to gid, "
551 sid_string_dbg(&t->sids[i])));
554 if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
555 &session_info->utok.groups,
556 &session_info->utok.ngroups)) {
557 return NT_STATUS_NO_MEMORY;
562 * Add the "Unix Group" SID for each gid to catch mapped groups
563 * and their Unix equivalent. This is to solve the backwards
564 * compatibility problem of 'valid users = +ntadmin' where
565 * ntadmin has been paired with "Domain Admins" in the group
566 * mapping table. Otherwise smb.conf would need to be changed
567 * to 'valid user = "Domain Admins"'. --jerry
569 * For consistency we also add the "Unix User" SID,
570 * so that the complete unix token is represented within
574 uid_to_unix_users_sid(session_info->utok.uid, &tmp_sid);
576 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
577 &session_info->security_token->sids,
578 &session_info->security_token->num_sids);
580 for ( i=0; i<session_info->utok.ngroups; i++ ) {
581 gid_to_unix_groups_sid(session_info->utok.groups[i], &tmp_sid);
582 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
583 &session_info->security_token->sids,
584 &session_info->security_token->num_sids);
587 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
588 debug_unix_user_token(DBGC_AUTH, 10,
589 session_info->utok.uid,
590 session_info->utok.gid,
591 session_info->utok.ngroups,
592 session_info->utok.groups);
594 status = log_nt_token(session_info->security_token);
595 if (!NT_STATUS_IS_OK(status)) {
599 *session_info_out = session_info;
603 /***************************************************************************
604 Make (and fill) a server_info struct from a 'struct passwd' by conversion
606 ***************************************************************************/
608 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
613 struct samu *sampass = NULL;
614 char *qualified_name = NULL;
615 TALLOC_CTX *mem_ctx = NULL;
616 struct dom_sid u_sid;
617 enum lsa_SidType type;
618 struct auth_serversupplied_info *result;
621 * The SID returned in server_info->sam_account is based
622 * on our SAM sid even though for a pure UNIX account this should
623 * not be the case as it doesn't really exist in the SAM db.
624 * This causes lookups on "[in]valid users" to fail as they
625 * will lookup this name as a "Unix User" SID to check against
626 * the user token. Fix this by adding the "Unix User"\unix_username
627 * SID to the sid array. The correct fix should probably be
628 * changing the server_info->sam_account user SID to be a
629 * S-1-22 Unix SID, but this might break old configs where
630 * plaintext passwords were used with no SAM backend.
633 mem_ctx = talloc_init("make_server_info_pw_tmp");
635 return NT_STATUS_NO_MEMORY;
638 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
639 unix_users_domain_name(),
641 if (!qualified_name) {
642 TALLOC_FREE(mem_ctx);
643 return NT_STATUS_NO_MEMORY;
646 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
649 TALLOC_FREE(mem_ctx);
650 return NT_STATUS_NO_SUCH_USER;
653 TALLOC_FREE(mem_ctx);
655 if (type != SID_NAME_USER) {
656 return NT_STATUS_NO_SUCH_USER;
659 if ( !(sampass = samu_new( NULL )) ) {
660 return NT_STATUS_NO_MEMORY;
663 status = samu_set_unix( sampass, pwd );
664 if (!NT_STATUS_IS_OK(status)) {
668 /* In pathological cases the above call can set the account
669 * name to the DOMAIN\username form. Reset the account name
670 * using unix_username */
671 pdb_set_username(sampass, unix_username, PDB_SET);
673 /* set the user sid to be the calculated u_sid */
674 pdb_set_user_sid(sampass, &u_sid, PDB_SET);
676 result = make_server_info(NULL);
677 if (result == NULL) {
678 TALLOC_FREE(sampass);
679 return NT_STATUS_NO_MEMORY;
682 status = samu_to_SamInfo3(result, sampass, lp_netbios_name(),
683 &result->info3, &result->extra);
684 TALLOC_FREE(sampass);
685 if (!NT_STATUS_IS_OK(status)) {
686 DEBUG(10, ("Failed to convert samu to info3: %s\n",
692 result->unix_name = talloc_strdup(result, unix_username);
693 result->sanitized_username = sanitize_username(result, unix_username);
695 if ((result->unix_name == NULL)
696 || (result->sanitized_username == NULL)) {
698 return NT_STATUS_NO_MEMORY;
701 result->utok.uid = pwd->pw_uid;
702 result->utok.gid = pwd->pw_gid;
704 *server_info = result;
709 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
710 struct netr_SamInfo3 *info3)
712 const char *guest_account = lp_guestaccount();
713 struct dom_sid domain_sid;
717 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
719 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
720 "account [%s]!\n", guest_account));
721 return NT_STATUS_NO_SUCH_USER;
724 /* Set acount name */
725 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
727 return NT_STATUS_NO_MEMORY;
729 init_lsa_String(&info3->base.account_name, tmp);
731 /* Set domain name */
732 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
734 return NT_STATUS_NO_MEMORY;
736 init_lsa_StringLarge(&info3->base.domain, tmp);
739 sid_copy(&domain_sid, get_global_sam_sid());
741 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
742 if (info3->base.domain_sid == NULL) {
743 return NT_STATUS_NO_MEMORY;
747 info3->base.rid = DOMAIN_RID_GUEST;
750 info3->base.primary_gid = BUILTIN_RID_GUESTS;
756 /***************************************************************************
757 Make (and fill) a user_info struct for a guest login.
758 This *must* succeed for smbd to start. If there is no mapping entry for
759 the guest gid, then create one.
761 The resulting structure is a 'session_info' because
762 create_local_token() has already been called on it. This is quite
763 nasty, as the auth subsystem isn't expect this, but the behaviour is
765 ***************************************************************************/
767 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **session_info)
769 struct auth_serversupplied_info *server_info;
770 static const char zeros[16] = {0};
771 const char *guest_account = lp_guestaccount();
772 const char *domain = lp_netbios_name();
773 struct netr_SamInfo3 info3;
778 tmp_ctx = talloc_stackframe();
779 if (tmp_ctx == NULL) {
780 return NT_STATUS_NO_MEMORY;
785 status = get_guest_info3(tmp_ctx, &info3);
786 if (!NT_STATUS_IS_OK(status)) {
787 DEBUG(0, ("get_guest_info3 failed with %s\n",
792 status = make_server_info_info3(tmp_ctx,
797 if (!NT_STATUS_IS_OK(status)) {
798 DEBUG(0, ("make_server_info_info3 failed with %s\n",
803 server_info->guest = True;
805 /* This should not be done here (we should produce a server
806 * info, and later construct a session info from it), but for
807 * now this does not change the previous behaviours */
808 status = create_local_token(tmp_ctx, server_info, NULL, session_info);
809 TALLOC_FREE(server_info);
810 if (!NT_STATUS_IS_OK(status)) {
811 DEBUG(0, ("create_local_token failed: %s\n",
815 talloc_steal(NULL, *session_info);
817 /* annoying, but the Guest really does have a session key, and it is
819 (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
820 (*session_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
822 alpha_strcpy(tmp, (*session_info)->info3->base.account_name.string,
823 ". _-$", sizeof(tmp));
824 (*session_info)->sanitized_username = talloc_strdup(*session_info, tmp);
826 status = NT_STATUS_OK;
828 TALLOC_FREE(tmp_ctx);
832 /***************************************************************************
833 Make (and fill) a auth_session_info struct for a system user login.
834 This *must* succeed for smbd to start.
835 ***************************************************************************/
837 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
838 struct auth_serversupplied_info **session_info)
843 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
845 return NT_STATUS_NO_SUCH_USER;
848 status = make_session_info_from_username(mem_ctx,
853 if (!NT_STATUS_IS_OK(status)) {
857 (*session_info)->system = true;
859 status = add_sid_to_array_unique((*session_info)->security_token->sids,
861 &(*session_info)->security_token->sids,
862 &(*session_info)->security_token->num_sids);
863 if (!NT_STATUS_IS_OK(status)) {
864 TALLOC_FREE((*session_info));
871 /****************************************************************************
872 Fake a auth_serversupplied_info just from a username (as a
873 session_info structure, with create_local_token() already called on
875 ****************************************************************************/
877 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
878 const char *username,
880 struct auth_serversupplied_info **session_info)
882 struct auth_serversupplied_info *result;
886 pwd = Get_Pwnam_alloc(talloc_tos(), username);
888 return NT_STATUS_NO_SUCH_USER;
891 status = make_server_info_pw(&result, pwd->pw_name, pwd);
895 if (!NT_STATUS_IS_OK(status)) {
899 result->nss_token = true;
900 result->guest = is_guest;
902 /* Now turn the server_info into a session_info with the full token etc */
903 status = create_local_token(mem_ctx, result, NULL, session_info);
909 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
910 const struct auth_serversupplied_info *src)
912 struct auth_serversupplied_info *dst;
914 dst = make_server_info(mem_ctx);
919 dst->guest = src->guest;
920 dst->system = src->system;
921 dst->utok.uid = src->utok.uid;
922 dst->utok.gid = src->utok.gid;
923 dst->utok.ngroups = src->utok.ngroups;
924 if (src->utok.ngroups != 0) {
925 dst->utok.groups = (gid_t *)talloc_memdup(
926 dst, src->utok.groups,
927 sizeof(gid_t)*dst->utok.ngroups);
929 dst->utok.groups = NULL;
932 if (src->security_token) {
933 dst->security_token = dup_nt_token(dst, src->security_token);
934 if (!dst->security_token) {
940 dst->session_key = data_blob_talloc( dst, src->session_key.data,
941 src->session_key.length);
943 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
944 src->lm_session_key.length);
946 dst->info3 = copy_netr_SamInfo3(dst, src->info3);
951 dst->extra = src->extra;
953 dst->unix_name = talloc_strdup(dst, src->unix_name);
954 if (!dst->unix_name) {
959 dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
960 if (!dst->sanitized_username) {
969 * Set a new session key. Used in the rpc server where we have to override the
970 * SMB level session key with SystemLibraryDTC
973 bool session_info_set_session_key(struct auth_serversupplied_info *info,
974 DATA_BLOB session_key)
976 TALLOC_FREE(info->session_key.data);
978 info->session_key = data_blob_talloc(
979 info, session_key.data, session_key.length);
981 return (info->session_key.data != NULL);
984 static struct auth_serversupplied_info *guest_info = NULL;
986 bool init_guest_info(void)
988 if (guest_info != NULL)
991 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
994 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
995 struct auth_serversupplied_info **server_info)
997 *server_info = copy_serverinfo(mem_ctx, guest_info);
998 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1001 static struct auth_serversupplied_info *system_info = NULL;
1003 NTSTATUS init_system_info(void)
1005 if (system_info != NULL)
1006 return NT_STATUS_OK;
1008 return make_new_session_info_system(NULL, &system_info);
1011 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1012 struct auth_serversupplied_info **session_info)
1014 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1015 *session_info = copy_serverinfo(mem_ctx, system_info);
1016 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1019 const struct auth_serversupplied_info *get_session_info_system(void)
1024 bool copy_current_user(struct current_user *dst, struct current_user *src)
1027 struct security_token *nt_token;
1029 groups = (gid_t *)memdup(src->ut.groups,
1030 sizeof(gid_t) * src->ut.ngroups);
1031 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1035 nt_token = dup_nt_token(NULL, src->nt_user_token);
1036 if (nt_token == NULL) {
1041 dst->conn = src->conn;
1042 dst->vuid = src->vuid;
1043 dst->ut.uid = src->ut.uid;
1044 dst->ut.gid = src->ut.gid;
1045 dst->ut.ngroups = src->ut.ngroups;
1046 dst->ut.groups = groups;
1047 dst->nt_user_token = nt_token;
1051 /***************************************************************************
1052 Purely internal function for make_server_info_info3
1053 ***************************************************************************/
1055 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1056 const char *username, char **found_username,
1057 struct passwd **pwd,
1058 bool *username_was_mapped)
1060 char *orig_dom_user = NULL;
1061 char *dom_user = NULL;
1062 char *lower_username = NULL;
1063 char *real_username = NULL;
1064 struct passwd *passwd;
1066 lower_username = talloc_strdup(mem_ctx, username);
1067 if (!lower_username) {
1068 return NT_STATUS_NO_MEMORY;
1070 strlower_m( lower_username );
1072 orig_dom_user = talloc_asprintf(mem_ctx,
1075 *lp_winbind_separator(),
1077 if (!orig_dom_user) {
1078 return NT_STATUS_NO_MEMORY;
1081 /* Get the passwd struct. Try to create the account if necessary. */
1083 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1085 return NT_STATUS_NO_MEMORY;
1088 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
1090 DEBUG(3, ("Failed to find authenticated user %s via "
1091 "getpwnam(), denying access.\n", dom_user));
1092 return NT_STATUS_NO_SUCH_USER;
1095 if (!real_username) {
1096 return NT_STATUS_NO_MEMORY;
1101 /* This is pointless -- there is no suport for differing
1102 unix and windows names. Make sure to always store the
1103 one we actually looked up and succeeded. Have I mentioned
1104 why I hate the 'winbind use default domain' parameter?
1107 *found_username = talloc_strdup( mem_ctx, real_username );
1109 return NT_STATUS_OK;
1112 /****************************************************************************
1113 Wrapper to allow the getpwnam() call to strip the domain name and
1114 try again in case a local UNIX user is already there. Also run through
1115 the username if we fallback to the username only.
1116 ****************************************************************************/
1118 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1119 char **p_save_username, bool create )
1121 struct passwd *pw = NULL;
1123 char *username = NULL;
1125 /* we only save a copy of the username it has been mangled
1126 by winbindd use default domain */
1127 *p_save_username = NULL;
1129 /* don't call map_username() here since it has to be done higher
1130 up the stack so we don't call it multiple times */
1132 username = talloc_strdup(mem_ctx, domuser);
1137 p = strchr_m( username, *lp_winbind_separator() );
1139 /* code for a DOMAIN\user string */
1142 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1144 /* make sure we get the case of the username correct */
1145 /* work around 'winbind use default domain = yes' */
1147 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1150 /* split the domain and username into 2 strings */
1154 *p_save_username = talloc_asprintf(mem_ctx,
1157 *lp_winbind_separator(),
1159 if (!*p_save_username) {
1164 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1171 /* setup for lookup of just the username */
1172 /* remember that p and username are overlapping memory */
1175 username = talloc_strdup(mem_ctx, p);
1181 /* just lookup a plain username */
1183 pw = Get_Pwnam_alloc(mem_ctx, username);
1185 /* Create local user if requested but only if winbindd
1186 is not running. We need to protect against cases
1187 where winbindd is failing and then prematurely
1188 creating users in /etc/passwd */
1190 if ( !pw && create && !winbind_ping() ) {
1191 /* Don't add a machine account. */
1192 if (username[strlen(username)-1] == '$')
1195 _smb_create_user(NULL, username, NULL);
1196 pw = Get_Pwnam_alloc(mem_ctx, username);
1199 /* one last check for a valid passwd struct */
1202 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1207 /***************************************************************************
1208 Make a server_info struct from the info3 returned by a domain logon
1209 ***************************************************************************/
1211 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1212 const char *sent_nt_username,
1214 struct auth_serversupplied_info **server_info,
1215 struct netr_SamInfo3 *info3)
1217 static const char zeros[16] = {0, };
1219 NTSTATUS nt_status = NT_STATUS_OK;
1220 char *found_username = NULL;
1221 const char *nt_domain;
1222 const char *nt_username;
1223 bool username_was_mapped;
1225 struct auth_serversupplied_info *result;
1226 struct dom_sid *group_sid;
1227 struct netr_SamInfo3 *i3;
1230 Here is where we should check the list of
1231 trusted domains, and verify that the SID
1235 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1237 /* If the server didn't give us one, just use the one we sent
1239 nt_username = sent_nt_username;
1242 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1244 /* If the server didn't give us one, just use the one we sent
1249 /* If getpwnam() fails try the add user script (2.2.x behavior).
1251 We use the _unmapped_ username here in an attempt to provide
1252 consistent username mapping behavior between kerberos and NTLM[SSP]
1253 authentication in domain mode security. I.E. Username mapping
1254 should be applied to the fully qualified username
1255 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1256 called map_username() unnecessarily in make_user_info_map() but
1257 that is how the current code is designed. Making the change here
1258 is the least disruptive place. -- jerry */
1260 /* this call will try to create the user if necessary */
1262 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1263 &found_username, &pwd,
1264 &username_was_mapped);
1266 if (!NT_STATUS_IS_OK(nt_status)) {
1270 result = make_server_info(NULL);
1271 if (result == NULL) {
1272 DEBUG(4, ("make_server_info failed!\n"));
1273 return NT_STATUS_NO_MEMORY;
1276 result->unix_name = talloc_strdup(result, found_username);
1278 result->sanitized_username = sanitize_username(result,
1280 if (result->sanitized_username == NULL) {
1281 TALLOC_FREE(result);
1282 return NT_STATUS_NO_MEMORY;
1285 /* copy in the info3 */
1286 result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1287 if (result->info3 == NULL) {
1288 TALLOC_FREE(result);
1289 return NT_STATUS_NO_MEMORY;
1292 /* Fill in the unix info we found on the way */
1293 result->utok.uid = pwd->pw_uid;
1294 result->utok.gid = pwd->pw_gid;
1296 /* We can't just trust that the primary group sid sent us is something
1297 * we can really use. Obtain the useable sid, and store the original
1298 * one as an additional group if it had to be replaced */
1299 nt_status = get_primary_group_sid(mem_ctx, found_username,
1301 if (!NT_STATUS_IS_OK(nt_status)) {
1302 TALLOC_FREE(result);
1306 /* store and check if it is the same we got originally */
1307 sid_peek_rid(group_sid, &i3->base.primary_gid);
1308 if (i3->base.primary_gid != info3->base.primary_gid) {
1309 uint32_t n = i3->base.groups.count;
1310 /* not the same, store the original as an additional group */
1311 i3->base.groups.rids =
1312 talloc_realloc(i3, i3->base.groups.rids,
1313 struct samr_RidWithAttribute, n + 1);
1314 if (i3->base.groups.rids == NULL) {
1315 TALLOC_FREE(result);
1316 return NT_STATUS_NO_MEMORY;
1318 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1319 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1320 i3->base.groups.count = n + 1;
1323 /* ensure we are never given NULL session keys */
1325 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1326 result->session_key = data_blob_null;
1328 result->session_key = data_blob_talloc(
1329 result, info3->base.key.key,
1330 sizeof(info3->base.key.key));
1333 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1334 result->lm_session_key = data_blob_null;
1336 result->lm_session_key = data_blob_talloc(
1337 result, info3->base.LMSessKey.key,
1338 sizeof(info3->base.LMSessKey.key));
1341 result->nss_token |= username_was_mapped;
1343 *server_info = result;
1345 return NT_STATUS_OK;
1348 /*****************************************************************************
1349 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1350 ******************************************************************************/
1352 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1353 const char *sent_nt_username,
1355 const struct wbcAuthUserInfo *info,
1356 struct auth_serversupplied_info **server_info)
1358 struct netr_SamInfo3 *info3;
1360 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1362 return NT_STATUS_NO_MEMORY;
1365 return make_server_info_info3(mem_ctx,
1366 sent_nt_username, domain,
1367 server_info, info3);
1371 * Verify whether or not given domain is trusted.
1373 * @param domain_name name of the domain to be verified
1374 * @return true if domain is one of the trusted ones or
1375 * false if otherwise
1378 bool is_trusted_domain(const char* dom_name)
1380 struct dom_sid trustdom_sid;
1383 /* no trusted domains for a standalone server */
1385 if ( lp_server_role() == ROLE_STANDALONE )
1388 if (dom_name == NULL || dom_name[0] == '\0') {
1392 if (strequal(dom_name, get_global_sam_name())) {
1396 /* if we are a DC, then check for a direct trust relationships */
1400 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1401 "[%s]\n", dom_name ));
1402 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1410 /* If winbind is around, ask it */
1412 result = wb_is_trusted_domain(dom_name);
1414 if (result == WBC_ERR_SUCCESS) {
1418 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1419 /* winbind could not find the domain */
1423 /* The only other possible result is that winbind is not up
1424 and running. We need to update the trustdom_cache
1427 update_trustdom_cache();
1430 /* now the trustdom cache should be available a DC could still
1431 * have a transitive trust so fall back to the cache of trusted
1432 * domains (like a domain member would use */
1434 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {