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);
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;
}
struct afsconf_cell cellconfig;
char local_cell[CELL_MAXNAMELEN+1];
+ memset(&cellconfig, 0, sizeof(cellconfig));
+
while ( count-- ) {
code = pkrb5_parse_name(ctx, principals[count], &princ);
if (code) goto loop_cleanup;
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);
}
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));
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);
}
{
int rc;
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;
}
rock.cellp = cp;
rock.flags = flags;
- code = cm_SearchCellFile(cp->name, NULL, cm_AddCellProc, &rock);
+ code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
if (code == 0) {
lock_ObtainMutex(&cp->mx);
cp->timeout = time(0) + 7200;
cm_cell_t *cp, *cp2;
long code;
char fullname[CELL_MAXNAMELEN]="";
+ char linkedName[CELL_MAXNAMELEN]="";
char name[CELL_MAXNAMELEN]="";
int hasWriteLock = 0;
int hasMutex = 0;
rock.cellp = cp;
rock.flags = flags;
- code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, &rock);
+ code = cm_SearchCellFileEx(namep, fullname, linkedName, cm_AddCellProc, &rock);
if (code) {
- osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s",
- osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname));
+ osi_Log4(afsd_logp,"in cm_GetCell_gen cm_SearchCellFileEx(%s) returns code= %d fullname= %s linkedName= %s",
+ osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname),
+ osi_LogSaveString(afsd_logp,linkedName));
#ifdef AFS_AFSDB_ENV
if (cm_dnsEnabled) {
strncpy(cp->name, fullname, CELL_MAXNAMELEN);
cp->name[CELL_MAXNAMELEN-1] = '\0';
+ strncpy(cp->linkedName, linkedName, CELL_MAXNAMELEN);
+ cp->linkedName[CELL_MAXNAMELEN-1] = '\0';
+
cm_AddCellToNameHashTable(cp);
cm_AddCellToIDHashTable(cp);
lock_ReleaseMutex(&cp->mx);
newnamep[0] = '\0';
}
}
+
+ if (cp && cp->linkedName[0]) {
+ cm_cell_t * linkedCellp = NULL;
+
+ if (!strcmp(cp->name, cp->linkedName)) {
+ cp->linkedName[0] = '\0';
+ } else if (!(flags & CM_FLAG_NOMOUNTCHASE)) {
+ linkedCellp = cm_GetCell(cp->linkedName, CM_FLAG_CREATE|CM_FLAG_NOPROBE|CM_FLAG_NOMOUNTCHASE);
+
+ lock_ObtainWrite(&cm_cellLock);
+ if (!linkedCellp ||
+ (linkedCellp->linkedName[0] && strcmp(cp->name, linkedCellp->linkedName))) {
+ cp->linkedName[0] = '\0';
+ } else {
+ strncpy(linkedCellp->linkedName, cp->name, CELL_MAXNAMELEN);
+ linkedCellp->linkedName[CELL_MAXNAMELEN-1]='\0';
+ }
+ lock_ReleaseWrite(&cm_cellLock);
+ }
+ }
return cp;
}
osi_mutex_t mx; /* mutex locking fields (flags) */
long flags; /* locked by mx */
time_t timeout; /* if dns, time at which the server addrs expire (mx) */
+ char linkedName[CELL_MAXNAMELEN]; /* linked cell name; cm_cellLock */
} cm_cell_t;
/* These are bit flag values */
* newCellNamep. Anomaly: if cellNamep is ambiguous, we may modify
* newCellNamep but return an error code.
*
- * newCellNamep is required to be CELL_MAXNAMELEN in size.
+ * Linked Cells: the CellServDB format permits linked cells
+ * >cell [linked-cell] #Description
+ *
+ * newCellNamep and linkedNamep are required to be CELL_MAXNAMELEN in size.
*/
long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
cm_configProc_t *procp, void *rockp)
{
+ return cm_SearchCellFileEx(cellNamep, newCellNamep, NULL, procp, rockp);
+}
+
+long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
+ char *linkedNamep,
+ cm_configProc_t *procp, void *rockp)
+{
char wdir[MAX_PATH]="";
FILE *tfilep = NULL, *bestp, *tempp;
- char *tp;
+ char *tp, *linkp;
char lineBuffer[257];
struct hostent *thp;
char *valuep;
#endif
/* have we seen the cell line for the guy we're looking for? */
while (1) {
+ linkp = NULL;
tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
if (tracking)
(void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
/* skip blank lines */
if (lineBuffer[0] == 0) continue;
+ /*
+ * The format is:
+ * >[cell] [linked-cell] #[Description]
+ * where linked-cell and Description are optional
+ */
if (lineBuffer[0] == '>') {
if (inRightCell) {
fclose(tfilep);
return(foundCell ? 0 : -6);
}
- /* trim off at white space or '#' chars */
- tp = strchr(lineBuffer, ' ');
- if (tp) *tp = 0;
- tp = strchr(lineBuffer, '\t');
- if (tp) *tp = 0;
- tp = strchr(lineBuffer, '#');
- if (tp) *tp = 0;
+ /*
+ * terminate the cellname at the first white space
+ * leaving 'tp' pointing to the next string if any
+ */
+ for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
+ if (tp) {
+ *tp = '\0';
+ for (tp++ ;tp && isspace(*tp); tp++);
+ if (*tp != '#') {
+ linkp = tp;
+ for (; tp && !isspace(*tp); tp++);
+ if (tp)
+ *tp = '\0';
+ }
+ }
/* now see if this is the right cell */
if (stricmp(lineBuffer+1, cellNamep) == 0) {
newCellNamep[CELL_MAXNAMELEN-1] = '\0';
strlwr(newCellNamep);
}
+ if (linkedNamep) {
+ strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
+ linkedNamep[CELL_MAXNAMELEN-1] = '\0';
+ strlwr(linkedNamep);
+ }
inRightCell = 1;
tracking = 0;
#ifdef CELLSERV_DEBUG
newCellNamep[CELL_MAXNAMELEN-1] = '\0';
strlwr(newCellNamep);
}
+ if (linkedNamep) {
+ strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
+ linkedNamep[CELL_MAXNAMELEN-1] = '\0';
+ strlwr(linkedNamep);
+ }
inRightCell = 0;
tracking = 0;
partial = 1;
extern long cm_GetRootCellName(char *namep);
extern long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
- cm_configProc_t *procp, void *rockp);
+ cm_configProc_t *procp, void *rockp);
+
+extern long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
+ char *linkedNamep,
+ cm_configProc_t *procp, void *rockp);
extern long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
- cm_configProc_t *procp, void *rockp);
+ cm_configProc_t *procp, void *rockp);
extern long cm_WriteConfigString(char *labelp, char *valuep);
rock.cellp = cp;
rock.flags = 0;
- code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, &rock);
+ code = cm_SearchCellFileEx(cp->name, cp->name, cp->linkedName, cm_AddCellProc, &rock);
#ifdef AFS_AFSDB_ENV
if (code) {
if (cm_dnsEnabled) {
int i;
char * p, * r;
+ memset(&info, 0, sizeof(info));
tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
code = afsconf_GetCellInfo(tdir, ucellp->cellp->name, "afsprot", &info);
afsconf_Close(tdir);
code = ubik_ClientInit(serverconns, &pruclient);
if (code) {
+ if (info.linkedCell)
+ free(info.linkedCell);
return code;
}
pruclient = NULL;
}
+ if (info.linkedCell)
+ free(info.linkedCell);
return 0;
}
#endif /* QUERY_AFSID */
/* otherwise, we didn't find it so consult the VLDB */
sprintf(volNameString, "%u", volumeID);
code = cm_FindVolumeByName(cellp, volNameString, userp, reqp,
- flags, outVolpp);
+ flags | CM_GETVOL_FLAG_IGNORE_LINKED_CELL, outVolpp);
+
+ if (code == CM_ERROR_NOSUCHVOLUME && cellp->linkedName[0] &&
+ !(flags & CM_GETVOL_FLAG_IGNORE_LINKED_CELL)) {
+ cm_cell_t *linkedCellp = cm_GetCell(cellp->linkedName, flags);
+
+ if (linkedCellp)
+ code = cm_FindVolumeByID(linkedCellp, volumeID, userp, reqp, flags, outVolpp);
+ }
return code;
}
cm_PutVolume(volp);
lock_ReleaseRead(&cm_volumeLock);
}
+
+ if (code == CM_ERROR_NOSUCHVOLUME && cellp->linkedName[0] &&
+ !(flags & CM_GETVOL_FLAG_IGNORE_LINKED_CELL)) {
+ cm_cell_t *linkedCellp = cm_GetCell(cellp->linkedName, flags);
+
+ if (linkedCellp)
+ code = cm_FindVolumeByName(linkedCellp, volumeNamep, userp, reqp, flags, outVolpp);
+ }
return code;
}
#define CM_GETVOL_FLAG_CREATE 1
#define CM_GETVOL_FLAG_NO_LRU_UPDATE 2
#define CM_GETVOL_FLAG_NO_RESET 4
+#define CM_GETVOL_FLAG_IGNORE_LINKED_CELL 8
/* hash define. Must not include the cell, since the callback revocation code
* doesn't necessarily know the cell in the case of a multihomed server
struct ViceIoctl blob;
char * parent;
+ memset(&info, 0, sizeof(info));
+
if (as->parms[2].items) /* cell name specified */
cellName = as->parms[2].items->data;
else
#else /* not WIN32 */
code = symlink(space, path);
#endif /* not WIN32 */
+
+ if (info.linkedCell)
+ free(info.linkedCell);
+
if (code) {
Die(errno, path);
return 1;
struct afsconf_cell info;
struct chservinfo checkserv;
+ memset(&info, 0, sizeof(info));
memset(&checkserv, 0, sizeof(struct chservinfo));
blob.in_size=sizeof(struct chservinfo);
blob.in=(caddr_t)&checkserv;
}
strcpy(checkserv.tbuffer,info.name);
checkserv.tsize=(int)strlen(info.name)+1;
+ if (info.linkedCell)
+ free(info.linkedCell);
} else {
strcpy(checkserv.tbuffer,"\0");
checkserv.tsize=0;
} args;
int error = 0;
+ memset(&info, 0, sizeof(info));
memset(&args, 0, sizeof(args)); /* avoid Purify UMR error */
for(ti=as->parms[0].items; ti; ti=ti->next) {
/* once per cell */
error = 1;
continue;
}
+ if (info.linkedCell)
+ free(info.linkedCell);
blob.in_size = 1+(long)strlen(info.name);
blob.in = info.name;
code = pioctl_utf8(0, VIOC_GETCELLSTATUS, &blob, 1);
} args;
int error = 0;
+ memset(&info, 0, sizeof(info));
+
/* Check arguments. */
if (as->parms[1].items && as->parms[2].items) {
fprintf(stderr, "Cannot specify both -suid and -nosuid.\n");
error = 1;
continue;
}
+ if (info.linkedCell)
+ free(info.linkedCell);
strcpy(args.cname, info.name);
blob.in_size = sizeof(args);
blob.in = (caddr_t) &args;
afs_uuid_create @17
afs_uuid_equal @18
cm_GetCellServDB @19
+ cm_SearchCellFileEx @20
pp.host.retry = 0;
pp.verbose = 1;
- /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
+ /* WIN32: cm_SearchCellFile(cell, newcell, linkedCell, pcallback, pdata) */
rc = pcm_SearchCellFile(cell, newcell, pingFS, (void *)&pp);
}
#endif /* USE_FSPROBE */
if ( !cell ) cell = "";
if ( !service ) service = "";
+ memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));
memset(RealmName, '\0', sizeof(RealmName));
memset(CellName, '\0', sizeof(CellName));
memset(ServiceName, '\0', sizeof(ServiceName));
_reportf(L"Same token already exists");
- return 0;
+ rc = 0;
+ goto cleanup;
}
// * Reset the "aclient" structure before we call ktc_SetToken.
if (context)
pkrb5_free_context(context);
- return 0;
+ goto cleanup;
}
_reportf(L"SetToken returns code %d", rc);
!memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) {
/* success! */
- return(0);
+ rc = 0;
+ goto cleanup;
}
// Reset the "aclient" structure before we call ktc_SetToken.
if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0)) {
afs_report_error(rc, "ktc_SetToken()");
- return(rc);
+ goto cleanup;
}
} else if (method == AFS_TOKEN_AUTO ||
method >= AFS_TOKEN_USER) {
}
}
+ cleanup:
+ if (ak_cellconfig.linkedCell)
+ free(ak_cellconfig.linkedCell);
+
return rc;
}
if (strlen(cell) == 0)
StringCbCopyA(cell, (MAXCELLCHARS+1) * sizeof(char), local_cell);
- /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
+ /* WIN32: cm_SearchCellFile(cell, newcell, pcallback, pdata) */
StringCbCopyA(cellconfig->name, (MAXCELLCHARS+1) * sizeof(char), cell);
rc = cm_SearchCellFile(cell, NULL, afs_get_cellconfig_callback,
int rc;
ZeroMemory(local_cell, sizeof(local_cell));
+ ZeroMemory(&cellconfig, sizeof(cellconfig));
rc = afs_get_cellconfig(cell, &cellconfig, local_cell);
if (rc)
return FALSE;
realm = afs_realm_of_cell(&cellconfig, FALSE);
+ if (cellconfig.linkedCell)
+ free(cellconfig.linkedCell);
if (realm == NULL)
return FALSE;