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"
25 #define DBGC_CLASS DBGC_AUTH
28 NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
30 const char *princ_name,
31 struct PAC_LOGON_INFO *logon_info,
33 bool *mapped_to_guest,
45 char *unixuser = NULL;
46 struct passwd *pw = NULL;
48 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
50 p = strchr_m(princ_name, '@');
52 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
54 return NT_STATUS_LOGON_FAILURE;
57 user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
59 return NT_STATUS_NO_MEMORY;
62 realm = talloc_strdup(talloc_tos(), p + 1);
64 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 if (logon_info && logon_info->info3.base.domain.string) {
75 domain = talloc_strdup(mem_ctx,
76 logon_info->info3.base.domain.string);
78 return NT_STATUS_NO_MEMORY;
80 DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
83 /* If we have winbind running, we can (and must) shorten the
84 username by using the short netbios name. Otherwise we will
85 have inconsistent user names. With Kerberos, we get the
86 fully qualified realm, with ntlmssp we get the short
87 name. And even w2k3 does use ntlmssp if you for example
88 connect to an ip address. */
91 struct wbcDomainInfo *info = NULL;
93 DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
96 wbc_status = wbcDomainInfo(realm, &info);
98 if (WBC_ERROR_IS_OK(wbc_status)) {
99 domain = talloc_strdup(mem_ctx,
103 DEBUG(3, ("Could not find short name: %s\n",
104 wbcErrorString(wbc_status)));
105 domain = talloc_strdup(mem_ctx, realm);
108 return NT_STATUS_NO_MEMORY;
110 DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
113 fuser = talloc_asprintf(mem_ctx,
116 *lp_winbind_separator(),
119 return NT_STATUS_NO_MEMORY;
122 *is_mapped = map_username(mem_ctx, fuser, &fuser);
124 return NT_STATUS_NO_MEMORY;
127 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
130 return NT_STATUS_NO_MEMORY;
132 /* if a real user check pam account restrictions */
133 /* only really perfomed if "obey pam restriction" is true */
134 /* do this before an eventual mapping to guest occurs */
135 status = smb_pam_accountcheck(pw->pw_name, cli_name);
136 if (!NT_STATUS_IS_OK(status)) {
137 DEBUG(1, ("PAM account restrictions prevent user "
138 "[%s] login\n", unixuser));
144 /* this was originally the behavior of Samba 2.2, if a user
145 did not have a local uid but has been authenticated, then
146 map them to a guest account */
148 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
149 *mapped_to_guest = true;
150 fuser = talloc_strdup(mem_ctx, lp_guestaccount());
152 return NT_STATUS_NO_MEMORY;
154 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
157 /* extra sanity check that the guest account is valid */
159 DEBUG(1, ("Username %s is invalid on this system\n",
161 return NT_STATUS_LOGON_FAILURE;
166 return NT_STATUS_NO_MEMORY;
169 *username = talloc_strdup(mem_ctx, unixuser);
171 return NT_STATUS_NO_MEMORY;
180 NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
185 struct PAC_LOGON_INFO *logon_info,
186 bool mapped_to_guest,
187 struct auth_serversupplied_info **server_info)
191 if (mapped_to_guest) {
192 status = make_server_info_guest(mem_ctx, server_info);
193 if (!NT_STATUS_IS_OK(status)) {
194 DEBUG(1, ("make_server_info_guest failed: %s!\n",
199 } else if (logon_info) {
200 /* pass the unmapped username here since map_username()
201 will be called again in make_server_info_info3() */
203 status = make_server_info_info3(mem_ctx,
207 if (!NT_STATUS_IS_OK(status)) {
208 DEBUG(1, ("make_server_info_info3 failed: %s!\n",
215 * We didn't get a PAC, we have to make up the user
216 * ourselves. Try to ask the pdb backend to provide
217 * SID consistency with ntlmssp session setup
219 struct samu *sampass;
220 /* The stupid make_server_info_XX functions here
221 don't take a talloc context. */
222 struct auth_serversupplied_info *tmp = NULL;
224 sampass = samu_new(talloc_tos());
225 if (sampass == NULL) {
226 return NT_STATUS_NO_MEMORY;
229 if (pdb_getsampwnam(sampass, username)) {
230 DEBUG(10, ("found user %s in passdb, calling "
231 "make_server_info_sam\n", username));
232 status = make_server_info_sam(&tmp, sampass);
235 * User not in passdb, make it up artificially
237 DEBUG(10, ("didn't find user %s in passdb, calling "
238 "make_server_info_pw\n", username));
239 status = make_server_info_pw(&tmp, username, pw);
241 TALLOC_FREE(sampass);
243 if (!NT_STATUS_IS_OK(status)) {
244 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
249 /* Steal tmp server info into the server_info pointer. */
250 *server_info = talloc_move(mem_ctx, &tmp);
252 /* make_server_info_pw does not set the domain. Without this
253 * we end up with the local netbios name in substitutions for
256 if ((*server_info)->info3 != NULL) {
257 (*server_info)->info3->base.domain.string =
258 talloc_strdup((*server_info)->info3, ntdomain);
266 #else /* HAVE_KRB5 */
267 NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
268 const char *cli_name,
269 const char *princ_name,
270 struct PAC_LOGON_INFO *logon_info,
272 bool *mapped_to_guest,
278 return NT_STATUS_NOT_IMPLEMENTED;
281 NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
286 struct PAC_LOGON_INFO *logon_info,
287 bool mapped_to_guest,
288 struct auth_serversupplied_info **server_info)
290 return NT_STATUS_NOT_IMPLEMENTED;
293 #endif /* HAVE_KRB5 */