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/>.
21 #include "librpc/gen_ndr/krb5pac.h"
22 #include "nsswitch/libwbclient/wbclient.h"
26 #define DBGC_CLASS DBGC_AUTH
29 NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
31 const char *princ_name,
32 struct PAC_LOGON_INFO *logon_info,
34 bool *mapped_to_guest,
46 char *unixuser = NULL;
47 struct passwd *pw = NULL;
49 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
51 p = strchr_m(princ_name, '@');
53 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
55 return NT_STATUS_LOGON_FAILURE;
58 user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
60 return NT_STATUS_NO_MEMORY;
63 realm = talloc_strdup(talloc_tos(), p + 1);
65 return NT_STATUS_NO_MEMORY;
68 if (!strequal(realm, lp_realm())) {
69 DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
70 if (!lp_allow_trusted_domains()) {
71 return NT_STATUS_LOGON_FAILURE;
75 if (logon_info && logon_info->info3.base.domain.string) {
76 domain = talloc_strdup(mem_ctx,
77 logon_info->info3.base.domain.string);
79 return NT_STATUS_NO_MEMORY;
81 DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
84 /* If we have winbind running, we can (and must) shorten the
85 username by using the short netbios name. Otherwise we will
86 have inconsistent user names. With Kerberos, we get the
87 fully qualified realm, with ntlmssp we get the short
88 name. And even w2k3 does use ntlmssp if you for example
89 connect to an ip address. */
92 struct wbcDomainInfo *info = NULL;
94 DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
97 wbc_status = wbcDomainInfo(realm, &info);
99 if (WBC_ERROR_IS_OK(wbc_status)) {
100 domain = talloc_strdup(mem_ctx,
104 DEBUG(3, ("Could not find short name: %s\n",
105 wbcErrorString(wbc_status)));
106 domain = talloc_strdup(mem_ctx, realm);
109 return NT_STATUS_NO_MEMORY;
111 DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
114 fuser = talloc_asprintf(mem_ctx,
117 *lp_winbind_separator(),
120 return NT_STATUS_NO_MEMORY;
123 *is_mapped = map_username(mem_ctx, fuser, &fuser);
125 return NT_STATUS_NO_MEMORY;
128 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
131 return NT_STATUS_NO_MEMORY;
133 /* if a real user check pam account restrictions */
134 /* only really perfomed if "obey pam restriction" is true */
135 /* do this before an eventual mapping to guest occurs */
136 status = smb_pam_accountcheck(pw->pw_name, cli_name);
137 if (!NT_STATUS_IS_OK(status)) {
138 DEBUG(1, ("PAM account restrictions prevent user "
139 "[%s] login\n", unixuser));
145 /* this was originally the behavior of Samba 2.2, if a user
146 did not have a local uid but has been authenticated, then
147 map them to a guest account */
149 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
150 *mapped_to_guest = true;
151 fuser = talloc_strdup(mem_ctx, lp_guestaccount());
153 return NT_STATUS_NO_MEMORY;
155 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
158 /* extra sanity check that the guest account is valid */
160 DEBUG(1, ("Username %s is invalid on this system\n",
162 return NT_STATUS_LOGON_FAILURE;
167 return NT_STATUS_NO_MEMORY;
170 *username = talloc_strdup(mem_ctx, unixuser);
172 return NT_STATUS_NO_MEMORY;
181 NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
186 struct PAC_LOGON_INFO *logon_info,
187 bool mapped_to_guest,
188 struct auth_serversupplied_info **server_info)
192 if (mapped_to_guest) {
193 status = make_server_info_guest(mem_ctx, server_info);
194 if (!NT_STATUS_IS_OK(status)) {
195 DEBUG(1, ("make_server_info_guest failed: %s!\n",
200 } else if (logon_info) {
201 /* pass the unmapped username here since map_username()
202 will be called again in make_server_info_info3() */
204 status = make_server_info_info3(mem_ctx,
208 if (!NT_STATUS_IS_OK(status)) {
209 DEBUG(1, ("make_server_info_info3 failed: %s!\n",
216 * We didn't get a PAC, we have to make up the user
217 * ourselves. Try to ask the pdb backend to provide
218 * SID consistency with ntlmssp session setup
220 struct samu *sampass;
221 /* The stupid make_server_info_XX functions here
222 don't take a talloc context. */
223 struct auth_serversupplied_info *tmp = NULL;
225 sampass = samu_new(talloc_tos());
226 if (sampass == NULL) {
227 return NT_STATUS_NO_MEMORY;
230 if (pdb_getsampwnam(sampass, username)) {
231 DEBUG(10, ("found user %s in passdb, calling "
232 "make_server_info_sam\n", username));
233 status = make_server_info_sam(&tmp, sampass);
236 * User not in passdb, make it up artificially
238 DEBUG(10, ("didn't find user %s in passdb, calling "
239 "make_server_info_pw\n", username));
240 status = make_server_info_pw(&tmp, username, pw);
242 TALLOC_FREE(sampass);
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
250 /* Steal tmp server info into the server_info pointer. */
251 *server_info = talloc_move(mem_ctx, &tmp);
253 /* make_server_info_pw does not set the domain. Without this
254 * we end up with the local netbios name in substitutions for
257 if ((*server_info)->info3 != NULL) {
258 (*server_info)->info3->base.domain.string =
259 talloc_strdup((*server_info)->info3, ntdomain);
267 #else /* HAVE_KRB5 */
268 NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
269 const char *cli_name,
270 const char *princ_name,
271 struct PAC_LOGON_INFO *logon_info,
273 bool *mapped_to_guest,
279 return NT_STATUS_NOT_IMPLEMENTED;
282 NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
287 struct PAC_LOGON_INFO *logon_info,
288 bool mapped_to_guest,
289 struct auth_serversupplied_info **server_info)
291 return NT_STATUS_NOT_IMPLEMENTED;
294 #endif /* HAVE_KRB5 */