/*
* 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 (code) {
osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry RDR_BulkStatLookup failed for scp=0x%p code=0x%x",
scp, code);
- return code;
+ if (code != CM_ERROR_NOACCESS)
+ return code;
}
lock_ObtainWrite(&scp->rw);
/*
pCurrentEntry->ChangeTime = pCurrentEntry->CreationTime;
pCurrentEntry->EndOfFile = scp->length;
- pCurrentEntry->AllocationSize = scp->length;
+ pCurrentEntry->AllocationSize.QuadPart =
+ ((scp->length.QuadPart/1024)+1)*1024;
if (bMustFake) {
switch (scp->fileType) {
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:
{
} else {
osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_FollowMountPoint failed scp=0x%p code=0x%x",
scp, code2);
+ if (code2 == CM_ERROR_TOO_MANY_SYMLINKS)
+ code = CM_ERROR_TOO_MANY_SYMLINKS;
}
}
} else {
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;
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)
bScpLocked = TRUE;
}
code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ CM_SCACHESYNC_LOCK);
if (code) {
osi_Log2(afsd_logp, "RDR_CleanupFileEntry cm_SyncOp (2) failure scp=0x%p code=0x%x",
scp, code);
bDeleteFile ? CM_UNLOCK_FLAG_BY_FID : 0,
userp, &req);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
if (code)
goto on_error;
}
code = cm_Lookup(dscp, FileName, 0, userp, &req, &scp);
- if (code) {
+ if (code && code != CM_ERROR_INEXACT_MATCH) {
smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
(*ResultCB)->ResultStatus = status;
(*ResultCB)->ResultBufferLength = 0;
if (!bCheckOnly) {
/* Drop all locks since the file is being deleted */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ CM_SCACHESYNC_LOCK);
if (code) {
smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
(*ResultCB)->ResultStatus = status;
CM_UNLOCK_FLAG_BY_FID,
userp, &req);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
lock_ReleaseWrite(&scp->rw);
if (scp->fileType == CM_SCACHETYPE_DIRECTORY)
cm_EndDirOp(&dirop);
}
- if (code != 0) {
+ if (code != 0 && code != CM_ERROR_INEXACT_MATCH) {
osi_Log1(afsd_logp, "RDR_RenameFileEntry cm_BPlusDirLookup failed code 0x%x",
code);
(*ResultCB)->ResultStatus = STATUS_OBJECT_PATH_INVALID;
cm_EndDirOp(&dirop);
}
- if (code != 0) {
+ if (code != 0 && code != CM_ERROR_INEXACT_MATCH) {
osi_Log1(afsd_logp, "RDR_HardLinkFileEntry cm_BPlusDirLookup failed code 0x%x",
code);
(*ResultCB)->ResultStatus = STATUS_OBJECT_PATH_INVALID;
bHaveBuffer = TRUE;
} else if (bufp->flags & CM_BUF_DIRTY) {
bHaveBuffer = FALSE;
-#if 0
- code = buf_CleanAsyncLocked(scp, bufp, &req, 0, NULL);
- switch (code) {
- case 0:
- bHaveBuffer = TRUE;
- break;
- case CM_ERROR_RETRY:
- /* Couldn't flush it, obtain it asynchronously so we don't block the thread. */
- bHaveBuffer = FALSE;
- code = 0;
- break;
- default:
- smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
- RDR_SetFileStatus(&FileId, &userp->authgroup, status);
- bHaveBuffer = FALSE;
- code = 0;
- }
-#endif
} else {
osi_hyper_t minLength; /* effective end of file */
cm_fid_t RootFid;
cm_req_t req;
- RDR_InitReq(&req, bWow64);
+ cm_InitReq(&req);
*ResultCB = (AFSCommResult *)malloc( sizeof( AFSCommResult));
if (!(*ResultCB))
cm_req_t req;
DWORD status;
- RDR_InitReq(&req, bWow64);
+ cm_InitReq(&req);
*ResultCB = (AFSCommResult *)malloc( sizeof( AFSCommResult) + sizeof(AFSPIOCtlIOResultCB));
if (!(*ResultCB))
DWORD status;
afs_uint32 pflags = (bIsLocalSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
- RDR_InitReq(&req, bWow64);
+ cm_InitReq(&req);
*ResultCB = (AFSCommResult *)malloc( sizeof( AFSCommResult) + sizeof(AFSPIOCtlIOResultCB));
if (!(*ResultCB))
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ CM_SCACHESYNC_LOCK);
if (code) {
lock_ReleaseWrite(&scp->rw);
smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
}
}
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ CM_SCACHESYNC_LOCK);
if (code) {
lock_ReleaseWrite(&scp->rw);
smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
pResultCB->Result[i].Status = status;
}
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ CM_SCACHESYNC_LOCK);
if (code) {
lock_ReleaseWrite(&scp->rw);
smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
code = cm_UnlockByKey(scp, key, 0, userp, &req);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
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);
}
}
/* 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,