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"
27 #define DBGC_CLASS DBGC_AUTH
30 NTSTATUS
get_user_from_kerberos_info(TALLOC_CTX
*mem_ctx
,
32 const char *princ_name
,
33 struct PAC_LOGON_INFO
*logon_info
,
35 bool *mapped_to_guest
,
47 char *unixuser
= NULL
;
48 struct passwd
*pw
= NULL
;
50 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name
));
52 p
= strchr_m(princ_name
, '@');
54 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
56 return NT_STATUS_LOGON_FAILURE
;
59 user
= talloc_strndup(mem_ctx
, princ_name
, p
- princ_name
);
61 return NT_STATUS_NO_MEMORY
;
64 realm
= talloc_strdup(talloc_tos(), p
+ 1);
66 return NT_STATUS_NO_MEMORY
;
69 if (!strequal(realm
, lp_realm())) {
70 DEBUG(3, ("Ticket for foreign realm %s@%s\n", user
, realm
));
71 if (!lp_allow_trusted_domains()) {
72 return NT_STATUS_LOGON_FAILURE
;
76 if (logon_info
&& logon_info
->info3
.base
.logon_domain
.string
) {
77 domain
= talloc_strdup(mem_ctx
,
78 logon_info
->info3
.base
.logon_domain
.string
);
80 return NT_STATUS_NO_MEMORY
;
82 DEBUG(10, ("Domain is [%s] (using PAC)\n", domain
));
85 /* If we have winbind running, we can (and must) shorten the
86 username by using the short netbios name. Otherwise we will
87 have inconsistent user names. With Kerberos, we get the
88 fully qualified realm, with ntlmssp we get the short
89 name. And even w2k3 does use ntlmssp if you for example
90 connect to an ip address. */
93 struct wbcDomainInfo
*info
= NULL
;
95 DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
98 wbc_status
= wbcDomainInfo(realm
, &info
);
100 if (WBC_ERROR_IS_OK(wbc_status
)) {
101 domain
= talloc_strdup(mem_ctx
,
105 DEBUG(3, ("Could not find short name: %s\n",
106 wbcErrorString(wbc_status
)));
107 domain
= talloc_strdup(mem_ctx
, realm
);
110 return NT_STATUS_NO_MEMORY
;
112 DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain
));
115 fuser
= talloc_asprintf(mem_ctx
,
118 *lp_winbind_separator(),
121 return NT_STATUS_NO_MEMORY
;
124 *is_mapped
= map_username(mem_ctx
, fuser
, &fuser
);
126 return NT_STATUS_NO_MEMORY
;
129 pw
= smb_getpwnam(mem_ctx
, fuser
, &unixuser
, true);
132 return NT_STATUS_NO_MEMORY
;
134 /* if a real user check pam account restrictions */
135 /* only really perfomed if "obey pam restriction" is true */
136 /* do this before an eventual mapping to guest occurs */
137 status
= smb_pam_accountcheck(pw
->pw_name
, cli_name
);
138 if (!NT_STATUS_IS_OK(status
)) {
139 DEBUG(1, ("PAM account restrictions prevent user "
140 "[%s] login\n", unixuser
));
146 /* this was originally the behavior of Samba 2.2, if a user
147 did not have a local uid but has been authenticated, then
148 map them to a guest account */
150 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID
) {
151 *mapped_to_guest
= true;
152 fuser
= talloc_strdup(mem_ctx
, lp_guestaccount());
154 return NT_STATUS_NO_MEMORY
;
156 pw
= smb_getpwnam(mem_ctx
, fuser
, &unixuser
, true);
159 /* extra sanity check that the guest account is valid */
161 DEBUG(1, ("Username %s is invalid on this system\n",
163 return NT_STATUS_LOGON_FAILURE
;
168 return NT_STATUS_NO_MEMORY
;
171 *username
= talloc_strdup(mem_ctx
, unixuser
);
173 return NT_STATUS_NO_MEMORY
;
182 NTSTATUS
make_session_info_krb5(TALLOC_CTX
*mem_ctx
,
187 struct PAC_LOGON_INFO
*logon_info
,
188 bool mapped_to_guest
, bool username_was_mapped
,
189 DATA_BLOB
*session_key
,
190 struct auth_session_info
**session_info
)
193 struct auth_serversupplied_info
*server_info
;
195 if (mapped_to_guest
) {
196 status
= make_server_info_guest(mem_ctx
, &server_info
);
197 if (!NT_STATUS_IS_OK(status
)) {
198 DEBUG(1, ("make_server_info_guest failed: %s!\n",
203 } else if (logon_info
) {
204 /* pass the unmapped username here since map_username()
205 will be called again in make_server_info_info3() */
207 status
= make_server_info_info3(mem_ctx
,
211 if (!NT_STATUS_IS_OK(status
)) {
212 DEBUG(1, ("make_server_info_info3 failed: %s!\n",
219 * We didn't get a PAC, we have to make up the user
220 * ourselves. Try to ask the pdb backend to provide
221 * SID consistency with ntlmssp session setup
223 struct samu
*sampass
;
224 /* The stupid make_server_info_XX functions here
225 don't take a talloc context. */
226 struct auth_serversupplied_info
*tmp
= NULL
;
228 sampass
= samu_new(talloc_tos());
229 if (sampass
== NULL
) {
230 return NT_STATUS_NO_MEMORY
;
233 if (pdb_getsampwnam(sampass
, username
)) {
234 DEBUG(10, ("found user %s in passdb, calling "
235 "make_server_info_sam\n", username
));
236 status
= make_server_info_sam(&tmp
, sampass
);
239 * User not in passdb, make it up artificially
241 DEBUG(10, ("didn't find user %s in passdb, calling "
242 "make_server_info_pw\n", username
));
243 status
= make_server_info_pw(&tmp
, username
, pw
);
246 TALLOC_FREE(sampass
);
248 if (!NT_STATUS_IS_OK(status
)) {
249 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
254 /* Steal tmp server info into the server_info pointer. */
255 server_info
= talloc_move(mem_ctx
, &tmp
);
257 /* make_server_info_pw does not set the domain. Without this
258 * we end up with the local netbios name in substitutions for
261 if (server_info
->info3
!= NULL
) {
262 server_info
->info3
->base
.logon_domain
.string
=
263 talloc_strdup(server_info
->info3
, ntdomain
);
267 server_info
->nss_token
|= username_was_mapped
;
269 status
= create_local_token(mem_ctx
, server_info
, session_key
, ntuser
, session_info
);
270 talloc_free(server_info
);
271 if (!NT_STATUS_IS_OK(status
)) {
272 DEBUG(10,("failed to create local token: %s\n",
280 #else /* HAVE_KRB5 */
281 NTSTATUS
get_user_from_kerberos_info(TALLOC_CTX
*mem_ctx
,
282 const char *cli_name
,
283 const char *princ_name
,
284 struct PAC_LOGON_INFO
*logon_info
,
286 bool *mapped_to_guest
,
292 return NT_STATUS_NOT_IMPLEMENTED
;
295 NTSTATUS
make_session_info_krb5(TALLOC_CTX
*mem_ctx
,
300 struct PAC_LOGON_INFO
*logon_info
,
301 bool mapped_to_guest
, bool username_was_mapped
,
302 DATA_BLOB
*session_key
,
303 struct auth_session_info
**session_info
)
305 return NT_STATUS_NOT_IMPLEMENTED
;
308 #endif /* HAVE_KRB5 */