From: Jeffrey Altman Date: Mon, 11 Jul 2011 22:49:58 +0000 (+0100) Subject: Windows: always open dscp in smb_ReceiveNTTranCreate X-Git-Tag: openafs-devel-1_7_1~311 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=27af8b4b537236d8c678465d034721dd220641c8 Windows: always open dscp in smb_ReceiveNTTranCreate There were two code paths in smb_ReceiveNTTranCreate that included asserts in case the directory cm_scache_t object had not been evaluated. RT129299 contains a report that at least one of them had been tripped in production. There is no reason to avoid evaluating the directory scp. It must exist in the cache and obtaining a reference in all cases simplifies the logic of this overly complex function. FIXES 129299 Change-Id: I7b32c81f11c3fef53f8a21a44f3594d5cd9e1552 Reviewed-on: http://gerrit.openafs.org/4967 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 699202c..1d50da5 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -8400,6 +8400,16 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out osi_Log4(smb_logp,"... co[%x],sdl[%x],eal[%x],as[%x],flags[%x]",createOptions,sdLen,eaLen,allocSize); osi_Log3(smb_logp,"... imp[%x],sec[%x],flags[%x]", impLevel, secFlags, flags); + if ( realDirFlag == 1 && + ( createDisp == FILE_SUPERSEDE || + createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF)) + { + osi_Log0(smb_logp, "NTTranCreate rejecting invalid readDirFlag and createDisp combination"); + free(realPathp); + return CM_ERROR_INVAL; + } + /* * Nothing here to handle SMB_IOCTL_FILENAME. * Will add it if necessary. @@ -8494,59 +8504,43 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out dscp = NULL; code = 0; - if ( createDisp == FILE_OPEN || - createDisp == FILE_OVERWRITE || - createDisp == FILE_OVERWRITE_IF) { - code = cm_NameI(baseDirp, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); - if (code == 0) { -#ifdef DFS_SUPPORT - if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - if (baseFidp) - smb_ReleaseFID(baseFidp); - if ( WANTS_DFS_PATHNAMES(inp) || pnc ) - return CM_ERROR_PATH_NOT_COVERED; - else - return CM_ERROR_NOSUCHPATH; - } -#endif /* DFS_SUPPORT */ - code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, CM_FLAG_FOLLOW, - userp, &req, &scp); - if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) { - code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp); - if (code == 0 && realDirFlag == 1) { - cm_ReleaseSCache(scp); - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - if (baseFidp) - smb_ReleaseFID(baseFidp); - return CM_ERROR_EXISTS; - } - } - } - } else { - code = cm_NameI(baseDirp, realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &scp); + + code = cm_NameI(baseDirp, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); + if (code == 0) { #ifdef DFS_SUPPORT - if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, realPathp); - cm_ReleaseSCache(scp); + if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); - if (baseFidp) - smb_ReleaseFID(baseFidp); + if (baseFidp) + smb_ReleaseFID(baseFidp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) return CM_ERROR_PATH_NOT_COVERED; else return CM_ERROR_NOSUCHPATH; } #endif /* DFS_SUPPORT */ + code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, CM_FLAG_FOLLOW, + userp, &req, &scp); + if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) { + + code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp); + if (code == 0 && realDirFlag == 1 && + (createDisp == FILE_OPEN || + createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF)) { + cm_ReleaseSCache(scp); + cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + if (baseFidp) + smb_ReleaseFID(baseFidp); + return CM_ERROR_EXISTS; + } + } } if (code == 0) @@ -8556,27 +8550,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out code == CM_ERROR_NOSUCHPATH || code == CM_ERROR_BPLUS_NOMATCH || (code == 0 && (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)))) { - /* look up parent directory */ - if ( !dscp ) { - code = cm_NameI(baseDirp, spacep->wdata, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - 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->wdata); - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - if (baseFidp) - smb_ReleaseFID(baseFidp); - if ( WANTS_DFS_PATHNAMES(inp) || pnc ) - return CM_ERROR_PATH_NOT_COVERED; - else - return CM_ERROR_NOSUCHPATH; - } -#endif /* DFS_SUPPORT */ - } else - code = 0; + code = 0; cm_FreeSpace(spacep); @@ -8584,6 +8558,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out smb_ReleaseFID(baseFidp); if (code) { + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return code; @@ -8594,11 +8569,15 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out else lastNamep++; - if (!smb_IsLegalFilename(lastNamep)) + if (!smb_IsLegalFilename(lastNamep)) { + cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); return CM_ERROR_BADNTFILENAME; + } if (!foundscp) { - if (createDisp == FILE_CREATE || createDisp == FILE_OVERWRITE_IF) { + if (createDisp == FILE_CREATE || createDisp == FILE_OVERWRITE_IF || createDisp == FILE_OPEN_IF) { code = cm_Lookup(dscp, lastNamep, CM_FLAG_FOLLOW, userp, &req, &scp); } else { @@ -8628,8 +8607,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp); if (code) { cm_CheckNTOpenDone(scp, userp, &req, &ldp); - if (dscp) - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); @@ -8640,8 +8618,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (createDisp == FILE_CREATE) { /* oops, file shouldn't be there */ cm_CheckNTOpenDone(scp, userp, &req, &ldp); - if (dscp) - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); @@ -8672,8 +8649,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp); if (code) { cm_CheckNTOpenDone(scp, userp, &req, &ldp); - if (dscp) - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); if (scp) cm_ReleaseSCache(scp); cm_ReleaseUser(userp); @@ -8689,14 +8665,13 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out } else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) { /* don't create if not found */ - if (dscp) - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_NOSUCHFILE; } else if (realDirFlag == 0 || realDirFlag == -1) { - osi_assertx(dscp != NULL, "null cm_scache_t"); + /* createDisp: FILE_SUPERSEDE, FILE_CREATE, FILE_OPEN_IF, FILE_OVERWRITE_IF */ osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %S", osi_LogSaveClientString(smb_logp, lastNamep)); openAction = 2; /* created file */ @@ -8748,8 +8723,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out } /* lookup succeeded */ } } else { - /* create directory */ - osi_assertx(dscp != NULL, "null cm_scache_t"); + /* create directory; createDisp: FILE_CREATE, FILE_OPEN_IF */ osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating directory %S", osi_LogSaveClientString(smb_logp, lastNamep));