NTSTATUS SrvBuildTreeRelativePath( PLWIO_SRV_TREE pTree, PWSTR pwszFilename, PIO_FILE_NAME pFilename ) { NTSTATUS ntStatus = STATUS_SUCCESS; BOOLEAN bInLock = FALSE; PWSTR pwszFilePath = NULL; if (SrvTreeIsNamedPipe(pTree)) { LWIO_LOCK_RWMUTEX_SHARED(bInLock, &pTree->pShareInfo->mutex); ntStatus = SrvBuildFilePath( pTree->pShareInfo->pwszPath, pwszFilename, &pwszFilePath); BAIL_ON_NT_STATUS(ntStatus); } else { wchar16_t wszBackslash[] = {'\\', 0}; if (!IsNullOrEmptyString(pwszFilename) && SMBWc16sCmp(pwszFilename, &wszBackslash[0])) { ntStatus = SrvBuildFilePath( NULL, pwszFilename, &pwszFilePath); BAIL_ON_NT_STATUS(ntStatus); } LWIO_LOCK_RWMUTEX_SHARED(bInLock, &pTree->pShareInfo->mutex); pFilename->RootFileHandle = pTree->hFile; } pFilename->FileName = pwszFilePath; cleanup: LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->pShareInfo->mutex); return ntStatus; error: goto cleanup; }
BOOLEAN LwIoCompareCreds( PIO_CREDS pCredsOne, PIO_CREDS pCredsTwo ) { if (pCredsOne == NULL && pCredsTwo == NULL) { return TRUE; } else if (pCredsOne != NULL && pCredsTwo != NULL && pCredsOne->type == pCredsTwo->type) { switch (pCredsOne->type) { case IO_CREDS_TYPE_PLAIN: return (!SMBWc16sCmp(pCredsOne->payload.plain.pwszUsername, pCredsTwo->payload.plain.pwszUsername) && !SMBWc16sCmp(pCredsOne->payload.plain.pwszPassword, pCredsTwo->payload.plain.pwszPassword)); case IO_CREDS_TYPE_KRB5_CCACHE: return (!SMBWc16sCmp(pCredsOne->payload.krb5Ccache.pwszPrincipal, pCredsTwo->payload.krb5Ccache.pwszPrincipal) && !SMBWc16sCmp(pCredsOne->payload.krb5Ccache.pwszCachePath, pCredsTwo->payload.krb5Ccache.pwszCachePath)); case IO_CREDS_TYPE_KRB5_TGT: return (!SMBWc16sCmp(pCredsOne->payload.krb5Tgt.pwszClientPrincipal, pCredsTwo->payload.krb5Tgt.pwszClientPrincipal) && !SMBWc16sCmp(pCredsOne->payload.krb5Tgt.pwszServerPrincipal, pCredsTwo->payload.krb5Tgt.pwszServerPrincipal) && (pCredsOne->payload.krb5Tgt.ulTgtSize == pCredsTwo->payload.krb5Tgt.ulTgtSize) && memcpy(pCredsOne->payload.krb5Tgt.pTgtData, pCredsTwo->payload.krb5Tgt.pTgtData, pCredsOne->payload.krb5Tgt.ulTgtSize) == 0); } } return FALSE; }
static NTSTATUS SrvDeleteSingleFile( PSRV_EXEC_CONTEXT pExecContext ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext; PSRV_EXEC_CONTEXT_SMB_V1 pCtxSmb1 = pCtxProtocol->pSmb1Context; PSRV_DELETE_STATE_SMB_V1 pDeleteState = NULL; wchar16_t wszDot[] = {'.', 0}; pDeleteState = (PSRV_DELETE_STATE_SMB_V1)pCtxSmb1->hState; if (!pDeleteState->bPendingCreate) { if ((SMBWc16sCmp(pDeleteState->pwszSearchPattern2, wszDot) == 0)) { ntStatus = STATUS_OBJECT_NAME_INVALID; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = SrvBuildFilePath( pDeleteState->pwszFilesystemPath, pDeleteState->pwszSearchPattern2, &pDeleteState->fileName.Name); BAIL_ON_NT_STATUS(ntStatus); pDeleteState->fileName.RootFileHandle = pDeleteState->pTree->hFile; SrvPrepareDeleteStateAsync(pDeleteState, pExecContext); pDeleteState->bPendingCreate = TRUE; ntStatus = SrvIoCreateFile( pDeleteState->pTree->pShareInfo, &pDeleteState->hFile, pDeleteState->pAcb, &pDeleteState->ioStatusBlock, pDeleteState->pSession->pIoSecurityContext, &pDeleteState->fileName, pDeleteState->pSecurityDescriptor, pDeleteState->pSecurityQOS, DELETE, 0, FILE_ATTRIBUTE_NORMAL, FILE_NO_SHARE, FILE_OPEN, FILE_DELETE_ON_CLOSE|FILE_NON_DIRECTORY_FILE, NULL, 0, pDeleteState->pEcpList); BAIL_ON_NT_STATUS(ntStatus); SrvReleaseDeleteStateAsync(pDeleteState); // completed sync } pDeleteState->bPendingCreate = FALSE; ntStatus = pDeleteState->ioStatusBlock.Status; BAIL_ON_NT_STATUS(ntStatus); if (pDeleteState->hFile) { IoCloseFile(pDeleteState->hFile); pDeleteState->hFile = NULL; } cleanup: return ntStatus; error: /* Have to do some error mapping here to match WinXP */ switch (ntStatus) { case STATUS_PENDING: case STATUS_ACCESS_DENIED: case STATUS_FILE_IS_A_DIRECTORY: case STATUS_SHARING_VIOLATION: case STATUS_OBJECT_NAME_INVALID: break; case STATUS_OBJECT_NAME_NOT_FOUND: case STATUS_NO_SUCH_FILE: ntStatus = STATUS_OBJECT_NAME_NOT_FOUND; break; default: ntStatus = STATUS_CANNOT_DELETE; break; } goto cleanup; }
static NTSTATUS SrvDeleteFiles( PSRV_EXEC_CONTEXT pExecContext ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext; PSRV_EXEC_CONTEXT_SMB_V1 pCtxSmb1 = pCtxProtocol->pSmb1Context; PSRV_DELETE_STATE_SMB_V1 pDeleteState = NULL; PWSTR pwszFilename = NULL; wchar16_t wszDot[] = {'.', 0}; pDeleteState = (PSRV_DELETE_STATE_SMB_V1)pCtxSmb1->hState; if (pDeleteState->bPendingCreate) { pDeleteState->bPendingCreate = FALSE; ntStatus = pDeleteState->ioStatusBlock.Status; BAIL_ON_NT_STATUS(ntStatus); IoCloseFile(pDeleteState->hFile); pDeleteState->hFile = NULL; pDeleteState->bDeletedFile = TRUE; pDeleteState->iResult++; } for (;;) { for ( ; pDeleteState->iResult < pDeleteState->usSearchResultCount; pDeleteState->iResult++) { BOOLEAN bEligibleForDelete = FALSE; FILE_ATTRIBUTES ulIncludeAttributes = 0; if (!pDeleteState->pResult) { pDeleteState->pResult = (PSMB_FIND_FILE_BOTH_DIRECTORY_INFO_HEADER)pDeleteState->pData; } else if (pDeleteState->pResult->NextEntryOffset) { PBYTE pTmp = (PBYTE)pDeleteState->pResult + pDeleteState->pResult->NextEntryOffset; pDeleteState->pResult = (PSMB_FIND_FILE_BOTH_DIRECTORY_INFO_HEADER)pTmp; } else { ntStatus = STATUS_INTERNAL_ERROR; BAIL_ON_NT_STATUS(ntStatus); } if (pwszFilename) { SrvFreeMemory(pwszFilename); pwszFilename = NULL; } ulIncludeAttributes = SMB_FILE_ATTRIBUTES_TO_NATIVE(pDeleteState->usSearchAttributes); bEligibleForDelete = (IsSetFlag(pDeleteState->pResult->FileAttributes, ulIncludeAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))) || (!IsSetFlag(pDeleteState->pResult->FileAttributes, (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))); if (!bEligibleForDelete) { if (!pDeleteState->bPathHasWildCards) { if ((SMBWc16sCmp(pDeleteState->pwszSearchPattern2, wszDot) == 0)) { ntStatus = STATUS_OBJECT_NAME_INVALID; } else if (IsSetFlag(pDeleteState->pResult->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)) { ntStatus = STATUS_FILE_IS_A_DIRECTORY; } else { ntStatus = STATUS_NO_SUCH_FILE; } BAIL_ON_NT_STATUS(ntStatus); } continue; } if (pDeleteState->bUseLongFilenames) { ntStatus = SrvAllocateMemory( pDeleteState->pResult->FileNameLength + sizeof(wchar16_t), (PVOID*)&pwszFilename); BAIL_ON_NT_STATUS(ntStatus); memcpy((PBYTE)pwszFilename, (PBYTE)pDeleteState->pResult->FileName, pDeleteState->pResult->FileNameLength); } else { ntStatus = SrvAllocateMemory( pDeleteState->pResult->ShortNameLength + sizeof(wchar16_t), (PVOID*)&pwszFilename); BAIL_ON_NT_STATUS(ntStatus); memcpy((PBYTE)pwszFilename, (PBYTE)pDeleteState->pResult->ShortName, pDeleteState->pResult->ShortNameLength); } if (SMBWc16sCmp(pwszFilename, wszDot) == 0) { ntStatus = STATUS_OBJECT_NAME_INVALID; BAIL_ON_NT_STATUS(ntStatus); } SRV_FREE_UNICODE_STRING(&pDeleteState->fileName.Name); ntStatus = SrvBuildFilePath( pDeleteState->pwszFilesystemPath, pwszFilename, &pDeleteState->fileName.Name); BAIL_ON_NT_STATUS(ntStatus); pDeleteState->fileName.RootFileHandle = pDeleteState->pTree->hFile; SrvPrepareDeleteStateAsync(pDeleteState, pExecContext); pDeleteState->bPendingCreate = TRUE; ntStatus = SrvIoCreateFile( pDeleteState->pTree->pShareInfo, &pDeleteState->hFile, pDeleteState->pAcb, &pDeleteState->ioStatusBlock, pDeleteState->pSession->pIoSecurityContext, &pDeleteState->fileName, pDeleteState->pSecurityDescriptor, pDeleteState->pSecurityQOS, DELETE, 0, FILE_ATTRIBUTE_NORMAL, FILE_NO_SHARE, FILE_OPEN, FILE_DELETE_ON_CLOSE|FILE_NON_DIRECTORY_FILE, NULL, 0, pDeleteState->pEcpList); BAIL_ON_NT_STATUS(ntStatus); SrvReleaseDeleteStateAsync(pDeleteState); // completed sync pDeleteState->bPendingCreate = FALSE; IoCloseFile(pDeleteState->hFile); pDeleteState->hFile = NULL; pDeleteState->bDeletedFile = TRUE; } if (pDeleteState->bEndOfSearch) { break; } if (pDeleteState->pData) { SrvFreeMemory(pDeleteState->pData); pDeleteState->pData = NULL; } pDeleteState->iResult = 0; pDeleteState->pResult = NULL; ntStatus = SrvFinderGetSearchResults( pDeleteState->hSearchSpace, FALSE, /* bReturnSingleEntry */ FALSE, /* bRestartScan */ 10, /* Desired search count */ UINT16_MAX, /* Max data count */ pDeleteState->usDataOffset, &pDeleteState->pData, &pDeleteState->usDataLen, &pDeleteState->usSearchResultCount, &pDeleteState->bEndOfSearch); if (ntStatus == STATUS_NO_MORE_MATCHES) { ntStatus = STATUS_ASSERTION_FAILURE; BAIL_ON_NT_STATUS(ntStatus); } if (ntStatus == STATUS_NO_SUCH_FILE) { ntStatus = STATUS_SUCCESS; break; } } if (!pDeleteState->bDeletedFile) { if (pDeleteState->bPathHasWildCards) { ntStatus = STATUS_NO_SUCH_FILE; } else { ntStatus = STATUS_OBJECT_NAME_NOT_FOUND; } BAIL_ON_NT_STATUS(ntStatus); } cleanup: if (pwszFilename) { SrvFreeMemory(pwszFilename); } return ntStatus; error: /* Have to do some error mapping here to match WinXP */ switch (ntStatus) { case STATUS_PENDING: case STATUS_ACCESS_DENIED: case STATUS_FILE_IS_A_DIRECTORY: case STATUS_SHARING_VIOLATION: case STATUS_OBJECT_NAME_NOT_FOUND: case STATUS_OBJECT_NAME_INVALID: case STATUS_NO_SUCH_FILE: break; default: ntStatus = STATUS_CANNOT_DELETE; break; } goto cleanup; }