xref: /freebsd/crypto/krb5/src/windows/kfwlogon/kfwcommon.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert Copyright 2005,2006 by the Massachusetts Institute of Technology
3*7f2fe78bSCy Schubert Copyright 2007 by Secure Endpoints Inc.
4*7f2fe78bSCy Schubert 
5*7f2fe78bSCy Schubert All rights reserved.
6*7f2fe78bSCy Schubert 
7*7f2fe78bSCy Schubert Permission to use, copy, modify, and distribute this software and its
8*7f2fe78bSCy Schubert documentation for any purpose and without fee is hereby granted,
9*7f2fe78bSCy Schubert provided that the above copyright notice appear in all copies and that
10*7f2fe78bSCy Schubert both that copyright notice and this permission notice appear in
11*7f2fe78bSCy Schubert supporting documentation, and that the name of the Massachusetts
12*7f2fe78bSCy Schubert Institute of Technology (M.I.T.) not be used in advertising or publicity
13*7f2fe78bSCy Schubert pertaining to distribution of the software without specific, written
14*7f2fe78bSCy Schubert prior permission.
15*7f2fe78bSCy Schubert 
16*7f2fe78bSCy Schubert M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
17*7f2fe78bSCy Schubert ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
18*7f2fe78bSCy Schubert M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
19*7f2fe78bSCy Schubert ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20*7f2fe78bSCy Schubert WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21*7f2fe78bSCy Schubert ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22*7f2fe78bSCy Schubert SOFTWARE.
23*7f2fe78bSCy Schubert 
24*7f2fe78bSCy Schubert */
25*7f2fe78bSCy Schubert 
26*7f2fe78bSCy Schubert #include "kfwlogon.h"
27*7f2fe78bSCy Schubert #include <windows.h>
28*7f2fe78bSCy Schubert #include <Aclapi.h>
29*7f2fe78bSCy Schubert #include <userenv.h>
30*7f2fe78bSCy Schubert #include <Sddl.h>
31*7f2fe78bSCy Schubert 
32*7f2fe78bSCy Schubert #include <io.h>
33*7f2fe78bSCy Schubert #include <sys/stat.h>
34*7f2fe78bSCy Schubert #include <sys/types.h>
35*7f2fe78bSCy Schubert #include <fcntl.h>
36*7f2fe78bSCy Schubert 
37*7f2fe78bSCy Schubert #include <winsock2.h>
38*7f2fe78bSCy Schubert #include <lm.h>
39*7f2fe78bSCy Schubert #include <nb30.h>
40*7f2fe78bSCy Schubert 
41*7f2fe78bSCy Schubert #include <errno.h>
42*7f2fe78bSCy Schubert #include <malloc.h>
43*7f2fe78bSCy Schubert 
44*7f2fe78bSCy Schubert 
45*7f2fe78bSCy Schubert /* Function Pointer Declarations for Delayed Loading */
46*7f2fe78bSCy Schubert // CCAPI
47*7f2fe78bSCy Schubert DECL_FUNC_PTR(cc_initialize);
48*7f2fe78bSCy Schubert DECL_FUNC_PTR(cc_shutdown);
49*7f2fe78bSCy Schubert DECL_FUNC_PTR(cc_get_NC_info);
50*7f2fe78bSCy Schubert DECL_FUNC_PTR(cc_free_NC_info);
51*7f2fe78bSCy Schubert 
52*7f2fe78bSCy Schubert // leash functions
53*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_lifetime);
54*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_forwardable);
55*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_renew_till);
56*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_noaddresses);
57*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_proxiable);
58*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_publicip);
59*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_life_min);
60*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_life_max);
61*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_renew_min);
62*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_renew_max);
63*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_renewable);
64*7f2fe78bSCy Schubert DECL_FUNC_PTR(Leash_get_default_mslsa_import);
65*7f2fe78bSCy Schubert 
66*7f2fe78bSCy Schubert // krb5 functions
67*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_change_password);
68*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_opt_init);
69*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life);
70*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life);
71*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable);
72*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable);
73*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list);
74*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_init_creds_password);
75*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_build_principal_ext);
76*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_get_name);
77*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_resolve);
78*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_default);
79*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_default_name);
80*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_set_default_name);
81*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_initialize);
82*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_destroy);
83*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_close);
84*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_store_cred);
85*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_copy_creds);
86*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_retrieve_cred);
87*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_get_principal);
88*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_start_seq_get);
89*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_next_cred);
90*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_end_seq_get);
91*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_remove_cred);
92*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_set_flags);
93*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_cc_get_type);
94*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_context);
95*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_cred_contents);
96*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_principal);
97*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_in_tkt_with_password);
98*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_init_context);
99*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_parse_name);
100*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_timeofday);
101*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_timestamp_to_sfstring);
102*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_unparse_name);
103*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_credentials);
104*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_mk_req);
105*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_sname_to_principal);
106*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_credentials_renew);
107*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_data);
108*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_data_contents);
109*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_unparsed_name);
110*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_os_localaddr);
111*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_copy_keyblock_contents);
112*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_copy_data);
113*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_creds);
114*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_build_principal);
115*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_renewed_creds);
116*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_default_config_files);
117*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_config_files);
118*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_default_realm);
119*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_default_realm);
120*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_ticket);
121*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_decode_ticket);
122*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_get_host_realm);
123*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_host_realm);
124*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_free_addresses);
125*7f2fe78bSCy Schubert DECL_FUNC_PTR(krb5_c_random_make_octets);
126*7f2fe78bSCy Schubert 
127*7f2fe78bSCy Schubert // ComErr functions
128*7f2fe78bSCy Schubert DECL_FUNC_PTR(com_err);
129*7f2fe78bSCy Schubert DECL_FUNC_PTR(error_message);
130*7f2fe78bSCy Schubert 
131*7f2fe78bSCy Schubert // Profile functions
132*7f2fe78bSCy Schubert DECL_FUNC_PTR(profile_init);
133*7f2fe78bSCy Schubert DECL_FUNC_PTR(profile_release);
134*7f2fe78bSCy Schubert DECL_FUNC_PTR(profile_get_subsection_names);
135*7f2fe78bSCy Schubert DECL_FUNC_PTR(profile_free_list);
136*7f2fe78bSCy Schubert DECL_FUNC_PTR(profile_get_string);
137*7f2fe78bSCy Schubert DECL_FUNC_PTR(profile_release_string);
138*7f2fe78bSCy Schubert 
139*7f2fe78bSCy Schubert // Service functions
140*7f2fe78bSCy Schubert DECL_FUNC_PTR(OpenSCManagerA);
141*7f2fe78bSCy Schubert DECL_FUNC_PTR(OpenServiceA);
142*7f2fe78bSCy Schubert DECL_FUNC_PTR(QueryServiceStatus);
143*7f2fe78bSCy Schubert DECL_FUNC_PTR(CloseServiceHandle);
144*7f2fe78bSCy Schubert DECL_FUNC_PTR(LsaNtStatusToWinError);
145*7f2fe78bSCy Schubert 
146*7f2fe78bSCy Schubert // LSA Functions
147*7f2fe78bSCy Schubert DECL_FUNC_PTR(LsaConnectUntrusted);
148*7f2fe78bSCy Schubert DECL_FUNC_PTR(LsaLookupAuthenticationPackage);
149*7f2fe78bSCy Schubert DECL_FUNC_PTR(LsaCallAuthenticationPackage);
150*7f2fe78bSCy Schubert DECL_FUNC_PTR(LsaFreeReturnBuffer);
151*7f2fe78bSCy Schubert DECL_FUNC_PTR(LsaGetLogonSessionData);
152*7f2fe78bSCy Schubert 
153*7f2fe78bSCy Schubert // CCAPI
154*7f2fe78bSCy Schubert FUNC_INFO ccapi_fi[] = {
155*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(cc_initialize),
156*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(cc_shutdown),
157*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(cc_get_NC_info),
158*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(cc_free_NC_info),
159*7f2fe78bSCy Schubert     END_FUNC_INFO
160*7f2fe78bSCy Schubert };
161*7f2fe78bSCy Schubert 
162*7f2fe78bSCy Schubert FUNC_INFO leash_fi[] = {
163*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_lifetime),
164*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_renew_till),
165*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_forwardable),
166*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_noaddresses),
167*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_proxiable),
168*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_publicip),
169*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_life_min),
170*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_life_max),
171*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_renew_min),
172*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_renew_max),
173*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_renewable),
174*7f2fe78bSCy Schubert     END_FUNC_INFO
175*7f2fe78bSCy Schubert };
176*7f2fe78bSCy Schubert 
177*7f2fe78bSCy Schubert FUNC_INFO leash_opt_fi[] = {
178*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(Leash_get_default_mslsa_import),
179*7f2fe78bSCy Schubert     END_FUNC_INFO
180*7f2fe78bSCy Schubert };
181*7f2fe78bSCy Schubert 
182*7f2fe78bSCy Schubert FUNC_INFO k5_fi[] = {
183*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_change_password),
184*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_opt_init),
185*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life),
186*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life),
187*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable),
188*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable),
189*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list),
190*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_init_creds_password),
191*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_build_principal_ext),
192*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_get_name),
193*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_resolve),
194*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_default),
195*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_default_name),
196*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_set_default_name),
197*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_initialize),
198*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_destroy),
199*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_close),
200*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_copy_creds),
201*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_store_cred),
202*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_retrieve_cred),
203*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_get_principal),
204*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_start_seq_get),
205*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_next_cred),
206*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_end_seq_get),
207*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_remove_cred),
208*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_set_flags),
209*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_cc_get_type),
210*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_context),
211*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_cred_contents),
212*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_principal),
213*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_in_tkt_with_password),
214*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_init_context),
215*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_parse_name),
216*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_timeofday),
217*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_timestamp_to_sfstring),
218*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_unparse_name),
219*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_credentials),
220*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_mk_req),
221*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_sname_to_principal),
222*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_credentials_renew),
223*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_data),
224*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_data_contents),
225*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_unparsed_name),
226*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_os_localaddr),
227*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_copy_keyblock_contents),
228*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_copy_data),
229*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_creds),
230*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_build_principal),
231*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_renewed_creds),
232*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_addresses),
233*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_default_config_files),
234*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_config_files),
235*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_default_realm),
236*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_default_realm),
237*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_ticket),
238*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_decode_ticket),
239*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_get_host_realm),
240*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_host_realm),
241*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_free_addresses),
242*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(krb5_c_random_make_octets),
243*7f2fe78bSCy Schubert     END_FUNC_INFO
244*7f2fe78bSCy Schubert };
245*7f2fe78bSCy Schubert 
246*7f2fe78bSCy Schubert FUNC_INFO profile_fi[] = {
247*7f2fe78bSCy Schubert         MAKE_FUNC_INFO(profile_init),
248*7f2fe78bSCy Schubert         MAKE_FUNC_INFO(profile_release),
249*7f2fe78bSCy Schubert         MAKE_FUNC_INFO(profile_get_subsection_names),
250*7f2fe78bSCy Schubert         MAKE_FUNC_INFO(profile_free_list),
251*7f2fe78bSCy Schubert         MAKE_FUNC_INFO(profile_get_string),
252*7f2fe78bSCy Schubert         MAKE_FUNC_INFO(profile_release_string),
253*7f2fe78bSCy Schubert         END_FUNC_INFO
254*7f2fe78bSCy Schubert };
255*7f2fe78bSCy Schubert 
256*7f2fe78bSCy Schubert FUNC_INFO ce_fi[] = {
257*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(com_err),
258*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(error_message),
259*7f2fe78bSCy Schubert     END_FUNC_INFO
260*7f2fe78bSCy Schubert };
261*7f2fe78bSCy Schubert 
262*7f2fe78bSCy Schubert FUNC_INFO service_fi[] = {
263*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(OpenSCManagerA),
264*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(OpenServiceA),
265*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(QueryServiceStatus),
266*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(CloseServiceHandle),
267*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(LsaNtStatusToWinError),
268*7f2fe78bSCy Schubert     END_FUNC_INFO
269*7f2fe78bSCy Schubert };
270*7f2fe78bSCy Schubert 
271*7f2fe78bSCy Schubert FUNC_INFO lsa_fi[] = {
272*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(LsaConnectUntrusted),
273*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(LsaLookupAuthenticationPackage),
274*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(LsaCallAuthenticationPackage),
275*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(LsaFreeReturnBuffer),
276*7f2fe78bSCy Schubert     MAKE_FUNC_INFO(LsaGetLogonSessionData),
277*7f2fe78bSCy Schubert     END_FUNC_INFO
278*7f2fe78bSCy Schubert };
279*7f2fe78bSCy Schubert 
280*7f2fe78bSCy Schubert /* Static Declarations */
281*7f2fe78bSCy Schubert static int       inited = 0;
282*7f2fe78bSCy Schubert static HINSTANCE hKrb5 = 0;
283*7f2fe78bSCy Schubert static HINSTANCE hKrb524 = 0;
284*7f2fe78bSCy Schubert static HINSTANCE hSecur32 = 0;
285*7f2fe78bSCy Schubert static HINSTANCE hAdvApi32 = 0;
286*7f2fe78bSCy Schubert static HINSTANCE hComErr = 0;
287*7f2fe78bSCy Schubert static HINSTANCE hService = 0;
288*7f2fe78bSCy Schubert static HINSTANCE hProfile = 0;
289*7f2fe78bSCy Schubert static HINSTANCE hLeash = 0;
290*7f2fe78bSCy Schubert static HINSTANCE hLeashOpt = 0;
291*7f2fe78bSCy Schubert static HINSTANCE hCCAPI = 0;
292*7f2fe78bSCy Schubert 
293*7f2fe78bSCy Schubert static DWORD TraceOption = 0;
294*7f2fe78bSCy Schubert static HANDLE hDLL;
295*7f2fe78bSCy Schubert 
IsDebugLogging(void)296*7f2fe78bSCy Schubert BOOL IsDebugLogging(void)
297*7f2fe78bSCy Schubert {
298*7f2fe78bSCy Schubert     DWORD LSPsize;
299*7f2fe78bSCy Schubert     HKEY NPKey;
300*7f2fe78bSCy Schubert     DWORD dwDebug = FALSE;
301*7f2fe78bSCy Schubert 
302*7f2fe78bSCy Schubert     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
303*7f2fe78bSCy Schubert 		     "System\\CurrentControlSet\\Services\\MIT Kerberos\\NetworkProvider",
304*7f2fe78bSCy Schubert 		     0, KEY_QUERY_VALUE, &NPKey) == ERROR_SUCCESS)
305*7f2fe78bSCy Schubert     {
306*7f2fe78bSCy Schubert 	LSPsize=sizeof(dwDebug);
307*7f2fe78bSCy Schubert 	if (RegQueryValueEx(NPKey, "Debug", NULL, NULL, (LPBYTE)&dwDebug, &LSPsize) != ERROR_SUCCESS)
308*7f2fe78bSCy Schubert 	{
309*7f2fe78bSCy Schubert 	    dwDebug = FALSE;
310*7f2fe78bSCy Schubert 	}
311*7f2fe78bSCy Schubert 	RegCloseKey (NPKey);
312*7f2fe78bSCy Schubert     }
313*7f2fe78bSCy Schubert 
314*7f2fe78bSCy Schubert     return(dwDebug ? TRUE : FALSE);
315*7f2fe78bSCy Schubert }
316*7f2fe78bSCy Schubert 
DebugEvent0(char * a)317*7f2fe78bSCy Schubert void DebugEvent0(char *a)
318*7f2fe78bSCy Schubert {
319*7f2fe78bSCy Schubert     HANDLE h; char *ptbuf[1];
320*7f2fe78bSCy Schubert 
321*7f2fe78bSCy Schubert     if (IsDebugLogging()) {
322*7f2fe78bSCy Schubert 	h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME);
323*7f2fe78bSCy Schubert 	if (h) {
324*7f2fe78bSCy Schubert             ptbuf[0] = a;
325*7f2fe78bSCy Schubert             ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
326*7f2fe78bSCy Schubert             DeregisterEventSource(h);
327*7f2fe78bSCy Schubert         }
328*7f2fe78bSCy Schubert     }
329*7f2fe78bSCy Schubert }
330*7f2fe78bSCy Schubert 
331*7f2fe78bSCy Schubert #define MAXBUF_ 512
DebugEvent(char * b,...)332*7f2fe78bSCy Schubert void DebugEvent(char *b,...)
333*7f2fe78bSCy Schubert {
334*7f2fe78bSCy Schubert     HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
335*7f2fe78bSCy Schubert     va_list marker;
336*7f2fe78bSCy Schubert 
337*7f2fe78bSCy Schubert     if (IsDebugLogging()) {
338*7f2fe78bSCy Schubert 	h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME);
339*7f2fe78bSCy Schubert         if (h) {
340*7f2fe78bSCy Schubert             va_start(marker,b);
341*7f2fe78bSCy Schubert             StringCbVPrintf(buf, MAXBUF_+1,b,marker);
342*7f2fe78bSCy Schubert             buf[MAXBUF_] = '\0';
343*7f2fe78bSCy Schubert             ptbuf[0] = buf;
344*7f2fe78bSCy Schubert             ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
345*7f2fe78bSCy Schubert             DeregisterEventSource(h);
346*7f2fe78bSCy Schubert             va_end(marker);
347*7f2fe78bSCy Schubert         }
348*7f2fe78bSCy Schubert     }
349*7f2fe78bSCy Schubert }
350*7f2fe78bSCy Schubert 
351*7f2fe78bSCy Schubert static HANDLE hInitMutex = NULL;
352*7f2fe78bSCy Schubert static BOOL bInit = FALSE;
353*7f2fe78bSCy Schubert 
354*7f2fe78bSCy Schubert /* KFW_initialize cannot be called from DllEntryPoint */
355*7f2fe78bSCy Schubert void
KFW_initialize(void)356*7f2fe78bSCy Schubert KFW_initialize(void)
357*7f2fe78bSCy Schubert {
358*7f2fe78bSCy Schubert     static int inited = 0;
359*7f2fe78bSCy Schubert 
360*7f2fe78bSCy Schubert     if ( !inited ) {
361*7f2fe78bSCy Schubert         char mutexName[MAX_PATH];
362*7f2fe78bSCy Schubert         HANDLE hMutex = NULL;
363*7f2fe78bSCy Schubert 
364*7f2fe78bSCy Schubert         sprintf(mutexName, "AFS KFW Init pid=%d", getpid());
365*7f2fe78bSCy Schubert 
366*7f2fe78bSCy Schubert         hMutex = CreateMutex( NULL, TRUE, mutexName );
367*7f2fe78bSCy Schubert         if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
368*7f2fe78bSCy Schubert             if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
369*7f2fe78bSCy Schubert                 return;
370*7f2fe78bSCy Schubert             }
371*7f2fe78bSCy Schubert         }
372*7f2fe78bSCy Schubert         if ( !inited ) {
373*7f2fe78bSCy Schubert             inited = 1;
374*7f2fe78bSCy Schubert             LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
375*7f2fe78bSCy Schubert             LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
376*7f2fe78bSCy Schubert             LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
377*7f2fe78bSCy Schubert             LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
378*7f2fe78bSCy Schubert             LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
379*7f2fe78bSCy Schubert             LoadFuncs(LEASH_DLL, leash_fi, &hLeash, 0, 1, 0, 0);
380*7f2fe78bSCy Schubert             LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
381*7f2fe78bSCy Schubert             LoadFuncs(LEASH_DLL, leash_opt_fi, &hLeashOpt, 0, 1, 0, 0);
382*7f2fe78bSCy Schubert         }
383*7f2fe78bSCy Schubert         ReleaseMutex(hMutex);
384*7f2fe78bSCy Schubert         CloseHandle(hMutex);
385*7f2fe78bSCy Schubert     }
386*7f2fe78bSCy Schubert }
387*7f2fe78bSCy Schubert 
388*7f2fe78bSCy Schubert void
KFW_cleanup(void)389*7f2fe78bSCy Schubert KFW_cleanup(void)
390*7f2fe78bSCy Schubert {
391*7f2fe78bSCy Schubert     if (hLeashOpt)
392*7f2fe78bSCy Schubert         FreeLibrary(hLeashOpt);
393*7f2fe78bSCy Schubert     if (hCCAPI)
394*7f2fe78bSCy Schubert         FreeLibrary(hCCAPI);
395*7f2fe78bSCy Schubert     if (hLeash)
396*7f2fe78bSCy Schubert         FreeLibrary(hLeash);
397*7f2fe78bSCy Schubert     if (hKrb524)
398*7f2fe78bSCy Schubert         FreeLibrary(hKrb524);
399*7f2fe78bSCy Schubert     if (hSecur32)
400*7f2fe78bSCy Schubert         FreeLibrary(hSecur32);
401*7f2fe78bSCy Schubert     if (hService)
402*7f2fe78bSCy Schubert         FreeLibrary(hService);
403*7f2fe78bSCy Schubert     if (hComErr)
404*7f2fe78bSCy Schubert         FreeLibrary(hComErr);
405*7f2fe78bSCy Schubert     if (hProfile)
406*7f2fe78bSCy Schubert         FreeLibrary(hProfile);
407*7f2fe78bSCy Schubert     if (hKrb5)
408*7f2fe78bSCy Schubert         FreeLibrary(hKrb5);
409*7f2fe78bSCy Schubert }
410*7f2fe78bSCy Schubert 
411*7f2fe78bSCy Schubert 
412*7f2fe78bSCy Schubert int
KFW_is_available(void)413*7f2fe78bSCy Schubert KFW_is_available(void)
414*7f2fe78bSCy Schubert {
415*7f2fe78bSCy Schubert     KFW_initialize();
416*7f2fe78bSCy Schubert     if ( hKrb5 && hComErr && hService &&
417*7f2fe78bSCy Schubert #ifdef USE_MS2MIT
418*7f2fe78bSCy Schubert          hSecur32 &&
419*7f2fe78bSCy Schubert #endif /* USE_MS2MIT */
420*7f2fe78bSCy Schubert          hProfile && hLeash && hCCAPI )
421*7f2fe78bSCy Schubert         return TRUE;
422*7f2fe78bSCy Schubert 
423*7f2fe78bSCy Schubert     return FALSE;
424*7f2fe78bSCy Schubert }
425*7f2fe78bSCy Schubert 
426*7f2fe78bSCy Schubert /* Given a principal return an existing ccache or create one and return */
427*7f2fe78bSCy Schubert int
KFW_get_ccache(krb5_context alt_ctx,krb5_principal principal,krb5_ccache * cc)428*7f2fe78bSCy Schubert KFW_get_ccache(krb5_context alt_ctx, krb5_principal principal, krb5_ccache * cc)
429*7f2fe78bSCy Schubert {
430*7f2fe78bSCy Schubert     krb5_context ctx;
431*7f2fe78bSCy Schubert     char * pname = 0;
432*7f2fe78bSCy Schubert     char * ccname = 0;
433*7f2fe78bSCy Schubert     krb5_error_code code;
434*7f2fe78bSCy Schubert 
435*7f2fe78bSCy Schubert     if (!pkrb5_init_context)
436*7f2fe78bSCy Schubert         return 0;
437*7f2fe78bSCy Schubert 
438*7f2fe78bSCy Schubert     if ( alt_ctx ) {
439*7f2fe78bSCy Schubert         ctx = alt_ctx;
440*7f2fe78bSCy Schubert     } else {
441*7f2fe78bSCy Schubert         code = pkrb5_init_context(&ctx);
442*7f2fe78bSCy Schubert         if (code) goto cleanup;
443*7f2fe78bSCy Schubert     }
444*7f2fe78bSCy Schubert 
445*7f2fe78bSCy Schubert     if ( principal ) {
446*7f2fe78bSCy Schubert         code = pkrb5_unparse_name(ctx, principal, &pname);
447*7f2fe78bSCy Schubert         if (code) goto cleanup;
448*7f2fe78bSCy Schubert 
449*7f2fe78bSCy Schubert 	ccname = (char *)malloc(strlen(pname) + 5);
450*7f2fe78bSCy Schubert 	sprintf(ccname,"API:%s",pname);
451*7f2fe78bSCy Schubert 
452*7f2fe78bSCy Schubert 	DebugEvent0(ccname);
453*7f2fe78bSCy Schubert 	code = pkrb5_cc_resolve(ctx, ccname, cc);
454*7f2fe78bSCy Schubert     } else {
455*7f2fe78bSCy Schubert         code = pkrb5_cc_default(ctx, cc);
456*7f2fe78bSCy Schubert         if (code) goto cleanup;
457*7f2fe78bSCy Schubert     }
458*7f2fe78bSCy Schubert 
459*7f2fe78bSCy Schubert   cleanup:
460*7f2fe78bSCy Schubert     if (ccname)
461*7f2fe78bSCy Schubert         free(ccname);
462*7f2fe78bSCy Schubert     if (pname)
463*7f2fe78bSCy Schubert         pkrb5_free_unparsed_name(ctx,pname);
464*7f2fe78bSCy Schubert     if (ctx && (ctx != alt_ctx))
465*7f2fe78bSCy Schubert         pkrb5_free_context(ctx);
466*7f2fe78bSCy Schubert     return(code);
467*7f2fe78bSCy Schubert }
468*7f2fe78bSCy Schubert 
469*7f2fe78bSCy Schubert 
470*7f2fe78bSCy Schubert int
KFW_kinit(krb5_context alt_ctx,krb5_ccache alt_cc,HWND hParent,char * principal_name,char * password,krb5_deltat lifetime,DWORD forwardable,DWORD proxiable,krb5_deltat renew_life,DWORD addressless,DWORD publicIP)471*7f2fe78bSCy Schubert KFW_kinit( krb5_context alt_ctx,
472*7f2fe78bSCy Schubert             krb5_ccache  alt_cc,
473*7f2fe78bSCy Schubert             HWND hParent,
474*7f2fe78bSCy Schubert             char *principal_name,
475*7f2fe78bSCy Schubert             char *password,
476*7f2fe78bSCy Schubert             krb5_deltat lifetime,
477*7f2fe78bSCy Schubert             DWORD                       forwardable,
478*7f2fe78bSCy Schubert             DWORD                       proxiable,
479*7f2fe78bSCy Schubert             krb5_deltat                 renew_life,
480*7f2fe78bSCy Schubert             DWORD                       addressless,
481*7f2fe78bSCy Schubert             DWORD                       publicIP
482*7f2fe78bSCy Schubert             )
483*7f2fe78bSCy Schubert {
484*7f2fe78bSCy Schubert     krb5_error_code		        code = 0;
485*7f2fe78bSCy Schubert     krb5_context		        ctx = 0;
486*7f2fe78bSCy Schubert     krb5_ccache			        cc = 0;
487*7f2fe78bSCy Schubert     krb5_principal		        me = 0;
488*7f2fe78bSCy Schubert     char*                       name = 0;
489*7f2fe78bSCy Schubert     krb5_creds			        my_creds;
490*7f2fe78bSCy Schubert     krb5_get_init_creds_opt     options;
491*7f2fe78bSCy Schubert     krb5_address **             addrs = NULL;
492*7f2fe78bSCy Schubert     int                         i = 0, addr_count = 0;
493*7f2fe78bSCy Schubert 
494*7f2fe78bSCy Schubert     if (!pkrb5_init_context)
495*7f2fe78bSCy Schubert         return 0;
496*7f2fe78bSCy Schubert 
497*7f2fe78bSCy Schubert     pkrb5_get_init_creds_opt_init(&options);
498*7f2fe78bSCy Schubert     memset(&my_creds, 0, sizeof(my_creds));
499*7f2fe78bSCy Schubert 
500*7f2fe78bSCy Schubert     if (alt_ctx)
501*7f2fe78bSCy Schubert     {
502*7f2fe78bSCy Schubert         ctx = alt_ctx;
503*7f2fe78bSCy Schubert     }
504*7f2fe78bSCy Schubert     else
505*7f2fe78bSCy Schubert     {
506*7f2fe78bSCy Schubert         code = pkrb5_init_context(&ctx);
507*7f2fe78bSCy Schubert         if (code) goto cleanup;
508*7f2fe78bSCy Schubert     }
509*7f2fe78bSCy Schubert 
510*7f2fe78bSCy Schubert     if ( alt_cc ) {
511*7f2fe78bSCy Schubert         cc = alt_cc;
512*7f2fe78bSCy Schubert     } else {
513*7f2fe78bSCy Schubert         code = pkrb5_cc_default(ctx, &cc);
514*7f2fe78bSCy Schubert         if (code) goto cleanup;
515*7f2fe78bSCy Schubert     }
516*7f2fe78bSCy Schubert 
517*7f2fe78bSCy Schubert     code = pkrb5_parse_name(ctx, principal_name, &me);
518*7f2fe78bSCy Schubert     if (code)
519*7f2fe78bSCy Schubert 	goto cleanup;
520*7f2fe78bSCy Schubert 
521*7f2fe78bSCy Schubert     code = pkrb5_unparse_name(ctx, me, &name);
522*7f2fe78bSCy Schubert     if (code)
523*7f2fe78bSCy Schubert 	goto cleanup;
524*7f2fe78bSCy Schubert 
525*7f2fe78bSCy Schubert     if (lifetime == 0)
526*7f2fe78bSCy Schubert         lifetime = pLeash_get_default_lifetime();
527*7f2fe78bSCy Schubert     lifetime *= 60;
528*7f2fe78bSCy Schubert 
529*7f2fe78bSCy Schubert     if (renew_life > 0)
530*7f2fe78bSCy Schubert 	renew_life *= 60;
531*7f2fe78bSCy Schubert 
532*7f2fe78bSCy Schubert     if (lifetime)
533*7f2fe78bSCy Schubert         pkrb5_get_init_creds_opt_set_tkt_life(&options, lifetime);
534*7f2fe78bSCy Schubert 	pkrb5_get_init_creds_opt_set_forwardable(&options,
535*7f2fe78bSCy Schubert                                                  forwardable ? 1 : 0);
536*7f2fe78bSCy Schubert 	pkrb5_get_init_creds_opt_set_proxiable(&options,
537*7f2fe78bSCy Schubert                                                proxiable ? 1 : 0);
538*7f2fe78bSCy Schubert 	pkrb5_get_init_creds_opt_set_renew_life(&options,
539*7f2fe78bSCy Schubert                                                renew_life);
540*7f2fe78bSCy Schubert     if (addressless)
541*7f2fe78bSCy Schubert         pkrb5_get_init_creds_opt_set_address_list(&options,NULL);
542*7f2fe78bSCy Schubert     else {
543*7f2fe78bSCy Schubert 	if (publicIP)
544*7f2fe78bSCy Schubert         {
545*7f2fe78bSCy Schubert             // we are going to add the public IP address specified by the user
546*7f2fe78bSCy Schubert             // to the list provided by the operating system
547*7f2fe78bSCy Schubert             krb5_address ** local_addrs=NULL;
548*7f2fe78bSCy Schubert             DWORD           netIPAddr;
549*7f2fe78bSCy Schubert 
550*7f2fe78bSCy Schubert             pkrb5_os_localaddr(ctx, &local_addrs);
551*7f2fe78bSCy Schubert             while ( local_addrs[i++] );
552*7f2fe78bSCy Schubert             addr_count = i + 1;
553*7f2fe78bSCy Schubert 
554*7f2fe78bSCy Schubert             addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *));
555*7f2fe78bSCy Schubert             if ( !addrs ) {
556*7f2fe78bSCy Schubert                 pkrb5_free_addresses(ctx, local_addrs);
557*7f2fe78bSCy Schubert                 goto cleanup;
558*7f2fe78bSCy Schubert             }
559*7f2fe78bSCy Schubert             memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
560*7f2fe78bSCy Schubert             i = 0;
561*7f2fe78bSCy Schubert             while ( local_addrs[i] ) {
562*7f2fe78bSCy Schubert                 addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
563*7f2fe78bSCy Schubert                 if (addrs[i] == NULL) {
564*7f2fe78bSCy Schubert                     pkrb5_free_addresses(ctx, local_addrs);
565*7f2fe78bSCy Schubert                     goto cleanup;
566*7f2fe78bSCy Schubert                 }
567*7f2fe78bSCy Schubert 
568*7f2fe78bSCy Schubert                 addrs[i]->magic = local_addrs[i]->magic;
569*7f2fe78bSCy Schubert                 addrs[i]->addrtype = local_addrs[i]->addrtype;
570*7f2fe78bSCy Schubert                 addrs[i]->length = local_addrs[i]->length;
571*7f2fe78bSCy Schubert                 addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
572*7f2fe78bSCy Schubert                 if (!addrs[i]->contents) {
573*7f2fe78bSCy Schubert                     pkrb5_free_addresses(ctx, local_addrs);
574*7f2fe78bSCy Schubert                     goto cleanup;
575*7f2fe78bSCy Schubert                 }
576*7f2fe78bSCy Schubert 
577*7f2fe78bSCy Schubert                 memcpy(addrs[i]->contents,local_addrs[i]->contents,
578*7f2fe78bSCy Schubert                         local_addrs[i]->length);        /* safe */
579*7f2fe78bSCy Schubert                 i++;
580*7f2fe78bSCy Schubert             }
581*7f2fe78bSCy Schubert             pkrb5_free_addresses(ctx, local_addrs);
582*7f2fe78bSCy Schubert 
583*7f2fe78bSCy Schubert             addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
584*7f2fe78bSCy Schubert             if (addrs[i] == NULL)
585*7f2fe78bSCy Schubert                 goto cleanup;
586*7f2fe78bSCy Schubert 
587*7f2fe78bSCy Schubert             addrs[i]->magic = KV5M_ADDRESS;
588*7f2fe78bSCy Schubert             addrs[i]->addrtype = AF_INET;
589*7f2fe78bSCy Schubert             addrs[i]->length = 4;
590*7f2fe78bSCy Schubert             addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
591*7f2fe78bSCy Schubert             if (!addrs[i]->contents)
592*7f2fe78bSCy Schubert                 goto cleanup;
593*7f2fe78bSCy Schubert 
594*7f2fe78bSCy Schubert             netIPAddr = htonl(publicIP);
595*7f2fe78bSCy Schubert             memcpy(addrs[i]->contents,&netIPAddr,4);
596*7f2fe78bSCy Schubert 
597*7f2fe78bSCy Schubert             pkrb5_get_init_creds_opt_set_address_list(&options,addrs);
598*7f2fe78bSCy Schubert 
599*7f2fe78bSCy Schubert         }
600*7f2fe78bSCy Schubert     }
601*7f2fe78bSCy Schubert 
602*7f2fe78bSCy Schubert     code = pkrb5_get_init_creds_password(ctx,
603*7f2fe78bSCy Schubert                                        &my_creds,
604*7f2fe78bSCy Schubert                                        me,
605*7f2fe78bSCy Schubert                                        password, // password
606*7f2fe78bSCy Schubert                                        NULL,     // no prompter
607*7f2fe78bSCy Schubert                                        hParent, // prompter data
608*7f2fe78bSCy Schubert                                        0, // start time
609*7f2fe78bSCy Schubert                                        0, // service name
610*7f2fe78bSCy Schubert                                        &options);
611*7f2fe78bSCy Schubert     if (code)
612*7f2fe78bSCy Schubert 	goto cleanup;
613*7f2fe78bSCy Schubert 
614*7f2fe78bSCy Schubert     code = pkrb5_cc_initialize(ctx, cc, me);
615*7f2fe78bSCy Schubert     if (code)
616*7f2fe78bSCy Schubert 	goto cleanup;
617*7f2fe78bSCy Schubert 
618*7f2fe78bSCy Schubert     code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
619*7f2fe78bSCy Schubert     if (code)
620*7f2fe78bSCy Schubert 	goto cleanup;
621*7f2fe78bSCy Schubert 
622*7f2fe78bSCy Schubert  cleanup:
623*7f2fe78bSCy Schubert     if ( addrs ) {
624*7f2fe78bSCy Schubert         for ( i=0;i<addr_count;i++ ) {
625*7f2fe78bSCy Schubert             if ( addrs[i] ) {
626*7f2fe78bSCy Schubert                 if ( addrs[i]->contents )
627*7f2fe78bSCy Schubert                     free(addrs[i]->contents);
628*7f2fe78bSCy Schubert                 free(addrs[i]);
629*7f2fe78bSCy Schubert             }
630*7f2fe78bSCy Schubert         }
631*7f2fe78bSCy Schubert     }
632*7f2fe78bSCy Schubert     if (my_creds.client == me)
633*7f2fe78bSCy Schubert 	my_creds.client = 0;
634*7f2fe78bSCy Schubert     pkrb5_free_cred_contents(ctx, &my_creds);
635*7f2fe78bSCy Schubert     if (name)
636*7f2fe78bSCy Schubert         pkrb5_free_unparsed_name(ctx, name);
637*7f2fe78bSCy Schubert     if (me)
638*7f2fe78bSCy Schubert         pkrb5_free_principal(ctx, me);
639*7f2fe78bSCy Schubert     if (cc && (cc != alt_cc))
640*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, cc);
641*7f2fe78bSCy Schubert     if (ctx && (ctx != alt_ctx))
642*7f2fe78bSCy Schubert         pkrb5_free_context(ctx);
643*7f2fe78bSCy Schubert     return(code);
644*7f2fe78bSCy Schubert }
645*7f2fe78bSCy Schubert 
646*7f2fe78bSCy Schubert 
647*7f2fe78bSCy Schubert int
KFW_get_cred(char * username,char * password,int lifetime,char ** reasonP)648*7f2fe78bSCy Schubert KFW_get_cred( char * username,
649*7f2fe78bSCy Schubert 	      char * password,
650*7f2fe78bSCy Schubert 	      int lifetime,
651*7f2fe78bSCy Schubert 	      char ** reasonP )
652*7f2fe78bSCy Schubert {
653*7f2fe78bSCy Schubert     krb5_context ctx = 0;
654*7f2fe78bSCy Schubert     krb5_ccache cc = 0;
655*7f2fe78bSCy Schubert     char * realm = 0;
656*7f2fe78bSCy Schubert     krb5_principal principal = 0;
657*7f2fe78bSCy Schubert     char * pname = 0;
658*7f2fe78bSCy Schubert     krb5_error_code code;
659*7f2fe78bSCy Schubert 
660*7f2fe78bSCy Schubert     if (!pkrb5_init_context || !username || !password || !password[0])
661*7f2fe78bSCy Schubert         return 0;
662*7f2fe78bSCy Schubert 
663*7f2fe78bSCy Schubert     DebugEvent0(username);
664*7f2fe78bSCy Schubert 
665*7f2fe78bSCy Schubert     code = pkrb5_init_context(&ctx);
666*7f2fe78bSCy Schubert     if ( code ) goto cleanup;
667*7f2fe78bSCy Schubert 
668*7f2fe78bSCy Schubert     code = pkrb5_get_default_realm(ctx, &realm);
669*7f2fe78bSCy Schubert 
670*7f2fe78bSCy Schubert     if (realm) {
671*7f2fe78bSCy Schubert         pname = malloc(strlen(username) + strlen(realm) + 2);
672*7f2fe78bSCy Schubert 	if (!pname)
673*7f2fe78bSCy Schubert 	    goto cleanup;
674*7f2fe78bSCy Schubert 	strcpy(pname, username);
675*7f2fe78bSCy Schubert 	strcat(pname, "@");
676*7f2fe78bSCy Schubert 	strcat(pname, realm);
677*7f2fe78bSCy Schubert     } else {
678*7f2fe78bSCy Schubert 	goto cleanup;
679*7f2fe78bSCy Schubert     }
680*7f2fe78bSCy Schubert 
681*7f2fe78bSCy Schubert     DebugEvent0(realm);
682*7f2fe78bSCy Schubert     DebugEvent0(pname);
683*7f2fe78bSCy Schubert 
684*7f2fe78bSCy Schubert     code = pkrb5_parse_name(ctx, pname, &principal);
685*7f2fe78bSCy Schubert     if ( code ) goto cleanup;
686*7f2fe78bSCy Schubert 
687*7f2fe78bSCy Schubert     DebugEvent0("parsed name");
688*7f2fe78bSCy Schubert     code = KFW_get_ccache(ctx, principal, &cc);
689*7f2fe78bSCy Schubert     if ( code ) goto cleanup;
690*7f2fe78bSCy Schubert 
691*7f2fe78bSCy Schubert     DebugEvent0("got ccache");
692*7f2fe78bSCy Schubert 
693*7f2fe78bSCy Schubert     if ( lifetime == 0 )
694*7f2fe78bSCy Schubert         lifetime = pLeash_get_default_lifetime();
695*7f2fe78bSCy Schubert 
696*7f2fe78bSCy Schubert     DebugEvent0("got lifetime");
697*7f2fe78bSCy Schubert 
698*7f2fe78bSCy Schubert     code = KFW_kinit( ctx, cc, HWND_DESKTOP,
699*7f2fe78bSCy Schubert 		      pname,
700*7f2fe78bSCy Schubert 		      password,
701*7f2fe78bSCy Schubert 		      lifetime,
702*7f2fe78bSCy Schubert 		      pLeash_get_default_forwardable(),
703*7f2fe78bSCy Schubert 		      pLeash_get_default_proxiable(),
704*7f2fe78bSCy Schubert 		      pLeash_get_default_renewable() ? pLeash_get_default_renew_till() : 0,
705*7f2fe78bSCy Schubert 		      pLeash_get_default_noaddresses(),
706*7f2fe78bSCy Schubert 		      pLeash_get_default_publicip());
707*7f2fe78bSCy Schubert     DebugEvent0("kinit returned");
708*7f2fe78bSCy Schubert     if ( code ) goto cleanup;
709*7f2fe78bSCy Schubert 
710*7f2fe78bSCy Schubert   cleanup:
711*7f2fe78bSCy Schubert     if ( pname )
712*7f2fe78bSCy Schubert         free(pname);
713*7f2fe78bSCy Schubert     if ( realm )
714*7f2fe78bSCy Schubert 	pkrb5_free_default_realm(ctx, realm);
715*7f2fe78bSCy Schubert     if ( cc )
716*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, cc);
717*7f2fe78bSCy Schubert 
718*7f2fe78bSCy Schubert     if ( code && reasonP ) {
719*7f2fe78bSCy Schubert         *reasonP = (char *)perror_message(code);
720*7f2fe78bSCy Schubert     }
721*7f2fe78bSCy Schubert     return(code);
722*7f2fe78bSCy Schubert }
723*7f2fe78bSCy Schubert 
KFW_set_ccache_dacl(char * filename,HANDLE hUserToken)724*7f2fe78bSCy Schubert int KFW_set_ccache_dacl(char *filename, HANDLE hUserToken)
725*7f2fe78bSCy Schubert {
726*7f2fe78bSCy Schubert     // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY;
727*7f2fe78bSCy Schubert     PSID pSystemSID = NULL;
728*7f2fe78bSCy Schubert     DWORD SystemSIDlength = 0, UserSIDlength = 0;
729*7f2fe78bSCy Schubert     PACL ccacheACL = NULL;
730*7f2fe78bSCy Schubert     DWORD ccacheACLlength = 0;
731*7f2fe78bSCy Schubert     PTOKEN_USER pTokenUser = NULL;
732*7f2fe78bSCy Schubert     DWORD retLen;
733*7f2fe78bSCy Schubert     DWORD gle;
734*7f2fe78bSCy Schubert     int ret = 0;
735*7f2fe78bSCy Schubert 
736*7f2fe78bSCy Schubert     if (!filename) {
737*7f2fe78bSCy Schubert 	DebugEvent0("KFW_set_ccache_dacl - invalid parms");
738*7f2fe78bSCy Schubert 	return 1;
739*7f2fe78bSCy Schubert     }
740*7f2fe78bSCy Schubert 
741*7f2fe78bSCy Schubert     DebugEvent0("KFW_set_ccache_dacl");
742*7f2fe78bSCy Schubert 
743*7f2fe78bSCy Schubert     /* Get System SID */
744*7f2fe78bSCy Schubert     if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) {
745*7f2fe78bSCy Schubert 	DebugEvent("KFW_set_ccache_dacl - ConvertStringSidToSid GLE = 0x%x", GetLastError());
746*7f2fe78bSCy Schubert 	ret = 1;
747*7f2fe78bSCy Schubert 	goto cleanup;
748*7f2fe78bSCy Schubert     }
749*7f2fe78bSCy Schubert 
750*7f2fe78bSCy Schubert     /* Create ACL */
751*7f2fe78bSCy Schubert     SystemSIDlength = GetLengthSid(pSystemSID);
752*7f2fe78bSCy Schubert     ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
753*7f2fe78bSCy Schubert         + SystemSIDlength - sizeof(DWORD);
754*7f2fe78bSCy Schubert 
755*7f2fe78bSCy Schubert     if (hUserToken) {
756*7f2fe78bSCy Schubert 	if (!GetTokenInformation(hUserToken, TokenUser, NULL, 0, &retLen))
757*7f2fe78bSCy Schubert 	{
758*7f2fe78bSCy Schubert 	    if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
759*7f2fe78bSCy Schubert 		pTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
760*7f2fe78bSCy Schubert 
761*7f2fe78bSCy Schubert 		if (!GetTokenInformation(hUserToken, TokenUser, pTokenUser, retLen, &retLen))
762*7f2fe78bSCy Schubert 		{
763*7f2fe78bSCy Schubert 		    DebugEvent("GetTokenInformation failed: GLE = %lX", GetLastError());
764*7f2fe78bSCy Schubert 		}
765*7f2fe78bSCy Schubert 	    }
766*7f2fe78bSCy Schubert 	}
767*7f2fe78bSCy Schubert 
768*7f2fe78bSCy Schubert 	if (pTokenUser) {
769*7f2fe78bSCy Schubert 	    UserSIDlength = GetLengthSid(pTokenUser->User.Sid);
770*7f2fe78bSCy Schubert 
771*7f2fe78bSCy Schubert 	    ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength
772*7f2fe78bSCy Schubert 		- sizeof(DWORD);
773*7f2fe78bSCy Schubert 	}
774*7f2fe78bSCy Schubert     }
775*7f2fe78bSCy Schubert 
776*7f2fe78bSCy Schubert     ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength);
777*7f2fe78bSCy Schubert     if (!ccacheACL) {
778*7f2fe78bSCy Schubert 	DebugEvent("KFW_set_ccache_dacl - LocalAlloc GLE = 0x%x", GetLastError());
779*7f2fe78bSCy Schubert 	ret = 1;
780*7f2fe78bSCy Schubert 	goto cleanup;
781*7f2fe78bSCy Schubert     }
782*7f2fe78bSCy Schubert 
783*7f2fe78bSCy Schubert     InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION);
784*7f2fe78bSCy Schubert     AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,
785*7f2fe78bSCy Schubert                          STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
786*7f2fe78bSCy Schubert                          pSystemSID);
787*7f2fe78bSCy Schubert     if (pTokenUser) {
788*7f2fe78bSCy Schubert 	AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,
789*7f2fe78bSCy Schubert 			     STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
790*7f2fe78bSCy Schubert 			     pTokenUser->User.Sid);
791*7f2fe78bSCy Schubert 	if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
792*7f2fe78bSCy Schubert 				   DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
793*7f2fe78bSCy Schubert 				   NULL,
794*7f2fe78bSCy Schubert 				   NULL,
795*7f2fe78bSCy Schubert 				   ccacheACL,
796*7f2fe78bSCy Schubert 				   NULL)) {
797*7f2fe78bSCy Schubert 	    gle = GetLastError();
798*7f2fe78bSCy Schubert 	    DebugEvent("SetNamedSecurityInfo DACL (1) failed: GLE = 0x%lX", gle);
799*7f2fe78bSCy Schubert 	    if (gle != ERROR_NO_TOKEN)
800*7f2fe78bSCy Schubert 		ret = 1;
801*7f2fe78bSCy Schubert 	}
802*7f2fe78bSCy Schubert 	if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
803*7f2fe78bSCy Schubert 				   OWNER_SECURITY_INFORMATION,
804*7f2fe78bSCy Schubert 				   pTokenUser->User.Sid,
805*7f2fe78bSCy Schubert 				   NULL,
806*7f2fe78bSCy Schubert 				   NULL,
807*7f2fe78bSCy Schubert 				   NULL)) {
808*7f2fe78bSCy Schubert 	    gle = GetLastError();
809*7f2fe78bSCy Schubert 	    DebugEvent("SetNamedSecurityInfo OWNER (2) failed: GLE = 0x%lX", gle);
810*7f2fe78bSCy Schubert 	    if (gle != ERROR_NO_TOKEN)
811*7f2fe78bSCy Schubert 		ret = 1;
812*7f2fe78bSCy Schubert 	}
813*7f2fe78bSCy Schubert     } else {
814*7f2fe78bSCy Schubert 	if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
815*7f2fe78bSCy Schubert 				   DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
816*7f2fe78bSCy Schubert 				   NULL,
817*7f2fe78bSCy Schubert 				   NULL,
818*7f2fe78bSCy Schubert 				   ccacheACL,
819*7f2fe78bSCy Schubert 				   NULL)) {
820*7f2fe78bSCy Schubert 	    gle = GetLastError();
821*7f2fe78bSCy Schubert 	    DebugEvent("SetNamedSecurityInfo DACL (3) failed: GLE = 0x%lX", gle);
822*7f2fe78bSCy Schubert 	    if (gle != ERROR_NO_TOKEN)
823*7f2fe78bSCy Schubert 		ret = 1;
824*7f2fe78bSCy Schubert 	}
825*7f2fe78bSCy Schubert     }
826*7f2fe78bSCy Schubert 
827*7f2fe78bSCy Schubert   cleanup:
828*7f2fe78bSCy Schubert     if (pSystemSID)
829*7f2fe78bSCy Schubert 	LocalFree(pSystemSID);
830*7f2fe78bSCy Schubert     if (pTokenUser)
831*7f2fe78bSCy Schubert 	LocalFree(pTokenUser);
832*7f2fe78bSCy Schubert     if (ccacheACL)
833*7f2fe78bSCy Schubert 	LocalFree(ccacheACL);
834*7f2fe78bSCy Schubert     return ret;
835*7f2fe78bSCy Schubert }
836*7f2fe78bSCy Schubert 
KFW_set_ccache_dacl_with_user_sid(char * filename,PSID pUserSID)837*7f2fe78bSCy Schubert int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID)
838*7f2fe78bSCy Schubert {
839*7f2fe78bSCy Schubert     // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY;
840*7f2fe78bSCy Schubert     PSID pSystemSID = NULL;
841*7f2fe78bSCy Schubert     DWORD SystemSIDlength = 0, UserSIDlength = 0;
842*7f2fe78bSCy Schubert     PACL ccacheACL = NULL;
843*7f2fe78bSCy Schubert     DWORD ccacheACLlength = 0;
844*7f2fe78bSCy Schubert     DWORD gle;
845*7f2fe78bSCy Schubert     int ret = 0;
846*7f2fe78bSCy Schubert 
847*7f2fe78bSCy Schubert     if (!filename) {
848*7f2fe78bSCy Schubert 	DebugEvent0("KFW_set_ccache_dacl_with_user_sid - invalid parms");
849*7f2fe78bSCy Schubert 	return 1;
850*7f2fe78bSCy Schubert     }
851*7f2fe78bSCy Schubert 
852*7f2fe78bSCy Schubert     DebugEvent0("KFW_set_ccache_dacl_with_user_sid");
853*7f2fe78bSCy Schubert 
854*7f2fe78bSCy Schubert     /* Get System SID */
855*7f2fe78bSCy Schubert     if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) {
856*7f2fe78bSCy Schubert 	DebugEvent("KFW_set_ccache_dacl - ConvertStringSidToSid GLE = 0x%x", GetLastError());
857*7f2fe78bSCy Schubert 	ret = 1;
858*7f2fe78bSCy Schubert 	goto cleanup;
859*7f2fe78bSCy Schubert     }
860*7f2fe78bSCy Schubert 
861*7f2fe78bSCy Schubert     /* Create ACL */
862*7f2fe78bSCy Schubert     SystemSIDlength = GetLengthSid(pSystemSID);
863*7f2fe78bSCy Schubert     ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
864*7f2fe78bSCy Schubert         + SystemSIDlength - sizeof(DWORD);
865*7f2fe78bSCy Schubert 
866*7f2fe78bSCy Schubert     if (pUserSID) {
867*7f2fe78bSCy Schubert 	UserSIDlength = GetLengthSid(pUserSID);
868*7f2fe78bSCy Schubert 
869*7f2fe78bSCy Schubert 	ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength
870*7f2fe78bSCy Schubert 	    - sizeof(DWORD);
871*7f2fe78bSCy Schubert     }
872*7f2fe78bSCy Schubert 
873*7f2fe78bSCy Schubert     ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength);
874*7f2fe78bSCy Schubert     if (!ccacheACL) {
875*7f2fe78bSCy Schubert 	DebugEvent("KFW_set_ccache_dacl - LocalAlloc GLE = 0x%x", GetLastError());
876*7f2fe78bSCy Schubert 	ret = 1;
877*7f2fe78bSCy Schubert 	goto cleanup;
878*7f2fe78bSCy Schubert     }
879*7f2fe78bSCy Schubert 
880*7f2fe78bSCy Schubert     InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION);
881*7f2fe78bSCy Schubert     AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,
882*7f2fe78bSCy Schubert                          STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
883*7f2fe78bSCy Schubert                          pSystemSID);
884*7f2fe78bSCy Schubert     if (pUserSID) {
885*7f2fe78bSCy Schubert 	AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,
886*7f2fe78bSCy Schubert 			     STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
887*7f2fe78bSCy Schubert 			     pUserSID);
888*7f2fe78bSCy Schubert 	if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
889*7f2fe78bSCy Schubert 				   DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
890*7f2fe78bSCy Schubert 				   NULL,
891*7f2fe78bSCy Schubert 				   NULL,
892*7f2fe78bSCy Schubert 				   ccacheACL,
893*7f2fe78bSCy Schubert 				   NULL)) {
894*7f2fe78bSCy Schubert 	    gle = GetLastError();
895*7f2fe78bSCy Schubert 	    DebugEvent("SetNamedSecurityInfo DACL (4) failed: GLE = 0x%lX", gle);
896*7f2fe78bSCy Schubert 	    if (gle != ERROR_NO_TOKEN)
897*7f2fe78bSCy Schubert 		ret = 1;
898*7f2fe78bSCy Schubert 	}
899*7f2fe78bSCy Schubert 	if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
900*7f2fe78bSCy Schubert 				   OWNER_SECURITY_INFORMATION,
901*7f2fe78bSCy Schubert 				   pUserSID,
902*7f2fe78bSCy Schubert 				   NULL,
903*7f2fe78bSCy Schubert 				   NULL,
904*7f2fe78bSCy Schubert 				   NULL)) {
905*7f2fe78bSCy Schubert 	    gle = GetLastError();
906*7f2fe78bSCy Schubert 	    DebugEvent("SetNamedSecurityInfo OWNER (5) failed: GLE = 0x%lX", gle);
907*7f2fe78bSCy Schubert 	    if (gle != ERROR_NO_TOKEN)
908*7f2fe78bSCy Schubert 		ret = 1;
909*7f2fe78bSCy Schubert 	}
910*7f2fe78bSCy Schubert     } else {
911*7f2fe78bSCy Schubert 	if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
912*7f2fe78bSCy Schubert 				   DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
913*7f2fe78bSCy Schubert 				   NULL,
914*7f2fe78bSCy Schubert 				   NULL,
915*7f2fe78bSCy Schubert 				   ccacheACL,
916*7f2fe78bSCy Schubert 				   NULL)) {
917*7f2fe78bSCy Schubert 	    gle = GetLastError();
918*7f2fe78bSCy Schubert 	    DebugEvent("SetNamedSecurityInfo DACL (6) failed: GLE = 0x%lX", gle);
919*7f2fe78bSCy Schubert 	    if (gle != ERROR_NO_TOKEN)
920*7f2fe78bSCy Schubert 		ret = 1;
921*7f2fe78bSCy Schubert 	}
922*7f2fe78bSCy Schubert     }
923*7f2fe78bSCy Schubert 
924*7f2fe78bSCy Schubert   cleanup:
925*7f2fe78bSCy Schubert     if (pSystemSID)
926*7f2fe78bSCy Schubert 	LocalFree(pSystemSID);
927*7f2fe78bSCy Schubert     if (ccacheACL)
928*7f2fe78bSCy Schubert 	LocalFree(ccacheACL);
929*7f2fe78bSCy Schubert     return ret;
930*7f2fe78bSCy Schubert }
931*7f2fe78bSCy Schubert 
KFW_obtain_user_temp_directory(HANDLE hUserToken,char * newfilename,int size)932*7f2fe78bSCy Schubert int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size)
933*7f2fe78bSCy Schubert {
934*7f2fe78bSCy Schubert     int  retval = 0;
935*7f2fe78bSCy Schubert     DWORD dwSize = size-1;	/* leave room for nul */
936*7f2fe78bSCy Schubert     DWORD dwLen  = 0;
937*7f2fe78bSCy Schubert 
938*7f2fe78bSCy Schubert     if (!hUserToken || !newfilename || size <= 0)
939*7f2fe78bSCy Schubert 	return 1;
940*7f2fe78bSCy Schubert 
941*7f2fe78bSCy Schubert     *newfilename = '\0';
942*7f2fe78bSCy Schubert 
943*7f2fe78bSCy Schubert     dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TEMP%", newfilename, dwSize);
944*7f2fe78bSCy Schubert     if ( !dwLen || dwLen > dwSize )
945*7f2fe78bSCy Schubert 	dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TMP%", newfilename, dwSize);
946*7f2fe78bSCy Schubert     if ( !dwLen || dwLen > dwSize )
947*7f2fe78bSCy Schubert 	return 1;
948*7f2fe78bSCy Schubert 
949*7f2fe78bSCy Schubert     newfilename[dwSize] = '\0';
950*7f2fe78bSCy Schubert     return 0;
951*7f2fe78bSCy Schubert }
952*7f2fe78bSCy Schubert 
953*7f2fe78bSCy Schubert void
KFW_copy_cache_to_system_file(const char * user,const char * filename)954*7f2fe78bSCy Schubert KFW_copy_cache_to_system_file(const char * user, const char * filename)
955*7f2fe78bSCy Schubert {
956*7f2fe78bSCy Schubert     char cachename[MAX_PATH + 8] = "FILE:";
957*7f2fe78bSCy Schubert     krb5_context		ctx = 0;
958*7f2fe78bSCy Schubert     krb5_error_code		code;
959*7f2fe78bSCy Schubert     krb5_principal              princ = 0;
960*7f2fe78bSCy Schubert     krb5_ccache			cc  = 0;
961*7f2fe78bSCy Schubert     krb5_ccache                 ncc = 0;
962*7f2fe78bSCy Schubert     PSECURITY_ATTRIBUTES        pSA = NULL;
963*7f2fe78bSCy Schubert 
964*7f2fe78bSCy Schubert     if (!pkrb5_init_context || !user || !filename)
965*7f2fe78bSCy Schubert         return;
966*7f2fe78bSCy Schubert 
967*7f2fe78bSCy Schubert     strncat(cachename, filename, sizeof(cachename));
968*7f2fe78bSCy Schubert     cachename[sizeof(cachename)-1] = '\0';
969*7f2fe78bSCy Schubert 
970*7f2fe78bSCy Schubert     DebugEvent("KFW_Logon_Event - ccache %s", cachename);
971*7f2fe78bSCy Schubert 
972*7f2fe78bSCy Schubert     DeleteFile(filename);
973*7f2fe78bSCy Schubert 
974*7f2fe78bSCy Schubert     code = pkrb5_init_context(&ctx);
975*7f2fe78bSCy Schubert     if (code) goto cleanup;
976*7f2fe78bSCy Schubert 
977*7f2fe78bSCy Schubert     code = pkrb5_parse_name(ctx, user, &princ);
978*7f2fe78bSCy Schubert     if (code) goto cleanup;
979*7f2fe78bSCy Schubert 
980*7f2fe78bSCy Schubert     code = KFW_get_ccache(ctx, princ, &cc);
981*7f2fe78bSCy Schubert     if (code) goto cleanup;
982*7f2fe78bSCy Schubert 
983*7f2fe78bSCy Schubert     code = pkrb5_cc_resolve(ctx, cachename, &ncc);
984*7f2fe78bSCy Schubert     if (code) goto cleanup;
985*7f2fe78bSCy Schubert 
986*7f2fe78bSCy Schubert     code = pkrb5_cc_initialize(ctx, ncc, princ);
987*7f2fe78bSCy Schubert     if (code) goto cleanup;
988*7f2fe78bSCy Schubert 
989*7f2fe78bSCy Schubert     code = KFW_set_ccache_dacl(filename, NULL);
990*7f2fe78bSCy Schubert     if (code) goto cleanup;
991*7f2fe78bSCy Schubert 
992*7f2fe78bSCy Schubert     code = pkrb5_cc_copy_creds(ctx,cc,ncc);
993*7f2fe78bSCy Schubert 
994*7f2fe78bSCy Schubert   cleanup:
995*7f2fe78bSCy Schubert     if ( cc ) {
996*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, cc);
997*7f2fe78bSCy Schubert         cc = 0;
998*7f2fe78bSCy Schubert     }
999*7f2fe78bSCy Schubert     if ( ncc ) {
1000*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, ncc);
1001*7f2fe78bSCy Schubert         ncc = 0;
1002*7f2fe78bSCy Schubert     }
1003*7f2fe78bSCy Schubert     if ( princ ) {
1004*7f2fe78bSCy Schubert         pkrb5_free_principal(ctx, princ);
1005*7f2fe78bSCy Schubert         princ = 0;
1006*7f2fe78bSCy Schubert     }
1007*7f2fe78bSCy Schubert 
1008*7f2fe78bSCy Schubert     if (ctx)
1009*7f2fe78bSCy Schubert         pkrb5_free_context(ctx);
1010*7f2fe78bSCy Schubert }
1011*7f2fe78bSCy Schubert 
1012*7f2fe78bSCy Schubert int
KFW_copy_file_cache_to_default_cache(char * filename)1013*7f2fe78bSCy Schubert KFW_copy_file_cache_to_default_cache(char * filename)
1014*7f2fe78bSCy Schubert {
1015*7f2fe78bSCy Schubert     char cachename[MAX_PATH + 8] = "FILE:";
1016*7f2fe78bSCy Schubert     krb5_context		ctx = 0;
1017*7f2fe78bSCy Schubert     krb5_error_code		code;
1018*7f2fe78bSCy Schubert     krb5_principal              princ = 0;
1019*7f2fe78bSCy Schubert     krb5_ccache			cc  = 0;
1020*7f2fe78bSCy Schubert     krb5_ccache                 ncc = 0;
1021*7f2fe78bSCy Schubert     int retval = 1;
1022*7f2fe78bSCy Schubert 
1023*7f2fe78bSCy Schubert     if (!pkrb5_init_context || !filename)
1024*7f2fe78bSCy Schubert         return 1;
1025*7f2fe78bSCy Schubert 
1026*7f2fe78bSCy Schubert     if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) )
1027*7f2fe78bSCy Schubert         return 1;
1028*7f2fe78bSCy Schubert 
1029*7f2fe78bSCy Schubert     code = pkrb5_init_context(&ctx);
1030*7f2fe78bSCy Schubert     if (code) return 1;
1031*7f2fe78bSCy Schubert 
1032*7f2fe78bSCy Schubert     strcat(cachename, filename);
1033*7f2fe78bSCy Schubert 
1034*7f2fe78bSCy Schubert     code = pkrb5_cc_resolve(ctx, cachename, &cc);
1035*7f2fe78bSCy Schubert     if (code) {
1036*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_cc_resolve failed");
1037*7f2fe78bSCy Schubert 	goto cleanup;
1038*7f2fe78bSCy Schubert     }
1039*7f2fe78bSCy Schubert 
1040*7f2fe78bSCy Schubert     code = pkrb5_cc_get_principal(ctx, cc, &princ);
1041*7f2fe78bSCy Schubert     if (code) {
1042*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_cc_get_principal failed");
1043*7f2fe78bSCy Schubert 	goto cleanup;
1044*7f2fe78bSCy Schubert     }
1045*7f2fe78bSCy Schubert 
1046*7f2fe78bSCy Schubert     code = pkrb5_cc_default(ctx, &ncc);
1047*7f2fe78bSCy Schubert     if (code) {
1048*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_cc_default failed");
1049*7f2fe78bSCy Schubert 	goto cleanup;
1050*7f2fe78bSCy Schubert     }
1051*7f2fe78bSCy Schubert     if (!code) {
1052*7f2fe78bSCy Schubert         code = pkrb5_cc_initialize(ctx, ncc, princ);
1053*7f2fe78bSCy Schubert 
1054*7f2fe78bSCy Schubert         if (!code)
1055*7f2fe78bSCy Schubert             code = pkrb5_cc_copy_creds(ctx,cc,ncc);
1056*7f2fe78bSCy Schubert 	if (code) {
1057*7f2fe78bSCy Schubert 	    DebugEvent0("kfwcpcc krb5_cc_copy_creds failed");
1058*7f2fe78bSCy Schubert 	    goto cleanup;
1059*7f2fe78bSCy Schubert 	}
1060*7f2fe78bSCy Schubert     }
1061*7f2fe78bSCy Schubert     if ( ncc ) {
1062*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, ncc);
1063*7f2fe78bSCy Schubert         ncc = 0;
1064*7f2fe78bSCy Schubert     }
1065*7f2fe78bSCy Schubert 
1066*7f2fe78bSCy Schubert     retval=0;   /* success */
1067*7f2fe78bSCy Schubert 
1068*7f2fe78bSCy Schubert   cleanup:
1069*7f2fe78bSCy Schubert     if ( cc ) {
1070*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, cc);
1071*7f2fe78bSCy Schubert         cc = 0;
1072*7f2fe78bSCy Schubert     }
1073*7f2fe78bSCy Schubert 
1074*7f2fe78bSCy Schubert     DeleteFile(filename);
1075*7f2fe78bSCy Schubert 
1076*7f2fe78bSCy Schubert     if ( princ ) {
1077*7f2fe78bSCy Schubert         pkrb5_free_principal(ctx, princ);
1078*7f2fe78bSCy Schubert         princ = 0;
1079*7f2fe78bSCy Schubert     }
1080*7f2fe78bSCy Schubert 
1081*7f2fe78bSCy Schubert     if (ctx)
1082*7f2fe78bSCy Schubert         pkrb5_free_context(ctx);
1083*7f2fe78bSCy Schubert 
1084*7f2fe78bSCy Schubert     return 0;
1085*7f2fe78bSCy Schubert }
1086*7f2fe78bSCy Schubert 
1087*7f2fe78bSCy Schubert 
1088*7f2fe78bSCy Schubert int
KFW_copy_file_cache_to_api_cache(char * filename)1089*7f2fe78bSCy Schubert KFW_copy_file_cache_to_api_cache(char * filename)
1090*7f2fe78bSCy Schubert {
1091*7f2fe78bSCy Schubert     char cachename[MAX_PATH + 8] = "FILE:";
1092*7f2fe78bSCy Schubert     krb5_context		ctx = 0;
1093*7f2fe78bSCy Schubert     krb5_error_code		code;
1094*7f2fe78bSCy Schubert     krb5_principal              princ = 0;
1095*7f2fe78bSCy Schubert     krb5_ccache			cc  = 0;
1096*7f2fe78bSCy Schubert     krb5_ccache                 ncc = 0;
1097*7f2fe78bSCy Schubert     char 			*name = NULL;
1098*7f2fe78bSCy Schubert     int retval = 1;
1099*7f2fe78bSCy Schubert 
1100*7f2fe78bSCy Schubert     if (!pkrb5_init_context || !filename)
1101*7f2fe78bSCy Schubert         return 1;
1102*7f2fe78bSCy Schubert 
1103*7f2fe78bSCy Schubert     if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) )
1104*7f2fe78bSCy Schubert         return 1;
1105*7f2fe78bSCy Schubert 
1106*7f2fe78bSCy Schubert     code = pkrb5_init_context(&ctx);
1107*7f2fe78bSCy Schubert     if (code) return 1;
1108*7f2fe78bSCy Schubert 
1109*7f2fe78bSCy Schubert     strcat(cachename, filename);
1110*7f2fe78bSCy Schubert 
1111*7f2fe78bSCy Schubert     code = pkrb5_cc_resolve(ctx, cachename, &cc);
1112*7f2fe78bSCy Schubert     if (code) {
1113*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_cc_resolve failed");
1114*7f2fe78bSCy Schubert 	goto cleanup;
1115*7f2fe78bSCy Schubert     }
1116*7f2fe78bSCy Schubert 
1117*7f2fe78bSCy Schubert     code = pkrb5_cc_get_principal(ctx, cc, &princ);
1118*7f2fe78bSCy Schubert     if (code) {
1119*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_cc_get_principal failed");
1120*7f2fe78bSCy Schubert 	goto cleanup;
1121*7f2fe78bSCy Schubert     }
1122*7f2fe78bSCy Schubert 
1123*7f2fe78bSCy Schubert     code = pkrb5_unparse_name(ctx, princ, &name);
1124*7f2fe78bSCy Schubert     if (code) {
1125*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_unparse_name failed");
1126*7f2fe78bSCy Schubert 	goto cleanup;
1127*7f2fe78bSCy Schubert     }
1128*7f2fe78bSCy Schubert 
1129*7f2fe78bSCy Schubert     sprintf(cachename, "API:%s", name);
1130*7f2fe78bSCy Schubert 
1131*7f2fe78bSCy Schubert     code = pkrb5_cc_resolve(ctx, cachename, &ncc);
1132*7f2fe78bSCy Schubert     if (code) {
1133*7f2fe78bSCy Schubert 	DebugEvent0("kfwcpcc krb5_cc_default failed");
1134*7f2fe78bSCy Schubert 	goto cleanup;
1135*7f2fe78bSCy Schubert     }
1136*7f2fe78bSCy Schubert     if (!code) {
1137*7f2fe78bSCy Schubert         code = pkrb5_cc_initialize(ctx, ncc, princ);
1138*7f2fe78bSCy Schubert 
1139*7f2fe78bSCy Schubert         if (!code)
1140*7f2fe78bSCy Schubert             code = pkrb5_cc_copy_creds(ctx,cc,ncc);
1141*7f2fe78bSCy Schubert 	if (code) {
1142*7f2fe78bSCy Schubert 	    DebugEvent0("kfwcpcc krb5_cc_copy_creds failed");
1143*7f2fe78bSCy Schubert 	    goto cleanup;
1144*7f2fe78bSCy Schubert 	}
1145*7f2fe78bSCy Schubert     }
1146*7f2fe78bSCy Schubert     if ( ncc ) {
1147*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, ncc);
1148*7f2fe78bSCy Schubert         ncc = 0;
1149*7f2fe78bSCy Schubert     }
1150*7f2fe78bSCy Schubert 
1151*7f2fe78bSCy Schubert     retval=0;   /* success */
1152*7f2fe78bSCy Schubert 
1153*7f2fe78bSCy Schubert   cleanup:
1154*7f2fe78bSCy Schubert     if (name)
1155*7f2fe78bSCy Schubert 	pkrb5_free_unparsed_name(ctx, name);
1156*7f2fe78bSCy Schubert 
1157*7f2fe78bSCy Schubert     if ( cc ) {
1158*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, cc);
1159*7f2fe78bSCy Schubert         cc = 0;
1160*7f2fe78bSCy Schubert     }
1161*7f2fe78bSCy Schubert 
1162*7f2fe78bSCy Schubert     DeleteFile(filename);
1163*7f2fe78bSCy Schubert 
1164*7f2fe78bSCy Schubert     if ( princ ) {
1165*7f2fe78bSCy Schubert         pkrb5_free_principal(ctx, princ);
1166*7f2fe78bSCy Schubert         princ = 0;
1167*7f2fe78bSCy Schubert     }
1168*7f2fe78bSCy Schubert 
1169*7f2fe78bSCy Schubert     if (ctx)
1170*7f2fe78bSCy Schubert         pkrb5_free_context(ctx);
1171*7f2fe78bSCy Schubert 
1172*7f2fe78bSCy Schubert     return 0;
1173*7f2fe78bSCy Schubert }
1174*7f2fe78bSCy Schubert 
1175*7f2fe78bSCy Schubert 
1176*7f2fe78bSCy Schubert int
KFW_destroy_tickets_for_principal(char * user)1177*7f2fe78bSCy Schubert KFW_destroy_tickets_for_principal(char * user)
1178*7f2fe78bSCy Schubert {
1179*7f2fe78bSCy Schubert     krb5_context		ctx = 0;
1180*7f2fe78bSCy Schubert     krb5_error_code		code;
1181*7f2fe78bSCy Schubert     krb5_principal      princ = 0;
1182*7f2fe78bSCy Schubert     krb5_ccache			cc  = 0;
1183*7f2fe78bSCy Schubert 
1184*7f2fe78bSCy Schubert     if (!pkrb5_init_context)
1185*7f2fe78bSCy Schubert         return 0;
1186*7f2fe78bSCy Schubert 
1187*7f2fe78bSCy Schubert     code = pkrb5_init_context(&ctx);
1188*7f2fe78bSCy Schubert     if (code) return 1;
1189*7f2fe78bSCy Schubert 
1190*7f2fe78bSCy Schubert     code = pkrb5_parse_name(ctx, user, &princ);
1191*7f2fe78bSCy Schubert     if (code) goto loop_cleanup;
1192*7f2fe78bSCy Schubert 
1193*7f2fe78bSCy Schubert     code = KFW_get_ccache(ctx, princ, &cc);
1194*7f2fe78bSCy Schubert     if (code) goto loop_cleanup;
1195*7f2fe78bSCy Schubert 
1196*7f2fe78bSCy Schubert     code = pkrb5_cc_destroy(ctx, cc);
1197*7f2fe78bSCy Schubert     if (!code) cc = 0;
1198*7f2fe78bSCy Schubert 
1199*7f2fe78bSCy Schubert   loop_cleanup:
1200*7f2fe78bSCy Schubert     if ( cc ) {
1201*7f2fe78bSCy Schubert         pkrb5_cc_close(ctx, cc);
1202*7f2fe78bSCy Schubert         cc = 0;
1203*7f2fe78bSCy Schubert     }
1204*7f2fe78bSCy Schubert     if ( princ ) {
1205*7f2fe78bSCy Schubert         pkrb5_free_principal(ctx, princ);
1206*7f2fe78bSCy Schubert         princ = 0;
1207*7f2fe78bSCy Schubert     }
1208*7f2fe78bSCy Schubert 
1209*7f2fe78bSCy Schubert     pkrb5_free_context(ctx);
1210*7f2fe78bSCy Schubert     return 0;
1211*7f2fe78bSCy Schubert }
1212*7f2fe78bSCy Schubert 
1213*7f2fe78bSCy Schubert 
1214*7f2fe78bSCy Schubert /* There are scenarios in which an interactive logon will not
1215*7f2fe78bSCy Schubert  * result in the LogonScript being executed.  This will result
1216*7f2fe78bSCy Schubert  * in orphaned cache files being left in the Temp directory.
1217*7f2fe78bSCy Schubert  * This function will search for cache files in the Temp
1218*7f2fe78bSCy Schubert  * directory and delete any that are older than five minutes.
1219*7f2fe78bSCy Schubert  */
1220*7f2fe78bSCy Schubert void
KFW_cleanup_orphaned_caches(void)1221*7f2fe78bSCy Schubert KFW_cleanup_orphaned_caches(void)
1222*7f2fe78bSCy Schubert {
1223*7f2fe78bSCy Schubert     char * temppath = NULL;
1224*7f2fe78bSCy Schubert     char * curdir = NULL;
1225*7f2fe78bSCy Schubert     DWORD count, count2;
1226*7f2fe78bSCy Schubert     WIN32_FIND_DATA FindFileData;
1227*7f2fe78bSCy Schubert     HANDLE hFind = INVALID_HANDLE_VALUE;
1228*7f2fe78bSCy Schubert     FILETIME now;
1229*7f2fe78bSCy Schubert     ULARGE_INTEGER uli_now;
1230*7f2fe78bSCy Schubert     FILETIME expired;
1231*7f2fe78bSCy Schubert 
1232*7f2fe78bSCy Schubert     count = GetTempPath(0, NULL);
1233*7f2fe78bSCy Schubert     if (count <= 0)
1234*7f2fe78bSCy Schubert         return;
1235*7f2fe78bSCy Schubert     temppath = (char *) malloc(count);
1236*7f2fe78bSCy Schubert     if (!temppath)
1237*7f2fe78bSCy Schubert         goto cleanup;
1238*7f2fe78bSCy Schubert     count2 = GetTempPath(count, temppath);
1239*7f2fe78bSCy Schubert     if (count2 <= 0 || count2 > count)
1240*7f2fe78bSCy Schubert         goto cleanup;
1241*7f2fe78bSCy Schubert 
1242*7f2fe78bSCy Schubert     count = GetCurrentDirectory(0, NULL);
1243*7f2fe78bSCy Schubert     curdir = (char *)malloc(count);
1244*7f2fe78bSCy Schubert     if (!curdir)
1245*7f2fe78bSCy Schubert         goto cleanup;
1246*7f2fe78bSCy Schubert     count2 = GetCurrentDirectory(count, curdir);
1247*7f2fe78bSCy Schubert     if (count2 <= 0 || count2 > count)
1248*7f2fe78bSCy Schubert         goto cleanup;
1249*7f2fe78bSCy Schubert 
1250*7f2fe78bSCy Schubert     if (!SetCurrentDirectory(temppath))
1251*7f2fe78bSCy Schubert         goto cleanup;
1252*7f2fe78bSCy Schubert 
1253*7f2fe78bSCy Schubert     GetSystemTimeAsFileTime(&now);
1254*7f2fe78bSCy Schubert     uli_now.u.LowPart = now.dwLowDateTime;
1255*7f2fe78bSCy Schubert     uli_now.u.HighPart = now.dwHighDateTime;
1256*7f2fe78bSCy Schubert 
1257*7f2fe78bSCy Schubert     uli_now.QuadPart -= 3000000000;        /* 5 minutes == 3 billion 100 nano seconds */
1258*7f2fe78bSCy Schubert 
1259*7f2fe78bSCy Schubert     expired.dwLowDateTime = uli_now.u.LowPart;
1260*7f2fe78bSCy Schubert     expired.dwHighDateTime = uli_now.u.HighPart;
1261*7f2fe78bSCy Schubert 
1262*7f2fe78bSCy Schubert     hFind = FindFirstFile("kfwlogon-*", &FindFileData);
1263*7f2fe78bSCy Schubert     if (hFind != INVALID_HANDLE_VALUE) {
1264*7f2fe78bSCy Schubert         do {
1265*7f2fe78bSCy Schubert             if (CompareFileTime(&FindFileData.ftCreationTime, &expired) < 0) {
1266*7f2fe78bSCy Schubert                 DebugEvent("Deleting orphaned cache file: \"%s\"", FindFileData.cFileName);
1267*7f2fe78bSCy Schubert                 DeleteFile(FindFileData.cFileName);
1268*7f2fe78bSCy Schubert             }
1269*7f2fe78bSCy Schubert         } while ( FindNextFile(hFind, &FindFileData) );
1270*7f2fe78bSCy Schubert     }
1271*7f2fe78bSCy Schubert 
1272*7f2fe78bSCy Schubert     SetCurrentDirectory(curdir);
1273*7f2fe78bSCy Schubert 
1274*7f2fe78bSCy Schubert   cleanup:
1275*7f2fe78bSCy Schubert     if (temppath)
1276*7f2fe78bSCy Schubert         free(temppath);
1277*7f2fe78bSCy Schubert     if (hFind != INVALID_HANDLE_VALUE)
1278*7f2fe78bSCy Schubert         FindClose(hFind);
1279*7f2fe78bSCy Schubert     if (curdir)
1280*7f2fe78bSCy Schubert         free(curdir);
1281*7f2fe78bSCy Schubert }
1282