LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
if ( KFW_is_available() ) {
- char rootcell[MAXCELLCHARS+1];
+ char rootcell[CELL_MAXNAMELEN+1];
#ifdef USE_MS2MIT
KFW_import_windows_lsa();
#endif /* USE_MS2MIT */
{
if (cache && *cache != NULL) {
pkrb5_cc_close(*ctx, *cache);
- *cache = NULL;
- }
+ *cache = NULL;
+ }
pkrb5_free_context(*ctx);
- *ctx = NULL;
+ *ctx = 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;
OutputDebugString("\n");
}
+ memset(&cellconfig, 0, sizeof(cellconfig));
+
code = pkrb5_init_context(&ctx);
if ( code ) goto cleanup;
sprintf(message,"found another cell for the same principal: %s\n",cell);
OutputDebugString(message);
}
+
+ if (cellconfig.linkedCell) {
+ free(cellconfig.linkedCell);
+ cellconfig.linkedCell = NULL;
+ }
code = KFW_AFS_get_cellconfig( cells[cell_count], (void*)&cellconfig, local_cell);
if ( code ) continue;
free(pname);
if ( cc )
pkrb5_cc_close(ctx, cc);
+ if ( cellconfig.linkedCell )
+ free(cellconfig.linkedCell);
if ( code && reasonP ) {
*reasonP = (char *)perror_message(code);
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("KFW_AFS_renew_expiring_tokens\n");
}
+ memset(&cellconfig, 0, sizeof(cellconfig));
+
code = pkrb5_init_context(&ctx);
if (code) goto cleanup;
OutputDebugString(cells[cell_count]);
OutputDebugString("\n");
}
+ if (cellconfig.linkedCell) {
+ free(cellconfig.linkedCell);
+ cellconfig.linkedCell = NULL;
+ }
code = KFW_AFS_get_cellconfig( cells[cell_count], (void*)&cellconfig, local_cell);
if ( code ) continue;
realm = afs_realm_of_cell(ctx, &cellconfig); // do not free
pkrb5_cc_close(ctx,cc);
if ( ctx )
pkrb5_free_context(ctx);
+ if (cellconfig.linkedCell)
+ free(cellconfig.linkedCell);
return 0;
}
krb5_ccache cc = 0;
const char * realm = NULL;
struct afsconf_cell cellconfig;
- char local_cell[MAXCELLCHARS+1];
+ char local_cell[CELL_MAXNAMELEN+1];
+
+ memset(&cellconfig, 0, sizeof(cellconfig));
while ( count-- ) {
code = pkrb5_parse_name(ctx, principals[count], &princ);
code = KFW_get_ccache(ctx, princ, &cc);
if (code) goto loop_cleanup;
+ if (cellconfig.linkedCell) {
+ free(cellconfig.linkedCell);
+ cellconfig.linkedCell = NULL;
+ }
code = KFW_AFS_get_cellconfig( cell, (void*)&cellconfig, local_cell);
if ( code ) goto loop_cleanup;
pkrb5_free_principal(ctx, service);
princ = 0;
}
+ if (cellconfig.linkedCell) {
+ free(cellconfig.linkedCell);
+ cellconfig.linkedCell = NULL;
+ }
KFW_AFS_update_cell_princ_map(ctx, cell, principals[count], code ? FALSE : TRUE);
free(principals[count]);
cleanup:
if (ctx)
- pkrb5_free_context(ctx);
+ pkrb5_free_context(ctx);
return (code ? FALSE : TRUE);
}
struct ktc_principal *aserver,
struct ktc_token *atoken)
{
- static char lastcell[MAXCELLCHARS+1] = { 0 };
+ static char lastcell[CELL_MAXNAMELEN+1] = { 0 };
static char confdir[512] = { 0 };
#ifdef AFS_ID_TO_NAME
char username_copy[BUFSIZ];
}
+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,
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 */
if (!pkrb5_init_context)
return 0;
+ memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));
memset(RealmName, '\0', sizeof(RealmName));
memset(CellName, '\0', sizeof(CellName));
memset(ServiceName, '\0', sizeof(ServiceName));
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,
- (int)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,
- (int)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,
- (int)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,
- (int)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 &&
pkrb5_cc_close(ctx, cc);
if (ctx && (ctx != alt_ctx))
pkrb5_free_context(ctx);
+ if (ak_cellconfig.linkedCell)
+ free(ak_cellconfig.linkedCell);
return(rc? rc : code);
}
KFW_AFS_get_cellconfig(char *cell, struct afsconf_cell *cellconfig, char *local_cell)
{
int rc;
- char newcell[MAXCELLCHARS+1];
+ char newcell[CELL_MAXNAMELEN+1];
+ char linkedcell[CELL_MAXNAMELEN+1]="";
local_cell[0] = (char)0;
memset(cellconfig, 0, sizeof(*cellconfig));
strcpy(cell, local_cell);
/* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
- strcpy(cellconfig->name, cell);
-
- rc = cm_SearchCellFile(cell, newcell, get_cellconfig_callback, (void*)cellconfig);
+ rc = cm_SearchCellFileEx(cell, newcell, linkedcell, get_cellconfig_callback, (void*)cellconfig);
#ifdef AFS_AFSDB_ENV
if (rc != 0) {
int ttl;
rc = cm_SearchCellByDNS(cell, newcell, &ttl, get_cellconfig_callback, (void*)cellconfig);
}
#endif
+
+ if (rc == 0) {
+ strcpy(cellconfig->name, newcell);
+ if (linkedcell[0])
+ cellconfig->linkedCell = strdup(linkedcell);
+ }
return rc;
}