/*
+ * Copyright (c) 2004, 2005, 2006, 2007, 2008 Secure Endpoints Inc.
* Copyright (c) 2003 SkyRope, LLC
* All rights reserved.
*
*/
-#define USE_MS2MIT
#undef USE_KRB4
+#ifndef _WIN64
+#define USE_KRB524 1
+#endif
+#define USE_MS2MIT 1
+#define USE_LEASH 1
+
#include "afskfw-int.h"
#include "afskfw.h"
+#include <userenv.h>
+
+#include <Sddl.h>
+#include <Aclapi.h>
#include <osilog.h>
-#include <rxkad_prototypes.h> /* for life_to_time */
#include <afs/ptserver.h>
#include <afs/ptuser.h>
+#include <rx/rxkad.h>
#include <WINNT\afsreg.h>
DECL_FUNC_PTR(cc_get_NC_info);
DECL_FUNC_PTR(cc_free_NC_info);
+#ifdef USE_LEASH
// leash functions
DECL_FUNC_PTR(Leash_get_default_lifetime);
DECL_FUNC_PTR(Leash_get_default_forwardable);
DECL_FUNC_PTR(Leash_get_default_renew_max);
DECL_FUNC_PTR(Leash_get_default_renewable);
DECL_FUNC_PTR(Leash_get_default_mslsa_import);
+#endif
// krb5 functions
DECL_FUNC_PTR(krb5_change_password);
DECL_FUNC_PTR(krb5_free_addresses);
DECL_FUNC_PTR(krb5_c_random_make_octets);
+#ifdef USE_KRB524
// Krb524 functions
DECL_FUNC_PTR(krb524_init_ets);
DECL_FUNC_PTR(krb524_convert_creds_kdc);
+#endif
+#ifdef USE_KRB4
// krb4 functions
DECL_FUNC_PTR(krb_get_cred);
DECL_FUNC_PTR(tkt_string);
DECL_FUNC_PTR(krb_get_tf_realm);
DECL_FUNC_PTR(krb_mk_req);
+#endif
// ComErr functions
DECL_FUNC_PTR(com_err);
END_FUNC_INFO
};
+#ifdef USE_LEASH
FUNC_INFO leash_fi[] = {
MAKE_FUNC_INFO(Leash_get_default_lifetime),
MAKE_FUNC_INFO(Leash_get_default_renew_till),
MAKE_FUNC_INFO(Leash_get_default_mslsa_import),
END_FUNC_INFO
};
+#endif
FUNC_INFO k5_fi[] = {
MAKE_FUNC_INFO(krb5_change_password),
};
#endif
+#ifdef USE_KRB524
FUNC_INFO k524_fi[] = {
MAKE_FUNC_INFO(krb524_init_ets),
MAKE_FUNC_INFO(krb524_convert_creds_kdc),
END_FUNC_INFO
};
+#endif
FUNC_INFO profile_fi[] = {
MAKE_FUNC_INFO(profile_init),
#ifdef USE_KRB4
static HINSTANCE hKrb4 = 0;
#endif /* USE_KRB4 */
+#ifdef USE_KRB524
static HINSTANCE hKrb524 = 0;
+#endif
#ifdef USE_MS2MIT
static HINSTANCE hSecur32 = 0;
#endif /* USE_MS2MIT */
static HINSTANCE hComErr = 0;
static HINSTANCE hService = 0;
static HINSTANCE hProfile = 0;
+#ifdef USE_LEASH
static HINSTANCE hLeash = 0;
static HINSTANCE hLeashOpt = 0;
+#endif
static HINSTANCE hCCAPI = 0;
static struct principal_ccache_data * princ_cc_data = NULL;
static struct cell_principal_map * cell_princ_map = NULL;
if ( !inited ) {
inited = 1;
LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
+ LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
+ LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
#ifdef USE_KRB4
LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
#endif /* USE_KRB4 */
- LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
#ifdef USE_MS2MIT
LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
#endif /* USE_MS2MIT */
+#ifdef USE_KRB524
LoadFuncs(KRB524_DLL, k524_fi, &hKrb524, 0, 1, 1, 1);
- LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
+#endif
+#ifdef USE_LEASH
LoadFuncs(LEASH_DLL, leash_fi, &hLeash, 0, 1, 0, 0);
- LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
LoadFuncs(LEASH_DLL, leash_opt_fi, &hLeashOpt, 0, 1, 0, 0);
+#endif
+ LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
if ( KFW_is_available() ) {
char rootcell[MAXCELLCHARS+1];
void
KFW_cleanup(void)
{
+#ifdef USE_LEASH
if (hLeashOpt)
FreeLibrary(hLeashOpt);
- if (hCCAPI)
- FreeLibrary(hCCAPI);
if (hLeash)
FreeLibrary(hLeash);
+#endif
+#ifdef USE_KRB524
if (hKrb524)
FreeLibrary(hKrb524);
+#endif
+ if (hCCAPI)
+ FreeLibrary(hCCAPI);
#ifdef USE_MS2MIT
if (hSecur32)
FreeLibrary(hSecur32);
FreeLibrary(hKrb5);
}
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+static int IsWow64()
+{
+ static int init = TRUE;
+ static int bIsWow64 = FALSE;
+
+ if (init) {
+ HMODULE hModule;
+ LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
+
+ hModule = GetModuleHandle(TEXT("kernel32"));
+ if (hModule) {
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hModule, "IsWow64Process");
+
+ if (NULL != fnIsWow64Process)
+ {
+ if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
+ {
+ // on error, assume FALSE.
+ // in other words, do nothing.
+ }
+ }
+ FreeLibrary(hModule);
+ }
+ init = FALSE;
+ }
+ return bIsWow64;
+}
+
+int
+KFW_accept_dotted_usernames(void)
+{
+ HKEY parmKey;
+ DWORD code, len;
+ DWORD value = 1;
+
+ code = RegOpenKeyEx(HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY,
+ 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(value);
+ code = RegQueryValueEx(parmKey, "AcceptDottedPrincipalNames", NULL, NULL,
+ (BYTE *) &value, &len);
+ RegCloseKey(parmKey);
+ }
+ if (code != ERROR_SUCCESS) {
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
+ 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(value);
+ code = RegQueryValueEx(parmKey, "AcceptDottedPrincipalNames", NULL, NULL,
+ (BYTE *) &value, &len);
+ RegCloseKey (parmKey);
+ }
+ }
+ return value;
+}
+
+
int
KFW_use_krb524(void)
{
DWORD use524 = 0;
code = RegOpenKeyEx(HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY,
- 0, KEY_QUERY_VALUE, &parmKey);
+ 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
len = sizeof(use524);
code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
}
if (code != ERROR_SUCCESS) {
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
- 0, KEY_QUERY_VALUE, &parmKey);
+ 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
len = sizeof(use524);
code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
DWORD enableKFW = 1;
code = RegOpenKeyEx(HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY,
- 0, KEY_QUERY_VALUE, &parmKey);
+ 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
len = sizeof(enableKFW);
code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
if (code != ERROR_SUCCESS) {
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
- 0, KEY_QUERY_VALUE, &parmKey);
+ 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
len = sizeof(enableKFW);
code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
#ifdef USE_MS2MIT
hSecur32 &&
#endif /* USE_MS2MIT */
+#ifdef USE_KRB524
hKrb524 &&
- hProfile && hLeash && hCCAPI )
+#endif
+#ifdef USE_LEASH
+ hLeash &&
+#endif
+ hProfile && hCCAPI )
return TRUE;
return FALSE;
}
{
if (cache && *cache != NULL) {
pkrb5_cc_close(*ctx, *cache);
- *cache = NULL;
- }
+ *cache = NULL;
+ }
pkrb5_free_context(*ctx);
- *ctx = NULL;
+ *ctx = NULL;
}
}
krb5_principal principal = 0;
char * pname = NULL;
const char * ccname = NULL;
+ const char * cctype = NULL;
+ char * ccfullname = NULL;
krb5_error_code code = 0;
krb5_error_code cc_code = 0;
krb5_cc_cursor cur;
ccname = pkrb5_cc_get_name(ctx, cc);
if (!ccname) goto cleanup;
+ cctype = pkrb5_cc_get_type(ctx, cc);
+ if (!cctype) goto cleanup;
+
+ ccfullname = malloc(strlen(ccname) + strlen(cctype) + 2);
+ if (!ccfullname) goto cleanup;
+
+ sprintf(ccfullname, "%s:%s", cctype, ccname);
+
// Search the existing list to see if we have a match
if ( next ) {
for ( ; next ; next = next->next ) {
- if ( !strcmp(next->principal,pname) && !strcmp(next->ccache_name, ccname) )
+ if ( !strcmp(next->principal,pname) && !strcmp(next->ccache_name, ccfullname) )
break;
}
}
next->next = princ_cc_data;
princ_cc_data = next;
next->principal = _strdup(pname);
- next->ccache_name = _strdup(ccname);
+ next->ccache_name = ccfullname;
+ ccfullname = NULL;
next->from_lsa = lsa;
next->expired = 1;
next->expiration_time = 0;
flags = KRB5_TC_OPENCLOSE; //turn on OPENCLOSE
code = pkrb5_cc_set_flags(ctx, cc, flags);
+ if ( ccfullname)
+ free(ccfullname);
if ( pname )
pkrb5_free_unparsed_name(ctx,pname);
if ( principal )
int
KFW_get_ccache(krb5_context alt_ctx, krb5_principal principal, krb5_ccache * cc)
{
- krb5_context ctx;
- char * pname = 0;
- char * ccname = 0;
+ krb5_context ctx = NULL;
+ char * pname = NULL;
+ char * ccname = NULL;
krb5_error_code code;
if (!pkrb5_init_context)
void
KFW_import_windows_lsa(void)
{
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
- krb5_principal princ = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal princ = NULL;
char * pname = NULL;
krb5_data * princ_realm;
krb5_error_code code;
if (!pkrb5_init_context)
return;
-#ifdef COMMENT
- if ( !MSLSA_IsKerberosLogon() )
- return;
-#endif
-
code = pkrb5_init_context(&ctx);
if (code) goto cleanup;
void
KFW_import_ccache_data(void)
{
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
- krb5_principal principal = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal principal = NULL;
krb5_creds creds;
krb5_error_code code;
krb5_error_code cc_code;
krb5_cc_cursor cur;
- apiCB * cc_ctx = 0;
+ apiCB * cc_ctx = NULL;
struct _infoNC ** pNCi = NULL;
int i, j, flags;
code = pkrb5_cc_close(ctx,cc);
cc = 0;
code = pkrb5_cc_close(ctx,oldcc);
- cc = 0;
+ oldcc = 0;
KRB5_error(code, "krb5_cc_copy_creds", 0, NULL, NULL);
continue;
}
OutputDebugString("Calling KFW_AFS_klog() to obtain token\n");
}
- code = KFW_AFS_klog(ctx, cc, "afs", cell->data, realm->data, pLeash_get_default_lifetime(),NULL);
+ code = KFW_AFS_klog(ctx, cc, "afs", cell->data, realm->data,
+#ifndef USE_LEASH
+ 600,
+#else
+ pLeash_get_default_lifetime(),
+#endif /* USE_LEASH */
+ NULL);
if ( IsDebuggerPresent() ) {
char message[256];
sprintf(message,"KFW_AFS_klog() returns: %d\n",code);
char * smbname,
char ** reasonP )
{
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
- char * realm = 0, * userrealm = 0;
- krb5_principal principal = 0;
- char * pname = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ char * realm = NULL, * userrealm = NULL;
+ krb5_principal principal = NULL;
+ char * pname = NULL;
krb5_error_code code;
- char local_cell[MAXCELLCHARS+1];
+ char local_cell[CELL_MAXNAMELEN+1];
char **cells = NULL;
int cell_count=0;
struct afsconf_cell cellconfig;
char * dot;
-
if (!pkrb5_init_context)
return 0;
userrealm = strchr(username,'@');
if ( userrealm ) {
pname = strdup(username);
- userrealm = strchr(pname, '@');
- *userrealm = '\0';
+ if (!KFW_accept_dotted_usernames()) {
+ userrealm = strchr(pname, '@');
+ *userrealm = '\0';
- /* handle kerberos iv notation */
- while ( dot = strchr(pname,'.') ) {
- *dot = '/';
+ /* handle kerberos iv notation */
+ while ( dot = strchr(pname,'.') ) {
+ *dot = '/';
+ }
+ *userrealm++ = '@';
}
- *userrealm++ = '@';
} else {
pname = malloc(strlen(username) + strlen(realm) + 2);
strcpy(pname, username);
- /* handle kerberos iv notation */
- while ( dot = strchr(pname,'.') ) {
- *dot = '/';
+ if (!KFW_accept_dotted_usernames()) {
+ /* handle kerberos iv notation */
+ while ( dot = strchr(pname,'.') ) {
+ *dot = '/';
+ }
}
-
strcat(pname,"@");
strcat(pname,realm);
}
if ( code ) goto cleanup;
if ( lifetime == 0 )
+#ifndef USE_LEASH
+ lifetime = 600;
+#else
lifetime = pLeash_get_default_lifetime();
+#endif
if ( password && password[0] ) {
code = KFW_kinit( ctx, cc, HWND_DESKTOP,
pname,
password,
lifetime,
+#ifndef USE_LEASH
+ 1, /* forwardable */
+ 0, /* not proxiable */
+ 1, /* renewable */
+ 1, /* noaddresses */
+ 0 /* no public ip */
+#else
pLeash_get_default_forwardable(),
pLeash_get_default_proxiable(),
pLeash_get_default_renewable() ? pLeash_get_default_renew_till() : 0,
pLeash_get_default_noaddresses(),
- pLeash_get_default_publicip());
+ pLeash_get_default_publicip()
+#endif /* USE_LEASH */
+ );
+
if ( IsDebuggerPresent() ) {
char message[256];
sprintf(message,"KFW_kinit() returns: %d\n",code);
KFW_AFS_update_princ_ccache_data(ctx, cc, FALSE);
}
- code = KFW_AFS_klog(ctx, cc, "afs", cell, realm, lifetime,smbname);
+ code = KFW_AFS_klog(ctx, cc, "afs", cell, realm, lifetime, smbname);
if ( IsDebuggerPresent() ) {
char message[256];
sprintf(message,"KFW_AFS_klog() returns: %d\n",code);
OutputDebugString("\n");
}
- code = KFW_AFS_klog(ctx, cc, "afs", cells[cell_count], realm, lifetime,smbname);
+ code = KFW_AFS_klog(ctx, cc, "afs", cells[cell_count], realm, lifetime, smbname);
if ( IsDebuggerPresent() ) {
char message[256];
sprintf(message,"KFW_AFS_klog() returns: %d\n",code);
int
KFW_AFS_destroy_tickets_for_cell(char * cell)
{
- krb5_context ctx = 0;
- krb5_error_code code;
+ krb5_context ctx = NULL;
+ krb5_error_code code;
int count;
char ** principals = NULL;
return 0;
if ( IsDebuggerPresent() ) {
- OutputDebugString("KFW_AFS_destroy_ticets_for_cell: ");
+ OutputDebugString("KFW_AFS_destroy_tickets_for_cell: ");
OutputDebugString(cell);
OutputDebugString("\n");
}
}
free(principals);
}
- pkrb5_free_context(ctx);
+ if (ctx)
+ pkrb5_free_context(ctx);
+ return 0;
+}
+
+int
+KFW_AFS_destroy_tickets_for_principal(char * user)
+{
+ krb5_context ctx = NULL;
+ krb5_error_code code;
+ int count;
+ char ** cells = NULL;
+ krb5_principal princ = NULL;
+ krb5_ccache cc = NULL;
+
+ if (!pkrb5_init_context)
+ return 0;
+
+ if ( IsDebuggerPresent() ) {
+ OutputDebugString("KFW_AFS_destroy_tickets_for_user: ");
+ OutputDebugString(user);
+ OutputDebugString("\n");
+ }
+
+ code = pkrb5_init_context(&ctx);
+ if (code) return 0;
+
+ code = pkrb5_parse_name(ctx, user, &princ);
+ if (code) goto loop_cleanup;
+
+ code = KFW_get_ccache(ctx, princ, &cc);
+ if (code) goto loop_cleanup;
+
+ code = pkrb5_cc_destroy(ctx, cc);
+ if (!code) cc = 0;
+
+ loop_cleanup:
+ if ( cc ) {
+ pkrb5_cc_close(ctx, cc);
+ cc = 0;
+ }
+ if ( princ ) {
+ pkrb5_free_principal(ctx, princ);
+ princ = 0;
+ }
+
+ count = KFW_AFS_find_cells_for_princ(ctx, user, &cells, TRUE);
+ if ( count >= 1 ) {
+ while ( count-- ) {
+ KFW_AFS_update_cell_princ_map(ctx, cells[count], user, FALSE);
+ free(cells[count]);
+ }
+ free(cells);
+ }
+
+ if (ctx)
+ pkrb5_free_context(ctx);
return 0;
}
int
KFW_AFS_renew_expiring_tokens(void)
{
- krb5_error_code code = 0;
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
krb5_timestamp now;
struct principal_ccache_data * pcc_next = princ_cc_data;
int cell_count;
char ** cells=NULL;
const char * realm = NULL;
- char local_cell[MAXCELLCHARS+1]="";
+ char local_cell[CELL_MAXNAMELEN+1]="";
struct afsconf_cell cellconfig;
if (!pkrb5_init_context)
OutputDebugString(realm);
OutputDebugString("\n");
}
- code = KFW_AFS_klog(ctx, cc, "afs", cells[cell_count], (char *)realm, pLeash_get_default_lifetime(),NULL);
+ code = KFW_AFS_klog(ctx, cc, "afs", cells[cell_count], (char *)realm, 0, NULL);
if ( IsDebuggerPresent() ) {
char message[256];
sprintf(message,"KFW_AFS_klog() returns: %d\n",code);
BOOL
KFW_AFS_renew_token_for_cell(char * cell)
{
- krb5_error_code code = 0;
- krb5_context ctx = 0;
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
int count;
char ** principals = NULL;
krb5_ccache cc = 0;
const char * realm = NULL;
struct afsconf_cell cellconfig;
- char local_cell[MAXCELLCHARS+1];
+ char local_cell[CELL_MAXNAMELEN+1];
while ( count-- ) {
code = pkrb5_parse_name(ctx, principals[count], &princ);
}
#endif /* COMMENT */
- code = KFW_AFS_klog(ctx, cc, "afs", cell, (char *)realm, pLeash_get_default_lifetime(),NULL);
+ code = KFW_AFS_klog(ctx, cc, "afs", cell, (char *)realm, 0,NULL);
if ( IsDebuggerPresent() ) {
char message[256];
sprintf(message,"KFW_AFS_klog() returns: %d\n",code);
code = -1; // we did not renew the tokens
cleanup:
- pkrb5_free_context(ctx);
+ if (ctx)
+ pkrb5_free_context(ctx);
return (code ? FALSE : TRUE);
}
int
KFW_renew(krb5_context alt_ctx, krb5_ccache alt_cc)
{
- krb5_error_code code = 0;
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
- krb5_principal me = 0;
- krb5_principal server = 0;
- krb5_creds my_creds;
- krb5_data *realm = 0;
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal me = NULL;
+ krb5_principal server = NULL;
+ krb5_creds my_creds;
+ krb5_data *realm = NULL;
if (!pkrb5_init_context)
return 0;
DWORD publicIP
)
{
- krb5_error_code code = 0;
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
- krb5_principal me = 0;
- char* name = 0;
- krb5_creds my_creds;
+ krb5_error_code code = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal me = NULL;
+ char* name = NULL;
+ krb5_creds my_creds;
krb5_get_init_creds_opt options;
krb5_address ** addrs = NULL;
int i = 0, addr_count = 0;
code = pkrb5_parse_name(ctx, principal_name, &me);
if (code)
- goto cleanup;
+ goto cleanup;
code = pkrb5_unparse_name(ctx, me, &name);
if (code)
- goto cleanup;
+ goto cleanup;
if (lifetime == 0)
+#ifndef USE_LEASH
+ lifetime = 600;
+#else
lifetime = pLeash_get_default_lifetime();
- else
- lifetime *= 5*60;
+#endif /* USE_LEASH */
+ lifetime *= 60;
- if (renew_life > 0)
- renew_life *= 5*60;
+ if (renew_life > 0)
+ renew_life *= 60;
if (lifetime)
pkrb5_get_init_creds_opt_set_tkt_life(&options, lifetime);
if (addressless)
pkrb5_get_init_creds_opt_set_address_list(&options,NULL);
else {
- if (publicIP)
+ if (publicIP)
{
// we are going to add the public IP address specified by the user
// to the list provided by the operating system
0, // service name
&options);
if (code)
- goto cleanup;
+ goto cleanup;
code = pkrb5_cc_initialize(ctx, cc, me);
if (code)
- goto cleanup;
+ goto cleanup;
code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
if (code)
- goto cleanup;
+ goto cleanup;
cleanup:
if ( addrs ) {
int
KFW_kdestroy(krb5_context alt_ctx, krb5_ccache alt_cc)
{
- krb5_context ctx;
- krb5_ccache cc;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
krb5_error_code code;
if (!pkrb5_init_context)
static LPWORD
lpwAlign( LPWORD lpIn )
{
- ULONG ul;
+ ULONG_PTR ul;
- ul = (ULONG) lpIn;
+ ul = (ULONG_PTR) lpIn;
ul += 3;
ul >>=2;
ul <<=2;
lpdit->dwExtendedStyle = 0;
lpdit->x = 10;
lpdit->y = 10 + i * 14;
- lpdit->cx = strlen(ptext[i]) * 4 + 10;
+ lpdit->cx = (short)strlen(ptext[i]) * 4 + 10;
lpdit->cy = 14;
lpdit->id = ID_TEXT + i; // text identifier
}
for ( i=0, pwid = 0; i<tb_cnt; i++) {
- if ( pwid < strlen(tb[i].label) )
- pwid = strlen(tb[i].label);
+ int len = (int)strlen(tb[i].label);
+ if ( pwid < len )
+ pwid = len;
}
for ( i=0; i<tb_cnt; i++) {
static int
multi_field_dialog(HWND hParent, char * preface, int n, struct textField tb[])
{
- HINSTANCE hInst = 0;
+ HINSTANCE hInst = 0;
int maxwidth = 0;
int numlines = 0;
int len;
*p++ = '\0';
}
if ( strlen(plines[numlines-1]) > maxwidth )
- maxwidth = strlen(plines[numlines-1]);
+ maxwidth = (int)strlen(plines[numlines-1]);
}
for ( i=0;i<n;i++ ) {
- len = strlen(tb[i].label) + 1 + (tb[i].len > 40 ? 40 : tb[i].len);
+ len = (int)strlen(tb[i].label) + 1 + (tb[i].len > 40 ? 40 : tb[i].len);
if ( maxwidth < len )
maxwidth = len;
}
- return(MultiInputDialog(hInst, hParent, plines, numlines, maxwidth, n, tb));
+ return(MultiInputDialog(hInst, hParent, plines, numlines, maxwidth, n, tb)?1:0);
}
static krb5_error_code KRB5_CALLCONV
HWND hParent = (HWND)data;
if (name)
- nlen = strlen(name)+2;
+ nlen = (int)strlen(name)+2;
if (banner)
- blen = strlen(banner)+2;
+ blen = (int)strlen(banner)+2;
tb = (struct textField *) malloc(sizeof(struct textField) * num_prompts);
if ( tb != NULL ) {
ok = multi_field_dialog(hParent,(char *)banner,num_prompts,tb);
if ( ok ) {
for ( i=0; i < num_prompts; i++ )
- prompts[i].reply->length = strlen(prompts[i].reply->data);
+ prompts[i].reply->length = (unsigned int)strlen(prompts[i].reply->data);
} else
errcode = -2;
}
struct ktc_principal *aserver,
struct ktc_token *atoken)
{
- static char lastcell[MAXCELLCHARS+1] = { 0 };
- static char confname[512] = { 0 };
+ static char lastcell[CELL_MAXNAMELEN+1] = { 0 };
+ static char confdir[512] = { 0 };
#ifdef AFS_ID_TO_NAME
char username_copy[BUFSIZ];
#endif /* AFS_ID_TO_NAME */
- long viceId; /* AFS uid of user */
+ long viceId = ANONYMOUSID; /* AFS uid of user */
int status = 0;
#ifdef ALLOW_REGISTER
afs_int32 id;
#endif /* ALLOW_REGISTER */
- if (confname[0] == '\0') {
- strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
- confname[sizeof(confname) - 2] = '\0';
- }
-
- /*
- * Talk about DUMB! It turns out that there is a bug in
- * pr_Initialize -- even if you give a different cell name
- * to it, it still uses a connection to a previous AFS server
- * if one exists. The way to fix this is to change the
- * _filename_ argument to pr_Initialize - that forces it to
- * re-initialize the connection. We do this by adding and
- * removing a "/" on the end of the configuration directory name.
- */
-
- if (lastcell[0] != '\0' && (strcmp(lastcell, aserver->cell) != 0)) {
- int i = strlen(confname);
- if (confname[i - 1] == '/') {
- confname[i - 1] = '\0';
- } else {
- confname[i] = '/';
- confname[i + 1] = '\0';
- }
- }
+ if (confdir[0] == '\0')
+ cm_GetConfigDir(confdir, sizeof(confdir));
strcpy(lastcell, aserver->cell);
- if (!pr_Initialize (0, confname, aserver->cell))
- status = pr_SNameToId (username, &viceId);
+ if (!pr_Initialize (0, confdir, aserver->cell)) {
+ char sname[PR_MAXNAMELEN];
+ strncpy(sname, username, PR_MAXNAMELEN);
+ sname[PR_MAXNAMELEN-1] = '\0';
+ status = pr_SNameToId (sname, &viceId);
+ pr_End();
+ }
/*
* This is a crock, but it is Transarc's crock, so
strncpy(aclient->cell, realm_of_user, MAXKTCREALMLEN - 1);
if (status = ktc_SetToken(aserver, atoken, aclient, 0))
return status;
-
- /*
- * In case you're wondering, we don't need to change the
- * filename here because we're still connecting to the
- * same cell -- we're just using a different authentication
- * level
- */
-
- if (status = pr_Initialize(1L, confname, aserver->cell))
- return status;
- if (status = pr_CreateUser(username, &id))
+ if (status = pr_Initialize(1L, confdir, aserver->cell))
return status;
+ status = pr_CreateUser(username, &id);
+ pr_End();
+ if (status)
+ return status;
#ifdef AFS_ID_TO_NAME
strncpy(username_copy, username, BUFSIZ);
snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
}
+static void
+copy_realm_of_ticket(krb5_context context, char * dest, size_t destlen, krb5_creds *v5cred) {
+ krb5_error_code code;
+ krb5_ticket *ticket;
+ size_t len;
+
+ code = pkrb5_decode_ticket(&v5cred->ticket, &ticket);
+ if (code == 0) {
+ len = krb5_princ_realm(context, ticket->server)->length;
+ if (len > destlen - 1)
+ len = destlen - 1;
+
+ strncpy(dest, krb5_princ_realm(context, ticket->server)->data, len);
+ dest[len] = '\0';
+
+ pkrb5_free_ticket(context, ticket);
+ }
+}
+
int
KFW_AFS_klog(
krb5_context alt_ctx,
char *service,
char *cell,
char *realm,
- int LifeTime,
+ int lifetime, /* unused parameter */
char *smbname
)
{
struct ktc_principal aclient;
char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
- char local_cell[MAXCELLCHARS+1];
- char Dmycell[MAXCELLCHARS+1];
+ char local_cell[CELL_MAXNAMELEN+1];
+ char Dmycell[CELL_MAXNAMELEN+1];
struct ktc_token atoken;
struct ktc_token btoken;
struct afsconf_cell ak_cellconfig; /* General information about the cell */
DWORD CurrentState;
char HostName[64];
BOOL try_krb5 = 0;
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
krb5_creds increds;
- krb5_creds * k5creds = 0;
+ krb5_creds * k5creds = NULL;
krb5_error_code code;
- krb5_principal client_principal = 0;
- krb5_data * k5data;
+ krb5_principal client_principal = NULL;
+ krb5_data * k5data = NULL;
int i, retry = 0;
CurrentState = 0;
goto skip_krb5_init;
}
- /* look for client principals which cannot be distinguished
- * from Kerberos 4 multi-component principal names
- */
- k5data = krb5_princ_component(ctx,client_principal,0);
- for ( i=0; i<k5data->length; i++ ) {
- if ( k5data->data[i] == '.' )
- break;
- }
- if (i != k5data->length)
- {
- OutputDebugString("Illegal Principal name contains dot in first component\n");
- rc = KRB5KRB_ERR_GENERIC;
- goto cleanup;
+ if (!KFW_accept_dotted_usernames()) {
+ /* look for client principals which cannot be distinguished
+ * from Kerberos 4 multi-component principal names
+ */
+ k5data = krb5_princ_component(ctx,client_principal,0);
+ for ( i=0; i<k5data->length; i++ ) {
+ if ( k5data->data[i] == '.' )
+ break;
+ }
+ if (i != k5data->length)
+ {
+ OutputDebugString("Illegal Principal name contains dot in first component\n");
+ rc = KRB5KRB_ERR_GENERIC;
+ goto cleanup;
+ }
}
i = krb5_princ_realm(ctx, client_principal)->length;
else
strcpy(CellName, cell);
+ /* This is for Kerberos v4 only */
if (strlen(realm) == 0)
strcpy(RealmName, realm_of_cell);
else
if ( try_krb5 ) {
int len;
+ code = KRB5KRB_ERR_GENERIC;
- /* First try service/cell@REALM */
- if (code = pkrb5_build_principal(ctx, &increds.server,
- strlen(RealmName),
- RealmName,
- ServiceName,
- CellName,
- 0))
- {
- goto cleanup;
- }
increds.client = client_principal;
increds.times.endtime = 0;
/* Ask for DES since that is what V4 understands */
increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
-
- if ( IsDebuggerPresent() ) {
- char * cname, *sname;
- pkrb5_unparse_name(ctx, increds.client, &cname);
- pkrb5_unparse_name(ctx, increds.server, &sname);
- OutputDebugString("Getting tickets for \"");
- OutputDebugString(cname);
- OutputDebugString("\" and service \"");
- OutputDebugString(sname);
- OutputDebugString("\"\n");
- pkrb5_free_unparsed_name(ctx,cname);
- pkrb5_free_unparsed_name(ctx,sname);
- }
-
- code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
- if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
- code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
- code == KRB5KRB_AP_ERR_MSG_TYPE) {
- /* Or service@REALM */
- pkrb5_free_principal(ctx,increds.server);
+ /* If there was a specific realm we are supposed to try
+ * then use it
+ */
+ if (strlen(realm) != 0) {
+ /* service/cell@REALM */
increds.server = 0;
code = pkrb5_build_principal(ctx, &increds.server,
- strlen(RealmName),
- RealmName,
- ServiceName,
- 0);
-
+ (int)strlen(realm),
+ realm,
+ ServiceName,
+ CellName,
+ 0);
if ( IsDebuggerPresent() ) {
char * cname, *sname;
pkrb5_unparse_name(ctx, increds.client, &cname);
pkrb5_unparse_name(ctx, increds.server, &sname);
- OutputDebugString("krb5_get_credentials() returned Service Principal Unknown\n");
- OutputDebugString("Trying again: getting tickets for \"");
+ OutputDebugString("Getting tickets for \"");
OutputDebugString(cname);
OutputDebugString("\" and service \"");
OutputDebugString(sname);
if (!code)
code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
- }
- if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
- code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
- code == KRB5KRB_AP_ERR_MSG_TYPE) &&
- strcmp(RealmName, realm_of_cell)) {
- /* Or service/cell@REALM_OF_CELL */
- strcpy(RealmName, realm_of_cell);
- pkrb5_free_principal(ctx,increds.server);
- increds.server = 0;
- code = pkrb5_build_principal(ctx, &increds.server,
- strlen(RealmName),
- RealmName,
- ServiceName,
- CellName,
- 0);
+ if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+ code == KRB5_ERR_HOST_REALM_UNKNOWN ||
+ code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
+ code == KRB5KRB_AP_ERR_MSG_TYPE) {
+ /* Or service@REALM */
+ pkrb5_free_principal(ctx,increds.server);
+ increds.server = 0;
+ code = pkrb5_build_principal(ctx, &increds.server,
+ (int)strlen(realm),
+ realm,
+ ServiceName,
+ 0);
+
+ if ( IsDebuggerPresent() ) {
+ char * cname, *sname;
+ pkrb5_unparse_name(ctx, increds.client, &cname);
+ pkrb5_unparse_name(ctx, increds.server, &sname);
+ OutputDebugString("krb5_get_credentials() returned Service Principal Unknown\n");
+ OutputDebugString("Trying again: getting tickets for \"");
+ OutputDebugString(cname);
+ OutputDebugString("\" and service \"");
+ OutputDebugString(sname);
+ OutputDebugString("\"\n");
+ pkrb5_free_unparsed_name(ctx,cname);
+ pkrb5_free_unparsed_name(ctx,sname);
+ }
+
+ if (!code)
+ code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+ }
+
+ if (code == 0) {
+ /* we have a local realm for the cell */
+ strcpy(realm_of_cell, realm);
+ }
+ } else {
+ /* Otherwise, first try service/cell@CLIENT_REALM */
+ if (code = pkrb5_build_principal(ctx, &increds.server,
+ (int)strlen(realm_of_user),
+ realm_of_user,
+ ServiceName,
+ CellName,
+ 0))
+ {
+ goto cleanup;
+ }
if ( IsDebuggerPresent() ) {
char * cname, *sname;
pkrb5_unparse_name(ctx, increds.client, &cname);
pkrb5_unparse_name(ctx, increds.server, &sname);
- OutputDebugString("krb5_get_credentials() returned Service Principal Unknown\n");
- OutputDebugString("Trying again: getting tickets for \"");
+ OutputDebugString("Getting tickets for \"");
OutputDebugString(cname);
OutputDebugString("\" and service \"");
OutputDebugString(sname);
pkrb5_free_unparsed_name(ctx,sname);
}
- if (!code)
- code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+ code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+ if (code == 0) {
+ /* The client's realm is a local realm for the cell.
+ * Save it so that later the pts registration will not
+ * be performed.
+ */
+ strcpy(realm_of_cell, realm_of_user);
+ }
-
- if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+ if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+ code == KRB5_ERR_HOST_REALM_UNKNOWN ||
code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
- code == KRB5KRB_AP_ERR_MSG_TYPE) {
- /* Or service@REALM_OF_CELL */
+ code == KRB5KRB_AP_ERR_MSG_TYPE) &&
+ strcmp(realm_of_user, realm_of_cell)) {
+ /* Then service/cell@CELL_REALM */
pkrb5_free_principal(ctx,increds.server);
increds.server = 0;
code = pkrb5_build_principal(ctx, &increds.server,
- strlen(RealmName),
- RealmName,
+ (int)strlen(realm_of_cell),
+ realm_of_cell,
+ ServiceName,
+ CellName,
+ 0);
+ if ( IsDebuggerPresent() ) {
+ char * cname, *sname;
+ pkrb5_unparse_name(ctx, increds.client, &cname);
+ pkrb5_unparse_name(ctx, increds.server, &sname);
+ OutputDebugString("krb5_get_credentials() returned Service Principal Unknown\n");
+ OutputDebugString("Trying again: getting tickets for \"");
+ OutputDebugString(cname);
+ OutputDebugString("\" and service \"");
+ OutputDebugString(sname);
+ OutputDebugString("\"\n");
+ pkrb5_free_unparsed_name(ctx,cname);
+ pkrb5_free_unparsed_name(ctx,sname);
+ }
+
+ if (!code)
+ code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+
+ if (!code && !strlen(realm_of_cell))
+ copy_realm_of_ticket(ctx, realm_of_cell, sizeof(realm_of_cell), k5creds);
+ }
+
+ if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+ code == KRB5_ERR_HOST_REALM_UNKNOWN ||
+ code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
+ code == KRB5KRB_AP_ERR_MSG_TYPE) {
+ /* Finally service@CELL_REALM */
+ pkrb5_free_principal(ctx,increds.server);
+ increds.server = 0;
+ code = pkrb5_build_principal(ctx, &increds.server,
+ (int)strlen(realm_of_cell),
+ realm_of_cell,
ServiceName,
0);
if (!code)
code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
+ if (!code && !strlen(realm_of_cell))
+ copy_realm_of_ticket(ctx, realm_of_cell, sizeof(realm_of_cell), k5creds);
}
}
retry++;
goto retry_gettoken5;
}
- goto try_krb524d;
+ goto cleanup;
}
if (atoken.kvno == btoken.kvno &&
char * p;
strcat(aclient.name, ".");
p = aclient.name + strlen(aclient.name);
- len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
+ len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - (int)strlen(aclient.name) - 1);
strncpy(p, k5creds->client->data[1].data, len);
p[len] = '\0';
}
strcpy(aclient.cell, realm_of_cell);
- len = min(k5creds->client->realm.length,strlen(realm_of_cell));
- if ( strncmp(realm_of_cell, k5creds->client->realm.data, len) ) {
+ len = min(k5creds->client->realm.length,(int)strlen(realm_of_cell));
+ /* For Khimaira, always append the realm name */
+ if ( 1 /* strncmp(realm_of_cell, k5creds->client->realm.data, len) */ ) {
char * p;
strcat(aclient.name, "@");
p = aclient.name + strlen(aclient.name);
- len = min(k5creds->client->realm.length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
+ len = min(k5creds->client->realm.length,MAXKTCNAMELEN - (int)strlen(aclient.name) - 1);
strncpy(p, k5creds->client->realm.data, len);
p[len] = '\0';
}
- ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
- &aclient, &aserver, &atoken);
+ GetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL, 0);
+ if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+ ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
+ &aclient, &aserver, &atoken);
if ( smbname ) {
strncpy(aclient.smbname, smbname, sizeof(aclient.smbname));
goto cleanup; /* We have successfully inserted the token */
try_krb524d:
+#ifndef USE_KRB524
+ goto cleanup;
+#else
/* Otherwise, the ticket could have been too large so try to
* convert using the krb524d running with the KDC
*/
try_krb5 = 0;
goto use_krb4;
}
+#endif /* USE_KRB524 */
} else {
use_krb4:
#ifdef USE_KRB4
}
strcpy(aclient.instance, "");
- if ( strcmp(realm_of_cell, creds.realm) )
- {
- strncat(aclient.name, "@", MAXKTCNAMELEN - 1);
- strncpy(aclient.name, creds.realm, MAXKTCREALMLEN - 1);
- }
+ strncat(aclient.name, "@", MAXKTCNAMELEN - 1);
+ strncat(aclient.name, creds.realm, MAXKTCREALMLEN - 1);
aclient.name[MAXKTCREALMLEN-1] = '\0';
strcpy(aclient.cell, CellName);
- ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
- &aclient, &aserver, &atoken);
+ GetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL, 0);
+ if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+ ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
+ &aclient, &aserver, &atoken);
if ( smbname ) {
strncpy(aclient.smbname, smbname, sizeof(aclient.smbname));
KFW_AFS_get_cellconfig(char *cell, struct afsconf_cell *cellconfig, char *local_cell)
{
int rc;
- char newcell[MAXCELLCHARS+1];
+ char newcell[CELL_MAXNAMELEN+1];
local_cell[0] = (char)0;
memset(cellconfig, 0, sizeof(*cellconfig));
BOOL KFW_probe_kdc(struct afsconf_cell * cellconfig)
{
- krb5_context ctx = 0;
- krb5_ccache cc = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
krb5_error_code code;
krb5_data pwdata;
- const char * realm = 0;
- krb5_principal principal = 0;
- char * pname = 0;
+ const char * realm = NULL;
+ krb5_principal principal = NULL;
+ char * pname = NULL;
char password[PROBE_PASSWORD_LEN+1];
BOOL serverReachable = 0;
realm = afs_realm_of_cell(ctx, cellconfig); // do not free
- code = pkrb5_build_principal(ctx, &principal, strlen(realm),
+ code = pkrb5_build_principal(ctx, &principal, (int)strlen(realm),
realm, PROBE_USERNAME, NULL, NULL);
if ( code ) goto cleanup;
BOOL
KFW_AFS_get_lsa_principal(char * szUser, DWORD *dwSize)
{
- krb5_context ctx = 0;
+ krb5_context ctx = NULL;
krb5_error_code code;
- krb5_ccache mslsa_ccache=0;
- krb5_principal princ = 0;
- char * pname = 0;
+ krb5_ccache mslsa_ccache=NULL;
+ krb5_principal princ = NULL;
+ char * pname = NULL;
BOOL success = 0;
if (!KFW_is_available())
szUser[*dwSize-1] = '\0';
success = 1;
}
- *dwSize = strlen(pname);
+ *dwSize = (DWORD)strlen(pname);
cleanup:
if (pname)
if (ctx)
pkrb5_free_context(ctx);
return success;
-}
\ No newline at end of file
+}
+
+int
+KFW_AFS_set_file_cache_dacl(char *filename, HANDLE hUserToken)
+{
+ // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY;
+ PSID pSystemSID = NULL;
+ DWORD SystemSIDlength = 0, UserSIDlength = 0;
+ PACL ccacheACL = NULL;
+ DWORD ccacheACLlength = 0;
+ PTOKEN_USER pTokenUser = NULL;
+ DWORD retLen;
+ DWORD gle;
+ int ret = 0;
+
+ if (!filename) {
+ return 1;
+ }
+
+ /* Get System SID */
+ if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) {
+ ret = 1;
+ goto cleanup;
+ }
+
+ /* Create ACL */
+ SystemSIDlength = GetLengthSid(pSystemSID);
+ ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
+ + SystemSIDlength - sizeof(DWORD);
+
+ if (hUserToken) {
+ if (!GetTokenInformation(hUserToken, TokenUser, NULL, 0, &retLen))
+ {
+ if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
+ pTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
+
+ GetTokenInformation(hUserToken, TokenUser, pTokenUser, retLen, &retLen);
+ }
+ }
+
+ if (pTokenUser) {
+ UserSIDlength = GetLengthSid(pTokenUser->User.Sid);
+
+ ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength
+ - sizeof(DWORD);
+ }
+ }
+
+ ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength);
+ if (!ccacheACL) {
+ ret = 1;
+ goto cleanup;
+ }
+ InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION);
+ AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,
+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
+ pSystemSID);
+ if (pTokenUser) {
+ AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,
+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
+ pTokenUser->User.Sid);
+ if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
+ NULL,
+ NULL,
+ ccacheACL,
+ NULL)) {
+ gle = GetLastError();
+ if (gle != ERROR_NO_TOKEN)
+ ret = 1;
+ }
+ if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION,
+ pTokenUser->User.Sid,
+ NULL,
+ NULL,
+ NULL)) {
+ gle = GetLastError();
+ if (gle != ERROR_NO_TOKEN)
+ ret = 1;
+ }
+ } else {
+ if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
+ NULL,
+ NULL,
+ ccacheACL,
+ NULL)) {
+ gle = GetLastError();
+ if (gle != ERROR_NO_TOKEN)
+ ret = 1;
+ }
+ }
+
+ cleanup:
+ if (pSystemSID)
+ LocalFree(pSystemSID);
+ if (pTokenUser)
+ LocalFree(pTokenUser);
+ if (ccacheACL)
+ LocalFree(ccacheACL);
+ return ret;
+}
+
+int
+KFW_AFS_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size)
+{
+ int retval = 0;
+ DWORD dwSize = size-1; /* leave room for nul */
+ DWORD dwLen = 0;
+
+ if (!hUserToken || !newfilename || size <= 0)
+ return 1;
+
+ *newfilename = '\0';
+
+ dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TEMP%", newfilename, dwSize);
+ if ( !dwLen || dwLen > dwSize )
+ dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TMP%", newfilename, dwSize);
+ if ( !dwLen || dwLen > dwSize )
+ return 1;
+
+ newfilename[dwSize] = '\0';
+ return 0;
+}
+
+void
+KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId)
+{
+ char filename[MAX_PATH] = "";
+ DWORD count;
+ char cachename[MAX_PATH + 8] = "FILE:";
+ krb5_context ctx = NULL;
+ krb5_error_code code;
+ krb5_principal princ = NULL;
+ krb5_ccache cc = NULL;
+ krb5_ccache ncc = NULL;
+
+ if (!pkrb5_init_context || !user || !szLogonId)
+ return;
+
+ count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
+ if ( count > sizeof(filename) || count == 0 ) {
+ GetWindowsDirectory(filename, sizeof(filename));
+ }
+
+ if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) )
+ return;
+
+ strcat(filename, "\\");
+ strcat(filename, szLogonId);
+
+ strcat(cachename, filename);
+
+ DeleteFile(filename);
+
+ code = pkrb5_init_context(&ctx);
+ if (code) goto cleanup;
+
+ code = pkrb5_parse_name(ctx, user, &princ);
+ if (code) goto cleanup;
+
+ code = KFW_get_ccache(ctx, princ, &cc);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_resolve(ctx, cachename, &ncc);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_initialize(ctx, ncc, princ);
+ if (code) goto cleanup;
+
+ code = KFW_AFS_set_file_cache_dacl(filename, NULL);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_copy_creds(ctx,cc,ncc);
+
+ cleanup:
+ if ( cc ) {
+ pkrb5_cc_close(ctx, cc);
+ cc = 0;
+ }
+ if ( ncc ) {
+ pkrb5_cc_close(ctx, ncc);
+ ncc = 0;
+ }
+ if ( princ ) {
+ pkrb5_free_principal(ctx, princ);
+ princ = 0;
+ }
+
+ if (ctx)
+ pkrb5_free_context(ctx);
+}
+
+int
+KFW_AFS_copy_file_cache_to_default_cache(char * filename)
+{
+ char cachename[MAX_PATH + 8] = "FILE:";
+ krb5_context ctx = NULL;
+ krb5_error_code code;
+ krb5_principal princ = NULL;
+ krb5_ccache cc = NULL;
+ krb5_ccache ncc = NULL;
+ int retval = 1;
+
+ if (!pkrb5_init_context || !filename)
+ return 1;
+
+ if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) )
+ return 1;
+
+ code = pkrb5_init_context(&ctx);
+ if (code) return 1;
+
+ strcat(cachename, filename);
+
+ code = pkrb5_cc_resolve(ctx, cachename, &cc);
+ if (code) goto cleanup;
+
+ code = pkrb5_cc_get_principal(ctx, cc, &princ);
+
+ code = pkrb5_cc_default(ctx, &ncc);
+ if (!code) {
+ code = pkrb5_cc_initialize(ctx, ncc, princ);
+
+ if (!code)
+ code = pkrb5_cc_copy_creds(ctx,cc,ncc);
+ }
+ if ( ncc ) {
+ pkrb5_cc_close(ctx, ncc);
+ ncc = 0;
+ }
+
+ retval=0; /* success */
+
+ cleanup:
+ if ( cc ) {
+ pkrb5_cc_close(ctx, cc);
+ cc = 0;
+ }
+
+ DeleteFile(filename);
+
+ if ( princ ) {
+ pkrb5_free_principal(ctx, princ);
+ princ = 0;
+ }
+
+ if (ctx)
+ pkrb5_free_context(ctx);
+
+ return 0;
+}
+
+/* We are including this
+
+/* Ticket lifetime. This defines the table used to lookup lifetime for the
+ fixed part of rande of the one byte lifetime field. Values less than 0x80
+ are intrpreted as the number of 5 minute intervals. Values from 0x80 to
+ 0xBF should be looked up in this table. The value of 0x80 is the same using
+ both methods: 10 and two-thirds hours . The lifetime of 0xBF is 30 days.
+ The intervening values of have a fixed ratio of roughly 1.06914. The value
+ oxFF is defined to mean a ticket has no expiration time. This should be
+ used advisedly since individual servers may impose defacto upperbounds on
+ ticket lifetimes. */
+
+#define TKTLIFENUMFIXED 64
+#define TKTLIFEMINFIXED 0x80
+#define TKTLIFEMAXFIXED 0xBF
+#define TKTLIFENOEXPIRE 0xFF
+#define MAXTKTLIFETIME (30*24*3600) /* 30 days */
+
+static const int tkt_lifetimes[TKTLIFENUMFIXED] = {
+ 38400, /* 10.67 hours, 0.44 days */
+ 41055, /* 11.40 hours, 0.48 days */
+ 43894, /* 12.19 hours, 0.51 days */
+ 46929, /* 13.04 hours, 0.54 days */
+ 50174, /* 13.94 hours, 0.58 days */
+ 53643, /* 14.90 hours, 0.62 days */
+ 57352, /* 15.93 hours, 0.66 days */
+ 61318, /* 17.03 hours, 0.71 days */
+ 65558, /* 18.21 hours, 0.76 days */
+ 70091, /* 19.47 hours, 0.81 days */
+ 74937, /* 20.82 hours, 0.87 days */
+ 80119, /* 22.26 hours, 0.93 days */
+ 85658, /* 23.79 hours, 0.99 days */
+ 91581, /* 25.44 hours, 1.06 days */
+ 97914, /* 27.20 hours, 1.13 days */
+ 104684, /* 29.08 hours, 1.21 days */
+ 111922, /* 31.09 hours, 1.30 days */
+ 119661, /* 33.24 hours, 1.38 days */
+ 127935, /* 35.54 hours, 1.48 days */
+ 136781, /* 37.99 hours, 1.58 days */
+ 146239, /* 40.62 hours, 1.69 days */
+ 156350, /* 43.43 hours, 1.81 days */
+ 167161, /* 46.43 hours, 1.93 days */
+ 178720, /* 49.64 hours, 2.07 days */
+ 191077, /* 53.08 hours, 2.21 days */
+ 204289, /* 56.75 hours, 2.36 days */
+ 218415, /* 60.67 hours, 2.53 days */
+ 233517, /* 64.87 hours, 2.70 days */
+ 249664, /* 69.35 hours, 2.89 days */
+ 266926, /* 74.15 hours, 3.09 days */
+ 285383, /* 79.27 hours, 3.30 days */
+ 305116, /* 84.75 hours, 3.53 days */
+ 326213, /* 90.61 hours, 3.78 days */
+ 348769, /* 96.88 hours, 4.04 days */
+ 372885, /* 103.58 hours, 4.32 days */
+ 398668, /* 110.74 hours, 4.61 days */
+ 426234, /* 118.40 hours, 4.93 days */
+ 455705, /* 126.58 hours, 5.27 days */
+ 487215, /* 135.34 hours, 5.64 days */
+ 520904, /* 144.70 hours, 6.03 days */
+ 556921, /* 154.70 hours, 6.45 days */
+ 595430, /* 165.40 hours, 6.89 days */
+ 636601, /* 176.83 hours, 7.37 days */
+ 680618, /* 189.06 hours, 7.88 days */
+ 727680, /* 202.13 hours, 8.42 days */
+ 777995, /* 216.11 hours, 9.00 days */
+ 831789, /* 231.05 hours, 9.63 days */
+ 889303, /* 247.03 hours, 10.29 days */
+ 950794, /* 264.11 hours, 11.00 days */
+ 1016537, /* 282.37 hours, 11.77 days */
+ 1086825, /* 301.90 hours, 12.58 days */
+ 1161973, /* 322.77 hours, 13.45 days */
+ 1242318, /* 345.09 hours, 14.38 days */
+ 1328218, /* 368.95 hours, 15.37 days */
+ 1420057, /* 394.46 hours, 16.44 days */
+ 1518247, /* 421.74 hours, 17.57 days */
+ 1623226, /* 450.90 hours, 18.79 days */
+ 1735464, /* 482.07 hours, 20.09 days */
+ 1855462, /* 515.41 hours, 21.48 days */
+ 1983758, /* 551.04 hours, 22.96 days */
+ 2120925, /* 589.15 hours, 24.55 days */
+ 2267576, /* 629.88 hours, 26.25 days */
+ 2424367, /* 673.44 hours, 28.06 days */
+ 2592000
+}; /* 720.00 hours, 30.00 days */
+
+/* life_to_time - takes a start time and a Kerberos standard lifetime char and
+ * returns the corresponding end time. There are four simple cases to be
+ * handled. The first is a life of 0xff, meaning no expiration, and results in
+ * an end time of 0xffffffff. The second is when life is less than the values
+ * covered by the table. In this case, the end time is the start time plus the
+ * number of 5 minute intervals specified by life. The third case returns
+ * start plus the MAXTKTLIFETIME if life is greater than TKTLIFEMAXFIXED. The
+ * last case, uses the life value (minus TKTLIFEMINFIXED) as an index into the
+ * table to extract the lifetime in seconds, which is added to start to produce
+ * the end time. */
+
+afs_uint32
+life_to_time(afs_uint32 start, unsigned char life)
+{
+ int realLife;
+
+ if (life == TKTLIFENOEXPIRE)
+ return NEVERDATE;
+ if (life < TKTLIFEMINFIXED)
+ return start + life * 5 * 60;
+ if (life > TKTLIFEMAXFIXED)
+ return start + MAXTKTLIFETIME;
+ realLife = tkt_lifetimes[life - TKTLIFEMINFIXED];
+ return start + realLife;
+}
+
+/* time_to_life - takes start and end times for the ticket and returns a
+ * Kerberos standard lifetime char possibily using the tkt_lifetimes table for
+ * lifetimes above 127*5minutes. First, the special case of (end ==
+ * 0xffffffff) is handled to mean no expiration. Then negative lifetimes and
+ * those greater than the maximum ticket lifetime are rejected. Then lifetimes
+ * less than the first table entry are handled by rounding the requested
+ * lifetime *up* to the next 5 minute interval. The final step is to search
+ * the table for the smallest entry *greater than or equal* to the requested
+ * entry. The actual code is prepared to handle the case where the table is
+ * unordered but that it an unnecessary frill. */
+
+static unsigned char
+time_to_life(afs_uint32 start, afs_uint32 end)
+{
+ int lifetime = end - start;
+ int best, best_i;
+ int i;
+
+ if (end == NEVERDATE)
+ return TKTLIFENOEXPIRE;
+ if ((lifetime > MAXKTCTICKETLIFETIME) || (lifetime <= 0))
+ return 0;
+ if (lifetime < tkt_lifetimes[0])
+ return (lifetime + 5 * 60 - 1) / (5 * 60);
+ best_i = -1;
+ best = MAXKTCTICKETLIFETIME;
+ for (i = 0; i < TKTLIFENUMFIXED; i++)
+ if (tkt_lifetimes[i] >= lifetime) {
+ int diff = tkt_lifetimes[i] - lifetime;
+ if (diff < best) {
+ best = diff;
+ best_i = i;
+ }
+ }
+ if (best_i < 0)
+ return 0;
+ return best_i + TKTLIFEMINFIXED;
+}
+