mirror of
https://git.openafs.org/openafs.git
synced 2025-01-22 17:00:15 +00:00
windows-insert-locking-without-afsid-20060422
This patch disables the lookup of the user's AFSID and instead solves the problem by tracking which cm_user_t created the file. If the user is unable to obtain a write lock and is the creator, then we check for the Insert bit. Otherwise, we deny access.
This commit is contained in:
parent
d463c0f7c6
commit
237ab6e5ba
@ -32,8 +32,8 @@
|
||||
* can't be locked. Thus, this must always be called in a while loop to stabilize
|
||||
* things, since we can always lose the race condition getting to the parent vnode.
|
||||
*/
|
||||
int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, long rights,
|
||||
long *outRightsp)
|
||||
int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, afs_uint32 rights,
|
||||
afs_uint32 *outRightsp)
|
||||
{
|
||||
cm_scache_t *aclScp;
|
||||
long code;
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "cm_user.h"
|
||||
|
||||
extern int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up,
|
||||
long rights, long *outRights);
|
||||
afs_uint32 rights, afs_uint32 *outRights);
|
||||
|
||||
extern long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *up,
|
||||
struct cm_req *reqp);
|
||||
|
@ -68,7 +68,7 @@ static void CleanupACLEnt(cm_aclent_t * aclp)
|
||||
* Get an acl cache entry for a particular user and file, or return that it doesn't exist.
|
||||
* Called with the scp locked.
|
||||
*/
|
||||
long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, long *rightsp)
|
||||
long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 *rightsp)
|
||||
{
|
||||
cm_aclent_t *aclp;
|
||||
long retval = -1;
|
||||
@ -147,7 +147,7 @@ static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp)
|
||||
*
|
||||
* The scp must be locked when this function is called.
|
||||
*/
|
||||
long cm_AddACLCache(cm_scache_t *scp, cm_user_t *userp, long rights)
|
||||
long cm_AddACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 rights)
|
||||
{
|
||||
register struct cm_aclent *aclp;
|
||||
|
||||
|
@ -25,7 +25,7 @@ typedef struct cm_aclent {
|
||||
struct cm_aclent *nextp; /* next guy same vnode */
|
||||
struct cm_scache *backp; /* back ptr to vnode */
|
||||
struct cm_user *userp; /* user whose access is cached */
|
||||
long randomAccess; /* watch for more rights in acl.h */
|
||||
afs_uint32 randomAccess; /* watch for more rights in acl.h */
|
||||
unsigned long tgtLifetime; /* time this expires */
|
||||
} cm_aclent_t;
|
||||
|
||||
@ -33,11 +33,11 @@ extern osi_rwlock_t cm_aclLock;
|
||||
|
||||
extern long cm_InitACLCache(int newFile, long size);
|
||||
|
||||
extern long cm_FindACLCache(struct cm_scache *scp, struct cm_user *userp, long *rightsp);
|
||||
extern long cm_FindACLCache(struct cm_scache *scp, struct cm_user *userp, afs_uint32 *rightsp);
|
||||
|
||||
static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp);
|
||||
|
||||
extern long cm_AddACLCache(struct cm_scache *scp, struct cm_user *userp, long rights);
|
||||
extern long cm_AddACLCache(struct cm_scache *scp, struct cm_user *userp, afs_uint32 rights);
|
||||
|
||||
extern void cm_FreeAllACLEnts(struct cm_scache *scp);
|
||||
|
||||
|
@ -1896,6 +1896,7 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef QUERY_AFSID
|
||||
long cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
|
||||
{
|
||||
afs_int32 code;
|
||||
@ -1970,7 +1971,7 @@ long cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* QUERY_AFSID */
|
||||
|
||||
long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
|
||||
{
|
||||
@ -2088,11 +2089,14 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
|
||||
ucellp->kvno = ct.AuthHandle;
|
||||
ucellp->expirationTime = ct.EndTimestamp;
|
||||
ucellp->gen++;
|
||||
#ifdef QUERY_AFSID
|
||||
ucellp->uid = ANONYMOUSID;
|
||||
#endif
|
||||
if (uname) {
|
||||
StringCbCopyA(ucellp->userName, MAXKTCNAMELEN, uname);
|
||||
|
||||
#ifdef QUERY_AFSID
|
||||
cm_UsernameToId(uname, ucellp, &ucellp->uid);
|
||||
#endif
|
||||
}
|
||||
ucellp->flags |= CM_UCELLFLAG_RXKAD;
|
||||
lock_ReleaseMutex(&userp->mx);
|
||||
|
@ -668,12 +668,12 @@ cm_scache_t * cm_FindSCacheParent(cm_scache_t * scp)
|
||||
* CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
|
||||
*/
|
||||
long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
|
||||
long rights, long flags)
|
||||
afs_uint32 rights, afs_uint32 flags)
|
||||
{
|
||||
osi_queueData_t *qdp;
|
||||
long code;
|
||||
cm_buf_t *tbufp;
|
||||
long outRights;
|
||||
afs_uint32 outRights;
|
||||
int bufLocked;
|
||||
|
||||
/* lookup this first */
|
||||
@ -874,7 +874,8 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
|
||||
return CM_ERROR_READONLY;
|
||||
|
||||
if (cm_HaveAccessRights(scp, up, rights, &outRights)) {
|
||||
if (~outRights & rights) return CM_ERROR_NOACCESS;
|
||||
if (~outRights & rights)
|
||||
return CM_ERROR_NOACCESS;
|
||||
}
|
||||
else {
|
||||
/* we don't know the required access rights */
|
||||
@ -990,7 +991,7 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
|
||||
/* for those syncops that setup for RPCs.
|
||||
* Called with scache locked.
|
||||
*/
|
||||
void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, long flags)
|
||||
void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, afs_uint32 flags)
|
||||
{
|
||||
osi_queueData_t *qdp;
|
||||
cm_buf_t *tbufp;
|
||||
@ -1074,7 +1075,7 @@ void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, long flags)
|
||||
* started before that, can cause old info to be merged from the first call.
|
||||
*/
|
||||
void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp,
|
||||
cm_user_t *userp, int flags)
|
||||
cm_user_t *userp, afs_uint32 flags)
|
||||
{
|
||||
// yj: i want to create some fake status for the /afs directory and the
|
||||
// entries under that directory
|
||||
|
@ -23,14 +23,6 @@ typedef struct cm_fid {
|
||||
unsigned long unique;
|
||||
} cm_fid_t;
|
||||
|
||||
#if 0
|
||||
typedef struct cm_accessCache {
|
||||
osi_queue_t q; /* queue header */
|
||||
struct cm_user *userp; /* user having access rights */
|
||||
unsigned long rights; /* rights */
|
||||
} cm_accessCache_t;
|
||||
#endif
|
||||
|
||||
/* Key used for byte range locking. Each unique key identifies a
|
||||
unique client per cm_scache_t for the purpose of locking. */
|
||||
typedef afs_uint64 cm_key_t;
|
||||
@ -130,6 +122,7 @@ typedef struct cm_scache {
|
||||
afs_uint32 dataVersion; /* data version */
|
||||
afs_uint32 owner; /* file owner */
|
||||
afs_uint32 group; /* file owning group */
|
||||
cm_user_t *creator; /* user, if new file */
|
||||
|
||||
/* pseudo file status */
|
||||
osi_hyper_t serverLength; /* length known to server */
|
||||
@ -317,12 +310,12 @@ extern cm_scache_t *cm_GetNewSCache(void);
|
||||
extern int cm_FidCmp(cm_fid_t *, cm_fid_t *);
|
||||
|
||||
extern long cm_SyncOp(cm_scache_t *, struct cm_buf *, struct cm_user *,
|
||||
struct cm_req *, long, long);
|
||||
struct cm_req *, afs_uint32, afs_uint32);
|
||||
|
||||
extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, long);
|
||||
extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, afs_uint32);
|
||||
|
||||
extern void cm_MergeStatus(cm_scache_t *, struct AFSFetchStatus *, struct AFSVolSync *,
|
||||
struct cm_user *, int flags);
|
||||
struct cm_user *, afs_uint32 flags);
|
||||
|
||||
extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *);
|
||||
|
||||
|
@ -32,7 +32,9 @@ typedef struct cm_ucell {
|
||||
int iterator; /* for use as ListTokens cookie */
|
||||
long flags; /* flags */
|
||||
char userName[MAXKTCNAMELEN]; /* user name */
|
||||
#ifdef QUERY_AFSID
|
||||
afs_uint32 uid; /* User's AFS ID in this cell */
|
||||
#endif
|
||||
} cm_ucell_t;
|
||||
|
||||
#define CM_UCELLFLAG_HASTIX 1 /* has Kerberos tickets */
|
||||
|
@ -2270,6 +2270,7 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp,
|
||||
code = cm_GetSCache(&newFid, &scp, userp, reqp);
|
||||
if (code == 0) {
|
||||
lock_ObtainMutex(&scp->mx);
|
||||
scp->creator = userp; /* remember who created it */
|
||||
if (!cm_HaveCallback(scp)) {
|
||||
cm_MergeStatus(scp, &newFileStatus, &volSync,
|
||||
userp, 0);
|
||||
@ -3434,7 +3435,8 @@ long cm_LockCheckPerms(cm_scache_t * scp,
|
||||
CM_SCACHESYNC_NEEDCALLBACK);
|
||||
|
||||
if (code == CM_ERROR_NOACCESS &&
|
||||
lock_type == LockWrite) {
|
||||
lock_type == LockWrite &&
|
||||
scp->creator == userp) {
|
||||
/* check for PRSFS_INSERT. */
|
||||
cm_ucell_t * ucp;
|
||||
|
||||
@ -3442,25 +3444,8 @@ long cm_LockCheckPerms(cm_scache_t * scp,
|
||||
CM_SCACHESYNC_GETSTATUS |
|
||||
CM_SCACHESYNC_NEEDCALLBACK);
|
||||
|
||||
if (code) {
|
||||
if (code == CM_ERROR_NOACCESS)
|
||||
osi_Log0(afsd_logp, "cm_LockCheckPerms user has no INSERT bits for scp");
|
||||
|
||||
goto return_code;
|
||||
}
|
||||
|
||||
code = CM_ERROR_NOACCESS;
|
||||
|
||||
lock_ObtainMutex(&userp->mx);
|
||||
for (ucp = userp->cellInfop; ucp; ucp = ucp->nextp) {
|
||||
if (scp->fid.cell == ucp->cellp->cellID) {
|
||||
if (scp->owner == ucp->uid)
|
||||
code = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
lock_ReleaseMutex(&userp->mx);
|
||||
osi_Log0(afsd_logp, "cm_LockCheckPerms user is creator but has no INSERT bits for scp");
|
||||
}
|
||||
|
||||
return_code:
|
||||
|
@ -5817,6 +5817,16 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
|
||||
fidp->flags &= ~SMB_FID_DELONCLOSE;
|
||||
}
|
||||
|
||||
/* if this was a newly created file, then clear the creator
|
||||
* in the stat cache entry. */
|
||||
if (fidp->flags & SMB_FID_CREATED) {
|
||||
lock_ObtainMutex(&fidp->scp->mx);
|
||||
if (fidp->scp->creator == userp)
|
||||
fidp->scp->creator = NULL;
|
||||
lock_ReleaseMutex(&fidp->scp->mx);
|
||||
fidp->flags &= ~SMB_FID_CREATED;
|
||||
}
|
||||
|
||||
if (fidp->flags & SMB_FID_NTOPEN) {
|
||||
fidp->NTopen_dscp = NULL;
|
||||
fidp->NTopen_pathp = NULL;
|
||||
@ -6846,6 +6856,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
afs_uint32 dosTime;
|
||||
char *tidPathp;
|
||||
cm_req_t req;
|
||||
int created = 0; /* the file was new */
|
||||
|
||||
cm_InitReq(&req);
|
||||
|
||||
@ -6945,11 +6956,13 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime);
|
||||
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
|
||||
&req);
|
||||
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
|
||||
if (code == 0) {
|
||||
created = 1;
|
||||
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
|
||||
smb_NotifyChange(FILE_ACTION_ADDED,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
dscp, lastNamep, NULL, TRUE);
|
||||
if (!excl && code == CM_ERROR_EXISTS) {
|
||||
} else if (!excl && code == CM_ERROR_EXISTS) {
|
||||
/* not an exclusive create, and someone else tried
|
||||
* creating it already, then we open it anyway. We
|
||||
* don't bother retrying after this, since if this next
|
||||
@ -6994,6 +7007,10 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
/* always create it open for read/write */
|
||||
fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
|
||||
|
||||
/* remember that the file was newly created */
|
||||
if (created)
|
||||
fidp->flags |= SMB_FID_CREATED;
|
||||
|
||||
/* save a pointer to the vnode */
|
||||
fidp->scp = scp;
|
||||
/* and the user */
|
||||
|
@ -358,7 +358,7 @@ typedef struct smb_fid {
|
||||
|
||||
#define SMB_FID_OPENREAD 1 /* open for reading */
|
||||
#define SMB_FID_OPENWRITE 2 /* open for writing */
|
||||
#define SMB_FID_UNUSED 4 /* free for use */
|
||||
#define SMB_FID_CREATED 4 /* a new file */
|
||||
#define SMB_FID_IOCTL 8 /* a file descriptor for the
|
||||
* magic ioctl file */
|
||||
#define SMB_FID_OPENDELETE 0x10 /* open for deletion (NT) */
|
||||
|
@ -2062,6 +2062,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
|
||||
long returnEALength;
|
||||
char *tidPathp;
|
||||
cm_req_t req;
|
||||
int created = 0;
|
||||
|
||||
cm_InitReq(&req);
|
||||
|
||||
@ -2280,11 +2281,13 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
|
||||
smb_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime);
|
||||
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
|
||||
&req);
|
||||
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
|
||||
if (code == 0) {
|
||||
created = 1;
|
||||
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
|
||||
smb_NotifyChange(FILE_ACTION_ADDED,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
dscp, lastNamep, NULL, TRUE);
|
||||
if (!excl && code == CM_ERROR_EXISTS) {
|
||||
} else if (!excl && code == CM_ERROR_EXISTS) {
|
||||
/* not an exclusive create, and someone else tried
|
||||
* creating it already, then we open it anyway. We
|
||||
* don't bother retrying after this, since if this next
|
||||
@ -2359,6 +2362,11 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
|
||||
fidp->flags |= SMB_FID_OPENREAD;
|
||||
if (openMode == 1 || openMode == 2)
|
||||
fidp->flags |= SMB_FID_OPENWRITE;
|
||||
|
||||
/* remember that the file was newly created */
|
||||
if (created)
|
||||
fidp->flags |= SMB_FID_CREATED;
|
||||
|
||||
lock_ReleaseMutex(&fidp->mx);
|
||||
|
||||
smb_ReleaseFID(fidp);
|
||||
@ -4515,6 +4523,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
int parmSlot; /* which parm we're dealing with */
|
||||
char *tidPathp;
|
||||
cm_req_t req;
|
||||
int created = 0;
|
||||
|
||||
cm_InitReq(&req);
|
||||
|
||||
@ -4697,11 +4706,13 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime);
|
||||
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
|
||||
&req);
|
||||
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
|
||||
if (code == 0) {
|
||||
created = 1;
|
||||
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
|
||||
smb_NotifyChange(FILE_ACTION_ADDED,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
dscp, lastNamep, NULL, TRUE);
|
||||
if (!excl && code == CM_ERROR_EXISTS) {
|
||||
} else if (!excl && code == CM_ERROR_EXISTS) {
|
||||
/* not an exclusive create, and someone else tried
|
||||
* creating it already, then we open it anyway. We
|
||||
* don't bother retrying after this, since if this next
|
||||
@ -4757,6 +4768,10 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
if (openMode == 1 || openMode == 2)
|
||||
fidp->flags |= SMB_FID_OPENWRITE;
|
||||
|
||||
/* remember if the file was newly created */
|
||||
if (created)
|
||||
fidp->flags |= SMB_FID_CREATED;
|
||||
|
||||
lock_ReleaseMutex(&fidp->mx);
|
||||
smb_ReleaseFID(fidp);
|
||||
|
||||
@ -5366,6 +5381,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
char *tidPathp;
|
||||
BOOL foundscp;
|
||||
cm_req_t req;
|
||||
int created = 0;
|
||||
|
||||
cm_InitReq(&req);
|
||||
|
||||
@ -5798,11 +5814,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
|
||||
setAttr.clientModTime = time(NULL);
|
||||
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req);
|
||||
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
|
||||
if (code == 0) {
|
||||
created = 1;
|
||||
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
|
||||
smb_NotifyChange(FILE_ACTION_ADDED,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
dscp, lastNamep, NULL, TRUE);
|
||||
if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
|
||||
} else if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
|
||||
/* Not an exclusive create, and someone else tried
|
||||
* creating it already, then we open it anyway. We
|
||||
* don't bother retrying after this, since if this next
|
||||
@ -6027,6 +6045,10 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
|
||||
|
||||
fidp->flags = fidflags;
|
||||
|
||||
/* remember if the file was newly created */
|
||||
if (created)
|
||||
fidp->flags |= SMB_FID_CREATED;
|
||||
|
||||
/* save parent dir and pathname for delete or change notification */
|
||||
if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
|
||||
fidp->flags |= SMB_FID_NTOPEN;
|
||||
@ -6133,6 +6155,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
|
||||
ULONG *lparmp;
|
||||
char *outData;
|
||||
cm_req_t req;
|
||||
int created = 0;
|
||||
|
||||
cm_InitReq(&req);
|
||||
|
||||
@ -6466,11 +6489,13 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
|
||||
setAttr.clientModTime = time(NULL);
|
||||
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
|
||||
&req);
|
||||
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
|
||||
if (code == 0) {
|
||||
created = 1;
|
||||
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
|
||||
smb_NotifyChange(FILE_ACTION_ADDED,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
dscp, lastNamep, NULL, TRUE);
|
||||
if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
|
||||
} else if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
|
||||
/* Not an exclusive create, and someone else tried
|
||||
* creating it already, then we open it anyway. We
|
||||
* don't bother retrying after this, since if this next
|
||||
@ -6627,6 +6652,10 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
|
||||
|
||||
fidp->flags = fidflags;
|
||||
|
||||
/* remember if the file was newly created */
|
||||
if (created)
|
||||
fidp->flags |= SMB_FID_CREATED;
|
||||
|
||||
/* save parent dir and pathname for deletion or change notification */
|
||||
if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
|
||||
fidp->flags |= SMB_FID_NTOPEN;
|
||||
|
Loading…
Reference in New Issue
Block a user