1 #include <windows.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <winsock2.h>
5 #include "leashdll.h"
6 #include <time.h>
7
8 #include <leashwin.h>
9 #include "leasherr.h"
10 #include "leash-int.h"
11 #include "leashids.h"
12
13 #include "reminder.h"
14
15 static char FAR *err_context;
16
17 char KRB_HelpFile[_MAX_PATH] = HELPFILE;
18
19 #define LEN 64 /* Maximum Hostname Length */
20
21 #define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */
22
23 static
24 char*
clean_string(char * s)25 clean_string(
26 char* s
27 )
28 {
29 char* p = s;
30 char* b = s;
31
32 if (!s) return s;
33
34 for (p = s; *p; p++) {
35 switch (*p) {
36 case '\007':
37 /* Add more cases here */
38 break;
39 default:
40 *b = *p;
41 b++;
42 }
43 }
44 *b = *p;
45 return s;
46 }
47
48 static
49 int
leash_error_message(const char * error,int rcL,int rc5,int rcA,char * result_string,int displayMB)50 leash_error_message(
51 const char *error,
52 int rcL,
53 int rc5,
54 int rcA,
55 char* result_string,
56 int displayMB
57 )
58 {
59 char message[2048];
60 char *p = message;
61 int size = sizeof(message) - 1; /* -1 to leave room for NULL terminator */
62 int n;
63
64 if (!rc5 && !rcL)
65 return 0;
66
67 n = _snprintf(p, size, "%s\n\n", error);
68 p += n;
69 size -= n;
70
71 if (rc5 && !result_string)
72 {
73 n = _snprintf(p, size,
74 "Kerberos 5: %s (error %ld)\n",
75 perror_message(rc5),
76 rc5
77 );
78 p += n;
79 size -= n;
80 }
81 if (rcL)
82 {
83 char buffer[1024];
84 n = _snprintf(p, size,
85 "\n%s\n",
86 err_describe(buffer, rcL)
87 );
88 p += n;
89 size -= n;
90 }
91 if (result_string)
92 {
93 n = _snprintf(p, size,
94 "%s\n",
95 result_string);
96 p += n;
97 size -= n;
98 }
99 #ifdef USE_MESSAGE_BOX
100 *p = 0; /* ensure NULL termination of message */
101 if ( displayMB )
102 MessageBox(NULL, message, "MIT Kerberos",
103 MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND);
104 #endif /* USE_MESSAGE_BOX */
105 if (rc5) return rc5;
106 if (rcL) return rcL;
107 return 0;
108 }
109
110
111 static
112 char *
make_postfix(const char * base,const char * postfix,char ** rcopy)113 make_postfix(
114 const char * base,
115 const char * postfix,
116 char ** rcopy
117 )
118 {
119 int base_size;
120 int ret_size;
121 char * copy = 0;
122 char * ret = 0;
123
124 base_size = strlen(base) + 1;
125 ret_size = base_size + strlen(postfix) + 1;
126 copy = malloc(base_size);
127 ret = malloc(ret_size);
128
129 if (!copy || !ret)
130 goto cleanup;
131
132 strncpy(copy, base, base_size);
133 copy[base_size - 1] = 0;
134
135 strncpy(ret, base, base_size);
136 strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1));
137 ret[ret_size - 1] = 0;
138
139 cleanup:
140 if (!copy || !ret) {
141 if (copy)
142 free(copy);
143 if (ret)
144 free(ret);
145 copy = ret = 0;
146 }
147 // INVARIANT: (ret ==> copy) && (copy ==> ret)
148 *rcopy = copy;
149 return ret;
150 }
151
152 static
153 long
make_temp_cache_v5(const char * postfix,krb5_context * pctx)154 make_temp_cache_v5(
155 const char * postfix,
156 krb5_context * pctx
157 )
158 {
159 static krb5_context ctx = 0;
160 static char * old_cache = 0;
161
162 // INVARIANT: old_cache ==> ctx && ctx ==> old_cache
163
164 if (pctx)
165 *pctx = 0;
166
167 if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve ||
168 !pkrb5_cc_default_name || !pkrb5_cc_set_default_name)
169 return 0;
170
171 if (old_cache) {
172 krb5_ccache cc = 0;
173 if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc))
174 pkrb5_cc_destroy(ctx, cc);
175 pkrb5_cc_set_default_name(ctx, old_cache);
176 free(old_cache);
177 old_cache = 0;
178 }
179 if (ctx) {
180 pkrb5_free_context(ctx);
181 ctx = 0;
182 }
183
184 if (postfix)
185 {
186 char * tmp_cache = 0;
187 krb5_error_code rc = 0;
188
189 rc = pkrb5_init_context(&ctx);
190 if (rc) goto cleanup;
191
192 tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix,
193 &old_cache);
194
195 if (!tmp_cache) {
196 rc = ENOMEM;
197 goto cleanup;
198 }
199
200 rc = pkrb5_cc_set_default_name(ctx, tmp_cache);
201
202 cleanup:
203 if (rc && ctx) {
204 pkrb5_free_context(ctx);
205 ctx = 0;
206 }
207 if (tmp_cache)
208 free(tmp_cache);
209 if (pctx)
210 *pctx = ctx;
211 return rc;
212 }
213 return 0;
214 }
215
216 long
Leash_checkpwd(char * principal,char * password)217 Leash_checkpwd(
218 char *principal,
219 char *password
220 )
221 {
222 return Leash_int_checkpwd(principal, password, 0);
223 }
224
225 long
Leash_int_checkpwd(char * principal,char * password,int displayErrors)226 Leash_int_checkpwd(
227 char * principal,
228 char * password,
229 int displayErrors
230 )
231 {
232 long rc = 0;
233 krb5_context ctx = 0; // statically allocated in make_temp_cache_v5
234 // XXX - we ignore errors in make_temp_cache_v? This is BAD!!!
235 make_temp_cache_v5("_checkpwd", &ctx);
236 rc = Leash_int_kinit_ex( ctx, 0,
237 principal, password, 0, 0, 0, 0,
238 Leash_get_default_noaddresses(),
239 Leash_get_default_publicip(),
240 displayErrors
241 );
242 make_temp_cache_v5(0, &ctx);
243 return rc;
244 }
245
246 static
247 long
Leash_changepwd_v5(char * principal,char * password,char * newpassword,char ** error_str)248 Leash_changepwd_v5(
249 char * principal,
250 char * password,
251 char * newpassword,
252 char** error_str
253 )
254 {
255 krb5_error_code rc = 0;
256 int result_code;
257 krb5_data result_code_string, result_string;
258 krb5_context context = 0;
259 krb5_principal princ = 0;
260 krb5_get_init_creds_opt opts;
261 krb5_creds creds;
262 DWORD addressless = 0;
263
264 result_string.data = 0;
265 result_code_string.data = 0;
266
267 if ( !pkrb5_init_context )
268 goto cleanup;
269
270 if (rc = pkrb5_init_context(&context))
271 goto cleanup;
272
273 if (rc = pkrb5_parse_name(context, principal, &princ))
274 goto cleanup;
275
276 pkrb5_get_init_creds_opt_init(&opts);
277 pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
278 pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
279 pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
280 pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
281
282 addressless = Leash_get_default_noaddresses();
283 if (addressless)
284 pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
285
286
287 if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password,
288 0, 0, 0, "kadmin/changepw", &opts))
289 goto cleanup;
290
291 if (rc = pkrb5_change_password(context, &creds, newpassword,
292 &result_code, &result_code_string,
293 &result_string))
294 goto cleanup;
295
296 if (result_code) {
297 int len = result_code_string.length +
298 (result_string.length ? (sizeof(": ") - 1) : 0) +
299 result_string.length;
300 if (len && error_str) {
301 *error_str = malloc(len + 1);
302 if (*error_str)
303 _snprintf(*error_str, len + 1,
304 "%.*s%s%.*s",
305 result_code_string.length, result_code_string.data,
306 result_string.length?": ":"",
307 result_string.length, result_string.data);
308 }
309 rc = result_code;
310 goto cleanup;
311 }
312
313 cleanup:
314 if (result_string.data)
315 pkrb5_free_data_contents(context, &result_string);
316
317 if (result_code_string.data)
318 pkrb5_free_data_contents(context, &result_code_string);
319
320 if (princ)
321 pkrb5_free_principal(context, princ);
322
323 if (context)
324 pkrb5_free_context(context);
325
326 return rc;
327 }
328
329 /*
330 * Leash_changepwd
331 *
332 * Try to change the password using krb5.
333 */
334 long
Leash_changepwd(char * principal,char * password,char * newpassword,char ** result_string)335 Leash_changepwd(
336 char * principal,
337 char * password,
338 char * newpassword,
339 char** result_string
340 )
341 {
342 return Leash_int_changepwd(principal, password, newpassword, result_string, 0);
343 }
344
345 long
Leash_int_changepwd(char * principal,char * password,char * newpassword,char ** result_string,int displayErrors)346 Leash_int_changepwd(
347 char * principal,
348 char * password,
349 char * newpassword,
350 char** result_string,
351 int displayErrors
352 )
353 {
354 char* v5_error_str = 0;
355 char* error_str = 0;
356 int rc5 = 0;
357 int rc = 0;
358 if (hKrb5)
359 rc = rc5 = Leash_changepwd_v5(principal, password, newpassword,
360 &v5_error_str);
361 if (!rc)
362 return 0;
363 if (v5_error_str) {
364 int len = 0;
365 char v5_prefix[] = "Kerberos 5: ";
366 char sep[] = "\n";
367
368 clean_string(v5_error_str);
369
370 if (v5_error_str)
371 len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) +
372 sizeof(sep);
373 error_str = malloc(len + 1);
374 if (error_str) {
375 char* p = error_str;
376 int size = len + 1;
377 int n;
378 if (v5_error_str) {
379 n = _snprintf(p, size, "%s%s%s%s",
380 sep, v5_prefix, v5_error_str, sep);
381 p += n;
382 size -= n;
383 }
384 if (result_string)
385 *result_string = error_str;
386 }
387 }
388 return leash_error_message("Error while changing password.",
389 0, rc5, 0, error_str,
390 displayErrors
391 );
392 }
393
394 int (*Lcom_err)(LPSTR,long,LPSTR,...);
395 LPSTR (*Lerror_message)(long);
396 LPSTR (*Lerror_table_name)(long);
397
398
399 long
Leash_kinit(char * principal,char * password,int lifetime)400 Leash_kinit(
401 char * principal,
402 char * password,
403 int lifetime
404 )
405 {
406 return Leash_int_kinit_ex( 0, 0,
407 principal,
408 password,
409 lifetime,
410 Leash_get_default_forwardable(),
411 Leash_get_default_proxiable(),
412 Leash_get_default_renew_till(),
413 Leash_get_default_noaddresses(),
414 Leash_get_default_publicip(),
415 0
416 );
417 }
418
419 long
Leash_kinit_ex(char * principal,char * password,int lifetime,int forwardable,int proxiable,int renew_life,int addressless,unsigned long publicip)420 Leash_kinit_ex(
421 char * principal,
422 char * password,
423 int lifetime,
424 int forwardable,
425 int proxiable,
426 int renew_life,
427 int addressless,
428 unsigned long publicip
429 )
430 {
431 return Leash_int_kinit_ex( 0, /* krb5 context */
432 0, /* parent window */
433 principal,
434 password,
435 lifetime,
436 forwardable,
437 proxiable,
438 renew_life,
439 addressless,
440 publicip,
441 0
442 );
443 }
444
445 long
Leash_int_kinit_ex(krb5_context ctx,HWND hParent,char * principal,char * password,int lifetime,int forwardable,int proxiable,int renew_life,int addressless,unsigned long publicip,int displayErrors)446 Leash_int_kinit_ex(
447 krb5_context ctx,
448 HWND hParent,
449 char * principal,
450 char * password,
451 int lifetime,
452 int forwardable,
453 int proxiable,
454 int renew_life,
455 int addressless,
456 unsigned long publicip,
457 int displayErrors
458 )
459 {
460 char aname[ANAME_SZ];
461 char inst[INST_SZ];
462 char realm[REALM_SZ];
463 char first_part[256];
464 char second_part[256];
465 char temp[1024];
466 char* custom_msg;
467 int count;
468 int i;
469 int rc5 = 0;
470 int rcA = 0;
471 int rcB = 0;
472 int rcL = 0;
473
474 if (lifetime < 5)
475 lifetime = 1;
476 else
477 lifetime /= 5;
478
479 if (renew_life > 0 && renew_life < 5)
480 renew_life = 1;
481 else
482 renew_life /= 5;
483
484 /* This should be changed if the maximum ticket lifetime */
485 /* changes */
486
487 if (lifetime > 255)
488 lifetime = 255;
489
490 err_context = "parsing principal";
491
492 memset(temp, '\0', sizeof(temp));
493 memset(inst, '\0', sizeof(inst));
494 memset(realm, '\0', sizeof(realm));
495 memset(first_part, '\0', sizeof(first_part));
496 memset(second_part, '\0', sizeof(second_part));
497
498 sscanf(principal, "%[/0-9a-zA-Z._-]@%[/0-9a-zA-Z._-]", first_part, second_part);
499 strcpy(temp, first_part);
500 strcpy(realm, second_part);
501 memset(first_part, '\0', sizeof(first_part));
502 memset(second_part, '\0', sizeof(second_part));
503 if (sscanf(temp, "%[@0-9a-zA-Z._-]/%[@0-9a-zA-Z._-]", first_part, second_part) == 2)
504 {
505 strcpy(aname, first_part);
506 strcpy(inst, second_part);
507 }
508 else
509 {
510 count = 0;
511 i = 0;
512 for (i = 0; temp[i]; i++)
513 {
514 if (temp[i] == '.')
515 ++count;
516 }
517 if (count > 1)
518 {
519 strcpy(aname, temp);
520 }
521 else
522 {
523 {
524 strcpy(aname, temp);
525 }
526 }
527 }
528
529 memset(temp, '\0', sizeof(temp));
530 strcpy(temp, aname);
531 if (strlen(inst) != 0)
532 {
533 strcat(temp, "/");
534 strcat(temp, inst);
535 }
536 if (strlen(realm) != 0)
537 {
538 strcat(temp, "@");
539 strcat(temp, realm);
540 }
541
542 rc5 = Leash_krb5_kinit(ctx, hParent,
543 temp, password, lifetime,
544 forwardable,
545 proxiable,
546 renew_life,
547 addressless,
548 publicip
549 );
550 custom_msg = (rc5 == KRB5KRB_AP_ERR_BAD_INTEGRITY) ? "Password incorrect" : NULL;
551 return leash_error_message("Ticket initialization failed.",
552 rcL, rc5, rcA, custom_msg,
553 displayErrors);
554 }
555
556 long FAR
Leash_renew(void)557 Leash_renew(void)
558 {
559 if ( hKrb5 && !LeashKRB5_renew() ) {
560 int lifetime;
561 lifetime = Leash_get_default_lifetime() / 5;
562 return 1;
563 }
564 return 0;
565 }
566
567 BOOL
GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)568 GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData)
569 {
570 NTSTATUS Status = 0;
571 HANDLE TokenHandle;
572 TOKEN_STATISTICS Stats;
573 DWORD ReqLen;
574 BOOL Success;
575 PSECURITY_LOGON_SESSION_DATA pSessionData;
576
577 if (!ppSessionData)
578 return FALSE;
579 *ppSessionData = NULL;
580
581 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
582 if ( !Success )
583 return FALSE;
584
585 Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
586 CloseHandle( TokenHandle );
587 if ( !Success )
588 return FALSE;
589
590 Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData );
591 if ( FAILED(Status) || !pSessionData )
592 return FALSE;
593
594 *ppSessionData = pSessionData;
595 return TRUE;
596 }
597
598 // IsKerberosLogon() does not validate whether or not there are valid tickets in the
599 // cache. It validates whether or not it is reasonable to assume that if we
600 // attempted to retrieve valid tickets we could do so. Microsoft does not
601 // automatically renew expired tickets. Therefore, the cache could contain
602 // expired or invalid tickets. Microsoft also caches the user's password
603 // and will use it to retrieve new TGTs if the cache is empty and tickets
604 // are requested.
605
606 BOOL
IsKerberosLogon(VOID)607 IsKerberosLogon(VOID)
608 {
609 PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
610 BOOL Success = FALSE;
611
612 if ( GetSecurityLogonSessionData(&pSessionData) ) {
613 if ( pSessionData->AuthenticationPackage.Buffer ) {
614 WCHAR buffer[256];
615 WCHAR *usBuffer;
616 int usLength;
617
618 Success = FALSE;
619 usBuffer = (pSessionData->AuthenticationPackage).Buffer;
620 usLength = (pSessionData->AuthenticationPackage).Length;
621 if (usLength < 256)
622 {
623 lstrcpynW (buffer, usBuffer, usLength);
624 lstrcatW (buffer,L"");
625 if ( !lstrcmpW(L"Kerberos",buffer) )
626 Success = TRUE;
627 }
628 }
629 pLsaFreeReturnBuffer(pSessionData);
630 }
631 return Success;
632 }
633
634 static BOOL
IsWindowsVista(void)635 IsWindowsVista (void)
636 {
637 static BOOL fChecked = FALSE;
638 static BOOL fIsVista = FALSE;
639
640 if (!fChecked)
641 {
642 OSVERSIONINFO Version;
643
644 memset (&Version, 0x00, sizeof(Version));
645 Version.dwOSVersionInfoSize = sizeof(Version);
646
647 if (GetVersionEx (&Version))
648 {
649 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6)
650 fIsVista = TRUE;
651 }
652 fChecked = TRUE;
653 }
654
655 return fIsVista;
656 }
657
658 static BOOL
IsProcessUacLimited(void)659 IsProcessUacLimited (void)
660 {
661 static BOOL fChecked = FALSE;
662 static BOOL fIsUAC = FALSE;
663
664 if (!fChecked)
665 {
666 NTSTATUS Status = 0;
667 HANDLE TokenHandle;
668 DWORD ElevationLevel;
669 DWORD ReqLen;
670 BOOL Success;
671
672 if (IsWindowsVista()) {
673 Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
674 if ( Success ) {
675 Success = GetTokenInformation( TokenHandle,
676 TokenOrigin+1 /* ElevationLevel */,
677 &ElevationLevel, sizeof(DWORD), &ReqLen );
678 CloseHandle( TokenHandle );
679 if ( Success && ElevationLevel == 3 /* Limited */ )
680 fIsUAC = TRUE;
681 }
682 }
683 fChecked = TRUE;
684 }
685 return fIsUAC;
686
687 }
688
689 long FAR
Leash_importable(void)690 Leash_importable(void)
691 {
692 /* Import functionality has been removed. */
693 return FALSE;
694 }
695
696 long FAR
Leash_import(void)697 Leash_import(void)
698 {
699 /* Import functionality has been removed. */
700 return 0;
701 }
702
703 long
Leash_kdestroy(void)704 Leash_kdestroy(void)
705 {
706 Leash_krb5_kdestroy();
707
708 return 0;
709 }
710
Leash_klist(HWND hlist,TICKETINFO FAR * ticketinfo)711 long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo)
712 {
713 return(255);
714 }
715
716
717 // This function can be used to set the help file that will be
718 // referenced the DLL's PasswordProcDLL function and err_describe
719 // function. Returns true if the help file has been set to the
720 // argument or the environment variable KERB_HELP. Returns FALSE if
721 // the default helpfile as defined in by HELPFILE in lsh_pwd.h is
722 // used.
Leash_set_help_file(char * szHelpFile)723 BOOL Leash_set_help_file( char *szHelpFile )
724 {
725 char tmpHelpFile[256];
726 BOOL ret = 0;
727
728 if( szHelpFile == NULL ){
729 GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile));
730 } else {
731 strcpy( KRB_HelpFile, szHelpFile );
732 ret++;
733 }
734
735 if( !ret && tmpHelpFile[0] ){
736 strcpy( KRB_HelpFile, tmpHelpFile );
737 ret++;
738 }
739
740 if( !ret){
741 strcpy( KRB_HelpFile, HELPFILE );
742 }
743
744 return(ret);
745 }
746
747
748
Leash_get_help_file(void)749 LPSTR Leash_get_help_file(void)
750 {
751 return( KRB_HelpFile);
752 }
753
754 int
Leash_debug(int class,int priority,char * fmt,...)755 Leash_debug(
756 int class,
757 int priority,
758 char* fmt, ...
759 )
760 {
761
762 return 0;
763 }
764
765
766 static int
get_profile_file(LPSTR confname,UINT szConfname)767 get_profile_file(LPSTR confname, UINT szConfname)
768 {
769 char **configFile = NULL;
770 if (hKrb5) {
771 if (pkrb5_get_default_config_files(&configFile) || !configFile[0])
772 {
773 GetWindowsDirectory(confname,szConfname);
774 confname[szConfname-1] = '\0';
775 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
776 confname[szConfname-1] = '\0';
777 return FALSE;
778 }
779
780 *confname = 0;
781
782 if (configFile)
783 {
784 strncpy(confname, *configFile, szConfname);
785 confname[szConfname-1] = '\0';
786 pkrb5_free_config_files(configFile);
787 }
788 }
789
790 if (!*confname)
791 {
792 GetWindowsDirectory(confname,szConfname);
793 confname[szConfname-1] = '\0';
794 strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
795 confname[szConfname-1] = '\0';
796 }
797
798 return FALSE;
799 }
800
801 static const char *const conf_yes[] = {
802 "y", "yes", "true", "t", "1", "on",
803 0,
804 };
805
806 static const char *const conf_no[] = {
807 "n", "no", "false", "nil", "0", "off",
808 0,
809 };
810
811 int
config_boolean_to_int(const char * s)812 config_boolean_to_int(const char *s)
813 {
814 const char *const *p;
815
816 for(p=conf_yes; *p; p++) {
817 if (!strcasecmp(*p,s))
818 return 1;
819 }
820
821 for(p=conf_no; *p; p++) {
822 if (!strcasecmp(*p,s))
823 return 0;
824 }
825
826 /* Default to "no" */
827 return 0;
828 }
829
830 /*
831 * Leash_get_default_lifetime:
832 *
833 * This function is used to get the default ticket lifetime for this
834 * process in minutes. A return value of 0 indicates no setting or
835 * "default" setting obtained.
836 *
837 * Here is where we look in order:
838 *
839 * - LIFETIME environment variable
840 * - HKCU\Software\MIT\Leash,lifetime
841 * - HKLM\Software\MIT\Leash,lifetime
842 * - string resource in the leash DLL
843 */
844
845 static BOOL
get_DWORD_from_registry(HKEY hBaseKey,char * key,char * value,DWORD * result)846 get_DWORD_from_registry(
847 HKEY hBaseKey,
848 char * key,
849 char * value,
850 DWORD * result
851 )
852 {
853 HKEY hKey;
854 DWORD dwCount;
855 LONG rc;
856
857 rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey);
858 if (rc)
859 return FALSE;
860
861 dwCount = sizeof(DWORD);
862 rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount);
863 RegCloseKey(hKey);
864
865 return rc?FALSE:TRUE;
866 }
867
868 static
869 BOOL
get_default_lifetime_from_registry(HKEY hBaseKey,DWORD * result)870 get_default_lifetime_from_registry(
871 HKEY hBaseKey,
872 DWORD * result
873 )
874 {
875 return get_DWORD_from_registry(hBaseKey,
876 LEASH_REGISTRY_KEY_NAME,
877 LEASH_REGISTRY_VALUE_LIFETIME,
878 result);
879 }
880
881 DWORD
Leash_reset_default_lifetime()882 Leash_reset_default_lifetime(
883 )
884 {
885 HKEY hKey;
886 LONG rc;
887
888 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
889 if (rc)
890 return rc;
891
892 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME);
893 RegCloseKey(hKey);
894
895 return rc;
896 }
897
898 DWORD
Leash_set_default_lifetime(DWORD minutes)899 Leash_set_default_lifetime(
900 DWORD minutes
901 )
902 {
903 HKEY hKey;
904 LONG rc;
905
906 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
907 0, 0, KEY_WRITE, 0, &hKey, 0);
908 if (rc)
909 return rc;
910
911 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD,
912 (LPBYTE) &minutes, sizeof(DWORD));
913 RegCloseKey(hKey);
914
915 return rc;
916 }
917
918 DWORD
Leash_get_default_lifetime()919 Leash_get_default_lifetime(
920 )
921 {
922 HMODULE hmLeash;
923 char env[32];
924 DWORD result;
925
926
927 if (GetEnvironmentVariable("LIFETIME",env,sizeof(env)))
928 {
929 return atoi(env);
930 }
931
932
933 if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) ||
934 get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result))
935 {
936 return result;
937 }
938
939 if ( hKrb5 ) {
940 CHAR confname[MAX_PATH];
941
942 if (!get_profile_file(confname, sizeof(confname)))
943 {
944 profile_t profile;
945 const char *filenames[2];
946 long retval;
947
948 filenames[0] = confname;
949 filenames[1] = NULL;
950 if (!pprofile_init(filenames, &profile)) {
951 char * value = NULL;
952
953 retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value);
954 if (retval == 0 && value) {
955 krb5_deltat d;
956
957 retval = pkrb5_string_to_deltat(value, &d);
958
959 if (retval == KRB5_DELTAT_BADFORMAT) {
960 /* Historically some sites use relations of
961 the form 'ticket_lifetime = 24000' where
962 the unit is left out but is assumed to be
963 seconds. Then there are other sites which
964 use the form 'ticket_lifetime = 600' where
965 the unit is assumed to be minutes. While
966 these are technically wrong (a unit needs
967 to be specified), we try to accommodate for
968 this using the safe assumption that the
969 unit is seconds and tack an 's' to the end
970 and see if that works. */
971
972 /* Of course, Leash is one of the platforms
973 that historically assumed no units and minutes
974 so this change is going to break some people
975 but its better to be consistent. */
976 size_t cch;
977 char buf[256];
978
979 do {
980 cch = strlen(value) + 2; /* NUL and new 's' */
981 if (cch > sizeof(buf))
982 break;
983
984 strcpy(buf, value);
985 strcat(buf, "s");
986
987 retval = pkrb5_string_to_deltat(buf, &d);
988
989 if (retval == 0) {
990 result = d / 60;
991 }
992 } while(0);
993 } else if (retval == 0) {
994 result = d / 60;
995 }
996
997 pprofile_release_string(value);
998 }
999 pprofile_release(profile);
1000 /* value has been released but we can still use a check for
1001 * non-NULL to see if we were able to read a value.
1002 */
1003 if (retval == 0 && value)
1004 return result;
1005 }
1006 }
1007 }
1008
1009 hmLeash = GetModuleHandle(LEASH_DLL);
1010 if (hmLeash)
1011 {
1012 char lifetime[80];
1013 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE,
1014 lifetime, sizeof(lifetime)))
1015 {
1016 lifetime[sizeof(lifetime) - 1] = 0;
1017 return atoi(lifetime);
1018 }
1019 }
1020 return 0;
1021 }
1022
1023 static
1024 BOOL
get_default_renew_till_from_registry(HKEY hBaseKey,DWORD * result)1025 get_default_renew_till_from_registry(
1026 HKEY hBaseKey,
1027 DWORD * result
1028 )
1029 {
1030 return get_DWORD_from_registry(hBaseKey,
1031 LEASH_REGISTRY_KEY_NAME,
1032 LEASH_REGISTRY_VALUE_RENEW_TILL,
1033 result);
1034 }
1035
1036 DWORD
Leash_reset_default_renew_till()1037 Leash_reset_default_renew_till(
1038 )
1039 {
1040 HKEY hKey;
1041 LONG rc;
1042
1043 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1044 if (rc)
1045 return rc;
1046
1047 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL);
1048 RegCloseKey(hKey);
1049
1050 return rc;
1051 }
1052
1053 DWORD
Leash_set_default_renew_till(DWORD minutes)1054 Leash_set_default_renew_till(
1055 DWORD minutes
1056 )
1057 {
1058 HKEY hKey;
1059 LONG rc;
1060
1061 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1062 0, 0, KEY_WRITE, 0, &hKey, 0);
1063 if (rc)
1064 return rc;
1065
1066 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD,
1067 (LPBYTE) &minutes, sizeof(DWORD));
1068 RegCloseKey(hKey);
1069
1070 return rc;
1071 }
1072
1073 DWORD
Leash_get_default_renew_till()1074 Leash_get_default_renew_till(
1075 )
1076 {
1077 HMODULE hmLeash;
1078 char env[32];
1079 DWORD result;
1080
1081 if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env)))
1082 {
1083 return atoi(env);
1084 }
1085
1086 if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) ||
1087 get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result))
1088 {
1089 return result;
1090 }
1091
1092 if ( hKrb5 ) {
1093 CHAR confname[MAX_PATH];
1094 if (!get_profile_file(confname, sizeof(confname)))
1095 {
1096 profile_t profile;
1097 const char *filenames[2];
1098 int value=0;
1099 long retval;
1100 filenames[0] = confname;
1101 filenames[1] = NULL;
1102
1103 if (!pprofile_init(filenames, &profile)) {
1104 char * value = NULL;
1105
1106 retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value);
1107 if (retval == 0 && value) {
1108 krb5_deltat d;
1109
1110 retval = pkrb5_string_to_deltat(value, &d);
1111 if (retval == KRB5_DELTAT_BADFORMAT) {
1112 /* Historically some sites use relations of
1113 the form 'ticket_lifetime = 24000' where
1114 the unit is left out but is assumed to be
1115 seconds. Then there are other sites which
1116 use the form 'ticket_lifetime = 600' where
1117 the unit is assumed to be minutes. While
1118 these are technically wrong (a unit needs
1119 to be specified), we try to accommodate for
1120 this using the safe assumption that the
1121 unit is seconds and tack an 's' to the end
1122 and see if that works. */
1123
1124 /* Of course, Leash is one of the platforms
1125 that historically assumed no units and minutes
1126 so this change is going to break some people
1127 but its better to be consistent. */
1128 size_t cch;
1129 char buf[256];
1130 do {
1131 cch = strlen(value) + 2; /* NUL and new 's' */
1132 if (cch > sizeof(buf))
1133 break;
1134
1135 strcpy(buf, value);
1136 strcat(buf, "s");
1137
1138 retval = pkrb5_string_to_deltat(buf, &d);
1139 if (retval == 0) {
1140 result = d / 60;
1141 }
1142 } while(0);
1143 } else if (retval == 0) {
1144 result = d / 60;
1145 }
1146 pprofile_release_string(value);
1147 }
1148 pprofile_release(profile);
1149 /* value has been released but we can still use a check for
1150 * non-NULL to see if we were able to read a value.
1151 */
1152 if (retval == 0 && value)
1153 return result;
1154
1155 pprofile_release(profile);
1156 }
1157 }
1158 }
1159
1160 hmLeash = GetModuleHandle(LEASH_DLL);
1161 if (hmLeash)
1162 {
1163 char renew_till[80];
1164 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL,
1165 renew_till, sizeof(renew_till)))
1166 {
1167 renew_till[sizeof(renew_till) - 1] = 0;
1168 return atoi(renew_till);
1169 }
1170 }
1171 return 0;
1172 }
1173
1174 static
1175 BOOL
get_default_forwardable_from_registry(HKEY hBaseKey,DWORD * result)1176 get_default_forwardable_from_registry(
1177 HKEY hBaseKey,
1178 DWORD * result
1179 )
1180 {
1181 return get_DWORD_from_registry(hBaseKey,
1182 LEASH_REGISTRY_KEY_NAME,
1183 LEASH_REGISTRY_VALUE_FORWARDABLE,
1184 result);
1185 }
1186
1187 DWORD
Leash_reset_default_forwardable()1188 Leash_reset_default_forwardable(
1189 )
1190 {
1191 HKEY hKey;
1192 LONG rc;
1193
1194 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1195 if (rc)
1196 return rc;
1197
1198 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE);
1199 RegCloseKey(hKey);
1200
1201 return rc;
1202 }
1203
1204 DWORD
Leash_set_default_forwardable(DWORD minutes)1205 Leash_set_default_forwardable(
1206 DWORD minutes
1207 )
1208 {
1209 HKEY hKey;
1210 LONG rc;
1211
1212 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1213 0, 0, KEY_WRITE, 0, &hKey, 0);
1214 if (rc)
1215 return rc;
1216
1217 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD,
1218 (LPBYTE) &minutes, sizeof(DWORD));
1219 RegCloseKey(hKey);
1220
1221 return rc;
1222 }
1223
1224 DWORD
Leash_get_default_forwardable()1225 Leash_get_default_forwardable(
1226 )
1227 {
1228 HMODULE hmLeash;
1229
1230 char env[32];
1231 DWORD result;
1232
1233 if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env)))
1234 {
1235 return atoi(env);
1236 }
1237
1238 if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) ||
1239 get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result))
1240 {
1241 return result;
1242 }
1243
1244 if ( hKrb5 ) {
1245 CHAR confname[MAX_PATH];
1246 if (!get_profile_file(confname, sizeof(confname)))
1247 {
1248 profile_t profile;
1249 const char *filenames[2];
1250 char *value=0;
1251 long retval;
1252 filenames[0] = confname;
1253 filenames[1] = NULL;
1254 if (!pprofile_init(filenames, &profile)) {
1255 retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value);
1256 if ( value ) {
1257 result = config_boolean_to_int(value);
1258 pprofile_release_string(value);
1259 pprofile_release(profile);
1260 return result;
1261 }
1262 pprofile_release(profile);
1263 }
1264 }
1265 }
1266
1267 hmLeash = GetModuleHandle(LEASH_DLL);
1268 if (hmLeash)
1269 {
1270 char forwardable[80];
1271 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD,
1272 forwardable, sizeof(forwardable)))
1273 {
1274 forwardable[sizeof(forwardable) - 1] = 0;
1275 return atoi(forwardable);
1276 }
1277 }
1278 return 0;
1279 }
1280
1281 static
1282 BOOL
get_default_renewable_from_registry(HKEY hBaseKey,DWORD * result)1283 get_default_renewable_from_registry(
1284 HKEY hBaseKey,
1285 DWORD * result
1286 )
1287 {
1288 return get_DWORD_from_registry(hBaseKey,
1289 LEASH_REGISTRY_KEY_NAME,
1290 LEASH_REGISTRY_VALUE_RENEWABLE,
1291 result);
1292 }
1293
1294 DWORD
Leash_reset_default_renewable()1295 Leash_reset_default_renewable(
1296 )
1297 {
1298 HKEY hKey;
1299 LONG rc;
1300
1301 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1302 if (rc)
1303 return rc;
1304
1305 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE);
1306 RegCloseKey(hKey);
1307
1308 return rc;
1309 }
1310
1311 DWORD
Leash_set_default_renewable(DWORD minutes)1312 Leash_set_default_renewable(
1313 DWORD minutes
1314 )
1315 {
1316 HKEY hKey;
1317 LONG rc;
1318
1319 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1320 0, 0, KEY_WRITE, 0, &hKey, 0);
1321 if (rc)
1322 return rc;
1323
1324 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD,
1325 (LPBYTE) &minutes, sizeof(DWORD));
1326 RegCloseKey(hKey);
1327
1328 return rc;
1329 }
1330
1331 DWORD
Leash_get_default_renewable()1332 Leash_get_default_renewable(
1333 )
1334 {
1335 HMODULE hmLeash;
1336 char env[32];
1337 DWORD result;
1338
1339 if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env)))
1340 {
1341 return atoi(env);
1342 }
1343
1344 if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) ||
1345 get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result))
1346 {
1347 return result;
1348 }
1349
1350 if ( hKrb5 ) {
1351 CHAR confname[MAX_PATH];
1352 if (!get_profile_file(confname, sizeof(confname)))
1353 {
1354 profile_t profile;
1355 const char *filenames[2];
1356 char *value=0;
1357 long retval;
1358 filenames[0] = confname;
1359 filenames[1] = NULL;
1360 if (!pprofile_init(filenames, &profile)) {
1361 retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value);
1362 if ( value ) {
1363 result = config_boolean_to_int(value);
1364 pprofile_release_string(value);
1365 pprofile_release(profile);
1366 return result;
1367 }
1368 pprofile_release(profile);
1369 }
1370 }
1371 }
1372
1373 hmLeash = GetModuleHandle(LEASH_DLL);
1374 if (hmLeash)
1375 {
1376 char renewable[80];
1377 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW,
1378 renewable, sizeof(renewable)))
1379 {
1380 renewable[sizeof(renewable) - 1] = 0;
1381 return atoi(renewable);
1382 }
1383 }
1384 return 0;
1385 }
1386
1387 static
1388 BOOL
get_default_noaddresses_from_registry(HKEY hBaseKey,DWORD * result)1389 get_default_noaddresses_from_registry(
1390 HKEY hBaseKey,
1391 DWORD * result
1392 )
1393 {
1394 return get_DWORD_from_registry(hBaseKey,
1395 LEASH_REGISTRY_KEY_NAME,
1396 LEASH_REGISTRY_VALUE_NOADDRESSES,
1397 result);
1398 }
1399
1400 DWORD
Leash_reset_default_noaddresses()1401 Leash_reset_default_noaddresses(
1402 )
1403 {
1404 HKEY hKey;
1405 LONG rc;
1406
1407 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1408 if (rc)
1409 return rc;
1410
1411 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES);
1412 RegCloseKey(hKey);
1413
1414 return rc;
1415 }
1416
1417 DWORD
Leash_set_default_noaddresses(DWORD minutes)1418 Leash_set_default_noaddresses(
1419 DWORD minutes
1420 )
1421 {
1422 HKEY hKey;
1423 LONG rc;
1424
1425 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1426 0, 0, KEY_WRITE, 0, &hKey, 0);
1427 if (rc)
1428 return rc;
1429
1430 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD,
1431 (LPBYTE) &minutes, sizeof(DWORD));
1432 RegCloseKey(hKey);
1433
1434 return rc;
1435 }
1436
1437 DWORD
Leash_get_default_noaddresses()1438 Leash_get_default_noaddresses(
1439 )
1440 {
1441 HMODULE hmLeash;
1442 char env[32];
1443 DWORD result;
1444
1445 if ( hKrb5 ) {
1446 // if the profile file cannot be opened then the value will be true
1447 // if the noaddresses name cannot be found then the value will be true
1448 // if true in the library, we can't alter it by other means
1449 CHAR confname[MAX_PATH];
1450 result = 1;
1451 if (!get_profile_file(confname, sizeof(confname)))
1452 {
1453 profile_t profile;
1454 const char *filenames[2];
1455 char *value=0;
1456 long retval;
1457 filenames[0] = confname;
1458 filenames[1] = NULL;
1459 if (!pprofile_init(filenames, &profile)) {
1460 retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value);
1461 if ( value ) {
1462 result = config_boolean_to_int(value);
1463 pprofile_release_string(value);
1464 }
1465 pprofile_release(profile);
1466 }
1467 }
1468
1469 if ( result )
1470 return 1;
1471 }
1472
1473 // The library default is false, check other locations
1474
1475 if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env)))
1476 {
1477 return atoi(env);
1478 }
1479
1480 if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) ||
1481 get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result))
1482 {
1483 return result;
1484 }
1485
1486 hmLeash = GetModuleHandle(LEASH_DLL);
1487 if (hmLeash)
1488 {
1489 char noaddresses[80];
1490 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS,
1491 noaddresses, sizeof(noaddresses)))
1492 {
1493 noaddresses[sizeof(noaddresses) - 1] = 0;
1494 }
1495 }
1496 return 1;
1497 }
1498
1499 static
1500 BOOL
get_default_proxiable_from_registry(HKEY hBaseKey,DWORD * result)1501 get_default_proxiable_from_registry(
1502 HKEY hBaseKey,
1503 DWORD * result
1504 )
1505 {
1506 return get_DWORD_from_registry(hBaseKey,
1507 LEASH_REGISTRY_KEY_NAME,
1508 LEASH_REGISTRY_VALUE_PROXIABLE,
1509 result);
1510 }
1511
1512 DWORD
Leash_reset_default_proxiable()1513 Leash_reset_default_proxiable(
1514 )
1515 {
1516 HKEY hKey;
1517 LONG rc;
1518
1519 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1520 if (rc)
1521 return rc;
1522
1523 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE);
1524 RegCloseKey(hKey);
1525
1526 return rc;
1527 }
1528
1529 DWORD
Leash_set_default_proxiable(DWORD minutes)1530 Leash_set_default_proxiable(
1531 DWORD minutes
1532 )
1533 {
1534 HKEY hKey;
1535 LONG rc;
1536
1537 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1538 0, 0, KEY_WRITE, 0, &hKey, 0);
1539 if (rc)
1540 return rc;
1541
1542 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD,
1543 (LPBYTE) &minutes, sizeof(DWORD));
1544 RegCloseKey(hKey);
1545
1546 return rc;
1547 }
1548
1549 DWORD
Leash_get_default_proxiable()1550 Leash_get_default_proxiable(
1551 )
1552 {
1553 HMODULE hmLeash;
1554 char env[32];
1555 DWORD result;
1556
1557 if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env)))
1558 {
1559 return atoi(env);
1560 }
1561
1562 if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) ||
1563 get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result))
1564 {
1565 return result;
1566 }
1567
1568 if ( hKrb5 ) {
1569 CHAR confname[MAX_PATH];
1570 if (!get_profile_file(confname, sizeof(confname)))
1571 {
1572 profile_t profile;
1573 const char *filenames[2];
1574 char *value=0;
1575 long retval;
1576 filenames[0] = confname;
1577 filenames[1] = NULL;
1578 if (!pprofile_init(filenames, &profile)) {
1579 retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value);
1580 if ( value ) {
1581 result = config_boolean_to_int(value);
1582 pprofile_release_string(value);
1583 pprofile_release(profile);
1584 return result;
1585 }
1586 pprofile_release(profile);
1587 }
1588 }
1589 }
1590
1591 hmLeash = GetModuleHandle(LEASH_DLL);
1592 if (hmLeash)
1593 {
1594 char proxiable[80];
1595 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE,
1596 proxiable, sizeof(proxiable)))
1597 {
1598 proxiable[sizeof(proxiable) - 1] = 0;
1599 return atoi(proxiable);
1600 }
1601 }
1602 return 0;
1603 }
1604
1605 static
1606 BOOL
get_default_publicip_from_registry(HKEY hBaseKey,DWORD * result)1607 get_default_publicip_from_registry(
1608 HKEY hBaseKey,
1609 DWORD * result
1610 )
1611 {
1612 return get_DWORD_from_registry(hBaseKey,
1613 LEASH_REGISTRY_KEY_NAME,
1614 LEASH_REGISTRY_VALUE_PUBLICIP,
1615 result);
1616 }
1617
1618 DWORD
Leash_reset_default_publicip()1619 Leash_reset_default_publicip(
1620 )
1621 {
1622 HKEY hKey;
1623 LONG rc;
1624
1625 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1626 if (rc)
1627 return rc;
1628
1629 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP);
1630 RegCloseKey(hKey);
1631
1632 return rc;
1633 }
1634
1635 DWORD
Leash_set_default_publicip(DWORD minutes)1636 Leash_set_default_publicip(
1637 DWORD minutes
1638 )
1639 {
1640 HKEY hKey;
1641 LONG rc;
1642
1643 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1644 0, 0, KEY_WRITE, 0, &hKey, 0);
1645 if (rc)
1646 return rc;
1647
1648 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD,
1649 (LPBYTE) &minutes, sizeof(DWORD));
1650 RegCloseKey(hKey);
1651
1652 return rc;
1653 }
1654
1655 DWORD
Leash_get_default_publicip()1656 Leash_get_default_publicip(
1657 )
1658 {
1659 HMODULE hmLeash;
1660 char env[32];
1661 DWORD result;
1662
1663 if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env)))
1664 {
1665 return atoi(env);
1666 }
1667
1668 if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) ||
1669 get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result))
1670 {
1671 return result;
1672 }
1673
1674 hmLeash = GetModuleHandle(LEASH_DLL);
1675 if (hmLeash)
1676 {
1677 char publicip[80];
1678 if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP,
1679 publicip, sizeof(publicip)))
1680 {
1681 publicip[sizeof(publicip) - 1] = 0;
1682 return atoi(publicip);
1683 }
1684 }
1685 return 0;
1686 }
1687
1688 static
1689 BOOL
get_hide_kinit_options_from_registry(HKEY hBaseKey,DWORD * result)1690 get_hide_kinit_options_from_registry(
1691 HKEY hBaseKey,
1692 DWORD * result
1693 )
1694 {
1695 return get_DWORD_from_registry(hBaseKey,
1696 LEASH_REGISTRY_KEY_NAME,
1697 LEASH_REGISTRY_VALUE_KINIT_OPT,
1698 result);
1699 }
1700
1701 DWORD
Leash_reset_hide_kinit_options()1702 Leash_reset_hide_kinit_options(
1703 )
1704 {
1705 HKEY hKey;
1706 LONG rc;
1707
1708 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1709 if (rc)
1710 return rc;
1711
1712 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT);
1713 RegCloseKey(hKey);
1714
1715 return rc;
1716 }
1717
1718 DWORD
Leash_set_hide_kinit_options(DWORD minutes)1719 Leash_set_hide_kinit_options(
1720 DWORD minutes
1721 )
1722 {
1723 HKEY hKey;
1724 LONG rc;
1725
1726 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1727 0, 0, KEY_WRITE, 0, &hKey, 0);
1728 if (rc)
1729 return rc;
1730
1731 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD,
1732 (LPBYTE) &minutes, sizeof(DWORD));
1733 RegCloseKey(hKey);
1734
1735 return rc;
1736 }
1737
1738 DWORD
Leash_get_hide_kinit_options()1739 Leash_get_hide_kinit_options(
1740 )
1741 {
1742 HMODULE hmLeash;
1743 DWORD result;
1744
1745 if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) ||
1746 get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result))
1747 {
1748 return result;
1749 }
1750
1751 hmLeash = GetModuleHandle(LEASH_DLL);
1752 if (hmLeash)
1753 {
1754 char hide_kinit_options[80];
1755 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT,
1756 hide_kinit_options, sizeof(hide_kinit_options)))
1757 {
1758 hide_kinit_options[sizeof(hide_kinit_options) - 1] = 0;
1759 return atoi(hide_kinit_options);
1760 }
1761 }
1762 return 0; /* hide unless otherwise indicated */
1763 }
1764
1765
1766
1767 static
1768 BOOL
get_default_life_min_from_registry(HKEY hBaseKey,DWORD * result)1769 get_default_life_min_from_registry(
1770 HKEY hBaseKey,
1771 DWORD * result
1772 )
1773 {
1774 return get_DWORD_from_registry(hBaseKey,
1775 LEASH_REGISTRY_KEY_NAME,
1776 LEASH_REGISTRY_VALUE_LIFE_MIN,
1777 result);
1778 }
1779
1780 DWORD
Leash_reset_default_life_min()1781 Leash_reset_default_life_min(
1782 )
1783 {
1784 HKEY hKey;
1785 LONG rc;
1786
1787 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1788 if (rc)
1789 return rc;
1790
1791 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN);
1792 RegCloseKey(hKey);
1793
1794 return rc;
1795 }
1796
1797 DWORD
Leash_set_default_life_min(DWORD minutes)1798 Leash_set_default_life_min(
1799 DWORD minutes
1800 )
1801 {
1802 HKEY hKey;
1803 LONG rc;
1804
1805 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1806 0, 0, KEY_WRITE, 0, &hKey, 0);
1807 if (rc)
1808 return rc;
1809
1810 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD,
1811 (LPBYTE) &minutes, sizeof(DWORD));
1812 RegCloseKey(hKey);
1813
1814 return rc;
1815 }
1816
1817 DWORD
Leash_get_default_life_min()1818 Leash_get_default_life_min(
1819 )
1820 {
1821 HMODULE hmLeash;
1822 DWORD result;
1823
1824 if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) ||
1825 get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result))
1826 {
1827 return result;
1828 }
1829
1830 hmLeash = GetModuleHandle(LEASH_DLL);
1831 if (hmLeash)
1832 {
1833 char life_min[80];
1834 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN,
1835 life_min, sizeof(life_min)))
1836 {
1837 life_min[sizeof(life_min) - 1] = 0;
1838 return atoi(life_min);
1839 }
1840 }
1841 return 5; /* 5 minutes */
1842 }
1843
1844 static
1845 BOOL
get_default_life_max_from_registry(HKEY hBaseKey,DWORD * result)1846 get_default_life_max_from_registry(
1847 HKEY hBaseKey,
1848 DWORD * result
1849 )
1850 {
1851 return get_DWORD_from_registry(hBaseKey,
1852 LEASH_REGISTRY_KEY_NAME,
1853 LEASH_REGISTRY_VALUE_LIFE_MAX,
1854 result);
1855 }
1856
1857 DWORD
Leash_reset_default_life_max()1858 Leash_reset_default_life_max(
1859 )
1860 {
1861 HKEY hKey;
1862 LONG rc;
1863
1864 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1865 if (rc)
1866 return rc;
1867
1868 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX);
1869 RegCloseKey(hKey);
1870
1871 return rc;
1872 }
1873
1874 DWORD
Leash_set_default_life_max(DWORD minutes)1875 Leash_set_default_life_max(
1876 DWORD minutes
1877 )
1878 {
1879 HKEY hKey;
1880 LONG rc;
1881
1882 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1883 0, 0, KEY_WRITE, 0, &hKey, 0);
1884 if (rc)
1885 return rc;
1886
1887 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD,
1888 (LPBYTE) &minutes, sizeof(DWORD));
1889 RegCloseKey(hKey);
1890
1891 return rc;
1892 }
1893
1894 DWORD
Leash_get_default_life_max()1895 Leash_get_default_life_max(
1896 )
1897 {
1898 HMODULE hmLeash;
1899 DWORD result;
1900
1901 if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) ||
1902 get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result))
1903 {
1904 return result;
1905 }
1906
1907 hmLeash = GetModuleHandle(LEASH_DLL);
1908 if (hmLeash)
1909 {
1910 char life_max[80];
1911 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX,
1912 life_max, sizeof(life_max)))
1913 {
1914 life_max[sizeof(life_max) - 1] = 0;
1915 return atoi(life_max);
1916 }
1917 }
1918 return 1440;
1919 }
1920
1921 static
1922 BOOL
get_default_renew_min_from_registry(HKEY hBaseKey,DWORD * result)1923 get_default_renew_min_from_registry(
1924 HKEY hBaseKey,
1925 DWORD * result
1926 )
1927 {
1928 return get_DWORD_from_registry(hBaseKey,
1929 LEASH_REGISTRY_KEY_NAME,
1930 LEASH_REGISTRY_VALUE_RENEW_MIN,
1931 result);
1932 }
1933
1934 DWORD
Leash_reset_default_renew_min()1935 Leash_reset_default_renew_min(
1936 )
1937 {
1938 HKEY hKey;
1939 LONG rc;
1940
1941 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
1942 if (rc)
1943 return rc;
1944
1945 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN);
1946 RegCloseKey(hKey);
1947
1948 return rc;
1949 }
1950
1951 DWORD
Leash_set_default_renew_min(DWORD minutes)1952 Leash_set_default_renew_min(
1953 DWORD minutes
1954 )
1955 {
1956 HKEY hKey;
1957 LONG rc;
1958
1959 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
1960 0, 0, KEY_WRITE, 0, &hKey, 0);
1961 if (rc)
1962 return rc;
1963
1964 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD,
1965 (LPBYTE) &minutes, sizeof(DWORD));
1966 RegCloseKey(hKey);
1967
1968 return rc;
1969 }
1970
1971 DWORD
Leash_get_default_renew_min()1972 Leash_get_default_renew_min(
1973 )
1974 {
1975 HMODULE hmLeash;
1976 DWORD result;
1977
1978 if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) ||
1979 get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result))
1980 {
1981 return result;
1982 }
1983
1984 hmLeash = GetModuleHandle(LEASH_DLL);
1985 if (hmLeash)
1986 {
1987 char renew_min[80];
1988 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN,
1989 renew_min, sizeof(renew_min)))
1990 {
1991 renew_min[sizeof(renew_min) - 1] = 0;
1992 return atoi(renew_min);
1993 }
1994 }
1995 return 600; /* 10 hours */
1996 }
1997
1998 static
1999 BOOL
get_default_renew_max_from_registry(HKEY hBaseKey,DWORD * result)2000 get_default_renew_max_from_registry(
2001 HKEY hBaseKey,
2002 DWORD * result
2003 )
2004 {
2005 return get_DWORD_from_registry(hBaseKey,
2006 LEASH_REGISTRY_KEY_NAME,
2007 LEASH_REGISTRY_VALUE_RENEW_MAX,
2008 result);
2009 }
2010
2011 DWORD
Leash_reset_default_renew_max()2012 Leash_reset_default_renew_max(
2013 )
2014 {
2015 HKEY hKey;
2016 LONG rc;
2017
2018 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2019 if (rc)
2020 return rc;
2021
2022 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX);
2023 RegCloseKey(hKey);
2024
2025 return rc;
2026 }
2027
2028 DWORD
Leash_set_default_renew_max(DWORD minutes)2029 Leash_set_default_renew_max(
2030 DWORD minutes
2031 )
2032 {
2033 HKEY hKey;
2034 LONG rc;
2035
2036 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2037 0, 0, KEY_WRITE, 0, &hKey, 0);
2038 if (rc)
2039 return rc;
2040
2041 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD,
2042 (LPBYTE) &minutes, sizeof(DWORD));
2043 RegCloseKey(hKey);
2044
2045 return rc;
2046 }
2047
2048 DWORD
Leash_get_default_renew_max()2049 Leash_get_default_renew_max(
2050 )
2051 {
2052 HMODULE hmLeash;
2053 DWORD result;
2054
2055 if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) ||
2056 get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result))
2057 {
2058 return result;
2059 }
2060
2061 hmLeash = GetModuleHandle(LEASH_DLL);
2062 if (hmLeash)
2063 {
2064 char renew_max[80];
2065 if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX,
2066 renew_max, sizeof(renew_max)))
2067 {
2068 renew_max[sizeof(renew_max) - 1] = 0;
2069 return atoi(renew_max);
2070 }
2071 }
2072 return 60 * 24 * 30;
2073 }
2074
2075 static
2076 BOOL
get_default_uppercaserealm_from_registry(HKEY hBaseKey,DWORD * result)2077 get_default_uppercaserealm_from_registry(
2078 HKEY hBaseKey,
2079 DWORD * result
2080 )
2081 {
2082 return get_DWORD_from_registry(hBaseKey,
2083 LEASH_SETTINGS_REGISTRY_KEY_NAME,
2084 LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM,
2085 result);
2086 }
2087
2088 DWORD
Leash_reset_default_uppercaserealm()2089 Leash_reset_default_uppercaserealm(
2090 )
2091 {
2092 HKEY hKey;
2093 LONG rc;
2094
2095 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2096 if (rc)
2097 return rc;
2098
2099 rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM);
2100 RegCloseKey(hKey);
2101
2102 return rc;
2103 }
2104
2105 DWORD
Leash_set_default_uppercaserealm(DWORD onoff)2106 Leash_set_default_uppercaserealm(
2107 DWORD onoff
2108 )
2109 {
2110 HKEY hKey;
2111 LONG rc;
2112
2113 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0,
2114 0, 0, KEY_WRITE, 0, &hKey, 0);
2115 if (rc)
2116 return rc;
2117
2118 rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD,
2119 (LPBYTE) &onoff, sizeof(DWORD));
2120 RegCloseKey(hKey);
2121
2122 return rc;
2123 }
2124
2125 DWORD
Leash_get_default_uppercaserealm()2126 Leash_get_default_uppercaserealm(
2127 )
2128 {
2129 HMODULE hmLeash;
2130 DWORD result;
2131
2132 if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) ||
2133 get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result))
2134 {
2135 return result;
2136 }
2137
2138 hmLeash = GetModuleHandle(LEASH_DLL);
2139 if (hmLeash)
2140 {
2141 char uppercaserealm[80];
2142 if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM,
2143 uppercaserealm, sizeof(uppercaserealm)))
2144 {
2145 uppercaserealm[sizeof(uppercaserealm) - 1] = 0;
2146 return atoi(uppercaserealm);
2147 }
2148 }
2149 return 1;
2150 }
2151
2152 DWORD
Leash_reset_default_mslsa_import()2153 Leash_reset_default_mslsa_import(
2154 )
2155 {
2156 return ERROR_INVALID_FUNCTION;
2157 }
2158
2159 DWORD
Leash_set_default_mslsa_import(DWORD onoffmatch)2160 Leash_set_default_mslsa_import(
2161 DWORD onoffmatch
2162 )
2163 {
2164 return ERROR_INVALID_FUNCTION;
2165 }
2166
2167 DWORD
Leash_get_default_mslsa_import()2168 Leash_get_default_mslsa_import(
2169 )
2170 {
2171 return 0;
2172 }
2173
2174
2175 static
2176 BOOL
get_default_preserve_kinit_settings_from_registry(HKEY hBaseKey,DWORD * result)2177 get_default_preserve_kinit_settings_from_registry(
2178 HKEY hBaseKey,
2179 DWORD * result
2180 )
2181 {
2182 return get_DWORD_from_registry(hBaseKey,
2183 LEASH_REGISTRY_KEY_NAME,
2184 LEASH_REGISTRY_VALUE_PRESERVE_KINIT,
2185 result);
2186 }
2187
2188 DWORD
Leash_reset_default_preserve_kinit_settings()2189 Leash_reset_default_preserve_kinit_settings(
2190 )
2191 {
2192 HKEY hKey;
2193 LONG rc;
2194
2195 rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey);
2196 if (rc)
2197 return rc;
2198
2199 rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT);
2200 RegCloseKey(hKey);
2201
2202 return rc;
2203 }
2204
2205 DWORD
Leash_set_default_preserve_kinit_settings(DWORD onoff)2206 Leash_set_default_preserve_kinit_settings(
2207 DWORD onoff
2208 )
2209 {
2210 HKEY hKey;
2211 LONG rc;
2212
2213 rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0,
2214 0, 0, KEY_WRITE, 0, &hKey, 0);
2215 if (rc)
2216 return rc;
2217
2218 rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD,
2219 (LPBYTE) &onoff, sizeof(DWORD));
2220 RegCloseKey(hKey);
2221
2222 return rc;
2223 }
2224
2225 DWORD
Leash_get_default_preserve_kinit_settings()2226 Leash_get_default_preserve_kinit_settings(
2227 )
2228 {
2229 HMODULE hmLeash;
2230 DWORD result;
2231
2232 if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) ||
2233 get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result))
2234 {
2235 return result;
2236 }
2237
2238 hmLeash = GetModuleHandle(LEASH_DLL);
2239 if (hmLeash)
2240 {
2241 char preserve_kinit_settings[80];
2242 if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT,
2243 preserve_kinit_settings, sizeof(preserve_kinit_settings)))
2244 {
2245 preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0;
2246 return atoi(preserve_kinit_settings);
2247 }
2248 }
2249 return 1;
2250 }
2251
2252 void
Leash_reset_defaults(void)2253 Leash_reset_defaults(void)
2254 {
2255 Leash_reset_default_lifetime();
2256 Leash_reset_default_renew_till();
2257 Leash_reset_default_renewable();
2258 Leash_reset_default_forwardable();
2259 Leash_reset_default_noaddresses();
2260 Leash_reset_default_proxiable();
2261 Leash_reset_default_publicip();
2262 Leash_reset_hide_kinit_options();
2263 Leash_reset_default_life_min();
2264 Leash_reset_default_life_max();
2265 Leash_reset_default_renew_min();
2266 Leash_reset_default_renew_max();
2267 Leash_reset_default_uppercaserealm();
2268 Leash_reset_default_preserve_kinit_settings();
2269 }
2270
2271 static void
acquire_tkt_send_msg_leash(const char * title,const char * ccachename,const char * name,const char * realm)2272 acquire_tkt_send_msg_leash(const char *title,
2273 const char *ccachename,
2274 const char *name,
2275 const char *realm)
2276 {
2277 DWORD leashProcessId = 0;
2278 DWORD bufsize = 4096;
2279 DWORD step;
2280 HANDLE hLeashProcess = NULL;
2281 HANDLE hMapFile = NULL;
2282 HANDLE hTarget = NULL;
2283 HWND hLeashWnd = FindWindow("LEASH.0WNDCLASS", NULL);
2284 char *strs;
2285 void *view;
2286 if (!hLeashWnd)
2287 // no leash window
2288 return;
2289
2290 GetWindowThreadProcessId(hLeashWnd, &leashProcessId);
2291 hLeashProcess = OpenProcess(PROCESS_DUP_HANDLE,
2292 FALSE,
2293 leashProcessId);
2294 if (!hLeashProcess)
2295 // can't get process handle; use GetLastError() for more info
2296 return;
2297
2298 hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
2299 NULL, // default security
2300 PAGE_READWRITE, // read/write access
2301 0, // max size (high 32)
2302 bufsize, // max size (low 32)
2303 NULL); // name
2304 if (!hMapFile) {
2305 // GetLastError() for more info
2306 CloseHandle(hLeashProcess);
2307 return;
2308 }
2309
2310 SetForegroundWindow(hLeashWnd);
2311
2312 view = MapViewOfFile(hMapFile,
2313 FILE_MAP_ALL_ACCESS,
2314 0,
2315 0,
2316 bufsize);
2317 if (view != NULL) {
2318 /* construct a marshalling of data
2319 * <title><principal><realm><ccache>
2320 * then send to Leash
2321 */
2322 strs = (char *)view;
2323 // first reserve space for three more NULLs (4 strings total)
2324 bufsize -= 3;
2325 // Dialog title
2326 if (title != NULL)
2327 strcpy_s(strs, bufsize, title);
2328 else if (name != NULL && realm != NULL)
2329 sprintf_s(strs, bufsize,
2330 "MIT Kerberos: Get Ticket for %s@%s", name, realm);
2331 else
2332 strcpy_s(strs, bufsize, "MIT Kerberos: Get Ticket");
2333 step = strlen(strs);
2334 strs += step + 1;
2335 bufsize -= step;
2336 // name and realm
2337 if (name != NULL) {
2338 strcpy_s(strs, bufsize, name);
2339 step = strlen(strs);
2340 strs += step + 1;
2341 bufsize -= step;
2342 if (realm != NULL) {
2343 strcpy_s(strs, bufsize, realm);
2344 step = strlen(strs);
2345 strs += step + 1;
2346 bufsize -= step;
2347 } else {
2348 *strs = 0;
2349 strs++;
2350 }
2351 } else {
2352 *strs = 0;
2353 strs++;
2354 *strs = 0;
2355 strs++;
2356 }
2357
2358 /* Append the ccache name */
2359 if (ccachename != NULL)
2360 strcpy_s(strs, bufsize, ccachename);
2361 else
2362 *strs = 0;
2363
2364 UnmapViewOfFile(view);
2365 }
2366 // Duplicate the file mapping handle to one leash can use
2367 if (DuplicateHandle(GetCurrentProcess(),
2368 hMapFile,
2369 hLeashProcess,
2370 &hTarget,
2371 PAGE_READWRITE,
2372 FALSE,
2373 DUPLICATE_SAME_ACCESS |
2374 DUPLICATE_CLOSE_SOURCE)) {
2375 /* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */
2376 SendMessage(hLeashWnd, 32809, 0, (LPARAM) hTarget);
2377 } else {
2378 // GetLastError()
2379 }
2380 }
2381
2382 static int
acquire_tkt_send_msg(krb5_context ctx,const char * title,const char * ccachename,krb5_principal desiredKrb5Principal,char * out_ccname,int out_cclen)2383 acquire_tkt_send_msg(krb5_context ctx, const char * title,
2384 const char * ccachename,
2385 krb5_principal desiredKrb5Principal,
2386 char * out_ccname, int out_cclen)
2387 {
2388 krb5_error_code err;
2389 HWND hNetIdMgr;
2390 HWND hForeground;
2391 char *desiredName = 0;
2392 char *desiredRealm = 0;
2393
2394 /* do we want a specific client principal? */
2395 if (desiredKrb5Principal != NULL) {
2396 err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName);
2397 if (!err) {
2398 char * p;
2399 for (p = desiredName; *p && *p != '@'; p++);
2400 if ( *p == '@' ) {
2401 *p = '\0';
2402 desiredRealm = ++p;
2403 }
2404 }
2405 }
2406
2407 hForeground = GetForegroundWindow();
2408 hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
2409 if (hNetIdMgr != NULL) {
2410 HANDLE hMap;
2411 DWORD tid = GetCurrentThreadId();
2412 char mapname[256];
2413 NETID_DLGINFO *dlginfo;
2414
2415 sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
2416
2417 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2418 0, 4096, mapname);
2419 if (hMap == NULL) {
2420 return -1;
2421 } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
2422 CloseHandle(hMap);
2423 return -1;
2424 }
2425
2426 dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
2427 0, 0, 4096, NULL);
2428 if (dlginfo == NULL) {
2429 CloseHandle(hMap);
2430 return -1;
2431 }
2432
2433 memset(dlginfo, 0, sizeof(NETID_DLGINFO));
2434
2435 dlginfo->size = sizeof(NETID_DLGINFO);
2436 dlginfo->dlgtype = NETID_DLGTYPE_TGT;
2437 dlginfo->in.use_defaults = 1;
2438
2439 if (title) {
2440 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2441 title, -1,
2442 dlginfo->in.title, NETID_TITLE_SZ);
2443 } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
2444 char mytitle[NETID_TITLE_SZ];
2445 sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
2446 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2447 mytitle, -1,
2448 dlginfo->in.title, NETID_TITLE_SZ);
2449 } else {
2450 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2451 "Obtain Kerberos TGT", -1,
2452 dlginfo->in.title, NETID_TITLE_SZ);
2453 }
2454 if (desiredName)
2455 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2456 desiredName, -1,
2457 dlginfo->in.username, NETID_USERNAME_SZ);
2458 if (desiredRealm)
2459 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2460 desiredRealm, -1,
2461 dlginfo->in.realm, NETID_REALM_SZ);
2462 if (ccachename)
2463 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
2464 ccachename, -1,
2465 dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);
2466 SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
2467
2468 if (out_ccname && out_cclen > 0) {
2469 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1,
2470 out_ccname, out_cclen, NULL, NULL);
2471 }
2472
2473 UnmapViewOfFile(dlginfo);
2474 CloseHandle(hMap);
2475 } else {
2476 acquire_tkt_send_msg_leash(title,
2477 ccachename, desiredName, desiredRealm);
2478 }
2479
2480 SetForegroundWindow(hForeground);
2481 if (desiredName != NULL)
2482 pkrb5_free_unparsed_name(ctx, desiredName);
2483
2484 return 0;
2485 }
2486
cc_have_tickets(krb5_context ctx,krb5_ccache cache)2487 static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache)
2488 {
2489 krb5_cc_cursor cur = NULL;
2490 krb5_creds creds;
2491 krb5_flags flags;
2492 krb5_error_code code;
2493 BOOL have_tickets = FALSE;
2494
2495 // Don't need the actual ticket.
2496 flags = KRB5_TC_NOTICKET;
2497 code = pkrb5_cc_set_flags(ctx, cache, flags);
2498 if (code)
2499 goto cleanup;
2500 code = pkrb5_cc_start_seq_get(ctx, cache, &cur);
2501 if (code)
2502 goto cleanup;
2503
2504 _tzset();
2505 while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
2506 if ((!pkrb5_is_config_principal(ctx, creds.server)) &&
2507 ((time_t)(DWORD)creds.times.endtime - time(0) > 0))
2508 have_tickets = TRUE;
2509
2510 pkrb5_free_cred_contents(ctx, &creds);
2511 }
2512 if (code == KRB5_CC_END) {
2513 code = pkrb5_cc_end_seq_get(ctx, cache, &cur);
2514 if (code)
2515 goto cleanup;
2516 flags = 0;
2517 code = pkrb5_cc_set_flags(ctx, cache, flags);
2518 if (code)
2519 goto cleanup;
2520 }
2521 cleanup:
2522 return have_tickets;
2523 }
2524
2525 static BOOL
cc_have_tickets_for_princ(krb5_context ctx,krb5_ccache cache,krb5_principal princ)2526 cc_have_tickets_for_princ(krb5_context ctx,
2527 krb5_ccache cache,
2528 krb5_principal princ)
2529 {
2530 krb5_error_code code;
2531 krb5_principal cc_princ = NULL;
2532 BOOL have_tickets = FALSE;
2533 code = pkrb5_cc_get_principal(ctx, cache, &cc_princ);
2534 if (code)
2535 goto cleanup;
2536
2537 if (pkrb5_principal_compare(ctx, princ, cc_princ))
2538 have_tickets = cc_have_tickets(ctx, cache);
2539
2540 cleanup:
2541 if (cc_princ != NULL)
2542 pkrb5_free_principal(ctx, cc_princ);
2543 return have_tickets;
2544 }
2545
cc_default_have_tickets(krb5_context ctx)2546 static BOOL cc_default_have_tickets(krb5_context ctx)
2547 {
2548 krb5_ccache cache = NULL;
2549 BOOL have_tickets = FALSE;
2550 if (pkrb5_cc_default(ctx, &cache) == 0)
2551 have_tickets = cc_have_tickets(ctx, cache);
2552 if (cache != NULL)
2553 pkrb5_cc_close(ctx, cache);
2554 return have_tickets;
2555 }
2556
2557 static BOOL
cccol_have_tickets_for_princ(krb5_context ctx,krb5_principal princ,char * ccname,int cclen)2558 cccol_have_tickets_for_princ(krb5_context ctx,
2559 krb5_principal princ,
2560 char *ccname,
2561 int cclen)
2562 {
2563 krb5_error_code code;
2564 krb5_ccache cache;
2565 krb5_cccol_cursor cursor;
2566 BOOL have_tickets = FALSE;
2567 char *ccfullname;
2568
2569 code = pkrb5_cccol_cursor_new(ctx, &cursor);
2570 if (code)
2571 goto cleanup;
2572
2573 while (!have_tickets &&
2574 !(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) &&
2575 cache != NULL) {
2576 if (cc_have_tickets_for_princ(ctx, cache, princ)) {
2577 if (pkrb5_cc_get_full_name(ctx, cache, &ccfullname)==0) {
2578 strcpy_s(ccname, cclen, ccfullname);
2579 pkrb5_free_string(ctx, ccfullname);
2580 have_tickets = TRUE;
2581 }
2582 }
2583 pkrb5_cc_close(ctx, cache);
2584 }
2585 pkrb5_cccol_cursor_free(ctx, &cursor);
2586 cleanup:
2587
2588 return have_tickets;
2589 }
2590
2591 static void
acquire_tkt_no_princ(krb5_context context,char * ccname,int cclen)2592 acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
2593 {
2594 krb5_context ctx;
2595 DWORD gle;
2596 char ccachename[272]="";
2597 char loginenv[16];
2598 BOOL prompt;
2599 BOOL haveTickets;
2600
2601 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
2602 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
2603
2604 ctx = context;
2605
2606 SetLastError(0);
2607 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2608 gle = GetLastError();
2609 if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) {
2610 const char * ccdef = pkrb5_cc_default_name(ctx);
2611 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);
2612 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2613 }
2614
2615 haveTickets = cc_default_have_tickets(ctx);
2616
2617 if ( prompt && !haveTickets ) {
2618 acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen);
2619 /*
2620 * If the ticket manager returned an alternative credential cache
2621 * remember it as the default for this process.
2622 */
2623 if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) {
2624 SetEnvironmentVariable("KRB5CCNAME",ccname);
2625 }
2626
2627 } else if (ccachename[0] && ccname) {
2628 strncpy(ccname, ccachename, cclen);
2629 ccname[cclen-1] = '\0';
2630 }
2631 if ( !context )
2632 pkrb5_free_context(ctx);
2633 }
2634
2635
2636 static void
acquire_tkt_for_princ(krb5_context ctx,krb5_principal desiredPrincipal,char * ccname,int cclen)2637 acquire_tkt_for_princ(krb5_context ctx, krb5_principal desiredPrincipal,
2638 char * ccname, int cclen)
2639 {
2640 DWORD gle;
2641 char ccachename[272]="";
2642 char loginenv[16];
2643 BOOL prompt;
2644
2645 GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv));
2646 prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
2647
2648 SetLastError(0);
2649 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2650 gle = GetLastError();
2651 if ((gle == ERROR_ENVVAR_NOT_FOUND || !ccachename[0]) && ctx != NULL) {
2652 const char * ccdef = pkrb5_cc_default_name(ctx);
2653 SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL);
2654 GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
2655 }
2656 if (!cccol_have_tickets_for_princ(ctx, desiredPrincipal, ccname, cclen)) {
2657 if (prompt) {
2658 acquire_tkt_send_msg(ctx, NULL,
2659 ccachename, desiredPrincipal, ccname, cclen);
2660 /*
2661 * If the ticket manager returned an alternative credential cache
2662 * remember it as the default for this process.
2663 */
2664 if (ccname != NULL && ccname[0] &&
2665 strcmp(ccachename, ccname)) {
2666 SetEnvironmentVariable("KRB5CCNAME",ccname);
2667 }
2668 }
2669 }
2670 }
2671
2672
2673 void FAR
not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context,krb5_principal desiredKrb5Principal,char * ccname,int cclen)2674 not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context,
2675 krb5_principal desiredKrb5Principal,
2676 char * ccname, int cclen)
2677 {
2678 if (!desiredKrb5Principal) {
2679 acquire_tkt_no_princ(context, ccname, cclen);
2680 } else {
2681 acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen);
2682 }
2683 return;
2684 }
2685