static VOID SrvTree2Free( PLWIO_SRV_TREE_2 pTree ) { LWIO_LOG_DEBUG("Freeing tree [object:0x%x][tid:%u]", pTree, pTree->ulTid); // Cannot be in the parent since parent would have a reference. LWIO_ASSERT(!SrvTree2IsInParent_inlock(pTree)); if (pTree->pMutex) { pthread_rwlock_destroy(&pTree->mutex); pTree->pMutex = NULL; } if (pTree->pFileCollection) { LwRtlRBTreeFree(pTree->pFileCollection); } if (pTree->hFile) { IoCloseFile(pTree->hFile); } if (pTree->pShareInfo) { SrvShareReleaseInfo(pTree->pShareInfo); } if (pTree->resource.ulResourceId) { PSRV_RESOURCE pResource = NULL; SrvElementsUnregisterResource(pTree->resource.ulResourceId, &pResource); pTree->resource.ulResourceId = 0; } // Release parent at the end if (pTree->pSession) { SrvSession2Release(pTree->pSession); } SrvFreeMemory(pTree); }
static NTSTATUS SrvShareBootstrapNamedPipeRoot( IN OUT PLWIO_SRV_SHARE_ENTRY_LIST pShareList ) { NTSTATUS ntStatus = STATUS_SUCCESS; wchar16_t wszPipeRootName[] = {'I','P','C','$',0}; PSRV_SHARE_INFO pShareInfo = NULL; ntStatus = SrvShareFindByName( pShareList, &wszPipeRootName[0], &pShareInfo); if (ntStatus == STATUS_NOT_FOUND) { wchar16_t wszPipeSystemRoot[] = LWIO_SRV_PIPE_SYSTEM_ROOT_W; wchar16_t wszServiceType[] = LWIO_SRV_SHARE_STRING_ID_IPC_W; wchar16_t wszDesc[] = {'R','e','m','o','t','e',' ','I','P','C',0}; ntStatus = SrvShareAdd( pShareList, &wszPipeRootName[0], &wszPipeSystemRoot[0], &wszDesc[0], NULL, 0, &wszServiceType[0], 0); BAIL_ON_NT_STATUS(ntStatus); } cleanup: if (pShareInfo) { SrvShareReleaseInfo(pShareInfo); } return ntStatus; error: LWIO_LOG_ERROR("Failed to bootstrap default IPC$ shares. [error code: %d]", ntStatus); goto cleanup; }
static VOID SrvTreeFree( PLWIO_SRV_TREE pTree ) { LWIO_LOG_DEBUG("Freeing tree [object:0x%x][tid:%u]", pTree, pTree->tid); if (pTree->pMutex) { pthread_rwlock_destroy(&pTree->mutex); pTree->pMutex = NULL; } if (pTree->pFileCollection) { LwRtlRBTreeFree(pTree->pFileCollection); } if (pTree->pAsyncStateCollection) { LwRtlRBTreeFree(pTree->pAsyncStateCollection); } if (pTree->hFile) { IoCloseFile(pTree->hFile); } if (pTree->pShareInfo) { SrvShareReleaseInfo(pTree->pShareInfo); } SrvFreeMemory(pTree); }
static NTSTATUS SrvShareDbWriteToShareInfo( IN sqlite3_stmt* pSqlStatement, OUT PSRV_SHARE_INFO** pppShareInfoList, IN OUT PULONG pulNumSharesFound ) { NTSTATUS ntStatus = 0; PSRV_SHARE_INFO* ppShareInfoList = NULL; PSRV_SHARE_INFO pShareInfo = NULL; PWSTR pwszStringVal = NULL; ULONG ulIntVal = 0; ULONG ulNumSharesAllocated = 0; ULONG ulNumSharesAvailable = 0; ULONG iShare = 0; while ((ntStatus = sqlite3_step(pSqlStatement)) == SQLITE_ROW) { ULONG iCol = 0; if (!ulNumSharesAvailable) { PSRV_SHARE_INFO* ppShareInfoListNew = NULL; ULONG ulNumSharesNew = 5; ULONG ulNumSharesAllocatedNew = ulNumSharesAllocated + ulNumSharesNew; ntStatus = SrvAllocateMemory( sizeof(PSRV_SHARE_INFO) * ulNumSharesAllocatedNew, (PVOID*)&ppShareInfoListNew); BAIL_ON_NT_STATUS(ntStatus); if (ppShareInfoList) { memcpy((PBYTE)ppShareInfoListNew, (PBYTE)ppShareInfoList, sizeof(PSRV_SHARE_INFO) * ulNumSharesAllocated); SrvFreeMemory(ppShareInfoList); } ppShareInfoList = ppShareInfoListNew; ulNumSharesAllocated = ulNumSharesAllocatedNew; ulNumSharesAvailable = ulNumSharesNew; } ntStatus = SrvAllocateMemory( sizeof(SRV_SHARE_INFO), (PVOID*)&pShareInfo); BAIL_ON_NT_STATUS(ntStatus); pShareInfo->refcount = 1; pthread_rwlock_init(&pShareInfo->mutex, NULL); pShareInfo->pMutex = &pShareInfo->mutex; for (; iCol < 5; iCol++) { const unsigned char* pszStringVal = NULL; ULONG ulNumBytes = sqlite3_column_bytes(pSqlStatement, iCol); switch(iCol) { case 0: /* ShareName */ if (ulNumBytes) { pszStringVal = sqlite3_column_text(pSqlStatement, iCol); ntStatus = SrvMbsToWc16s( (PCSTR)pszStringVal, &pShareInfo->pwszName); BAIL_ON_NT_STATUS(ntStatus); } break; case 1: /* PathName */ if (ulNumBytes) { pszStringVal = sqlite3_column_text(pSqlStatement, iCol); ntStatus = SrvMbsToWc16s( (PCSTR)pszStringVal, &pShareInfo->pwszPath); BAIL_ON_NT_STATUS(ntStatus); } break; case 2: /* Comment */ if (ulNumBytes) { pszStringVal = sqlite3_column_text(pSqlStatement, iCol); ntStatus = SrvMbsToWc16s( (PCSTR)pszStringVal, &pShareInfo->pwszComment); } else { /* Deal with empty comments */ ntStatus = SrvMbsToWc16s( "", &pShareInfo->pwszComment); } BAIL_ON_NT_STATUS(ntStatus); break; case 3: /* Security Descriptor */ if (ulNumBytes) { PCVOID pBlob = sqlite3_column_blob(pSqlStatement, iCol); ntStatus = SrvAllocateMemory( ulNumBytes, (PVOID*)&pShareInfo->pSecDesc); BAIL_ON_NT_STATUS(ntStatus); memcpy(pShareInfo->pSecDesc, pBlob, ulNumBytes); pShareInfo->ulSecDescLen = ulNumBytes; } break; case 4: /* service */ if (ulNumBytes) { pszStringVal = sqlite3_column_text(pSqlStatement, iCol); } ntStatus = SrvMbsToWc16s( (PCSTR)pszStringVal, &pwszStringVal); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvShareMapServiceStringToId( pwszStringVal, &pShareInfo->service); BAIL_ON_NT_STATUS(ntStatus); break; case 5: /* flags */ if (ulNumBytes) { ulIntVal = sqlite3_column_int(pSqlStatement, iCol); } pShareInfo->ulFlags = ulIntVal; break; } } *(ppShareInfoList + iShare++) = pShareInfo; pShareInfo = NULL; ulNumSharesAvailable--; } if (ntStatus == SQLITE_DONE) { ntStatus = STATUS_SUCCESS; } BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pSqlStatement); *pppShareInfoList = ppShareInfoList; *pulNumSharesFound = iShare; cleanup: SRV_SAFE_FREE_MEMORY(pwszStringVal); if (pShareInfo) { SrvShareReleaseInfo(pShareInfo); } return ntStatus; error: *pppShareInfoList = NULL; *pulNumSharesFound = 0; if (ppShareInfoList) { SrvShareFreeInfoList(ppShareInfoList, iShare); } goto cleanup; }
NTSTATUS SrvShareRegFindByName( HANDLE hRepository, PWSTR pwszShareName, PSRV_SHARE_INFO* ppShareInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; HKEY hRootKey = NULL; HKEY hKey = NULL; HKEY hSecKey = NULL; REG_DATA_TYPE dataType = REG_UNKNOWN; ULONG ulValueLen = MAX_VALUE_LENGTH; REG_DATA_TYPE dataSecType = REG_UNKNOWN; ULONG ulSecValueLen = MAX_VALUE_LENGTH; PSRV_SHARE_INFO pShareInfo = NULL; BYTE pData[MAX_VALUE_LENGTH] = {0}; BYTE pSecData[MAX_VALUE_LENGTH] = {0}; wchar16_t wszHKTM[] = HKEY_THIS_MACHINE_W; wchar16_t wszSharesKey[] = REG_KEY_PATH_SRV_SHARES_W; wchar16_t wszShareSecKey[] = REG_KEY_PATH_SRV_SHARES_SECURITY_W; ntStatus = NtRegOpenKeyExW( hRepository, NULL, &wszHKTM[0], 0, KEY_READ, &hRootKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenKeyExW( hRepository, hRootKey, &wszSharesKey[0], 0, KEY_READ, &hKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegOpenKeyExW( hRepository, hRootKey, &wszShareSecKey[0], 0, KEY_READ, &hSecKey); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegGetValueW( hRepository, hKey, NULL, pwszShareName, RRF_RT_REG_MULTI_SZ, &dataType, pData, &ulValueLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NtRegGetValueW( hRepository, hSecKey, NULL, pwszShareName, RRF_RT_REG_BINARY, &dataSecType, pSecData, &ulSecValueLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvShareRegWriteToShareInfo( dataType, pwszShareName, pData, ulValueLen, dataSecType, pSecData, ulSecValueLen, &pShareInfo); BAIL_ON_NT_STATUS(ntStatus); *ppShareInfo = pShareInfo; cleanup: if (hRootKey) { NtRegCloseKey(hRepository, hRootKey); } if (hKey) { NtRegCloseKey(hRepository, hKey); } if (hSecKey) { NtRegCloseKey(hRepository, hSecKey); } return ntStatus; error: if (pShareInfo) { SrvShareReleaseInfo(pShareInfo); } goto cleanup; }
static NTSTATUS SrvShareRegWriteToShareInfo( IN REG_DATA_TYPE regDataType, IN PWSTR pwszShareName, IN PBYTE pData, IN ULONG ulDataLen, IN REG_DATA_TYPE regSecDataType, IN PBYTE pSecData, IN ULONG ulSecDataLen, OUT PSRV_SHARE_INFO* ppShareInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSRV_SHARE_INFO pShareInfo = NULL; PWSTR* ppwszValues = NULL; PSTR pszFlags = NULL; ntStatus = SrvAllocateMemory(sizeof(*pShareInfo), (PVOID*)&pShareInfo); BAIL_ON_NT_STATUS(ntStatus); pShareInfo->refcount = 1; pthread_rwlock_init(&pShareInfo->mutex, NULL); pShareInfo->pMutex = &pShareInfo->mutex; ntStatus = SrvAllocateStringW(pwszShareName, &pShareInfo->pwszName); BAIL_ON_NT_STATUS(ntStatus); if (pData) { ULONG iValue = 0; wchar16_t wszCommentPrefix[] = REG_KEY_COMMENT_PREFIX_W; ULONG ulCommentPrefixLen = (sizeof(wszCommentPrefix)/sizeof(wchar16_t)) - 1; wchar16_t wszPathPrefix[] = REG_KEY_PATH_PREFIX_W; ULONG ulPathPrefixLen = (sizeof(wszPathPrefix)/sizeof(wchar16_t)) - 1; wchar16_t wszServicePrefix[] = REG_KEY_SERVICE_PREFIX_W; ULONG ulServicePrefixLen = (sizeof(wszServicePrefix)/sizeof(wchar16_t)) - 1; wchar16_t wszFlagsPrefix[] = REG_KEY_FLAGS_PREFIX_W; ULONG ulFlagsPrefixLen = (sizeof(wszFlagsPrefix)/sizeof(wchar16_t)) - 1; ntStatus = NtRegByteArrayToMultiStrs(pData, ulDataLen, &ppwszValues); BAIL_ON_NT_STATUS(ntStatus); for (; ppwszValues[iValue]; iValue++) { PWSTR pwszValue = &ppwszValues[iValue][0]; if (!wc16sncmp(&wszPathPrefix[0], pwszValue, ulPathPrefixLen)) { SRV_SAFE_FREE_MEMORY(pShareInfo->pwszPath); ntStatus = SrvAllocateStringW( &pwszValue[ulPathPrefixLen], &pShareInfo->pwszPath); BAIL_ON_NT_STATUS(ntStatus); } else if (!wc16sncmp(&wszCommentPrefix[0], pwszValue, ulCommentPrefixLen)) { SRV_SAFE_FREE_MEMORY(pShareInfo->pwszComment); ntStatus = SrvAllocateStringW( &pwszValue[ulCommentPrefixLen], &pShareInfo->pwszComment); BAIL_ON_NT_STATUS(ntStatus); } else if (!wc16sncmp(&wszServicePrefix[0], pwszValue, ulServicePrefixLen)) { ntStatus = SrvShareMapServiceStringToIdW( &pwszValue[ulServicePrefixLen], &pShareInfo->service); BAIL_ON_NT_STATUS(ntStatus); } else if (!wc16sncmp(&wszFlagsPrefix[0], pwszValue, ulFlagsPrefixLen)) { ntStatus = RtlCStringAllocateFromWC16String( &pszFlags, &pwszValue[ulFlagsPrefixLen]); BAIL_ON_NT_STATUS(ntStatus); pShareInfo->ulFlags = strtol(pszFlags, NULL, 16); } else { ntStatus = STATUS_INVALID_PARAMETER_3; BAIL_ON_NT_STATUS(ntStatus); } } } if (!pShareInfo->pwszComment) { wchar16_t wszComment[] = {0}; ntStatus = SrvAllocateStringW( &wszComment[0], &pShareInfo->pwszComment); BAIL_ON_NT_STATUS(ntStatus); } if (ulSecDataLen) { ntStatus = SrvShareSetSecurity( pShareInfo, (PSECURITY_DESCRIPTOR_RELATIVE)pSecData, ulSecDataLen); BAIL_ON_NT_STATUS(ntStatus); } else { ntStatus = SrvShareSetDefaultSecurity(pShareInfo); BAIL_ON_NT_STATUS(ntStatus); } *ppShareInfo = pShareInfo; cleanup: if (ppwszValues) { RegFreeMultiStrsW(ppwszValues); } RTL_FREE(&pszFlags); return ntStatus; error: if (pShareInfo) { SrvShareReleaseInfo(pShareInfo); } goto cleanup; }