2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Simo Sorce 2010
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/krb5pac.h"
23 #include "nsswitch/libwbclient/wbclient.h"
25 #include "lib/param/loadparm.h"
28 #define DBGC_CLASS DBGC_AUTH
31 NTSTATUS
get_user_from_kerberos_info(TALLOC_CTX
*mem_ctx
,
33 const char *princ_name
,
35 bool *mapped_to_guest
,
42 const char *domain
= NULL
;
43 const char *realm
= NULL
;
47 char *unixuser
= NULL
;
48 struct passwd
*pw
= NULL
;
49 bool may_retry
= false;
51 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name
));
53 p
= strchr_m(princ_name
, '@');
55 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
57 return NT_STATUS_LOGON_FAILURE
;
60 user
= talloc_strndup(mem_ctx
, princ_name
, p
- princ_name
);
62 return NT_STATUS_NO_MEMORY
;
67 if (!strequal(realm
, lp_realm())) {
68 DEBUG(3, ("Ticket for foreign realm %s@%s\n", user
, realm
));
69 if (!lp_allow_trusted_domains()) {
70 return NT_STATUS_LOGON_FAILURE
;
74 domain
= lp_workgroup();
78 fuser
= talloc_asprintf(mem_ctx
,
81 *lp_winbind_separator(),
84 return NT_STATUS_NO_MEMORY
;
87 *is_mapped
= map_username(mem_ctx
, fuser
, &fuser
);
89 return NT_STATUS_NO_MEMORY
;
91 *mapped_to_guest
= false;
93 pw
= smb_getpwnam(mem_ctx
, fuser
, &unixuser
, true);
94 if (may_retry
&& pw
== NULL
&& !*is_mapped
) {
95 fuser
= talloc_strdup(mem_ctx
, user
);
97 return NT_STATUS_NO_MEMORY
;
99 pw
= smb_getpwnam(mem_ctx
, fuser
, &unixuser
, true);
103 return NT_STATUS_NO_MEMORY
;
105 /* if a real user check pam account restrictions */
106 /* only really performed if "obey pam restriction" is true */
107 /* do this before an eventual mapping to guest occurs */
108 status
= smb_pam_accountcheck(pw
->pw_name
, cli_name
);
109 if (!NT_STATUS_IS_OK(status
)) {
110 DEBUG(1, ("PAM account restrictions prevent user "
111 "[%s] login\n", unixuser
));
117 /* this was originally the behavior of Samba 2.2, if a user
118 did not have a local uid but has been authenticated, then
119 map them to a guest account */
121 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID
) {
122 *mapped_to_guest
= true;
123 fuser
= talloc_strdup(mem_ctx
, lp_guest_account());
125 return NT_STATUS_NO_MEMORY
;
127 pw
= smb_getpwnam(mem_ctx
, fuser
, &unixuser
, false);
130 /* extra sanity check that the guest account is valid */
132 DBG_NOTICE("Username %s is invalid on this system\n",
134 return NT_STATUS_LOGON_FAILURE
;
139 return NT_STATUS_NO_MEMORY
;
142 *username
= talloc_strdup(mem_ctx
, unixuser
);
144 return NT_STATUS_NO_MEMORY
;
147 *ntdomain
= talloc_strdup(mem_ctx
, domain
);
148 if (*ntdomain
== NULL
) {
149 return NT_STATUS_NO_MEMORY
;
157 NTSTATUS
make_session_info_krb5(TALLOC_CTX
*mem_ctx
,
162 bool mapped_to_guest
, bool username_was_mapped
,
163 struct auth_session_info
**session_info
)
166 struct auth_serversupplied_info
*server_info
;
168 if (mapped_to_guest
) {
169 status
= make_server_info_guest(mem_ctx
, &server_info
);
170 if (!NT_STATUS_IS_OK(status
)) {
171 DEBUG(1, ("make_server_info_guest failed: %s!\n",
178 * We didn't get a PAC, we have to make up the user
179 * ourselves. Try to ask the pdb backend to provide
180 * SID consistency with ntlmssp session setup
182 struct samu
*sampass
;
184 sampass
= samu_new(talloc_tos());
185 if (sampass
== NULL
) {
186 return NT_STATUS_NO_MEMORY
;
189 if (pdb_getsampwnam(sampass
, username
)) {
190 DEBUG(10, ("found user %s in passdb, calling "
191 "make_server_info_sam\n", username
));
192 status
= make_server_info_sam(mem_ctx
,
197 * User not in passdb, make it up artificially
199 DEBUG(10, ("didn't find user %s in passdb, calling "
200 "make_server_info_pw\n", username
));
201 status
= make_server_info_pw(mem_ctx
,
207 TALLOC_FREE(sampass
);
209 if (!NT_STATUS_IS_OK(status
)) {
210 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
215 /* make_server_info_pw does not set the domain. Without this
216 * we end up with the local netbios name in substitutions for
219 if (server_info
->info3
!= NULL
) {
220 server_info
->info3
->base
.logon_domain
.string
=
221 talloc_strdup(server_info
->info3
, ntdomain
);
225 server_info
->nss_token
|= username_was_mapped
;
227 status
= create_local_token(mem_ctx
, server_info
, NULL
, ntuser
, session_info
);
228 talloc_free(server_info
);
229 if (!NT_STATUS_IS_OK(status
)) {
230 DEBUG(10,("failed to create local token: %s\n",
238 #else /* HAVE_KRB5 */
239 NTSTATUS
get_user_from_kerberos_info(TALLOC_CTX
*mem_ctx
,
240 const char *cli_name
,
241 const char *princ_name
,
243 bool *mapped_to_guest
,
249 return NT_STATUS_NOT_IMPLEMENTED
;
252 NTSTATUS
make_session_info_krb5(TALLOC_CTX
*mem_ctx
,
257 bool mapped_to_guest
, bool username_was_mapped
,
258 struct auth_session_info
**session_info
)
260 return NT_STATUS_NOT_IMPLEMENTED
;
263 #endif /* HAVE_KRB5 */