#include <osilog.h>
#include <rxkad_prototypes.h> /* for life_to_time */
+#include <afs/ptserver.h>
/*
* TIMING _____________________________________________________________________
static char OpenAFSConfigKeyName[] = "SOFTWARE\\OpenAFS\\Client";
+int
+KFW_use_krb524(void)
+{
+ HKEY parmKey;
+ DWORD code, len;
+ DWORD use524 = 0;
+
+ code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(use524);
+ code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
+ (BYTE *) &use524, &len);
+ RegCloseKey(parmKey);
+ }
+ if (code != ERROR_SUCCESS) {
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(use524);
+ code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
+ (BYTE *) &use524, &len);
+ RegCloseKey (parmKey);
+ }
+ }
+ return use524;
+}
+
int
KFW_is_available(void)
{
HKEY parmKey;
- DWORD code, len;
+ DWORD code, len;
DWORD enableKFW = 1;
code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName,
0, KEY_QUERY_VALUE, &parmKey);
- if (code != ERROR_SUCCESS)
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
- 0, KEY_QUERY_VALUE, &parmKey);
- if (code == ERROR_SUCCESS) {
+ if (code == ERROR_SUCCESS) {
len = sizeof(enableKFW);
code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
(BYTE *) &enableKFW, &len);
- if (code != ERROR_SUCCESS) {
- enableKFW = 1;
- }
RegCloseKey (parmKey);
- }
+ }
+
+ if (code != ERROR_SUCCESS) {
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(enableKFW);
+ code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
+ (BYTE *) &enableKFW, &len);
+ RegCloseKey (parmKey);
+ }
+ }
if ( !enableKFW )
return FALSE;
princ_realm = krb5_princ_realm(ctx, princ);
for ( i=0; i<princ_realm->length; i++ ) {
- realm[i] = princ_realm->data[i];
+ realm[i] = princ_realm->data[i];
cell[i] = tolower(princ_realm->data[i]);
}
- cell[i] = '\0';
- realm[i] = '\0';
+ cell[i] = '\0';
+ realm[i] = '\0';
code = KFW_AFS_klog(ctx, cc, "afs", cell, realm, pLeash_get_default_lifetime(),NULL);
if ( IsDebuggerPresent() ) {
if ( lifetime == 0 )
lifetime = pLeash_get_default_lifetime();
- code = KFW_kinit(ctx, cc, HWND_DESKTOP,
- pname,
- password,
- lifetime,
- 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());
- if ( IsDebuggerPresent() ) {
- char message[256];
- sprintf(message,"KFW_kinit() returns: %d\n",code);
- OutputDebugString(message);
+ if ( password && password[0] ) {
+ code = KFW_kinit( ctx, cc, HWND_DESKTOP,
+ pname,
+ password,
+ lifetime,
+ 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());
+ if ( IsDebuggerPresent() ) {
+ char message[256];
+ sprintf(message,"KFW_kinit() returns: %d\n",code);
+ OutputDebugString(message);
+ }
+ if ( code ) goto cleanup;
+
+ KFW_AFS_update_princ_ccache_data(ctx, cc, FALSE);
}
- if ( code ) goto cleanup;
-
- KFW_AFS_update_princ_ccache_data(ctx, cc, FALSE);
code = KFW_AFS_klog(ctx, cc, "afs", cell, realm, lifetime,smbname);
if ( IsDebuggerPresent() ) {
return(0);
}
+
+#define ALLOW_REGISTER 1
+static int
+ViceIDToUsername(char *username,
+ char *realm_of_user,
+ char *realm_of_cell,
+ char * cell_to_use,
+ struct ktc_principal *aclient,
+ struct ktc_principal *aserver,
+ struct ktc_token *atoken)
+{
+ static char lastcell[MAXCELLCHARS+1] = { 0 };
+ static char confname[512] = { 0 };
+ char username_copy[BUFSIZ];
+ long viceId; /* 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';
+ }
+ }
+
+ strcpy(lastcell, aserver->cell);
+
+ if (!pr_Initialize (0, confname, aserver->cell))
+ status = pr_SNameToId (username, &viceId);
+
+ /*
+ * This is a crock, but it is Transarc's crock, so
+ * we have to play along in order to get the
+ * functionality. The way the afs id is stored is
+ * as a string in the username field of the token.
+ * Contrary to what you may think by looking at
+ * the code for tokens, this hack (AFS ID %d) will
+ * not work if you change %d to something else.
+ */
+
+ /*
+ * This code is taken from cklog -- it lets people
+ * automatically register with the ptserver in foreign cells
+ */
+
+#ifdef ALLOW_REGISTER
+ if (status == 0) {
+ if (viceId != ANONYMOUSID) {
+#else /* ALLOW_REGISTER */
+ if ((status == 0) && (viceId != ANONYMOUSID))
+#endif /* ALLOW_REGISTER */
+ {
+#ifdef AFS_ID_TO_NAME
+ strncpy(username_copy, username, BUFSIZ);
+ snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
+#endif /* AFS_ID_TO_NAME */
+ }
+#ifdef ALLOW_REGISTER
+ } else if (strcmp(realm_of_user, realm_of_cell) != 0) {
+ id = 0;
+ strncpy(aclient->name, username, MAXKTCNAMELEN - 1);
+ strcpy(aclient->instance, "");
+ 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, 0))
+ return status;
+ if (status = pr_CreateUser(username, &id))
+ return status;
+#ifdef AFS_ID_TO_NAME
+ strncpy(username_copy, username, BUFSIZ);
+ snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
+#endif /* AFS_ID_TO_NAME */
+ }
+ }
+#endif /* ALLOW_REGISTER */
+ return status;
+}
+
+
int
KFW_AFS_klog(
krb5_context alt_ctx,
memset(ServiceName, '\0', sizeof(ServiceName));
memset(realm_of_user, '\0', sizeof(realm_of_user));
memset(realm_of_cell, '\0', sizeof(realm_of_cell));
- if (cell && cell[0])
- strcpy(Dmycell, cell);
- else
- memset(Dmycell, '\0', sizeof(Dmycell));
+ if (cell && cell[0])
+ strcpy(Dmycell, cell);
+ else
+ memset(Dmycell, '\0', sizeof(Dmycell));
// NULL or empty cell returns information on local cell
if (rc = KFW_AFS_get_cellconfig(Dmycell, &ak_cellconfig, local_cell))
memset((char *)&increds, 0, sizeof(increds));
code = pkrb5_cc_get_principal(ctx, cc, &client_principal);
- if (code) {
+ if (code) {
if ( code == KRB5_CC_NOTFOUND && IsDebuggerPresent() )
{
OutputDebugString("Principal Not Found for ccache\n");
}
goto skip_krb5_init;
}
+
+ if ( strchr(krb5_princ_component(ctx,client_principal,0),'.') != NULL )
+ {
+ OutputDebugString("Illegal Principal name contains dot in first component\n");
+ rc = KRB5KRB_ERR_GENERIC;
+ goto cleanup;
+ }
+
i = krb5_princ_realm(ctx, client_principal)->length;
if (i > REALM_SZ-1)
i = REALM_SZ-1;
* No need to perform a krb524 translation which is
* commented out in the code below
*/
- if (k5creds->ticket.length > MAXKTCTICKETLEN)
+ if (KFW_use_krb524() ||
+ k5creds->ticket.length > MAXKTCTICKETLEN)
goto try_krb524d;
memset(&aserver, '\0', sizeof(aserver));
p[len] = '\0';
}
+ ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
+ &aclient, &aserver, &atoken);
+
if ( smbname ) {
- strncpy(aclient.smbname, smbname, MAXRANDOMNAMELEN);
- aclient.smbname[MAXRANDOMNAMELEN-1] = '\0';
+ strncpy(aclient.smbname, smbname, sizeof(aclient.smbname));
+ aclient.smbname[sizeof(aclient.smbname)-1] = '\0';
} else {
aclient.smbname[0] = '\0';
}
- rc = ktc_SetToken(&aserver, &atoken, &aclient, 0);
+ rc = ktc_SetToken(&aserver, &atoken, &aclient, (aclient.smbname[0]?AFS_SETTOK_LOGON:0));
if (!rc)
goto cleanup; /* We have successfully inserted the token */
strcpy(aclient.cell, CellName);
+ ViceIDToUsername(aclient.name, realm_of_user, realm_of_cell, CellName,
+ &aclient, &aserver, &atoken);
+
if ( smbname ) {
- strncpy(aclient.smbname, smbname, MAXRANDOMNAMELEN);
- aclient.smbname[MAXRANDOMNAMELEN-1] = '\0';
+ strncpy(aclient.smbname, smbname, sizeof(aclient.smbname));
+ aclient.smbname[sizeof(aclient.smbname)-1] = '\0';
} else {
aclient.smbname[0] = '\0';
}
- if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0))
+ if (rc = ktc_SetToken(&aserver, &atoken, &aclient, (aclient.smbname[0]?AFS_SETTOK_LOGON:0)))
{
KFW_AFS_error(rc, "ktc_SetToken()");
code = rc;