cm_lock_data_t **ldpp)
{
long rights;
- long code;
+ long code = 0;
osi_assertx(ldpp != NULL, "null cm_lock_data_t");
*ldpp = NULL;
/* Always allow delete; the RPC will tell us if it's OK */
- if (desiredAccess == DELETE)
- return 0;
-
rights = 0;
+ if (desiredAccess == DELETE)
+ goto done_2;
+
if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
rights |= (scp->fileType == CM_SCACHETYPE_DIRECTORY ? PRSFS_LOOKUP : PRSFS_READ);
if (desiredAccess & AFS_ACCESS_WRITE)
rights |= PRSFS_WRITE;
+ if (desiredAccess & DELETE)
+ rights |= PRSFS_DELETE;
+
lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, rights,
_done:
lock_ReleaseWrite(&scp->rw);
+ done_2:
osi_Log3(afsd_logp,"cm_CheckNTOpen scp 0x%p ldp 0x%p code 0x%x", scp, *ldpp, code);
return code;
}
tp = bufferp->datap + entryInBuffer;
dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */
+ /*
+ * here are some consistency checks
+ */
+ if (dep->flag != CM_DIR_FFIRST ||
+ strlen(dep->name) > 256) {
+ code = CM_ERROR_INVAL;
+ break;
+ }
+
/* while we're here, compute the next entry's location, too,
* since we'll need it when writing out the cookie into the
* dir listing stream.
#endif
code = cm_Lookup(dscp, cnamep, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp);
+ if (code)
+ goto done;
+
+ /* Check for RO volume */
+ if (dscp->flags & CM_SCACHEFLAG_RO) {
+ code = CM_ERROR_READONLY;
+ goto done;
+ }
/* make sure we don't screw up the dir status during the merge */
code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE,
StringCbCopyA((char *) tsp->data, sizeof(tsp->data), linkp+cm_mountRootLen+1);
else
tsp->data[0] = 0;
- *newRootScpp = cm_data.rootSCachep;
- cm_HoldSCache(cm_data.rootSCachep);
+ *newRootScpp = cm_RootSCachep(userp, reqp);
+ cm_HoldSCache(*newRootScpp);
} else if (linkp[0] == '\\' && linkp[1] == '\\') {
if (!strnicmp(&linkp[2], cm_NetbiosName, (len = (long)strlen(cm_NetbiosName))))
{
if (*p == '\\')
*p = '/';
}
- *newRootScpp = cm_data.rootSCachep;
- cm_HoldSCache(cm_data.rootSCachep);
+ *newRootScpp = cm_RootSCachep(userp, reqp);
+ cm_HoldSCache(*newRootScpp);
} else {
linkScp->fileType = CM_SCACHETYPE_DFSLINK;
StringCchCopyA(tsp->data,lengthof(tsp->data), linkp);
* but this seems to create problems. instead, we will just
* reject the link */
StringCchCopyA(tsp->data,lengthof(tsp->data), linkp+1);
- *newRootScpp = cm_data.rootSCachep;
- cm_HoldSCache(cm_data.rootSCachep);
+ *newRootScpp = cm_RootSCachep(userp, reqp);
+ cm_HoldSCache(*newRootScpp);
#else
/* we still copy the link data into the response so that
* the user can see what the link points to
case VOFFLINE:
case VSALVAGE:
case VNOSERVICE:
+ case VIO:
code = (&bbp->stats[0])->errorCode;
break;
default:
return cm_SetLength(scp, &attrp->length, userp, reqp);
lock_ObtainWrite(&scp->rw);
+ /* Check for RO volume */
+ if (scp->flags & CM_SCACHEFLAG_RO) {
+ code = CM_ERROR_READONLY;
+ lock_ReleaseWrite(&scp->rw);
+ return code;
+ }
+
/* otherwise, we have to make an RPC to get the status */
code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS);
if (code) {
}
#endif /* AFS_FREELANCE_CLIENT */
+ /* Check for RO volume */
+ if (dscp->flags & CM_SCACHEFLAG_RO)
+ return CM_ERROR_READONLY;
+
/* before starting the RPC, mark that we're changing the file data, so
* that someone who does a chmod will know to wait until our call
* completes.
}
#endif /* AFS_FREELANCE_CLIENT */
+ /* Check for RO volume */
+ if (dscp->flags & CM_SCACHEFLAG_RO)
+ return CM_ERROR_READONLY;
+
/* before starting the RPC, mark that we're changing the directory
* data, so that someone who does a chmod on the dir will wait until
* our call completes.
return CM_ERROR_CROSSDEVLINK;
}
+ /* Check for RO volume */
+ if (dscp->flags & CM_SCACHEFLAG_RO)
+ return CM_ERROR_READONLY;
+
cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, CM_DIROP_FLAG_NONE,
&dirop);
lock_ObtainWrite(&dscp->rw);
cm_dirOp_t dirop;
fschar_t *fnamep = NULL;
+ /* Check for RO volume */
+ if (dscp->flags & CM_SCACHEFLAG_RO)
+ return CM_ERROR_READONLY;
+
memset(&volSync, 0, sizeof(volSync));
/* before starting the RPC, mark that we're changing the directory data,
if (code)
goto done;
+ /* Check for RO volume */
+ if (dscp->flags & CM_SCACHEFLAG_RO) {
+ code = CM_ERROR_READONLY;
+ goto done;
+ }
+
/* before starting the RPC, mark that we're changing the directory data,
* so that someone who does a chmod on the dir will wait until our
* call completes.
} else {
code = 0;
}
+
+ /* Check for RO volume */
+ if (code == 0 &&
+ (oldDscp->flags & CM_SCACHEFLAG_RO) || (newDscp->flags & CM_SCACHEFLAG_RO)) {
+ code = CM_ERROR_READONLY;
+ }
+
if (code)
goto done;