source: vendor/3.6.0/source3/auth/user_krb5.c

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

File size: 7.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Simo Sorce 2010
5
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.
10
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.
15
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/>.
18*/
19
20#include "includes.h"
21#include "auth.h"
22#include "librpc/gen_ndr/krb5pac.h"
23#include "nsswitch/libwbclient/wbclient.h"
24#include "passdb.h"
25
26#undef DBGC_CLASS
27#define DBGC_CLASS DBGC_AUTH
28
29#ifdef HAVE_KRB5
30NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
31 const char *cli_name,
32 const char *princ_name,
33 struct PAC_LOGON_INFO *logon_info,
34 bool *is_mapped,
35 bool *mapped_to_guest,
36 char **ntuser,
37 char **ntdomain,
38 char **username,
39 struct passwd **_pw)
40{
41 NTSTATUS status;
42 char *domain = NULL;
43 char *realm = NULL;
44 char *user = NULL;
45 char *p;
46 char *fuser = NULL;
47 char *unixuser = NULL;
48 struct passwd *pw = NULL;
49
50 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
51
52 p = strchr_m(princ_name, '@');
53 if (!p) {
54 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
55 princ_name));
56 return NT_STATUS_LOGON_FAILURE;
57 }
58
59 user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
60 if (!user) {
61 return NT_STATUS_NO_MEMORY;
62 }
63
64 realm = talloc_strdup(talloc_tos(), p + 1);
65 if (!realm) {
66 return NT_STATUS_NO_MEMORY;
67 }
68
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;
73 }
74 }
75
76 if (logon_info && logon_info->info3.base.domain.string) {
77 domain = talloc_strdup(mem_ctx,
78 logon_info->info3.base.domain.string);
79 if (!domain) {
80 return NT_STATUS_NO_MEMORY;
81 }
82 DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
83 } else {
84
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. */
91
92 wbcErr wbc_status;
93 struct wbcDomainInfo *info = NULL;
94
95 DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
96 realm));
97
98 wbc_status = wbcDomainInfo(realm, &info);
99
100 if (WBC_ERROR_IS_OK(wbc_status)) {
101 domain = talloc_strdup(mem_ctx,
102 info->short_name);
103 wbcFreeMemory(info);
104 } else {
105 DEBUG(3, ("Could not find short name: %s\n",
106 wbcErrorString(wbc_status)));
107 domain = talloc_strdup(mem_ctx, realm);
108 }
109 if (!domain) {
110 return NT_STATUS_NO_MEMORY;
111 }
112 DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
113 }
114
115 fuser = talloc_asprintf(mem_ctx,
116 "%s%c%s",
117 domain,
118 *lp_winbind_separator(),
119 user);
120 if (!fuser) {
121 return NT_STATUS_NO_MEMORY;
122 }
123
124 *is_mapped = map_username(mem_ctx, fuser, &fuser);
125 if (!fuser) {
126 return NT_STATUS_NO_MEMORY;
127 }
128
129 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
130 if (pw) {
131 if (!unixuser) {
132 return NT_STATUS_NO_MEMORY;
133 }
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));
141 return status;
142 }
143 }
144 if (!pw) {
145
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 */
149
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());
153 if (!fuser) {
154 return NT_STATUS_NO_MEMORY;
155 }
156 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
157 }
158
159 /* extra sanity check that the guest account is valid */
160 if (!pw) {
161 DEBUG(1, ("Username %s is invalid on this system\n",
162 fuser));
163 return NT_STATUS_LOGON_FAILURE;
164 }
165 }
166
167 if (!unixuser) {
168 return NT_STATUS_NO_MEMORY;
169 }
170
171 *username = talloc_strdup(mem_ctx, unixuser);
172 if (!*username) {
173 return NT_STATUS_NO_MEMORY;
174 }
175 *ntuser = user;
176 *ntdomain = domain;
177 *_pw = pw;
178
179 return NT_STATUS_OK;
180}
181
182NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
183 char *ntuser,
184 char *ntdomain,
185 char *username,
186 struct passwd *pw,
187 struct PAC_LOGON_INFO *logon_info,
188 bool mapped_to_guest,
189 struct auth_serversupplied_info **server_info)
190{
191 NTSTATUS status;
192
193 if (mapped_to_guest) {
194 status = make_server_info_guest(mem_ctx, server_info);
195 if (!NT_STATUS_IS_OK(status)) {
196 DEBUG(1, ("make_server_info_guest failed: %s!\n",
197 nt_errstr(status)));
198 return status;
199 }
200
201 } else if (logon_info) {
202 /* pass the unmapped username here since map_username()
203 will be called again in make_server_info_info3() */
204
205 status = make_server_info_info3(mem_ctx,
206 ntuser, ntdomain,
207 server_info,
208 &logon_info->info3);
209 if (!NT_STATUS_IS_OK(status)) {
210 DEBUG(1, ("make_server_info_info3 failed: %s!\n",
211 nt_errstr(status)));
212 return status;
213 }
214
215 } else {
216 /*
217 * We didn't get a PAC, we have to make up the user
218 * ourselves. Try to ask the pdb backend to provide
219 * SID consistency with ntlmssp session setup
220 */
221 struct samu *sampass;
222 /* The stupid make_server_info_XX functions here
223 don't take a talloc context. */
224 struct auth_serversupplied_info *tmp = NULL;
225
226 sampass = samu_new(talloc_tos());
227 if (sampass == NULL) {
228 return NT_STATUS_NO_MEMORY;
229 }
230
231 if (pdb_getsampwnam(sampass, username)) {
232 DEBUG(10, ("found user %s in passdb, calling "
233 "make_server_info_sam\n", username));
234 status = make_server_info_sam(&tmp, sampass);
235 } else {
236 /*
237 * User not in passdb, make it up artificially
238 */
239 DEBUG(10, ("didn't find user %s in passdb, calling "
240 "make_server_info_pw\n", username));
241 status = make_server_info_pw(&tmp, username, pw);
242 }
243 TALLOC_FREE(sampass);
244
245 if (!NT_STATUS_IS_OK(status)) {
246 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
247 nt_errstr(status)));
248 return status;
249 }
250
251 /* Steal tmp server info into the server_info pointer. */
252 *server_info = talloc_move(mem_ctx, &tmp);
253
254 /* make_server_info_pw does not set the domain. Without this
255 * we end up with the local netbios name in substitutions for
256 * %D. */
257
258 if ((*server_info)->info3 != NULL) {
259 (*server_info)->info3->base.domain.string =
260 talloc_strdup((*server_info)->info3, ntdomain);
261 }
262
263 }
264
265 return NT_STATUS_OK;
266}
267
268#else /* HAVE_KRB5 */
269NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
270 const char *cli_name,
271 const char *princ_name,
272 struct PAC_LOGON_INFO *logon_info,
273 bool *is_mapped,
274 bool *mapped_to_guest,
275 char **ntuser,
276 char **ntdomain,
277 char **username,
278 struct passwd **_pw)
279{
280 return NT_STATUS_NOT_IMPLEMENTED;
281}
282
283NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
284 char *ntuser,
285 char *ntdomain,
286 char *username,
287 struct passwd *pw,
288 struct PAC_LOGON_INFO *logon_info,
289 bool mapped_to_guest,
290 struct auth_serversupplied_info **server_info)
291{
292 return NT_STATUS_NOT_IMPLEMENTED;
293}
294
295#endif /* HAVE_KRB5 */
Note: See TracBrowser for help on using the repository browser.