DEVEL15-windows-magic-share-names-20070613

Access to AFS volumes via magic share names

        \\afs\<cell><type><volume>

<cell> = cellname
<type> = % or #
<volume> = volume name or id


(cherry picked from commit 5ac7a7db9a)
This commit is contained in:
Asanka Herath 2007-06-13 23:28:25 +00:00 committed by Jeffrey Altman
parent 6ec04e3632
commit dbd5762ef4
3 changed files with 192 additions and 25 deletions

View File

@ -1294,6 +1294,114 @@ int cm_ExpandSysName(char *inp, char *outp, long outSize, unsigned int index)
return 1;
}
long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp,
cm_req_t *reqp, cm_scache_t ** outpScpp)
{
long code = 0;
char cellName[CELL_MAXNAMELEN];
char volumeName[VL_MAXNAMELEN];
size_t len;
char * cp;
char * tp;
cm_cell_t * cellp = NULL;
cm_volume_t * volp = NULL;
cm_fid_t fid;
int volType;
int mountType = RWVOL;
osi_Log1(afsd_logp, "cm_EvaluateVolumeReference for string [%s]",
osi_LogSaveString(afsd_logp, namep));
if (strnicmp(namep, CM_PREFIX_VOL, CM_PREFIX_VOL_CCH) != 0) {
goto _exit_invalid_path;
}
/* namep is assumed to look like the following:
@vol:<cellname>%<volume>\0
or
@vol:<cellname>#<volume>\0
*/
cp = namep + CM_PREFIX_VOL_CCH; /* cp points to cell name, hopefully */
tp = strchr(cp, '%');
if (tp == NULL)
tp = strchr(cp, '#');
if (tp == NULL ||
(len = tp - cp) == 0 ||
len > CELL_MAXNAMELEN)
goto _exit_invalid_path;
strncpy(cellName, cp, len);
cellName[len] = '\0';
if (*tp == '#')
mountType = ROVOL;
cp = tp+1; /* cp now points to volume, supposedly */
strncpy(volumeName, cp, VL_MAXNAMELEN-1);
volumeName[VL_MAXNAMELEN - 1] = 0;
/* OK, now we have the cell and the volume */
osi_Log2(afsd_logp, " Found cell [%s] and volume [%s]",
osi_LogSaveString(afsd_logp, cellName),
osi_LogSaveString(afsd_logp, volumeName));
cellp = cm_GetCell(cellName, CM_FLAG_CREATE);
if (cellp == NULL) {
goto _exit_invalid_path;
}
len = strlen(volumeName);
if (len >= 8 && strcmp(volumeName + len - 7, ".backup") == 0)
volType = BACKVOL;
else if (len >= 10 &&
strcmp(volumeName + len - 9, ".readonly") == 0)
volType = ROVOL;
else
volType = RWVOL;
if (cm_VolNameIsID(volumeName)) {
code = cm_GetVolumeByID(cellp, atoi(volumeName), userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
} else {
code = cm_GetVolumeByName(cellp, volumeName, userp, reqp,
CM_GETVOL_FLAG_CREATE, &volp);
}
if (code != 0)
goto _exit_cleanup;
fid.cell = cellp->cellID;
if (volType == BACKVOL)
fid.volume = volp->bk.ID;
else if (volType == ROVOL ||
(volType == RWVOL && mountType == ROVOL && volp->ro.ID != 0))
fid.volume = volp->ro.ID;
else
fid.volume = volp->rw.ID;
fid.vnode = 1;
fid.unique = 1;
code = cm_GetSCache(&fid, outpScpp, userp, reqp);
_exit_cleanup:
if (volp)
cm_PutVolume(volp);
if (code == 0)
return code;
_exit_invalid_path:
if (flags & CM_FLAG_CHECKPATH)
return CM_ERROR_NOSUCHPATH;
else
return CM_ERROR_NOSUCHFILE;
}
#ifdef DEBUG_REFCOUNT
long cm_LookupDbg(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp,
cm_req_t *reqp, cm_scache_t **outpScpp, char * file, long line)
@ -1319,32 +1427,47 @@ long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp,
return CM_ERROR_NOSUCHFILE;
}
for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) {
code = cm_ExpandSysName(namep, tname, sizeof(tname), sysNameIndex);
if (code > 0) {
code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp);
if (dscp == cm_data.rootSCachep &&
strnicmp(namep, CM_PREFIX_VOL, CM_PREFIX_VOL_CCH) == 0) {
return cm_EvaluateVolumeReference(namep, flags, userp, reqp, outpScpp);
}
if (cm_ExpandSysName(namep, NULL, 0, 0) > 0) {
for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) {
code = cm_ExpandSysName(namep, tname, sizeof(tname), sysNameIndex);
if (code > 0) {
code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp);
#ifdef DEBUG_REFCOUNT
afsi_log("%s:%d cm_LookupInternal (1) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0);
osi_Log3(afsd_logp, "cm_LookupInternal (1) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp);
afsi_log("%s:%d cm_LookupInternal (1) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0);
osi_Log3(afsd_logp, "cm_LookupInternal (1) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp);
#endif
if (code == 0) {
*outpScpp = scp;
return 0;
}
if (scp) {
cm_ReleaseSCache(scp);
scp = NULL;
}
} else {
code = cm_LookupInternal(dscp, namep, flags, userp, reqp, &scp);
if (code == 0) {
*outpScpp = scp;
return 0;
}
if (scp) {
cm_ReleaseSCache(scp);
scp = NULL;
}
} else {
code = cm_LookupInternal(dscp, namep, flags, userp, reqp, &scp);
#ifdef DEBUG_REFCOUNT
afsi_log("%s:%d cm_LookupInternal (2) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0);
osi_Log3(afsd_logp, "cm_LookupInternal (2) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp);
afsi_log("%s:%d cm_LookupInternal (2) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0);
osi_Log3(afsd_logp, "cm_LookupInternal (2) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp);
#endif
*outpScpp = scp;
return code;
*outpScpp = scp;
return code;
}
}
} else {
code = cm_LookupInternal(dscp, namep, flags, userp, reqp, &scp);
#ifdef DEBUG_REFCOUNT
afsi_log("%s:%d cm_LookupInternal (2) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0);
osi_Log3(afsd_logp, "cm_LookupInternal (2) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp);
#endif
*outpScpp = scp;
return code;
}
/* None of the possible sysName expansions could be found */
@ -3912,11 +4035,11 @@ long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
if (code != 0 &&
(scp->sharedLocks > 0 || scp->exclusiveLocks > 0) &&
scp->serverLock == -1) {
/* Oops. We lost the lock. */
cm_LockMarkSCacheLost(scp);
}
scp->serverLock == -1) {
/* Oops. We lost the lock. */
cm_LockMarkSCacheLost(scp);
}
}
} else if (code == 0) { /* server locks not enabled */
osi_Log0(afsd_logp,
" Skipping server lock for scp");

View File

@ -45,6 +45,17 @@ typedef struct cm_lookupSearch {
typedef int (*cm_DirFuncp_t)(struct cm_scache *, struct cm_dirEntry *, void *,
osi_hyper_t *entryOffsetp);
/* Special path syntax for direct references to volumes
The syntax: @vol:<cellname>{%,#}<volume> can be used to refer to a
specific volume in a specific cell, where:
<cellname> : name of the cell
<volume> : volume name or ID
*/
#define CM_PREFIX_VOL "@vol:"
#define CM_PREFIX_VOL_CCH 5
/* arrays */
extern unsigned char cm_foldUpper[];
@ -69,7 +80,10 @@ extern void cm_Gen8Dot3NameInt(const char * longname, cm_dirFid_t * pfid,
char *shortName, char **shortNameEndp);
extern long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp,
cm_req_t *reqp);
cm_req_t *reqp);
extern long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp,
cm_req_t *reqp, cm_scache_t ** outpScpp);
#ifdef DEBUG_REFCOUNT
extern long cm_NameIDbg(cm_scache_t *rootSCachep, char *pathp, long flags,

View File

@ -1798,6 +1798,36 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName,
return 0;
}
/* Check for volume references
They look like <cell>{%,#}<volume>
*/
if (strchr(shareName, '%') != NULL ||
strchr(shareName, '#') != NULL) {
char pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH];
/* make room for '/@vol:' + mountchar + NULL terminator*/
osi_Log1(smb_logp, "smb_FindShare found volume reference [%s]",
osi_LogSaveString(smb_logp, shareName));
snprintf(pathstr, sizeof(pathstr)/sizeof(char),
"/" CM_PREFIX_VOL "%s", shareName);
pathstr[sizeof(pathstr)/sizeof(char) - 1] = '\0';
len = strlen(pathstr);
*pathNamep = malloc(len);
if (*pathNamep) {
strcpy(*pathNamep, pathstr);
strlwr(*pathNamep);
osi_Log1(smb_logp, " returning pathname [%s]",
osi_LogSaveString(smb_logp, *pathNamep));
return 1;
} else {
return 0;
}
}
#ifndef DJGPP
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0, KEY_QUERY_VALUE, &parmKey);