2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
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/>.
25 #include "smbd/globals.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
30 #define DBGC_CLASS DBGC_AUTH
32 /****************************************************************************
33 Create a UNIX user on demand.
34 ****************************************************************************/
36 static int _smb_create_user(const char *domain
, const char *unix_username
, const char *homedir
)
38 TALLOC_CTX
*ctx
= talloc_tos();
42 add_script
= talloc_strdup(ctx
, lp_adduser_script());
43 if (!add_script
|| !*add_script
) {
46 add_script
= talloc_all_string_sub(ctx
,
54 add_script
= talloc_all_string_sub(ctx
,
63 add_script
= talloc_all_string_sub(ctx
,
71 ret
= smbrun(add_script
,NULL
);
74 ("smb_create_user: Running the command `%s' gave %d\n",
79 /****************************************************************************
80 Create an auth_usersupplied_data structure after appropriate mapping.
81 ****************************************************************************/
83 NTSTATUS
make_user_info_map(struct auth_usersupplied_info
**user_info
,
85 const char *client_domain
,
86 const char *workstation_name
,
89 DATA_BLOB
*lm_interactive_pwd
,
90 DATA_BLOB
*nt_interactive_pwd
,
97 fstring internal_username
;
98 fstrcpy(internal_username
, smb_name
);
99 was_mapped
= map_username(internal_username
);
101 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
102 client_domain
, smb_name
, workstation_name
));
104 domain
= client_domain
;
106 /* If you connect to a Windows domain member using a bogus domain name,
107 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
108 * the Windows box is a DC the name will become DOMAIN\user and be
109 * authenticated against AD, if the Windows box is a member server but
110 * not a DC the name will become WORKSTATION\user. A standalone
111 * non-domain member box will also map to WORKSTATION\user.
112 * This also deals with the client passing in a "" domain */
114 if (!is_trusted_domain(domain
) &&
115 !strequal(domain
, my_sam_name()))
117 if (lp_map_untrusted_to_domain())
118 domain
= my_sam_name();
120 domain
= get_global_sam_name();
121 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
122 "workstation [%s]\n",
123 client_domain
, domain
, smb_name
, workstation_name
));
126 /* We know that the given domain is trusted (and we are allowing them),
127 * it is our global SAM name, or for legacy behavior it is our
128 * primary domain name */
130 result
= make_user_info(user_info
, smb_name
, internal_username
,
131 client_domain
, domain
, workstation_name
,
133 lm_interactive_pwd
, nt_interactive_pwd
,
134 plaintext
, encrypted
);
135 if (NT_STATUS_IS_OK(result
)) {
136 (*user_info
)->was_mapped
= was_mapped
;
141 /****************************************************************************
142 Create an auth_usersupplied_data, making the DATA_BLOBs here.
143 Decrypt and encrypt the passwords.
144 ****************************************************************************/
146 bool make_user_info_netlogon_network(struct auth_usersupplied_info
**user_info
,
147 const char *smb_name
,
148 const char *client_domain
,
149 const char *workstation_name
,
150 uint32 logon_parameters
,
151 const uchar
*lm_network_pwd
,
153 const uchar
*nt_network_pwd
,
158 DATA_BLOB lm_blob
= data_blob(lm_network_pwd
, lm_pwd_len
);
159 DATA_BLOB nt_blob
= data_blob(nt_network_pwd
, nt_pwd_len
);
161 status
= make_user_info_map(user_info
,
162 smb_name
, client_domain
,
164 lm_pwd_len
? &lm_blob
: NULL
,
165 nt_pwd_len
? &nt_blob
: NULL
,
169 if (NT_STATUS_IS_OK(status
)) {
170 (*user_info
)->logon_parameters
= logon_parameters
;
172 ret
= NT_STATUS_IS_OK(status
) ? True
: False
;
174 data_blob_free(&lm_blob
);
175 data_blob_free(&nt_blob
);
179 /****************************************************************************
180 Create an auth_usersupplied_data, making the DATA_BLOBs here.
181 Decrypt and encrypt the passwords.
182 ****************************************************************************/
184 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info
**user_info
,
185 const char *smb_name
,
186 const char *client_domain
,
187 const char *workstation_name
,
188 uint32 logon_parameters
,
190 const uchar lm_interactive_pwd
[16],
191 const uchar nt_interactive_pwd
[16],
192 const uchar
*dc_sess_key
)
194 unsigned char lm_pwd
[16];
195 unsigned char nt_pwd
[16];
196 unsigned char local_lm_response
[24];
197 unsigned char local_nt_response
[24];
198 unsigned char key
[16];
200 memcpy(key
, dc_sess_key
, 16);
202 if (lm_interactive_pwd
)
203 memcpy(lm_pwd
, lm_interactive_pwd
, sizeof(lm_pwd
));
205 if (nt_interactive_pwd
)
206 memcpy(nt_pwd
, nt_interactive_pwd
, sizeof(nt_pwd
));
208 #ifdef DEBUG_PASSWORD
210 dump_data(100, key
, sizeof(key
));
212 DEBUG(100,("lm owf password:"));
213 dump_data(100, lm_pwd
, sizeof(lm_pwd
));
215 DEBUG(100,("nt owf password:"));
216 dump_data(100, nt_pwd
, sizeof(nt_pwd
));
219 if (lm_interactive_pwd
)
220 arcfour_crypt(lm_pwd
, key
, sizeof(lm_pwd
));
222 if (nt_interactive_pwd
)
223 arcfour_crypt(nt_pwd
, key
, sizeof(nt_pwd
));
225 #ifdef DEBUG_PASSWORD
226 DEBUG(100,("decrypt of lm owf password:"));
227 dump_data(100, lm_pwd
, sizeof(lm_pwd
));
229 DEBUG(100,("decrypt of nt owf password:"));
230 dump_data(100, nt_pwd
, sizeof(nt_pwd
));
233 if (lm_interactive_pwd
)
234 SMBOWFencrypt(lm_pwd
, chal
,
237 if (nt_interactive_pwd
)
238 SMBOWFencrypt(nt_pwd
, chal
,
241 /* Password info paranoia */
247 DATA_BLOB local_lm_blob
;
248 DATA_BLOB local_nt_blob
;
250 DATA_BLOB lm_interactive_blob
;
251 DATA_BLOB nt_interactive_blob
;
253 if (lm_interactive_pwd
) {
254 local_lm_blob
= data_blob(local_lm_response
,
255 sizeof(local_lm_response
));
256 lm_interactive_blob
= data_blob(lm_pwd
,
261 if (nt_interactive_pwd
) {
262 local_nt_blob
= data_blob(local_nt_response
,
263 sizeof(local_nt_response
));
264 nt_interactive_blob
= data_blob(nt_pwd
,
269 nt_status
= make_user_info_map(
271 smb_name
, client_domain
, workstation_name
,
272 lm_interactive_pwd
? &local_lm_blob
: NULL
,
273 nt_interactive_pwd
? &local_nt_blob
: NULL
,
274 lm_interactive_pwd
? &lm_interactive_blob
: NULL
,
275 nt_interactive_pwd
? &nt_interactive_blob
: NULL
,
278 if (NT_STATUS_IS_OK(nt_status
)) {
279 (*user_info
)->logon_parameters
= logon_parameters
;
282 ret
= NT_STATUS_IS_OK(nt_status
) ? True
: False
;
283 data_blob_free(&local_lm_blob
);
284 data_blob_free(&local_nt_blob
);
285 data_blob_free(&lm_interactive_blob
);
286 data_blob_free(&nt_interactive_blob
);
292 /****************************************************************************
293 Create an auth_usersupplied_data structure
294 ****************************************************************************/
296 bool make_user_info_for_reply(struct auth_usersupplied_info
**user_info
,
297 const char *smb_name
,
298 const char *client_domain
,
300 DATA_BLOB plaintext_password
)
303 DATA_BLOB local_lm_blob
;
304 DATA_BLOB local_nt_blob
;
305 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
308 * Not encrypted - do so.
311 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
314 if (plaintext_password
.data
&& plaintext_password
.length
) {
315 unsigned char local_lm_response
[24];
317 #ifdef DEBUG_PASSWORD
318 DEBUG(10,("Unencrypted password (len %d):\n",
319 (int)plaintext_password
.length
));
320 dump_data(100, plaintext_password
.data
,
321 plaintext_password
.length
);
324 SMBencrypt( (const char *)plaintext_password
.data
,
325 (const uchar
*)chal
, local_lm_response
);
326 local_lm_blob
= data_blob(local_lm_response
, 24);
328 /* We can't do an NT hash here, as the password needs to be
330 local_nt_blob
= data_blob_null
;
332 local_lm_blob
= data_blob_null
;
333 local_nt_blob
= data_blob_null
;
336 ret
= make_user_info_map(
337 user_info
, smb_name
, client_domain
,
338 get_remote_machine_name(),
339 local_lm_blob
.data
? &local_lm_blob
: NULL
,
340 local_nt_blob
.data
? &local_nt_blob
: NULL
,
342 plaintext_password
.data
&& plaintext_password
.length
? &plaintext_password
: NULL
,
345 data_blob_free(&local_lm_blob
);
346 return NT_STATUS_IS_OK(ret
) ? True
: False
;
349 /****************************************************************************
350 Create an auth_usersupplied_data structure
351 ****************************************************************************/
353 NTSTATUS
make_user_info_for_reply_enc(struct auth_usersupplied_info
**user_info
,
354 const char *smb_name
,
355 const char *client_domain
,
356 DATA_BLOB lm_resp
, DATA_BLOB nt_resp
)
358 return make_user_info_map(user_info
, smb_name
,
360 get_remote_machine_name(),
361 lm_resp
.data
&& (lm_resp
.length
> 0) ? &lm_resp
: NULL
,
362 nt_resp
.data
&& (nt_resp
.length
> 0) ? &nt_resp
: NULL
,
367 /****************************************************************************
368 Create a guest user_info blob, for anonymous authenticaion.
369 ****************************************************************************/
371 bool make_user_info_guest(struct auth_usersupplied_info
**user_info
)
375 nt_status
= make_user_info(user_info
,
384 return NT_STATUS_IS_OK(nt_status
) ? True
: False
;
387 static NTSTATUS
log_nt_token(NT_USER_TOKEN
*token
)
389 TALLOC_CTX
*frame
= talloc_stackframe();
394 if ((lp_log_nt_token_command() == NULL
) ||
395 (strlen(lp_log_nt_token_command()) == 0)) {
400 group_sidstr
= talloc_strdup(frame
, "");
401 for (i
=1; i
<token
->num_sids
; i
++) {
402 group_sidstr
= talloc_asprintf(
403 frame
, "%s %s", group_sidstr
,
404 sid_string_talloc(frame
, &token
->user_sids
[i
]));
407 command
= talloc_string_sub(
408 frame
, lp_log_nt_token_command(),
409 "%s", sid_string_talloc(frame
, &token
->user_sids
[0]));
410 command
= talloc_string_sub(frame
, command
, "%t", group_sidstr
);
412 if (command
== NULL
) {
414 return NT_STATUS_NO_MEMORY
;
417 DEBUG(8, ("running command: [%s]\n", command
));
418 if (smbrun(command
, NULL
) != 0) {
419 DEBUG(0, ("Could not log NT token\n"));
421 return NT_STATUS_ACCESS_DENIED
;
429 * Create the token to use from server_info->info3 and
430 * server_info->sids (the info3/sam groups). Find the unix gids.
433 NTSTATUS
create_local_token(struct auth_serversupplied_info
*server_info
)
437 struct dom_sid tmp_sid
;
440 * If winbind is not around, we can not make much use of the SIDs the
441 * domain controller provided us with. Likewise if the user name was
442 * mapped to some local unix user.
445 if (((lp_server_role() == ROLE_DOMAIN_MEMBER
) && !winbind_ping()) ||
446 (server_info
->nss_token
)) {
447 status
= create_token_from_username(server_info
,
448 server_info
->unix_name
,
450 &server_info
->utok
.uid
,
451 &server_info
->utok
.gid
,
452 &server_info
->unix_name
,
456 status
= create_local_nt_token_from_info3(server_info
,
463 if (!NT_STATUS_IS_OK(status
)) {
467 /* Convert the SIDs to gids. */
469 server_info
->utok
.ngroups
= 0;
470 server_info
->utok
.groups
= NULL
;
472 /* Start at index 1, where the groups start. */
474 for (i
=1; i
<server_info
->ptok
->num_sids
; i
++) {
476 struct dom_sid
*sid
= &server_info
->ptok
->user_sids
[i
];
478 if (!sid_to_gid(sid
, &gid
)) {
479 DEBUG(10, ("Could not convert SID %s to gid, "
480 "ignoring it\n", sid_string_dbg(sid
)));
483 add_gid_to_array_unique(server_info
, gid
,
484 &server_info
->utok
.groups
,
485 &server_info
->utok
.ngroups
);
489 * Add the "Unix Group" SID for each gid to catch mapped groups
490 * and their Unix equivalent. This is to solve the backwards
491 * compatibility problem of 'valid users = +ntadmin' where
492 * ntadmin has been paired with "Domain Admins" in the group
493 * mapping table. Otherwise smb.conf would need to be changed
494 * to 'valid user = "Domain Admins"'. --jerry
496 * For consistency we also add the "Unix User" SID,
497 * so that the complete unix token is represented within
501 uid_to_unix_users_sid(server_info
->utok
.uid
, &tmp_sid
);
503 add_sid_to_array_unique(server_info
->ptok
, &tmp_sid
,
504 &server_info
->ptok
->user_sids
,
505 &server_info
->ptok
->num_sids
);
507 for ( i
=0; i
<server_info
->utok
.ngroups
; i
++ ) {
508 gid_to_unix_groups_sid(server_info
->utok
.groups
[i
], &tmp_sid
);
509 add_sid_to_array_unique(server_info
->ptok
, &tmp_sid
,
510 &server_info
->ptok
->user_sids
,
511 &server_info
->ptok
->num_sids
);
514 debug_nt_user_token(DBGC_AUTH
, 10, server_info
->ptok
);
515 debug_unix_user_token(DBGC_AUTH
, 10,
516 server_info
->utok
.uid
,
517 server_info
->utok
.gid
,
518 server_info
->utok
.ngroups
,
519 server_info
->utok
.groups
);
521 status
= log_nt_token(server_info
->ptok
);
525 /***************************************************************************
526 Make (and fill) a server_info struct from a 'struct passwd' by conversion
528 ***************************************************************************/
530 NTSTATUS
make_server_info_pw(struct auth_serversupplied_info
**server_info
,
535 struct samu
*sampass
= NULL
;
536 char *qualified_name
= NULL
;
537 TALLOC_CTX
*mem_ctx
= NULL
;
538 struct dom_sid u_sid
;
539 enum lsa_SidType type
;
540 struct auth_serversupplied_info
*result
;
543 * The SID returned in server_info->sam_account is based
544 * on our SAM sid even though for a pure UNIX account this should
545 * not be the case as it doesn't really exist in the SAM db.
546 * This causes lookups on "[in]valid users" to fail as they
547 * will lookup this name as a "Unix User" SID to check against
548 * the user token. Fix this by adding the "Unix User"\unix_username
549 * SID to the sid array. The correct fix should probably be
550 * changing the server_info->sam_account user SID to be a
551 * S-1-22 Unix SID, but this might break old configs where
552 * plaintext passwords were used with no SAM backend.
555 mem_ctx
= talloc_init("make_server_info_pw_tmp");
557 return NT_STATUS_NO_MEMORY
;
560 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
561 unix_users_domain_name(),
563 if (!qualified_name
) {
564 TALLOC_FREE(mem_ctx
);
565 return NT_STATUS_NO_MEMORY
;
568 if (!lookup_name(mem_ctx
, qualified_name
, LOOKUP_NAME_ALL
,
571 TALLOC_FREE(mem_ctx
);
572 return NT_STATUS_NO_SUCH_USER
;
575 TALLOC_FREE(mem_ctx
);
577 if (type
!= SID_NAME_USER
) {
578 return NT_STATUS_NO_SUCH_USER
;
581 if ( !(sampass
= samu_new( NULL
)) ) {
582 return NT_STATUS_NO_MEMORY
;
585 status
= samu_set_unix( sampass
, pwd
);
586 if (!NT_STATUS_IS_OK(status
)) {
590 /* In pathological cases the above call can set the account
591 * name to the DOMAIN\username form. Reset the account name
592 * using unix_username */
593 pdb_set_username(sampass
, unix_username
, PDB_SET
);
595 /* set the user sid to be the calculated u_sid */
596 pdb_set_user_sid(sampass
, &u_sid
, PDB_SET
);
598 result
= make_server_info(NULL
);
599 if (result
== NULL
) {
600 TALLOC_FREE(sampass
);
601 return NT_STATUS_NO_MEMORY
;
604 status
= samu_to_SamInfo3(result
, sampass
, global_myname(),
605 &result
->info3
, &result
->extra
);
606 TALLOC_FREE(sampass
);
607 if (!NT_STATUS_IS_OK(status
)) {
608 DEBUG(10, ("Failed to convert samu to info3: %s\n",
614 result
->unix_name
= talloc_strdup(result
, unix_username
);
615 result
->sanitized_username
= sanitize_username(result
, unix_username
);
617 if ((result
->unix_name
== NULL
)
618 || (result
->sanitized_username
== NULL
)) {
620 return NT_STATUS_NO_MEMORY
;
623 result
->utok
.uid
= pwd
->pw_uid
;
624 result
->utok
.gid
= pwd
->pw_gid
;
626 *server_info
= result
;
631 /***************************************************************************
632 Make (and fill) a user_info struct for a guest login.
633 This *must* succeed for smbd to start. If there is no mapping entry for
634 the guest gid, then create one.
635 ***************************************************************************/
637 static NTSTATUS
make_new_server_info_guest(struct auth_serversupplied_info
**server_info
)
640 struct samu
*sampass
= NULL
;
641 struct dom_sid guest_sid
;
643 static const char zeros
[16] = {0, };
646 if ( !(sampass
= samu_new( NULL
)) ) {
647 return NT_STATUS_NO_MEMORY
;
650 sid_compose(&guest_sid
, get_global_sam_sid(), DOMAIN_RID_GUEST
);
653 ret
= pdb_getsampwsid(sampass
, &guest_sid
);
657 TALLOC_FREE(sampass
);
658 return NT_STATUS_NO_SUCH_USER
;
661 status
= make_server_info_sam(server_info
, sampass
);
662 if (!NT_STATUS_IS_OK(status
)) {
663 TALLOC_FREE(sampass
);
667 TALLOC_FREE(sampass
);
669 (*server_info
)->guest
= True
;
671 status
= create_local_token(*server_info
);
672 if (!NT_STATUS_IS_OK(status
)) {
673 DEBUG(10, ("create_local_token failed: %s\n",
678 /* annoying, but the Guest really does have a session key, and it is
680 (*server_info
)->user_session_key
= data_blob(zeros
, sizeof(zeros
));
681 (*server_info
)->lm_session_key
= data_blob(zeros
, sizeof(zeros
));
683 alpha_strcpy(tmp
, (*server_info
)->info3
->base
.account_name
.string
,
684 ". _-$", sizeof(tmp
));
685 (*server_info
)->sanitized_username
= talloc_strdup(*server_info
, tmp
);
690 /***************************************************************************
691 Make (and fill) a user_info struct for a system user login.
692 This *must* succeed for smbd to start.
693 ***************************************************************************/
695 static NTSTATUS
make_new_server_info_system(TALLOC_CTX
*mem_ctx
,
696 struct auth_serversupplied_info
**server_info
)
701 pwd
= getpwuid_alloc(mem_ctx
, sec_initial_uid());
703 return NT_STATUS_NO_MEMORY
;
706 status
= make_serverinfo_from_username(mem_ctx
,
710 if (!NT_STATUS_IS_OK(status
)) {
714 (*server_info
)->system
= true;
719 /****************************************************************************
720 Fake a auth_serversupplied_info just from a username
721 ****************************************************************************/
723 NTSTATUS
make_serverinfo_from_username(TALLOC_CTX
*mem_ctx
,
724 const char *username
,
726 struct auth_serversupplied_info
**presult
)
728 struct auth_serversupplied_info
*result
;
732 pwd
= getpwnam_alloc(talloc_tos(), username
);
734 return NT_STATUS_NO_SUCH_USER
;
737 status
= make_server_info_pw(&result
, pwd
->pw_name
, pwd
);
741 if (!NT_STATUS_IS_OK(status
)) {
745 result
->nss_token
= true;
746 result
->guest
= is_guest
;
748 status
= create_local_token(result
);
750 if (!NT_STATUS_IS_OK(status
)) {
760 struct auth_serversupplied_info
*copy_serverinfo(TALLOC_CTX
*mem_ctx
,
761 const struct auth_serversupplied_info
*src
)
763 struct auth_serversupplied_info
*dst
;
765 dst
= make_server_info(mem_ctx
);
770 dst
->guest
= src
->guest
;
771 dst
->system
= src
->system
;
772 dst
->utok
.uid
= src
->utok
.uid
;
773 dst
->utok
.gid
= src
->utok
.gid
;
774 dst
->utok
.ngroups
= src
->utok
.ngroups
;
775 if (src
->utok
.ngroups
!= 0) {
776 dst
->utok
.groups
= (gid_t
*)TALLOC_MEMDUP(
777 dst
, src
->utok
.groups
,
778 sizeof(gid_t
)*dst
->utok
.ngroups
);
780 dst
->utok
.groups
= NULL
;
784 dst
->ptok
= dup_nt_token(dst
, src
->ptok
);
791 dst
->user_session_key
= data_blob_talloc( dst
, src
->user_session_key
.data
,
792 src
->user_session_key
.length
);
794 dst
->lm_session_key
= data_blob_talloc(dst
, src
->lm_session_key
.data
,
795 src
->lm_session_key
.length
);
797 dst
->info3
= copy_netr_SamInfo3(dst
, src
->info3
);
802 dst
->extra
= src
->extra
;
804 dst
->pam_handle
= NULL
;
805 dst
->unix_name
= talloc_strdup(dst
, src
->unix_name
);
806 if (!dst
->unix_name
) {
811 dst
->sanitized_username
= talloc_strdup(dst
, src
->sanitized_username
);
812 if (!dst
->sanitized_username
) {
821 * Set a new session key. Used in the rpc server where we have to override the
822 * SMB level session key with SystemLibraryDTC
825 bool server_info_set_session_key(struct auth_serversupplied_info
*info
,
826 DATA_BLOB session_key
)
828 TALLOC_FREE(info
->user_session_key
.data
);
830 info
->user_session_key
= data_blob_talloc(
831 info
, session_key
.data
, session_key
.length
);
833 return (info
->user_session_key
.data
!= NULL
);
836 static struct auth_serversupplied_info
*guest_info
= NULL
;
838 bool init_guest_info(void)
840 if (guest_info
!= NULL
)
843 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info
));
846 NTSTATUS
make_server_info_guest(TALLOC_CTX
*mem_ctx
,
847 struct auth_serversupplied_info
**server_info
)
849 *server_info
= copy_serverinfo(mem_ctx
, guest_info
);
850 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
853 static struct auth_serversupplied_info
*system_info
= NULL
;
855 bool init_system_info(void)
857 if (system_info
!= NULL
)
860 return NT_STATUS_IS_OK(make_new_server_info_system(talloc_autofree_context(), &system_info
));
863 NTSTATUS
make_server_info_system(TALLOC_CTX
*mem_ctx
,
864 struct auth_serversupplied_info
**server_info
)
866 if (system_info
== NULL
) return NT_STATUS_UNSUCCESSFUL
;
867 *server_info
= copy_serverinfo(mem_ctx
, system_info
);
868 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
871 bool copy_current_user(struct current_user
*dst
, struct current_user
*src
)
874 NT_USER_TOKEN
*nt_token
;
876 groups
= (gid_t
*)memdup(src
->ut
.groups
,
877 sizeof(gid_t
) * src
->ut
.ngroups
);
878 if ((src
->ut
.ngroups
!= 0) && (groups
== NULL
)) {
882 nt_token
= dup_nt_token(NULL
, src
->nt_user_token
);
883 if (nt_token
== NULL
) {
888 dst
->conn
= src
->conn
;
889 dst
->vuid
= src
->vuid
;
890 dst
->ut
.uid
= src
->ut
.uid
;
891 dst
->ut
.gid
= src
->ut
.gid
;
892 dst
->ut
.ngroups
= src
->ut
.ngroups
;
893 dst
->ut
.groups
= groups
;
894 dst
->nt_user_token
= nt_token
;
898 /***************************************************************************
899 Purely internal function for make_server_info_info3
900 ***************************************************************************/
902 static NTSTATUS
check_account(TALLOC_CTX
*mem_ctx
, const char *domain
,
903 const char *username
, char **found_username
,
905 bool *username_was_mapped
)
907 fstring dom_user
, lower_username
;
908 fstring real_username
;
909 struct passwd
*passwd
;
911 fstrcpy( lower_username
, username
);
912 strlower_m( lower_username
);
914 fstr_sprintf(dom_user
, "%s%c%s", domain
, *lp_winbind_separator(),
917 /* Get the passwd struct. Try to create the account if necessary. */
919 *username_was_mapped
= map_username(dom_user
);
921 passwd
= smb_getpwnam( NULL
, dom_user
, real_username
, True
);
923 DEBUG(3, ("Failed to find authenticated user %s via "
924 "getpwnam(), denying access.\n", dom_user
));
925 return NT_STATUS_NO_SUCH_USER
;
930 /* This is pointless -- there is no suport for differing
931 unix and windows names. Make sure to always store the
932 one we actually looked up and succeeded. Have I mentioned
933 why I hate the 'winbind use default domain' parameter?
936 *found_username
= talloc_strdup( mem_ctx
, real_username
);
941 /****************************************************************************
942 Wrapper to allow the getpwnam() call to strip the domain name and
943 try again in case a local UNIX user is already there. Also run through
944 the username if we fallback to the username only.
945 ****************************************************************************/
947 struct passwd
*smb_getpwnam( TALLOC_CTX
*mem_ctx
, char *domuser
,
948 fstring save_username
, bool create
)
950 struct passwd
*pw
= NULL
;
954 /* we only save a copy of the username it has been mangled
955 by winbindd use default domain */
957 save_username
[0] = '\0';
959 /* don't call map_username() here since it has to be done higher
960 up the stack so we don't call it multiple times */
962 fstrcpy( username
, domuser
);
964 p
= strchr_m( username
, *lp_winbind_separator() );
966 /* code for a DOMAIN\user string */
969 fstring strip_username
;
971 pw
= Get_Pwnam_alloc( mem_ctx
, domuser
);
973 /* make sure we get the case of the username correct */
974 /* work around 'winbind use default domain = yes' */
976 if ( !strchr_m( pw
->pw_name
, *lp_winbind_separator() ) ) {
979 /* split the domain and username into 2 strings */
983 fstr_sprintf(save_username
, "%s%c%s", domain
, *lp_winbind_separator(), pw
->pw_name
);
986 fstrcpy( save_username
, pw
->pw_name
);
992 /* setup for lookup of just the username */
993 /* remember that p and username are overlapping memory */
996 fstrcpy( strip_username
, p
);
997 fstrcpy( username
, strip_username
);
1000 /* just lookup a plain username */
1002 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1004 /* Create local user if requested but only if winbindd
1005 is not running. We need to protect against cases
1006 where winbindd is failing and then prematurely
1007 creating users in /etc/passwd */
1009 if ( !pw
&& create
&& !winbind_ping() ) {
1010 /* Don't add a machine account. */
1011 if (username
[strlen(username
)-1] == '$')
1014 _smb_create_user(NULL
, username
, NULL
);
1015 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1018 /* one last check for a valid passwd struct */
1021 fstrcpy( save_username
, pw
->pw_name
);
1026 /***************************************************************************
1027 Make a server_info struct from the info3 returned by a domain logon
1028 ***************************************************************************/
1030 NTSTATUS
make_server_info_info3(TALLOC_CTX
*mem_ctx
,
1031 const char *sent_nt_username
,
1033 struct auth_serversupplied_info
**server_info
,
1034 struct netr_SamInfo3
*info3
)
1036 static const char zeros
[16] = {0, };
1038 NTSTATUS nt_status
= NT_STATUS_OK
;
1039 char *found_username
= NULL
;
1040 const char *nt_domain
;
1041 const char *nt_username
;
1042 bool username_was_mapped
;
1044 struct auth_serversupplied_info
*result
;
1045 struct dom_sid
*group_sid
;
1046 struct netr_SamInfo3
*i3
;
1049 Here is where we should check the list of
1050 trusted domains, and verify that the SID
1054 nt_username
= talloc_strdup(mem_ctx
, info3
->base
.account_name
.string
);
1056 /* If the server didn't give us one, just use the one we sent
1058 nt_username
= sent_nt_username
;
1061 nt_domain
= talloc_strdup(mem_ctx
, info3
->base
.domain
.string
);
1063 /* If the server didn't give us one, just use the one we sent
1068 /* If getpwnam() fails try the add user script (2.2.x behavior).
1070 We use the _unmapped_ username here in an attempt to provide
1071 consistent username mapping behavior between kerberos and NTLM[SSP]
1072 authentication in domain mode security. I.E. Username mapping
1073 should be applied to the fully qualified username
1074 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1075 called map_username() unnecessarily in make_user_info_map() but
1076 that is how the current code is designed. Making the change here
1077 is the least disruptive place. -- jerry */
1079 /* this call will try to create the user if necessary */
1081 nt_status
= check_account(mem_ctx
, nt_domain
, sent_nt_username
,
1082 &found_username
, &pwd
,
1083 &username_was_mapped
);
1085 if (!NT_STATUS_IS_OK(nt_status
)) {
1089 result
= make_server_info(NULL
);
1090 if (result
== NULL
) {
1091 DEBUG(4, ("make_server_info failed!\n"));
1092 return NT_STATUS_NO_MEMORY
;
1095 result
->unix_name
= talloc_strdup(result
, found_username
);
1097 result
->sanitized_username
= sanitize_username(result
,
1099 if (result
->sanitized_username
== NULL
) {
1100 TALLOC_FREE(result
);
1101 return NT_STATUS_NO_MEMORY
;
1104 /* copy in the info3 */
1105 result
->info3
= i3
= copy_netr_SamInfo3(result
, info3
);
1106 if (result
->info3
== NULL
) {
1107 TALLOC_FREE(result
);
1108 return NT_STATUS_NO_MEMORY
;
1111 /* Fill in the unix info we found on the way */
1112 result
->utok
.uid
= pwd
->pw_uid
;
1113 result
->utok
.gid
= pwd
->pw_gid
;
1115 /* We can't just trust that the primary group sid sent us is something
1116 * we can really use. Obtain the useable sid, and store the original
1117 * one as an additional group if it had to be replaced */
1118 nt_status
= get_primary_group_sid(mem_ctx
, found_username
,
1120 if (!NT_STATUS_IS_OK(nt_status
)) {
1121 TALLOC_FREE(result
);
1125 /* store and check if it is the same we got originally */
1126 sid_peek_rid(group_sid
, &i3
->base
.primary_gid
);
1127 if (i3
->base
.primary_gid
!= info3
->base
.primary_gid
) {
1128 uint32_t n
= i3
->base
.groups
.count
;
1129 /* not the same, store the original as an additional group */
1130 i3
->base
.groups
.rids
=
1131 talloc_realloc(i3
, i3
->base
.groups
.rids
,
1132 struct samr_RidWithAttribute
, n
+ 1);
1133 if (i3
->base
.groups
.rids
== NULL
) {
1134 TALLOC_FREE(result
);
1135 return NT_STATUS_NO_MEMORY
;
1137 i3
->base
.groups
.rids
[n
].rid
= info3
->base
.primary_gid
;
1138 i3
->base
.groups
.rids
[n
].attributes
= SE_GROUP_ENABLED
;
1139 i3
->base
.groups
.count
= n
+ 1;
1142 /* ensure we are never given NULL session keys */
1144 if (memcmp(info3
->base
.key
.key
, zeros
, sizeof(zeros
)) == 0) {
1145 result
->user_session_key
= data_blob_null
;
1147 result
->user_session_key
= data_blob_talloc(
1148 result
, info3
->base
.key
.key
,
1149 sizeof(info3
->base
.key
.key
));
1152 if (memcmp(info3
->base
.LMSessKey
.key
, zeros
, 8) == 0) {
1153 result
->lm_session_key
= data_blob_null
;
1155 result
->lm_session_key
= data_blob_talloc(
1156 result
, info3
->base
.LMSessKey
.key
,
1157 sizeof(info3
->base
.LMSessKey
.key
));
1160 result
->nss_token
|= username_was_mapped
;
1162 *server_info
= result
;
1164 return NT_STATUS_OK
;
1167 /*****************************************************************************
1168 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1169 ******************************************************************************/
1171 NTSTATUS
make_server_info_wbcAuthUserInfo(TALLOC_CTX
*mem_ctx
,
1172 const char *sent_nt_username
,
1174 const struct wbcAuthUserInfo
*info
,
1175 struct auth_serversupplied_info
**server_info
)
1177 struct netr_SamInfo3
*info3
;
1179 info3
= wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx
, info
);
1181 return NT_STATUS_NO_MEMORY
;
1184 return make_server_info_info3(mem_ctx
,
1185 sent_nt_username
, domain
,
1186 server_info
, info3
);
1190 * Verify whether or not given domain is trusted.
1192 * @param domain_name name of the domain to be verified
1193 * @return true if domain is one of the trusted ones or
1194 * false if otherwise
1197 bool is_trusted_domain(const char* dom_name
)
1199 struct dom_sid trustdom_sid
;
1202 /* no trusted domains for a standalone server */
1204 if ( lp_server_role() == ROLE_STANDALONE
)
1207 if (dom_name
== NULL
|| dom_name
[0] == '\0') {
1211 if (strequal(dom_name
, get_global_sam_name())) {
1215 /* if we are a DC, then check for a direct trust relationships */
1219 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1220 "[%s]\n", dom_name
));
1221 ret
= pdb_get_trusteddom_pw(dom_name
, NULL
, NULL
, NULL
);
1229 /* If winbind is around, ask it */
1231 result
= wb_is_trusted_domain(dom_name
);
1233 if (result
== WBC_ERR_SUCCESS
) {
1237 if (result
== WBC_ERR_DOMAIN_NOT_FOUND
) {
1238 /* winbind could not find the domain */
1242 /* The only other possible result is that winbind is not up
1243 and running. We need to update the trustdom_cache
1246 update_trustdom_cache();
1249 /* now the trustdom cache should be available a DC could still
1250 * have a transitive trust so fall back to the cache of trusted
1251 * domains (like a domain member would use */
1253 if ( trustdom_cache_fetch(dom_name
, &trustdom_sid
) ) {