Exemple #1
0
static
NTSTATUS
SrvShareBootstrapDiskRoot(
    IN OUT PLWIO_SRV_SHARE_ENTRY_LIST pShareList
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    wchar16_t wszFileRootName[] = {'C','$',0};
    PSTR  pszDefaultSharePath = NULL;
    PWSTR pwszFileSystemRoot = NULL;
    PSRV_SHARE_INFO pShareInfo = NULL;

    ntStatus = SrvShareFindByName(
                        pShareList,
                        &wszFileRootName[0],
                        &pShareInfo);
    if (ntStatus == STATUS_NOT_FOUND)
    {
        wchar16_t wszDesc[] =
                        {'D','e','f','a','u','l','t',' ','S','h','a','r','e',0};
        wchar16_t wszServiceType[] = LWIO_SRV_SHARE_STRING_ID_DISK_W;

        ntStatus = SrvGetDefaultSharePath(&pszDefaultSharePath);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvMbsToWc16s(pszDefaultSharePath, &pwszFileSystemRoot);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvCreateDefaultSharePath(pwszFileSystemRoot);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvShareAdd(
                        pShareList,
                        &wszFileRootName[0],
                        pwszFileSystemRoot,
                        &wszDesc[0],
                        NULL,
                        0,
                        &wszServiceType[0],
                        0);
    }
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    SRV_SAFE_FREE_MEMORY(pszDefaultSharePath);
    SRV_SAFE_FREE_MEMORY(pwszFileSystemRoot);

    return ntStatus;

error:

    LWIO_LOG_ERROR("Failed to bootstrap default shares. [error code: %d]",
                   ntStatus);

    goto cleanup;
}
Exemple #2
0
NTSTATUS
SrvSocketAddressToStringW(
    const struct sockaddr* pSocketAddress,
    PWSTR*           ppwszAddress
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    CHAR     szBuffer[SRV_SOCKET_ADDRESS_STRING_MAX_SIZE];
    PWSTR    pwszAddress = NULL;

    if (!pSocketAddress)
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvSocketAddressToString(
                        pSocketAddress,
                        &szBuffer[0],
                        sizeof(szBuffer));
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvMbsToWc16s(szBuffer, &pwszAddress);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppwszAddress = pwszAddress;

cleanup:

    return ntStatus;

error:

    *ppwszAddress = NULL;

    goto cleanup;
}
Exemple #3
0
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;
}
Exemple #4
0
NTSTATUS
SrvGetShareName(
    IN  PCSTR  pszHostname,
    IN  PCSTR  pszDomain,
    IN  PWSTR  pwszPath,
    OUT PWSTR* ppwszSharename
    )
{
    NTSTATUS ntStatus = 0;
    PWSTR    pwszSharename = NULL;
    PSTR     pszPath = NULL;
    PSTR     pszShareName = NULL;
    PSTR     pszCursor = NULL;

    ntStatus = SrvWc16sToMbs(pwszPath, &pszPath);
    BAIL_ON_NT_STATUS(ntStatus);

    pszCursor = pszPath;

    /* Skip a leading pair of backslashes */

    if ((strlen(pszCursor) > 2) &&
        (*pszCursor == '\\')    &&
        (*(pszCursor+1) == '\\'))
    {
        pszCursor += 2;
    }

    pszShareName = strchr(pszCursor, '\\');
    if (pszShareName == NULL)
    {
        pszShareName = pszCursor;
    }
    else
    {
        pszShareName++;
    }

    if (*pszShareName == '\0')
    {
        ntStatus = STATUS_BAD_NETWORK_PATH;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvMbsToWc16s(pszShareName, &pwszSharename);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppwszSharename = pwszSharename;

cleanup:

    if (pszPath)
    {
        SrvFreeMemory(pszPath);
    }

    return ntStatus;

error:

    *ppwszSharename = NULL;

    goto cleanup;
}
Exemple #5
0
NTSTATUS
SrvBuildNegotiateResponse_SMB_V1_NTLM_0_12(
    IN PLWIO_SRV_CONNECTION pConnection,
    IN PSMB_PACKET pSmbRequest,
    IN SMB_PROTOCOL_DIALECT Dialect,
    IN USHORT idxDialect,
    OUT PSMB_PACKET* ppSmbResponse
    )
{
    NTSTATUS ntStatus = 0;
    NEGOTIATE_RESPONSE_HEADER* pResponseHeader = NULL;
    time_t    curTime   = 0L;
    LONG64    llUTCTime = 0LL;
    uint16_t  byteCount = 0;
    uint8_t*  pDataCursor = NULL;
    PSRV_PROPERTIES pServerProperties = &pConnection->serverProperties;
    PSMB_PACKET pSmbResponse = NULL;
    PWSTR     pwszHostname = NULL;

    ntStatus = SMBPacketAllocate(
                    pConnection->hPacketAllocator,
                    &pSmbResponse);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SMBPacketBufferAllocate(
                    pConnection->hPacketAllocator,
                    (64 * 1024) + 4096,
                    &pSmbResponse->pRawBuffer,
                    &pSmbResponse->bufferLen);
    BAIL_ON_NT_STATUS(ntStatus);

    if ((pSmbRequest->pSMBHeader->flags2 & FLAG2_EXT_SEC) == 0)
    {
        pServerProperties->Capabilities &= ~CAP_EXTENDED_SECURITY;
    }

    ntStatus = SMBPacketMarshallHeader(
                pSmbResponse->pRawBuffer,
                pSmbResponse->bufferLen,
                COM_NEGOTIATE,
                0,
                TRUE,
                pSmbRequest->pSMBHeader->tid,
                SMB_V1_GET_PROCESS_ID(pSmbRequest->pSMBHeader),
                0,
                pSmbRequest->pSMBHeader->mid,
                FALSE,
                pSmbResponse);
    BAIL_ON_NT_STATUS(ntStatus);
    if ((pServerProperties->Capabilities & CAP_EXTENDED_SECURITY) == 0)
    {
        pSmbResponse->pSMBHeader->flags2 &= ~FLAG2_EXT_SEC;
    }

    pSmbResponse->pSMBHeader->wordCount = 17;

    pResponseHeader = (NEGOTIATE_RESPONSE_HEADER*)pSmbResponse->pParams;
    pSmbResponse->pData = pSmbResponse->pParams + sizeof(NEGOTIATE_RESPONSE_HEADER);
    pSmbResponse->bufferUsed += sizeof(NEGOTIATE_RESPONSE_HEADER);

    pResponseHeader->dialectIndex = idxDialect;

    pResponseHeader->securityMode = 0;
    if (pServerProperties->preferredSecurityMode == SMB_SECURITY_MODE_USER)
    {
        pResponseHeader->securityMode |= 0x1; // User level security
    }
    if (pServerProperties->bEncryptPasswords)
    {
        pResponseHeader->securityMode |= 0x2;
    }
    if (pServerProperties->bEnableSecuritySignatures)
    {
        pResponseHeader->securityMode |= 0x4;
    }
    if (pServerProperties->bRequireSecuritySignatures)
    {
        pResponseHeader->securityMode |= 0x8;
    }

    pResponseHeader->maxMpxCount = pServerProperties->MaxMpxCount;
    pResponseHeader->maxNumberVcs = pServerProperties->MaxNumberVCs;
    pResponseHeader->maxBufferSize = pServerProperties->MaxBufferSize;
    pResponseHeader->maxRawSize = pServerProperties->MaxRawSize;
    pResponseHeader->sessionKey = 0;
    pResponseHeader->capabilities = pServerProperties->Capabilities;

    curTime = time(NULL);

    ntStatus = WireSMBUTimeToTimeZone(curTime, &pResponseHeader->serverTimeZone);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = WireSMBUTimetoNTTime(curTime, FALSE, &llUTCTime);
    BAIL_ON_NT_STATUS(ntStatus);

    pResponseHeader->systemTimeLow = llUTCTime & 0xFFFFFFFFLL;
    pResponseHeader->systemTimeHigh = (llUTCTime & 0xFFFFFFFF00000000LL) >> 32;

    pDataCursor = pSmbResponse->pData;
    if (pResponseHeader->capabilities & CAP_EXTENDED_SECURITY)
    {
        PBYTE pNegHintsBlob = NULL; /* Do not free */
        ULONG ulNegHintsLength = 0;

        pResponseHeader->encryptionKeyLength = 0;

        memcpy(pDataCursor, pServerProperties->GUID, sizeof(pServerProperties->GUID));
        pDataCursor += sizeof(pServerProperties->GUID);

        byteCount += sizeof(pServerProperties->GUID);

        ntStatus = SrvGssNegHints(&pNegHintsBlob, &ulNegHintsLength);

        /* Microsoft clients ignore the security blob on the neg prot response
           so don't fail here if we can't get a negHintsBlob */

        if (ntStatus == STATUS_SUCCESS)
        {
            memcpy(pDataCursor, pNegHintsBlob, ulNegHintsLength);
            pDataCursor += ulNegHintsLength;
            byteCount += ulNegHintsLength;
        }
    }
    else
    {
        WCHAR wszWorkgroup[] = SRV_NATIVE_DOMAIN_W;
        CHAR  szHostname[HOST_NAME_MAX];
        PWSTR pwszDomain = pConnection->clientProperties.pwszNativeDomain;

        if (!pwszDomain)
        {
            pwszDomain = &wszWorkgroup[0];
        }

        if (gethostname(szHostname, HOST_NAME_MAX) == -1)
        {
            ntStatus = LwErrnoToNtStatus(errno);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        pResponseHeader->encryptionKeyLength =
            sizeof(pConnection->ServerChallenge);

        // Generate challenge and remember it in connection
        if (!RAND_bytes( pConnection->ServerChallenge,
                         sizeof(pConnection->ServerChallenge)))
        {
            ntStatus = STATUS_INTERNAL_ERROR;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        RtlCopyMemory(pDataCursor, &pConnection->ServerChallenge,
                      sizeof(pConnection->ServerChallenge));
        pDataCursor += sizeof(pConnection->ServerChallenge);
        byteCount += sizeof(pConnection->ServerChallenge);

        // Add domain name
        {
            size_t sDomainLen = (wc16slen(pwszDomain)+1) * sizeof(wchar16_t);

            RtlCopyMemory(pDataCursor, pwszDomain, sDomainLen);
            pDataCursor += sDomainLen;
            byteCount += sDomainLen;
        }

        // Add hostname
        {
            size_t sHostnameLen = 0;

            ntStatus = SrvMbsToWc16s(szHostname, &pwszHostname);
            BAIL_ON_NT_STATUS(ntStatus);

            sHostnameLen = (wc16slen(pwszHostname)+1) * sizeof(wchar16_t);
            RtlCopyMemory(pDataCursor, pwszHostname, sHostnameLen);
            pDataCursor += sHostnameLen;
            byteCount += sHostnameLen;
        }
    }

    pResponseHeader->byteCount = byteCount;
    pSmbResponse->bufferUsed += byteCount;

    ntStatus = SMBPacketMarshallFooter(pSmbResponse);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppSmbResponse = pSmbResponse;

cleanup:

    SRV_SAFE_FREE_MEMORY(pwszHostname);

    return ntStatus;

error:

    *ppSmbResponse = NULL;

    if (pSmbResponse)
    {
        SMBPacketRelease(pConnection->hPacketAllocator, pSmbResponse);
    }

    goto cleanup;
}