extern HANDLE WaitToTerminate;
-#undef DFS_SUPPORT
+#define DFS_SUPPORT 1
#define LOG_PACKET 1
#undef NOTSERVICE
#define LOCK_TESTING 1
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
+ /* Notify any volume status handlers that the cache manager has started */
+ cm_VolStatus_Service_Started();
+
/* the following ifdef chooses the mode of operation for the service. to enable
* a runtime flag (instead of compile-time), pioctl() would need to dynamically
* determine the mode, in order to use the correct ioctl special-file path. */
LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVICE_RUNNING);
}
- /* Notify any volume status handlers that we have started */
- cm_VolStatus_Service_Started();
-
/* allow an exit to be called when started */
hHookDll = LoadLibrary(AFSD_HOOK_DLL);
if (hHookDll)
#define CM_ERROR_NOT_A_DFSLINK (CM_ERROR_BASE+53)
#define CM_ERROR_INEXACT_MATCH (CM_ERROR_BASE+54)
#define CM_ERROR_BPLUS_NOMATCH (CM_ERROR_BASE+55)
+#define CM_ERROR_EAS_NOT_SUPPORTED (CM_ERROR_BASE+56)
/* Used by cm_FollowMountPoint and cm_GetVolumeByName */
#define RWVOL 0
#define CM_CONN_FLAG_FORCE_NEW 1
-/* structure used for tracking RPC progress */
+/*
+ * structure used for tracking RPC progress
+ * and for passing path info from the smb layer
+ * to the cache manager functions.
+ */
typedef struct cm_req {
DWORD startTime; /* Quit before RDR times us out */
int rpcError; /* RPC error code */
int volumeError; /* volume error code */
int accessError; /* access error code */
int flags;
+ char * tidPathp;
+ char * relPathp;
} cm_req_t;
/* flags in cm_req structure */
long code;
osi_hyper_t thyper;
cm_buf_t *bufferp;
- cm_dirEntry_t *dep;
+ cm_dirEntry_t *dep = 0;
unsigned short *hashTable;
unsigned int i, idx;
int BeyondPage = 0, HaveDot = 0, HaveDotDot = 0;
{
char *tp;
long code;
- cm_dirEntry_t *dep;
+ cm_dirEntry_t *dep = 0;
cm_buf_t *bufferp;
long temp;
osi_hyper_t dirLength;
if (!linkScp->mountPointStringp[0]) {
strncpy(linkScp->mountPointStringp, bufp->datap, temp);
linkScp->mountPointStringp[temp] = 0; /* null terminate */
+
+ if ( !strnicmp(linkScp->mountPointStringp, "msdfs:", strlen("msdfs:")) )
+ linkScp->fileType = CM_SCACHETYPE_DFSLINK;
}
buf_Release(bufp);
} /* don't have sym link contents cached */
char *linkp;
cm_space_t *tsp;
+ *newRootScpp = NULL;
+ *newSpaceBufferp = NULL;
+
lock_ObtainMutex(&linkScp->mx);
code = cm_HandleLink(linkScp, userp, reqp);
- if (code)
+ if (code)
goto done;
/* if we may overflow the buffer, bail out; buffer is signficantly
} else {
linkScp->fileType = CM_SCACHETYPE_DFSLINK;
strcpy(tsp->data, linkp);
- *newRootScpp = NULL;
code = CM_ERROR_PATH_NOT_COVERED;
}
- } else if ( !strnicmp(linkp, "msdfs:", (len = (long)strlen("msdfs:"))) ) {
+ } else if ( linkScp->fileType == CM_SCACHETYPE_DFSLINK ||
+ !strnicmp(linkp, "msdfs:", (len = (long)strlen("msdfs:"))) ) {
linkScp->fileType = CM_SCACHETYPE_DFSLINK;
strcpy(tsp->data, linkp);
- *newRootScpp = NULL;
code = CM_ERROR_PATH_NOT_COVERED;
} else if (*linkp == '\\' || *linkp == '/') {
#if 0
*/
linkScp->fileType = CM_SCACHETYPE_INVALID;
strcpy(tsp->data, linkp);
- *newRootScpp = NULL;
code = CM_ERROR_NOSUCHPATH;
#endif
} else {
/* a relative link */
strcpy(tsp->data, linkp);
- *newRootScpp = NULL;
}
if (pathSuffixp[0] != 0) { /* if suffix string is non-null */
strcat(tsp->data, "\\");
strcat(tsp->data, pathSuffixp);
}
- *newSpaceBufferp = tsp;
+ if (code == 0)
+ *newSpaceBufferp = tsp;
+ else {
+ cm_FreeSpace(tsp);
+
+ if (code == CM_ERROR_PATH_NOT_COVERED && reqp->tidPathp && reqp->relPathp)
+ cm_VolStatus_Notify_DFS_Mapping(linkScp, reqp->tidPathp, reqp->relPathp);
+ }
done:
lock_ReleaseMutex(&linkScp->mx);
extern long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp,
cm_scache_t **outScpp, cm_user_t *userp, cm_req_t *reqp);
+extern long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp,
+ cm_req_t *reqp, cm_scache_t **outScpp);
+
+
extern long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key,
int allowWait, cm_user_t *userp, cm_req_t *reqp,
dll_VolStatus_Funcs_t dll_funcs;
cm_VolStatus_Funcs_t cm_funcs;
+static char volstat_NetbiosName[64] = "";
+
+afs_uint32
+cm_VolStatus_Active(void)
+{
+ return (hVolStatus != NULL);
+}
+
/* This function is used to load any Volume Status Handlers
* and their associated function pointers.
*/
dummyLen = sizeof(wd);
code = RegQueryValueEx(parmKey, "VolStatusHandler", NULL, NULL,
(BYTE *) &wd, &dummyLen);
+
+ if (code == 0) {
+ dummyLen = sizeof(volstat_NetbiosName);
+ code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
+ (BYTE *)volstat_NetbiosName, &dummyLen);
+ }
RegCloseKey (parmKey);
}
cm_funcs.cm_VolStatus_Path_To_ID = cm_VolStatus_Path_To_ID;
cm_funcs.cm_VolStatus_Path_To_DFSlink = cm_VolStatus_Path_To_DFSlink;
+ dll_funcs.version = DLL_VOLSTATUS_FUNCS_VERSION;
code = dll_VolStatus_Initialization(&dll_funcs, &cm_funcs);
}
}
}
+ osi_Log1(afsd_logp,"cm_VolStatus_Initialization 0x%x", code);
+
return code;
}
long
cm_VolStatus_Finalize(void)
{
+ osi_Log1(afsd_logp,"cm_VolStatus_Finalize handle 0x%x", hVolStatus);
+
if (hVolStatus == NULL)
return 0;
{
long code = 0;
+ osi_Log1(afsd_logp,"cm_VolStatus_Service_Started handle 0x%x", hVolStatus);
+
if (hVolStatus == NULL)
return 0;
{
long code = 0;
+ osi_Log1(afsd_logp,"cm_VolStatus_Service_Stopped handle 0x%x", hVolStatus);
+
if (hVolStatus == NULL)
return 0;
}
+
+long
+cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, char *tidPathp, char *pathp)
+{
+ long code = 0;
+ char src[1024], *p;
+ size_t len;
+
+ if (hVolStatus == NULL || dll_funcs.version < 2)
+ return 0;
+
+ snprintf(src,sizeof(src), "\\\\%s%s", volstat_NetbiosName, tidPathp);
+ len = strlen(src);
+ if ((src[len-1] == '\\' || src[len-1] == '/') &&
+ (pathp[0] == '\\' || pathp[0] == '/'))
+ strncat(src, &pathp[1], sizeof(src));
+ else
+ strncat(src, pathp, sizeof(src));
+
+ for ( p=src; *p; p++ ) {
+ if (*p == '/')
+ *p = '\\';
+ }
+
+ code = dll_funcs.dll_VolStatus_Notify_DFS_Mapping(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
+ src, scp->mountPointStringp);
+
+ return code;
+}
+
+long
+cm_VolStatus_Invalidate_DFS_Mapping(cm_scache_t *scp)
+{
+ long code = 0;
+
+ if (hVolStatus == NULL || dll_funcs.version < 2)
+ return 0;
+
+ code = dll_funcs.dll_VolStatus_Invalidate_DFS_Mapping(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
+
+ return code;
+}
+
+
long __fastcall
-cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID)
+cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID, enum volstatus *pstatus)
{
- afs_uint32 code;
+ afs_uint32 code = 0;
cm_req_t req;
cm_scache_t *scp;
if (cellID == NULL || volID == NULL)
return CM_ERROR_INVAL;
- cm_InitReq(&req);
+ osi_Log2(afsd_logp,"cm_VolStatus_Path_To_ID share %s path %s",
+ osi_LogSaveString(afsd_logp, (char *)share), osi_LogSaveString(afsd_logp, (char *)path));
+ cm_InitReq(&req);
- code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_FOLLOW, cm_rootUserp, (char *)share, &req, &scp);
+ code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, cm_rootUserp, (char *)share, &req, &scp);
if (code)
- return code;
+ goto done;
lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL,cm_rootUserp, &req, 0,
if (code) {
lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
- return code;
+ goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
*cellID = scp->fid.cell;
*volID = scp->fid.volume;
+ *pstatus = cm_GetVolumeStatus(scp->volp, scp->fid.volume);
lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
- return 0;
+ done:
+ osi_Log1(afsd_logp,"cm_VolStatus_Path_To_ID code 0x%x",code);
+ return code;
}
long __fastcall
cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 *pBufSize, char *pBuffer)
{
- afs_uint32 code;
+ afs_uint32 code = 0;
cm_req_t req;
cm_scache_t *scp;
size_t len;
if (pBufSize == NULL || (pBuffer == NULL && *pBufSize != 0))
return CM_ERROR_INVAL;
+ osi_Log2(afsd_logp,"cm_VolStatus_Path_To_DFSlink share %s path %s",
+ osi_LogSaveString(afsd_logp, (char *)share), osi_LogSaveString(afsd_logp, (char *)path));
+
cm_InitReq(&req);
- code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_FOLLOW, cm_rootUserp, (char *)share, &req, &scp);
+ code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ cm_rootUserp, (char *)share, &req, &scp);
if (code)
- return code;
+ goto done;
lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, cm_rootUserp, &req, 0,
if (code) {
lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
- return code;
+ goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (scp->fileType != CM_SCACHETYPE_DFSLINK)
- return CM_ERROR_NOT_A_DFSLINK;
+ if (scp->fileType != CM_SCACHETYPE_DFSLINK) {
+ code = CM_ERROR_NOT_A_DFSLINK;
+ goto done;
+ }
len = strlen(scp->mountPointStringp) + 1;
if (pBuffer == NULL)
else if (*pBufSize >= len) {
strcpy(pBuffer, scp->mountPointStringp);
*pBufSize = len;
- } else
+ } else {
code = CM_ERROR_TOOBIG;
+ goto done;
+ }
lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
- return 0;
+ done:
+ osi_Log1(afsd_logp,"cm_VolStatus_Path_To_DFSlink code 0x%x",code);
+ return code;
}
extern long cm_VolStatus_Change_Notification(afs_uint32 cellID, afs_uint32 volID, enum volstatus status);
-extern long __fastcall cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID);
+extern long __fastcall cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID, enum volstatus *pstatus);
extern long __fastcall cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 *pBufSize, char *pBuffer);
-#define DLL_VOLSTATUS_FUNCS_VERSION 1
+extern long cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, char *tidPathp, char *pathp);
+
+extern long cm_VolStatus_Invalidate_DFS_Mapping(cm_scache_t *scp);
+
+#define DLL_VOLSTATUS_FUNCS_VERSION 2
typedef struct dll_VolStatus_Funcs {
afs_uint32 version;
+ /* version 1 */
long (__fastcall * dll_VolStatus_Service_Started)(void);
long (__fastcall * dll_VolStatus_Service_Stopped)(void);
long (__fastcall * dll_VolStatus_Network_Started)(const char *netbios32, const char *netbios64);
long (__fastcall * dll_VolStatus_Network_Stopped)(const char *netbios32, const char *netbios64);
long (__fastcall * dll_VolStatus_Network_Addr_Change)(void);
long (__fastcall * dll_VolStatus_Change_Notification)(afs_uint32 cellID, afs_uint32 volID, enum volstatus status);
+ /* version 2 */
+ long (__fastcall * dll_VolStatus_Notify_DFS_Mapping)(afs_uint32 cellID, afs_uint32 volID,
+ afs_uint32 vnodeID, afs_uint32 uniqID,
+ char *src, char *target);
+ long (__fastcall * dll_VolStatus_Invalidate_DFS_Mapping)(afs_uint32 cellID, afs_uint32 volID,
+ afs_uint32 vnodeID, afs_uint32 uniqID);
} dll_VolStatus_Funcs_t;
#define CM_VOLSTATUS_FUNCS_VERSION 1
typedef struct cm_VolStatus_Funcs {
afs_uint32 version;
- long (__fastcall * cm_VolStatus_Path_To_ID)(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID);
+ long (__fastcall * cm_VolStatus_Path_To_ID)(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID, enum volstatus *pstatus);
long (__fastcall * cm_VolStatus_Path_To_DFSlink)(const char * share, const char * path, afs_uint32 *pBufSize, char *pBuffer);
} cm_VolStatus_Funcs_t;
else if (code == CM_ERROR_PATH_NOT_COVERED) {
NTStatus = 0xC0000257L; /* Path Not Covered */
}
-#ifdef COMMENT
else if (code == CM_ERROR_ALLBUSY) {
- NTStatus = 0xC00000BFL; /* Network Busy */
+ NTStatus = 0xC000022DL; /* Retry */
}
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
- NTStatus = 0xC0000350L; /* Remote Host Down */
- }
-#else
- /* we do not want to be telling the SMB/CIFS client that
- * the AFS Client Service is busy or down.
- */
- else if (code == CM_ERROR_ALLBUSY ||
- code == CM_ERROR_ALLOFFLINE ||
- code == CM_ERROR_ALLDOWN) {
NTStatus = 0xC00000BEL; /* Bad Network Path */
- }
-#endif
+ }
else if (code == RXKADUNKNOWNKEY) {
NTStatus = 0xC0000322L; /* Bad Kerberos key */
}
/* mask starts out all blanks */
memset(maskp, ' ', 11);
+ maskp[11] = '\0';
/* find last backslash, or use whole thing if there is none */
tp = strrchr(pathp, '\\');
- if (!tp) tp = pathp;
- else tp++; /* skip slash */
+ if (!tp)
+ tp = pathp;
+ else
+ tp++; /* skip slash */
up = maskp;
/* names starting with a dot are illegal */
- if (*tp == '.') valid8Dot3 = 0;
+ if (*tp == '.')
+ valid8Dot3 = 0;
for(i=0;; i++) {
tc = *tp++;
- if (tc == 0) return valid8Dot3;
- if (tc == '.' || tc == '"') break;
- if (i < 8) *up++ = tc;
- else valid8Dot3 = 0;
+ if (tc == 0)
+ return valid8Dot3;
+ if (tc == '.' || tc == '"')
+ break;
+ if (i < 8)
+ *up++ = tc;
+ else
+ valid8Dot3 = 0;
}
/* if we get here, tp point after the dot */
{
unsigned char *pathp;
unsigned char *tp;
- unsigned char mask[11];
+ unsigned char mask[12];
unsigned char *statBlockp;
unsigned char initStatBlock[21];
int statLen;
return 0;
}
-long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
- cm_user_t *userp, cm_req_t *reqp)
+static long
+smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
+ char * tidPathp, char * relPathp,
+ cm_user_t *userp, cm_req_t *reqp)
{
long code = 0;
cm_scache_t *scp;
char attr;
smb_dirListPatch_t *patchp;
smb_dirListPatch_t *npatchp;
+ char path[AFSPATHMAX];
for (patchp = *dirPatchespp; patchp; patchp =
(smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
dptr = patchp->dptr;
+ snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
+
code = cm_GetSCache(&patchp->fid, &scp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
+
if (code) {
if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE )
*dptr++ = SMB_ATTR_HIDDEN;
char *tp;
long code = 0;
char *pathp;
- cm_dirEntry_t *dep;
+ cm_dirEntry_t *dep = 0;
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
char shortName[13];
char *actualName;
char *shortNameEnd;
- char mask[11];
+ char mask[12];
int returnedNames;
long nextEntryCookie;
int numDirChunks; /* # of 32 byte dir chunks in this entry */
int starPattern;
int rootPath = 0;
int caseFold;
- char *tidPathp;
+ char *tidPathp = 0;
cm_req_t req;
cm_fid_t fid;
int fileType;
dsp = smb_NewDirSearch(0);
dsp->attribute = attribute;
smb_Get8Dot3MaskFromPath(mask, pathp);
- memcpy(dsp->mask, mask, 11);
+ memcpy(dsp->mask, mask, 12);
/* track if this is likely to match a lot of entries */
if (smb_IsStarMask(mask))
*/
memcpy(&clientCookie, &inCookiep[17], 4);
- memcpy(mask, dsp->mask, 11);
+ memcpy(mask, dsp->mask, 12);
/* assume we're doing a star match if it has continued for more
* than one call.
smb_ReleaseDirSearch(dsp);
return CM_ERROR_NOFILES;
}
+ strcpy(dsp->tidPath, tidPathp ? tidPathp : "/");
+ strcpy(dsp->relPath, spacep->data);
+
code = cm_NameI(cm_data.rootSCachep, spacep->data,
caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp);
if (code == 0) {
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data);
cm_ReleaseSCache(scp);
lock_ReleaseMutex(&dsp->mx);
cm_ReleaseUser(userp);
smb_DeleteDirSearch(dsp);
smb_ReleaseDirSearch(dsp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
* the status info for files in the dir.
*/
if (starPattern) {
- smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
+ smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper,
/* apply and free last set of patches; if not doing a star match, this
* will be empty, but better safe (and freeing everything) than sorry.
*/
- smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
+ smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
/* special return code for unsuccessful search */
if (code == 0 && dataLength < 21 && returnedNames == 0)
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(inp) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
cm_DirEntryListAdd(dep->name, &rockp->matches);
- rockp->any = 1;
+ rockp->any = 1;
- /* If we made a case sensitive exact match, we might as well quit now. */
- if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
- code = CM_ERROR_STOPNOW;
+ /* If we made a case sensitive exact match, we might as well quit now. */
+ if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
+ code = CM_ERROR_STOPNOW;
else
code = 0;
}
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp,spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->data);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->data);
cm_ReleaseSCache(oldDscp);
cm_ReleaseSCache(newDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->data);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->data);
cm_ReleaseSCache(newDscp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
* locked by smb_globalLock */
unsigned short attribute; /* search attribute
* (used for extended protocol) */
+ char tidPath[256]; /* tid path */
+ char relPath[1024]; /* relative path */
char mask[256]; /* search mask for V3 */
} smb_dirSearch_t;
if (vcp->flags & SMB_VCFLAG_USENT)
{
int policy = smb_FindShareCSCPolicy(shareName);
+ HKEY parmKey;
+ DWORD code;
+ DWORD dwAdvertiseDFS = 0, dwSize = sizeof(DWORD);
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ code = RegQueryValueEx(parmKey, "AdvertiseDFS", NULL, NULL,
+ (BYTE *)&dwAdvertiseDFS, &dwSize);
+ if (code != ERROR_SUCCESS)
+ dwAdvertiseDFS = 0;
+ RegCloseKey (parmKey);
+ }
smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS |
-#ifdef DFS_SUPPORT
- SMB_SHARE_IS_IN_DFS |
-#endif
+ (dwAdvertiseDFS ? SMB_SHARE_IS_IN_DFS : 0) |
(policy << 2));
}
} else {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
} else {
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, lastNamep);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
+ DebugBreak();
return CM_ERROR_PATH_NOT_COVERED;
}
#endif /* DFS_SUPPORT */
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(p) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
infoLevel != SMB_INFO_QUERY_ALL_EAS) {
osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
- smb_SendTran2Error(vcp, p, opx, CM_ERROR_BAD_LEVEL);
+ smb_SendTran2Error(vcp, p, opx,
+ infoLevel == SMB_INFO_QUERY_ALL_EAS ? CM_ERROR_EAS_NOT_SUPPORTED : CM_ERROR_BAD_LEVEL);
return 0;
}
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(p) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
}
else if (infoLevel == SMB_INFO_QUERY_ALL_EAS) {
/* we don't support EAs */
- code = CM_ERROR_INVAL;
+ code = CM_ERROR_EAS_NOT_SUPPORTED;
}
done:
long code = 0;
int maxReferralLevel = 0;
char requestFileName[1024] = "";
+ char referralPath[1024] = "";
smb_tran2Packet_t *outp = 0;
cm_user_t *userp = 0;
+ cm_scache_t *scp = 0;
+ cm_scache_t *dscp = 0;
cm_req_t req;
CPINFO CodePageInfo;
- int i, nbnLen, reqLen;
+ int i, nbnLen, reqLen, refLen;
int idx;
cm_InitReq(&req);
nbnLen = strlen(cm_NetbiosName);
reqLen = strlen(requestFileName);
- if (reqLen == nbnLen + 5 &&
- requestFileName[0] == '\\' &&
+ if (reqLen > nbnLen + 2 && requestFileName[0] == '\\' &&
!_strnicmp(cm_NetbiosName,&requestFileName[1],nbnLen) &&
- requestFileName[nbnLen+1] == '\\' &&
- (!_strnicmp("all",&requestFileName[nbnLen+2],3) ||
- !_strnicmp("*.",&requestFileName[nbnLen+2],2)))
+ requestFileName[nbnLen+1] == '\\')
{
- USHORT * sp;
- struct smb_v2_referral * v2ref;
- outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, 2 * (reqLen + 8));
-
- sp = (USHORT *)outp->datap;
- idx = 0;
- sp[idx++] = reqLen; /* path consumed */
- sp[idx++] = 1; /* number of referrals */
- sp[idx++] = 0x03; /* flags */
+ int found = 0;
+
+ if (!_strnicmp("all",&requestFileName[nbnLen+2],3) ||
+ !_strnicmp("*.",&requestFileName[nbnLen+2],2))
+ {
+ found = 1;
+ strcpy(referralPath, requestFileName);
+ refLen = reqLen;
+ } else {
+ userp = smb_GetTran2User(vcp, p);
+ if (!userp) {
+ osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral unable to resolve user [%d]", p->uid);
+ code = CM_ERROR_BADSMB;
+ goto done;
+ }
+
+ /*
+ * We have a requested path. Check to see if it is something
+ * we know about.
+ */
+ code = cm_NameI(cm_data.rootSCachep, &requestFileName[nbnLen+2],
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
+ userp, NULL, &req, &scp);
+ if (code == 0) {
+ /* Yes it is. */
+ found = 1;
+ strcpy(referralPath, requestFileName);
+ refLen = reqLen;
+ } else if (code == CM_ERROR_PATH_NOT_COVERED ) {
+ char temp[1024];
+ char pathName[1024];
+ char *lastComponent;
+ /*
+ * we have a msdfs link somewhere in the path
+ * we should figure out where in the path the link is.
+ * and return it.
+ */
+ osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral PATH_NOT_COVERED [%s]", requestFileName);
+
+ strcpy(temp, &requestFileName[nbnLen+2]);
+
+ do {
+ if (dscp) {
+ cm_ReleaseSCache(dscp);
+ dscp = 0;
+ }
+ if (scp) {
+ cm_ReleaseSCache(scp);
+ scp = 0;
+ }
+ smb_StripLastComponent(pathName, &lastComponent, temp);
+
+ code = cm_NameI(cm_data.rootSCachep, pathName,
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
+ userp, NULL, &req, &dscp);
+ if (code == 0) {
+ code = cm_NameI(dscp, ++lastComponent,
+ CM_FLAG_CASEFOLD,
+ userp, NULL, &req, &scp);
+ if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK)
+ break;
+ }
+ } while (code == CM_ERROR_PATH_NOT_COVERED);
+
+ /* scp should now be the DfsLink we are looking for */
+ if (scp) {
+ /* figure out how much of the input path was used */
+ reqLen = nbnLen+2 + strlen(pathName) + 1 + strlen(lastComponent);
+
+ strcpy(referralPath, &scp->mountPointStringp[strlen("msdfs:")]);
+ refLen = strlen(referralPath);
+ found = 1;
+ }
+ } else {
+ char shareName[MAX_PATH + 1];
+ char *p, *q;
+ /* we may have a sharename that is a volume reference */
+
+ for (p = &requestFileName[nbnLen+2], q = shareName; *p && *p != '\\'; p++, q++)
+ {
+ *q = *p;
+ }
+ *q = '\0';
+
+ if (smb_FindShare(vcp, vcp->usersp, shareName, &p)) {
+ code = cm_NameI(cm_data.rootSCachep, "",
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, p, &req, &scp);
+ free(p);
+
+ if (code == 0) {
+ found = 1;
+ strcpy(referralPath, requestFileName);
+ refLen = reqLen;
+ }
+ }
+ }
+ }
+
+ if (found)
+ {
+ USHORT * sp;
+ struct smb_v2_referral * v2ref;
+ outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, 2 * (refLen + 8));
+
+ sp = (USHORT *)outp->datap;
+ idx = 0;
+ sp[idx++] = reqLen; /* path consumed */
+ sp[idx++] = 1; /* number of referrals */
+ sp[idx++] = 0x03; /* flags */
#ifdef DFS_VERSION_1
- sp[idx++] = 1; /* Version Number */
- sp[idx++] = reqLen + 4; /* Referral Size */
- sp[idx++] = 1; /* Type = SMB Server */
- sp[idx++] = 0; /* Do not strip path consumed */
- for ( i=0;i<=reqLen; i++ )
- sp[i+idx] = requestFileName[i];
+ sp[idx++] = 1; /* Version Number */
+ sp[idx++] = refLen + 4; /* Referral Size */
+ sp[idx++] = 1; /* Type = SMB Server */
+ sp[idx++] = 0; /* Do not strip path consumed */
+ for ( i=0;i<=refLen; i++ )
+ sp[i+idx] = referralPath[i];
#else /* DFS_VERSION_2 */
- sp[idx++] = 2; /* Version Number */
- sp[idx++] = sizeof(struct smb_v2_referral); /* Referral Size */
- idx += (sizeof(struct smb_v2_referral) / 2);
- v2ref = (struct smb_v2_referral *) &sp[5];
- v2ref->ServerType = 1; /* SMB Server */
- v2ref->ReferralFlags = 0x03;
- v2ref->Proximity = 0; /* closest */
- v2ref->TimeToLive = 3600; /* seconds */
- v2ref->DfsPathOffset = idx * 2;
- v2ref->DfsAlternativePathOffset = idx * 2;
- v2ref->NetworkAddressOffset = 0;
- for ( i=0;i<=reqLen; i++ )
- sp[i+idx] = requestFileName[i];
+ sp[idx++] = 2; /* Version Number */
+ sp[idx++] = sizeof(struct smb_v2_referral); /* Referral Size */
+ idx += (sizeof(struct smb_v2_referral) / 2);
+ v2ref = (struct smb_v2_referral *) &sp[5];
+ v2ref->ServerType = 1; /* SMB Server */
+ v2ref->ReferralFlags = 0x03;
+ v2ref->Proximity = 0; /* closest */
+ v2ref->TimeToLive = 3600; /* seconds */
+ v2ref->DfsPathOffset = idx * 2;
+ v2ref->DfsAlternativePathOffset = idx * 2;
+ v2ref->NetworkAddressOffset = 0;
+ for ( i=0;i<=refLen; i++ )
+ sp[i+idx] = referralPath[i];
#endif
+ }
} else {
- userp = smb_GetTran2User(vcp, p);
- if (!userp) {
- osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral unable to resolve user [%d]", p->uid);
- code = CM_ERROR_BADSMB;
- goto done;
- }
-
- /* not done yet */
code = CM_ERROR_NOSUCHPATH;
}
-
+
done:
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
if (userp)
cm_ReleaseUser(userp);
if (code == 0)
return CM_ERROR_BADOP;
}
-long
-smb_ApplyV3DirListPatches(cm_scache_t *dscp,
- smb_dirListPatch_t **dirPatchespp, int infoLevel, cm_user_t *userp,
- cm_req_t *reqp)
+static long
+smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp,
+ char * tidPathp, char * relPathp,
+ int infoLevel, cm_user_t *userp,
+ cm_req_t *reqp)
{
long code = 0;
cm_scache_t *scp;
smb_dirListPatch_t *npatchp;
afs_uint32 rights;
afs_int32 mustFake = 0;
+ char path[AFSPATHMAX];
code = cm_FindACLCache(dscp, userp, &rights);
if (code == 0 && !(rights & PRSFS_READ))
for(patchp = *dirPatchespp; patchp; patchp =
(smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
+ snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
+
code = cm_GetSCache(&patchp->fid, &scp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
if (code)
continue;
code = 0;
while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
lock_ReleaseMutex(&scp->mx);
+ snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
if (code == 0) {
/* we have a more accurate file to use (the
* target of the symbolic link). Otherwise,
/* Copy attributes */
lattr = smb_ExtAttributes(scp);
- if (code == CM_ERROR_NOSUCHPATH && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ if (code == CM_ERROR_NOSUCHPATH && scp->fileType == CM_SCACHETYPE_SYMLINK ||
+ code == CM_ERROR_PATH_NOT_COVERED && scp->fileType == CM_SCACHETYPE_DFSLINK) {
if (lattr == SMB_ATTR_NORMAL)
lattr = SMB_ATTR_DIRECTORY;
else
int attribute;
long nextCookie;
long code = 0, code2 = 0;
- char *pathp;
+ char *pathp = 0;
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
int searchFlags;
int eos;
smb_tran2Packet_t *outp; /* response packet */
- char *tidPathp;
+ char *tidPathp = 0;
int align;
char shortName[13]; /* 8.3 name if needed */
int NeedShortName;
char *shortNameEnd;
+ cm_dirEntry_t * dep = NULL;
cm_req_t req;
char * s;
#ifdef DFS_SUPPORT_BUT_NOT_FIND_FIRST
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
curPatchp->fid.unique = targetscp->fid.unique;
/* temp */
- curPatchp->dep = NULL;
+ dep = (cm_dirEntry_t *)malloc(sizeof(cm_dirEntry_t)+strlen(maskp));
+ strcpy(dep->name, maskp);
+ dep->fid.vnode = targetscp->fid.vnode;
+ dep->fid.unique = targetscp->fid.unique;
+ curPatchp->dep = dep;
}
if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS) {
}
/* apply the patches */
- code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, &req);
+ code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, tidPathp, spacep->data, infoLevel, userp, &req);
outp->parmsp[0] = 0;
outp->parmsp[1] = 1; /* number of names returned */
skip_file:
smb_FreeTran2Packet(outp);
+ if (dep)
+ free(dep);
cm_ReleaseSCache(scp);
cm_ReleaseSCache(targetscp);
cm_ReleaseUser(userp);
char *tp;
long code = 0, code2 = 0;
char *pathp;
- cm_dirEntry_t *dep;
+ cm_dirEntry_t *dep = 0;
int maxCount;
- smb_dirListPatch_t *dirListPatchesp;
- smb_dirListPatch_t *curPatchp;
+ smb_dirListPatch_t *dirListPatchesp = 0;
+ smb_dirListPatch_t *curPatchp = 0;
cm_buf_t *bufferp;
long temp;
long orbytes; /* # of bytes in this output record */
smb_ReleaseDirSearch(dsp);
return 0;
}
+
+ strcpy(dsp->tidPath, tidPathp ? tidPathp : "/");
+ strcpy(dsp->relPath, spacep->data);
+
code = cm_NameI(cm_data.rootSCachep, spacep->data,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, tidPathp, &req, &scp);
if (code == 0) {
#ifdef DFS_SUPPORT_BUT_NOT_FIND_FIRST
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
* of all of the status info for files in the dir.
*/
if (starPattern) {
- smb_ApplyV3DirListPatches(scp, &dirListPatchesp,
- infoLevel, userp,
- &req);
+ code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, infoLevel, userp, &req);
+
lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* apply and free last set of patches; if not doing a star match, this
* will be empty, but better safe (and freeing everything) than sorry.
*/
- code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, &req);
-
+ code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath,
+ dsp->relPath, infoLevel, userp, &req);
+
/* now put out the final parameters */
if (returnedNames == 0)
eos = 1;
#ifdef DFS_SUPPORT
if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
userp, tidPathp, &req, &scp);
#ifdef DFS_SUPPORT
if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, realPathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (code == 0 && dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
if (scp)
cm_ReleaseSCache(scp);
cm_ReleaseSCache(dscp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
userp, tidPathp, &req, &scp);
#ifdef DFS_SUPPORT
if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, realPathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
userp, tidPathp, &req, &dscp);
#ifdef DFS_SUPPORT
if (code == 0 && dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;