/*
* Copyright (c) 2008 Secure Endpoints, Inc.
- * Copyright (c) 2009-2013 Your File System, Inc.
+ * Copyright (c) 2009-2014 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
if (!(dwFlags & RDR_POP_NO_GETSTATUS))
cm_SyncOpDone( scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if ((dwFlags & RDR_POP_NO_GETSTATUS) || !cm_HaveCallback(scp)) {
- pCurrentEntry->TargetNameOffset = 0;
- pCurrentEntry->TargetNameLength = 0;
- }
- else
+ pCurrentEntry->TargetNameOffset = 0;
+ pCurrentEntry->TargetNameLength = 0;
+ if (!(dwFlags & RDR_POP_NO_GETSTATUS) && cm_HaveCallback(scp)) {
switch (scp->fileType) {
case CM_SCACHETYPE_MOUNTPOINT:
- if (dwFlags & RDR_POP_FOLLOW_MOUNTPOINTS) {
+ {
if ((code2 = cm_ReadMountPoint(scp, userp, reqp)) == 0) {
cm_scache_t *targetScp = NULL;
#endif
pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * len);
- code2 = cm_FollowMountPoint(scp, dscp, userp, reqp, &targetScp);
-
- if (code2 == 0) {
- pCurrentEntry->TargetFileId.Cell = targetScp->fid.cell;
- pCurrentEntry->TargetFileId.Volume = targetScp->fid.volume;
- pCurrentEntry->TargetFileId.Vnode = targetScp->fid.vnode;
- pCurrentEntry->TargetFileId.Unique = targetScp->fid.unique;
- pCurrentEntry->TargetFileId.Hash = targetScp->fid.hash;
-
- osi_Log4(afsd_logp, "RDR_PopulateCurrentEntry target FID cell=0x%x vol=0x%x vn=0x%x uniq=0x%x",
- pCurrentEntry->TargetFileId.Cell, pCurrentEntry->TargetFileId.Volume,
- pCurrentEntry->TargetFileId.Vnode, pCurrentEntry->TargetFileId.Unique);
-
- cm_ReleaseSCache(targetScp);
- } else {
- osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_FollowMountPoint failed scp=0x%p code=0x%x",
- scp, code2);
+ if (dwFlags & RDR_POP_FOLLOW_MOUNTPOINTS) {
+ code2 = cm_FollowMountPoint(scp, dscp, userp, reqp, &targetScp);
+ if (code2 == 0) {
+ pCurrentEntry->TargetFileId.Cell = targetScp->fid.cell;
+ pCurrentEntry->TargetFileId.Volume = targetScp->fid.volume;
+ pCurrentEntry->TargetFileId.Vnode = targetScp->fid.vnode;
+ pCurrentEntry->TargetFileId.Unique = targetScp->fid.unique;
+ pCurrentEntry->TargetFileId.Hash = targetScp->fid.hash;
+
+ osi_Log4(afsd_logp, "RDR_PopulateCurrentEntry target FID cell=0x%x vol=0x%x vn=0x%x uniq=0x%x",
+ pCurrentEntry->TargetFileId.Cell, pCurrentEntry->TargetFileId.Volume,
+ pCurrentEntry->TargetFileId.Vnode, pCurrentEntry->TargetFileId.Unique);
+
+ cm_ReleaseSCache(targetScp);
+ } else {
+ osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_FollowMountPoint failed scp=0x%p code=0x%x",
+ scp, code2);
+ }
}
} else {
osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_ReadMountPoint failed scp=0x%p code=0x%x",
code2 = cm_HandleLink(scp, userp, reqp);
if (code2 == 0) {
- size_t wtarget_len = 0;
-
if (scp->mountPointStringp[0]) {
char * mp;
char * s;
size_t offset = 0;
+ size_t wtarget_len = 0;
len = strlen(scp->mountPointStringp) + 1;
mp = strdup(scp->mountPointStringp);
}
free(mp);
- }
- pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * (wtarget_len - 1));
+ pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * (wtarget_len - 1));
+ }
} else {
osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_HandleLink failed scp=0x%p code=0x%x",
scp, code2);
pCurrentEntry->TargetNameOffset = 0;
pCurrentEntry->TargetNameLength = 0;
}
+ }
lock_ReleaseWrite(&scp->rw);
dwEntryLength += pCurrentEntry->FileNameLength + pCurrentEntry->TargetNameLength;
entryp->name,
cm_shortNames && cm_Is8Dot3(entryp->name) ? NULL : entryp->shortName,
(bWow64 ? RDR_POP_WOW64 : 0) |
- (bSkipStatus ? RDR_POP_NO_GETSTATUS : 0),
+ (bSkipStatus ? RDR_POP_NO_GETSTATUS : 0) |
+ RDR_POP_EVALUATE_SYMLINKS,
code,
&pCurrentEntry, &dwMaxEntryLength);
cm_ReleaseSCache(scp);
IN BOOL CaseSensitive,
IN BOOL LastComponent,
IN BOOL bWow64,
- IN BOOL bHoldFid,
IN BOOL bNoFollow,
+ IN BOOL bHoldFid,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB)
{
dscp, scp, userp, &req,
FileName, shortName,
(bWow64 ? RDR_POP_WOW64 : 0) |
- (bNoFollow ? 0 : (RDR_POP_FOLLOW_MOUNTPOINTS | RDR_POP_EVALUATE_SYMLINKS)),
+ (bNoFollow ? 0 : RDR_POP_FOLLOW_MOUNTPOINTS) |
+ RDR_POP_EVALUATE_SYMLINKS,
0, NULL, &dwRemaining);
if (bHoldFid)
RDR_FlagScpInUse( scp, FALSE );
code = RDR_PopulateCurrentEntry(pCurrentEntry, dwRemaining,
dscp, scp, userp, &req, NULL, NULL,
(bWow64 ? RDR_POP_WOW64 : 0) |
- (bNoFollow ? 0 : (RDR_POP_FOLLOW_MOUNTPOINTS | RDR_POP_EVALUATE_SYMLINKS)),
+ (bNoFollow ? 0 : RDR_POP_FOLLOW_MOUNTPOINTS) |
+ RDR_POP_EVALUATE_SYMLINKS,
0, NULL, &dwRemaining);
if (bHoldFid)
cm_req_t req;
DWORD status;
FILETIME ft = {0x832cf000, 0x01abfcc4}; /* October 1, 1982 00:00:00 +0600 */
- afs_uint32 flags;
char volName[32]="(unknown)";
char offLineMsg[256]="server temporarily inaccessible";
char *OfflineMsg;
char *MOTD;
struct rx_connection * rxconnp;
- int sync_done = 0;
int scp_locked = 0;
RDR_InitReq(&req, bWow64);
if ( pResultCB->CellLength )
pResultCB->CellLength--;
} else {
- volp = cm_GetVolumeByFID(&scp->fid);
- if (!volp) {
+ volp = cm_FindVolumeByFID(&scp->fid, userp, &req);
+ if (!volp) {
code = CM_ERROR_NOSUCHVOLUME;
goto _done;
}
+
volType = cm_VolumeType(volp, scp->fid.volume);
if (cm_volumeInfoReadOnlyFlag && (volType == ROVOL || volType == BACKVOL))
if (code == -1)
{
- flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS;
- if (scp->volumeCreationDate == 0)
- flags |= CM_SCACHESYNC_FORCECB;
- code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, flags);
- if (code == 0)
- {
- sync_done = 1;
-
- Name = volName;
- OfflineMsg = offLineMsg;
- MOTD = motd;
- lock_ReleaseWrite(&scp->rw);
- scp_locked = 0;
-
- do {
- code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
- if (code) continue;
-
- rxconnp = cm_GetRxConn(connp);
- code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
- &volStat, &Name, &OfflineMsg, &MOTD);
- rx_PutConnection(rxconnp);
-
- } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
- code = cm_MapRPCError(code, &req);
-
- if (code == 0 && volType == ROVOL)
- {
-
- lock_ObtainWrite(&volp->rw);
- volp->volumeSizeRO = volStat.BlocksInUse * 1024;
- _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
- lock_ReleaseWrite(&volp->rw);
- }
+ Name = volName;
+ OfflineMsg = offLineMsg;
+ MOTD = motd;
+ lock_ReleaseWrite(&scp->rw);
+ scp_locked = 0;
+
+ do {
+ code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
+ if (code) continue;
+
+ rxconnp = cm_GetRxConn(connp);
+ code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
+ &volStat, &Name, &OfflineMsg, &MOTD);
+ rx_PutConnection(rxconnp);
+
+ } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
+ code = cm_MapRPCError(code, &req);
+
+ if (code == 0 && volType == ROVOL)
+ {
+ lock_ObtainWrite(&volp->rw);
+ volp->volumeSizeRO = volStat.BlocksInUse * 1024;
+ _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
+ lock_ReleaseWrite(&volp->rw);
}
}
pResultCB->AvailableAllocationUnits.QuadPart = volStat.PartBlocksAvail;
}
}
- } else {
+ } else if ( code != CM_ERROR_ALLBUSY &&
+ code != CM_ERROR_ALLOFFLINE &&
+ code != CM_ERROR_ALLDOWN)
+ {
/*
* Lie about the available space. Out of quota errors will need
* detected when the file server rejects the store data.
/* do not include the trailing nul */
if ( pResultCB->CellLength )
pResultCB->CellLength--;
-
- if (sync_done) {
- if (!scp_locked) {
- lock_ObtainWrite(&scp->rw);
- scp_locked = 1;
- }
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- }
}
pResultCB->VolumeLabelLength *= sizeof(WCHAR); /* convert to bytes from chars */
pResultCB->CellLength *= sizeof(WCHAR); /* convert to bytes from chars */
char *OfflineMsg;
char *MOTD;
struct rx_connection * rxconnp;
- int sync_done = 0;
int scp_locked = 0;
RDR_InitReq(&req, bWow64);
pResultCB->TotalAllocationUnits.QuadPart = 100;
pResultCB->AvailableAllocationUnits.QuadPart = 0;
} else {
- volp = cm_GetVolumeByFID(&scp->fid);
- if (!volp) {
+ volp = cm_FindVolumeByFID(&scp->fid, userp, &req);
+ if (!volp) {
code = CM_ERROR_NOSUCHVOLUME;
goto _done;
}
if (code == -1)
{
- code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code == 0)
- {
- sync_done = 1;
-
- Name = volName;
- OfflineMsg = offLineMsg;
- MOTD = motd;
- lock_ReleaseWrite(&scp->rw);
- scp_locked = 0;
-
- do {
- code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
- if (code) continue;
-
- rxconnp = cm_GetRxConn(connp);
- code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
- &volStat, &Name, &OfflineMsg, &MOTD);
- rx_PutConnection(rxconnp);
-
- } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
- code = cm_MapRPCError(code, &req);
-
- if (code == 0 && volType == ROVOL)
- {
-
- lock_ObtainWrite(&volp->rw);
- volp->volumeSizeRO = volStat.BlocksInUse * 1024;
- _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
- lock_ReleaseWrite(&volp->rw);
- }
+ Name = volName;
+ OfflineMsg = offLineMsg;
+ MOTD = motd;
+ lock_ReleaseWrite(&scp->rw);
+ scp_locked = 0;
+
+ do {
+ code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
+ if (code) continue;
+
+ rxconnp = cm_GetRxConn(connp);
+ code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
+ &volStat, &Name, &OfflineMsg, &MOTD);
+ rx_PutConnection(rxconnp);
+
+ } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
+ code = cm_MapRPCError(code, &req);
+
+ if (code == 0 && volType == ROVOL)
+ {
+ lock_ObtainWrite(&volp->rw);
+ volp->volumeSizeRO = volStat.BlocksInUse * 1024;
+ _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
+ lock_ReleaseWrite(&volp->rw);
}
}
pResultCB->AvailableAllocationUnits.QuadPart = (volType == ROVOL || volType == BACKVOL) ? 0 : 0x3F000000;
code = 0;
}
-
- if (sync_done) {
- if (!scp_locked) {
- lock_ObtainWrite(&scp->rw);
- scp_locked = 1;
- }
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- }
}
_done:
/* Ensure that the caller can access this file */
lock_ObtainWrite(&scp->rw);
- code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE,
+ /*
+ * Request PRSFS_WRITE | PRSFS_LOCK in order to bypass the unix mode
+ * check in cm_HaveAccessRights(). By the time RDR_WriteFile is called
+ * it is already too late to deny the write due to the readonly attribute.
+ * The Windows cache may have already accepted the data. Only if the
+ * user does not have real write permission should the write be denied.
+ */
+ code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE | PRSFS_LOCK,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code == CM_ERROR_NOACCESS && scp->creator == userp) {
code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_INSERT,