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"
24 #define DBGC_CLASS DBGC_AUTH
27 NTSTATUS
get_user_from_kerberos_info(TALLOC_CTX
*mem_ctx
,
29 const char *princ_name
,
30 struct PAC_LOGON_INFO
*logon_info
,
32 bool *mapped_to_guest
,
45 struct passwd
*pw
= NULL
;
47 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name
));
49 p
= strchr_m(princ_name
, '@');
51 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
53 return NT_STATUS_LOGON_FAILURE
;
56 user
= talloc_strndup(mem_ctx
, princ_name
, p
- princ_name
);
58 return NT_STATUS_NO_MEMORY
;
61 realm
= talloc_strdup(talloc_tos(), p
+ 1);
63 return NT_STATUS_NO_MEMORY
;
66 if (!strequal(realm
, lp_realm())) {
67 DEBUG(3, ("Ticket for foreign realm %s@%s\n", user
, realm
));
68 if (!lp_allow_trusted_domains()) {
69 return NT_STATUS_LOGON_FAILURE
;
73 if (logon_info
&& logon_info
->info3
.base
.domain
.string
) {
74 domain
= talloc_strdup(mem_ctx
,
75 logon_info
->info3
.base
.domain
.string
);
77 return NT_STATUS_NO_MEMORY
;
79 DEBUG(10, ("Domain is [%s] (using PAC)\n", domain
));
82 /* If we have winbind running, we can (and must) shorten the
83 username by using the short netbios name. Otherwise we will
84 have inconsistent user names. With Kerberos, we get the
85 fully qualified realm, with ntlmssp we get the short
86 name. And even w2k3 does use ntlmssp if you for example
87 connect to an ip address. */
90 struct wbcDomainInfo
*info
= NULL
;
92 DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
95 wbc_status
= wbcDomainInfo(realm
, &info
);
97 if (WBC_ERROR_IS_OK(wbc_status
)) {
98 domain
= talloc_strdup(mem_ctx
,
102 DEBUG(3, ("Could not find short name: %s\n",
103 wbcErrorString(wbc_status
)));
104 domain
= talloc_strdup(mem_ctx
, realm
);
107 return NT_STATUS_NO_MEMORY
;
109 DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain
));
112 /* We have to use fstring for this - map_username requires it. */
113 fstr_sprintf(fuser
, "%s%c%s", domain
, *lp_winbind_separator(), user
);
115 *is_mapped
= map_username(fuser
);
117 pw
= smb_getpwnam(mem_ctx
, fuser
, unixuser
, true);
119 /* if a real user check pam account restrictions */
120 /* only really perfomed if "obey pam restriction" is true */
121 /* do this before an eventual mapping to guest occurs */
122 status
= smb_pam_accountcheck(pw
->pw_name
, cli_name
);
123 if (!NT_STATUS_IS_OK(status
)) {
124 DEBUG(1, ("PAM account restrictions prevent user "
125 "[%s] login\n", unixuser
));
131 /* this was originally the behavior of Samba 2.2, if a user
132 did not have a local uid but has been authenticated, then
133 map them to a guest account */
135 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID
) {
136 *mapped_to_guest
= true;
137 fstrcpy(fuser
, lp_guestaccount());
138 pw
= smb_getpwnam(mem_ctx
, fuser
, unixuser
, true);
141 /* extra sanity check that the guest account is valid */
143 DEBUG(1, ("Username %s is invalid on this system\n",
145 return NT_STATUS_LOGON_FAILURE
;
149 *username
= talloc_strdup(mem_ctx
, unixuser
);
151 return NT_STATUS_NO_MEMORY
;
160 NTSTATUS
make_server_info_krb5(TALLOC_CTX
*mem_ctx
,
165 struct PAC_LOGON_INFO
*logon_info
,
166 bool mapped_to_guest
,
167 struct auth_serversupplied_info
**server_info
)
171 if (mapped_to_guest
) {
172 status
= make_server_info_guest(mem_ctx
, server_info
);
173 if (!NT_STATUS_IS_OK(status
)) {
174 DEBUG(1, ("make_server_info_guest failed: %s!\n",
179 } else if (logon_info
) {
180 /* pass the unmapped username here since map_username()
181 will be called again in make_server_info_info3() */
183 status
= make_server_info_info3(mem_ctx
,
187 if (!NT_STATUS_IS_OK(status
)) {
188 DEBUG(1, ("make_server_info_info3 failed: %s!\n",
195 * We didn't get a PAC, we have to make up the user
196 * ourselves. Try to ask the pdb backend to provide
197 * SID consistency with ntlmssp session setup
199 struct samu
*sampass
;
200 /* The stupid make_server_info_XX functions here
201 don't take a talloc context. */
202 struct auth_serversupplied_info
*tmp
= NULL
;
204 sampass
= samu_new(talloc_tos());
205 if (sampass
== NULL
) {
206 return NT_STATUS_NO_MEMORY
;
209 if (pdb_getsampwnam(sampass
, username
)) {
210 DEBUG(10, ("found user %s in passdb, calling "
211 "make_server_info_sam\n", username
));
212 status
= make_server_info_sam(&tmp
, sampass
);
215 * User not in passdb, make it up artificially
217 DEBUG(10, ("didn't find user %s in passdb, calling "
218 "make_server_info_pw\n", username
));
219 status
= make_server_info_pw(&tmp
, username
, pw
);
221 TALLOC_FREE(sampass
);
223 if (!NT_STATUS_IS_OK(status
)) {
224 DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
229 /* Steal tmp server info into the server_info pointer. */
230 *server_info
= talloc_move(mem_ctx
, &tmp
);
232 /* make_server_info_pw does not set the domain. Without this
233 * we end up with the local netbios name in substitutions for
236 if ((*server_info
)->info3
!= NULL
) {
237 (*server_info
)->info3
->base
.domain
.string
=
238 talloc_strdup((*server_info
)->info3
, ntdomain
);
246 #else /* HAVE_KRB5 */
247 NTSTATUS
get_user_from_kerberos_info(TALLOC_CTX
*mem_ctx
,
248 const char *cli_name
,
249 const char *princ_name
,
250 struct PAC_LOGON_INFO
*logon_info
,
252 bool *mapped_to_guest
,
258 return NT_STATUS_NOT_IMPLEMENTED
;
261 NTSTATUS
make_server_info_krb5(TALLOC_CTX
*mem_ctx
,
266 struct PAC_LOGON_INFO
*logon_info
,
267 bool mapped_to_guest
,
268 struct auth_serversupplied_info
**server_info
)
270 return NT_STATUS_NOT_IMPLEMENTED
;
273 #endif /* HAVE_KRB5 */