/*
- * Copyright (c) 2004, 2005, 2006 Secure Endpoints Inc.
+ * Copyright (c) 2004, 2005, 2006, 2007 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>
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);
}
+
+int
+KFW_accept_dotted_usernames(void)
+{
+ HKEY parmKey;
+ DWORD code, len;
+ DWORD value = 1;
+
+ code = RegOpenKeyEx(HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY,
+ 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, 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)
{
#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;
}
krb5_principal principal = 0;
char * pname = NULL;
const char * ccname = NULL;
+ const char * cctype = 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;
+
// Search the existing list to see if we have a match
if ( next ) {
for ( ; next ; next = next->next ) {
next->next = princ_cc_data;
princ_cc_data = next;
next->principal = _strdup(pname);
- next->ccache_name = _strdup(ccname);
+ next->ccache_name = malloc(strlen(ccname) + strlen(cctype) + 2);
+ if (next->ccache_name)
+ sprintf(next->ccache_name, "%s:%s", cctype, ccname);
next->from_lsa = lsa;
next->expired = 1;
next->expiration_time = 0;
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;
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 **cells = NULL;
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);
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;
}
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 = 0;
- krb5_error_code code;
+ krb5_context ctx = NULL;
+ krb5_error_code code;
int count;
char ** cells = NULL;
- krb5_principal princ = 0;
- krb5_ccache cc = 0;
+ krb5_principal princ = NULL;
+ krb5_ccache cc = NULL;
if (!pkrb5_init_context)
return 0;
}
code = pkrb5_init_context(&ctx);
- if (code) ctx = 0;
+ if (code) return 0;
code = pkrb5_parse_name(ctx, user, &princ);
if (code) goto loop_cleanup;
free(cells);
}
- pkrb5_free_context(ctx);
+ 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;
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;
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;
goto cleanup;
if (lifetime == 0)
+#ifndef USE_LEASH
+ lifetime = 600;
+#else
lifetime = pLeash_get_default_lifetime();
+#endif /* USE_LEASH */
lifetime *= 60;
if (renew_life > 0)
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)
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;
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
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;
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())
DWORD dwLen = 0;
if (!hUserToken || !newfilename || size <= 0)
- return;
+ return 1;
*newfilename = '\0';
char filename[MAX_PATH] = "";
DWORD count;
char cachename[MAX_PATH + 8] = "FILE:";
- krb5_context ctx = 0;
+ krb5_context ctx = NULL;
krb5_error_code code;
- krb5_principal princ = 0;
- krb5_ccache cc = 0;
- krb5_ccache ncc = 0;
+ krb5_principal princ = NULL;
+ krb5_ccache cc = NULL;
+ krb5_ccache ncc = NULL;
if (!pkrb5_init_context || !user || !szLogonId)
return;
DeleteFile(filename);
code = pkrb5_init_context(&ctx);
- if (code) ctx = 0;
+ if (code) goto cleanup;
code = pkrb5_parse_name(ctx, user, &princ);
if (code) goto cleanup;
KFW_AFS_copy_file_cache_to_default_cache(char * filename)
{
char cachename[MAX_PATH + 8] = "FILE:";
- krb5_context ctx = 0;
+ krb5_context ctx = NULL;
krb5_error_code code;
- krb5_principal princ = 0;
- krb5_ccache cc = 0;
- krb5_ccache ncc = 0;
+ krb5_principal princ = NULL;
+ krb5_ccache cc = NULL;
+ krb5_ccache ncc = NULL;
int retval = 1;
if (!pkrb5_init_context || !filename)
if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) )
return 1;
- strcat(cachename, filename);
-
code = pkrb5_init_context(&ctx);
- if (code) ctx = 0;
+ if (code) return 1;
+
+ strcat(cachename, filename);
code = pkrb5_cc_resolve(ctx, cachename, &cc);
if (code) goto cleanup;