tests: Expected failures in reparse point tests should not be errors
[Samba.git] / source3 / auth / user_krb5.c
blob169bf563368f61ae97f3bdf5e5a6d1a4a5e69254
1 /*
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/>.
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 #include "lib/param/loadparm.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
30 #ifdef HAVE_KRB5
31 NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
32 const char *cli_name,
33 const char *princ_name,
34 bool *is_mapped,
35 bool *mapped_to_guest,
36 char **ntuser,
37 char **ntdomain,
38 char **username,
39 struct passwd **_pw)
41 NTSTATUS status;
42 const char *domain = NULL;
43 const char *realm = NULL;
44 char *user = NULL;
45 char *p;
46 char *fuser = 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, '@');
54 if (!p) {
55 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
56 princ_name));
57 return NT_STATUS_LOGON_FAILURE;
60 user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
61 if (!user) {
62 return NT_STATUS_NO_MEMORY;
65 realm = p + 1;
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;
72 domain = realm;
73 } else {
74 domain = lp_workgroup();
75 may_retry = true;
78 fuser = talloc_asprintf(mem_ctx,
79 "%s%c%s",
80 domain,
81 *lp_winbind_separator(),
82 user);
83 if (!fuser) {
84 return NT_STATUS_NO_MEMORY;
87 *is_mapped = map_username(mem_ctx, fuser, &fuser);
88 if (!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);
96 if (!fuser) {
97 return NT_STATUS_NO_MEMORY;
99 pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true);
101 if (pw) {
102 if (!unixuser) {
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));
112 return status;
115 if (!pw) {
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());
124 if (!fuser) {
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 */
131 if (!pw) {
132 DBG_NOTICE("Username %s is invalid on this system\n",
133 fuser);
134 return NT_STATUS_LOGON_FAILURE;
138 if (!unixuser) {
139 return NT_STATUS_NO_MEMORY;
142 *username = talloc_strdup(mem_ctx, unixuser);
143 if (!*username) {
144 return NT_STATUS_NO_MEMORY;
146 *ntuser = user;
147 *ntdomain = talloc_strdup(mem_ctx, domain);
148 if (*ntdomain == NULL) {
149 return NT_STATUS_NO_MEMORY;
152 *_pw = pw;
154 return NT_STATUS_OK;
157 NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
158 char *ntuser,
159 char *ntdomain,
160 char *username,
161 struct passwd *pw,
162 bool mapped_to_guest, bool username_was_mapped,
163 struct auth_session_info **session_info)
165 NTSTATUS status;
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",
172 nt_errstr(status)));
173 return status;
176 } else {
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,
193 sampass,
194 &server_info);
195 } else {
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,
202 username,
204 &server_info);
207 TALLOC_FREE(sampass);
209 if (!NT_STATUS_IS_OK(status)) {
210 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
211 nt_errstr(status)));
212 return status;
215 /* make_server_info_pw does not set the domain. Without this
216 * we end up with the local netbios name in substitutions for
217 * %D. */
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",
231 nt_errstr(status)));
232 return status;
235 return NT_STATUS_OK;
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,
242 bool *is_mapped,
243 bool *mapped_to_guest,
244 char **ntuser,
245 char **ntdomain,
246 char **username,
247 struct passwd **_pw)
249 return NT_STATUS_NOT_IMPLEMENTED;
252 NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
253 char *ntuser,
254 char *ntdomain,
255 char *username,
256 struct passwd *pw,
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 */