Example #1
0
int
main(
    int argc,
    char** ppszArgv
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    if (argc >= 2)
    {
        if (LwRtlCStringIsEqual(ppszArgv[1], "status", TRUE))
        {
            status = Status(argc - 1, ppszArgv + 1);
            BAIL_ON_NT_STATUS(status);
        }
        else if (LwRtlCStringIsEqual(ppszArgv[1], "load", TRUE))
        {
            int iArg = 2;

            for (; iArg < argc; iArg++)
            {
                status = Load(ppszArgv[iArg]);
                BAIL_ON_NT_STATUS(status);
            }
        }
        else if (LwRtlCStringIsEqual(ppszArgv[1], "unload", TRUE))
        {
            int iArg = 2;

            for (; iArg < argc; iArg++)
            {
                status = Unload(ppszArgv[iArg]);
                BAIL_ON_NT_STATUS(status);
            }
        }
        else
        {
            Usage(ppszArgv[0]);
        }
    }
    else
    {
        Usage(ppszArgv[0]);
    }

cleanup:

    return status ? 1 : 0;

error:

    goto cleanup;
}
Example #2
0
static
NTSTATUS
PvfsFindParentFCB(
    PPVFS_FCB *ppParentFcb,
    PCSTR pszFilename
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_FCB pFcb = NULL;
    PSTR pszDirname = NULL;
    PPVFS_CB_TABLE_ENTRY pBucket = NULL;

    if (LwRtlCStringIsEqual(pszFilename, "/", TRUE))
    {
        ntError = STATUS_SUCCESS;
        *ppParentFcb = NULL;

        goto cleanup;
    }

    ntError = PvfsFileDirname(&pszDirname, pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCbTableGetBucket(&pBucket, &gPvfsDriverState.FcbTable, pszDirname);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCbTableLookup((PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pFcb), pBucket, pszDirname);
    if (ntError == STATUS_OBJECT_NAME_NOT_FOUND)
    {
        ntError = PvfsCreateFCB(
                      &pFcb,
                      pszDirname,
                      FALSE,
                      0,
                      0);
    }
    BAIL_ON_NT_STATUS(ntError);

    *ppParentFcb = PvfsReferenceFCB(pFcb);

cleanup:
    if (pFcb)
    {
        PvfsReleaseFCB(&pFcb);
    }

    if (pszDirname)
    {
        LwRtlCStringFree(&pszDirname);
    }

    return ntError;

error:

    goto cleanup;
}
Example #3
0
static
BOOLEAN
PvfsSysIsEmptyDir(
    PSTR pszDirname
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    BOOLEAN isEmptyDir = TRUE;
    DIR *pDir = NULL;
    struct dirent *pDirEntry = NULL;
    struct dirent dirEntry = { 0 };

    ntError = PvfsSysOpenDir(pszDirname, &pDir);
    BAIL_ON_NT_STATUS(ntError);

    for (ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry);
            pDirEntry;
            ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry))
    {
        /* First check the error return */
        BAIL_ON_NT_STATUS(ntError);

        if (!LwRtlCStringIsEqual(pDirEntry->d_name, ".", FALSE) &&
                !LwRtlCStringIsEqual(pDirEntry->d_name, "..", FALSE))
        {
            isEmptyDir = FALSE;
            break;
        }
    }

error:
    if (pDir)
    {
        PvfsSysCloseDir(pDir);
    }

    return NT_SUCCESS(ntError) ? isEmptyDir : FALSE;
}
Example #4
0
static
NTSTATUS
SrvBuildNegotiateResponseForDialect(
    IN PLWIO_SRV_CONNECTION pConnection,
    IN PSMB_PACKET pSmbRequest,
    IN PSTR* ppszDialectArray,
    IN ULONG ulNumDialects,
    OUT PSMB_PACKET* ppSmbResponse
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    SHORT dialectIdx = 0;
    BOOLEAN supportSMBV2 = SrvProtocolConfigIsSmb2Enabled();
    PSMB_PACKET pSmbResponse = NULL;
    SMB_PROTOCOL_VERSION protocolVersion = SMB_PROTOCOL_VERSION_UNKNOWN;
    SMB_PROTOCOL_DIALECT protocolDialect = SMB_PROTOCOL_DIALECT_UNKNOWN;

    for (dialectIdx = ulNumDialects-1; dialectIdx >= 0; dialectIdx--)
    {
        if (supportSMBV2 &&
            LwRtlCStringIsEqual(
                ppszDialectArray[dialectIdx],
                SRV_NEGOTIATE_DIALECT_STRING_SMB_2_1,
                TRUE))
        {
            protocolVersion = SMB_PROTOCOL_VERSION_2;
            protocolDialect = SMB_PROTOCOL_DIALECT_SMB_2_1;
        }
        else if (supportSMBV2 &&
                 LwRtlCStringIsEqual(
                     ppszDialectArray[dialectIdx],
                     SRV_NEGOTIATE_DIALECT_STRING_SMB_2,
                     TRUE))
        {
            protocolVersion = SMB_PROTOCOL_VERSION_2;
            protocolDialect = SMB_PROTOCOL_DIALECT_SMB_2_0;
        }
        else if (LwRtlCStringIsEqual(
                     ppszDialectArray[dialectIdx],
                     SRV_NEGOTIATE_DIALECT_STRING_NTLM_0_12,
                     TRUE))
        {
            protocolVersion = SMB_PROTOCOL_VERSION_1;
            protocolDialect = SMB_PROTOCOL_DIALECT_NTLM_0_12;
        }

        if (protocolVersion != SMB_PROTOCOL_VERSION_UNKNOWN)
        {
            // Found the dialect we want so exit loop
            break;
        }
    }

    switch (protocolVersion)
    {
        case SMB_PROTOCOL_VERSION_UNKNOWN:
            ntStatus = SrvBuildNegotiateResponse_SMB_V1_Invalid(
                           pConnection,
                           pSmbRequest,
                           &pSmbResponse);
            break;

        case SMB_PROTOCOL_VERSION_1:
            ntStatus = SrvBuildNegotiateResponse_SMB_V1_NTLM_0_12(
                           pConnection,
                           pSmbRequest,
                           protocolDialect,
                           dialectIdx,
                           &pSmbResponse);
            break;

        case SMB_PROTOCOL_VERSION_2:
            ntStatus = SrvBuildNegotiateResponse_SMB_V2(
                           pConnection,
                           pSmbRequest,
                           protocolDialect,
                           &pSmbResponse);
            break;
    }
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvConnectionSetProtocolVersion(
                   pConnection,
                   protocolVersion,
                   protocolDialect);
    BAIL_ON_NT_STATUS(ntStatus);

error:
    if (!NT_SUCCESS(ntStatus))
    {
        if (pSmbResponse)
        {
            SMBPacketRelease(pConnection->hPacketAllocator, pSmbResponse);
            pSmbResponse = NULL;
        }
    }

    *ppSmbResponse = pSmbResponse;

    return ntStatus;
}
Example #5
0
DWORD
RegShellUtilExport(
    HANDLE hReg,
    PREG_EXPORT_STATE pExportState,
    HKEY hKey,
    PCSTR pszKeyName,
    DWORD dwNumSubKeys,
    DWORD dwMaxSubKeyLen
    )
{
    DWORD dwError = 0;
    REG_DATA_TYPE prevType = REG_NONE;
    SECURITY_INFORMATION SecInfoAll = OWNER_SECURITY_INFORMATION
                                     |GROUP_SECURITY_INFORMATION
                                     |DACL_SECURITY_INFORMATION
                                     |SACL_SECURITY_INFORMATION;
    PBYTE pSecDescRel = NULL;
    ULONG ulSecDescLen = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    PSTR pszStringSecurityDescriptor = NULL;

    dwError = RegGetKeySecurity(hReg,
                                hKey,
                                SecInfoAll,
                                NULL,
                                &ulSecDescLen);
    BAIL_ON_REG_ERROR(dwError);

    dwError = RegAllocateMemory(ulSecDescLen, (PVOID)&pSecDescRel);
    BAIL_ON_REG_ERROR(dwError);

    dwError = RegGetKeySecurity(hReg,
                                hKey,
                                SecInfoAll,
                                (PSECURITY_DESCRIPTOR_RELATIVE)pSecDescRel,
                                &ulSecDescLen);
    BAIL_ON_REG_ERROR(dwError);

    if (LwRtlCStringIsEqual(pszKeyName,HKEY_THIS_MACHINE,TRUE) ||
        ulSecDescLen != pExportState->ulRootKeySecDescLen ||
        !LwRtlEqualMemory(pSecDescRel, pExportState->pRootKeySecDescRel, ulSecDescLen))
    {
        dwError = RegNtStatusToWin32Error(
                      RtlAllocateSddlCStringFromSecurityDescriptor(
                          &pszStringSecurityDescriptor,
                         (PSECURITY_DESCRIPTOR_RELATIVE)pSecDescRel,
                          SDDL_REVISION_1,
                          SecInfoAll)
                         );
        BAIL_ON_REG_ERROR(dwError);
    }

    if (hKey)
    {
        dwError = ProcessExportedKeyInfo(hReg,
                                         pExportState,
                                         hKey,
                                         pszKeyName,
                                         pExportState->dwExportFormat == 1 ?
                                             NULL : pszStringSecurityDescriptor,
                                         &prevType);
        BAIL_ON_REG_ERROR(dwError);
    }
    if (hKey && dwNumSubKeys != 0)
    {
        dwError = ProcessSubKeys(hReg,
                                 pExportState,
                                 hKey,
                                 pszKeyName,
                                 dwNumSubKeys,
                                 dwMaxSubKeyLen);
        BAIL_ON_REG_ERROR(dwError);
    }
    else if (hKey == NULL && dwNumSubKeys == 0)
    {
        dwError = ProcessRootKeys(hReg,
                                  pExportState);
        BAIL_ON_REG_ERROR(dwError);
    }
    else if (hKey == NULL && dwNumSubKeys != 0)
    {
        dwError = ERROR_INTERNAL_ERROR;
        BAIL_ON_REG_ERROR(dwError);
    }

cleanup:
    if (pszStringSecurityDescriptor)
    {
        RegFreeString(pszStringSecurityDescriptor);
    }
    LWREG_SAFE_FREE_MEMORY(pSecDescRel);

    if (pSecDescRel)
    {
        RegMemoryFree(pSecDescRel);
        pSecDescRel = NULL;
    }

    return dwError;

error:
    goto cleanup;
}
Example #6
0
DWORD
SrvSvcRegisterForRPC(
    PSTR pszServiceName,
    rpc_binding_vector_p_t* ppServerBinding
    )
{
    volatile DWORD dwError = 0;
    volatile DWORD dwRpcStatus = 0;
    rpc_binding_vector_p_t pServerBinding = NULL;
    BOOLEAN bRegistered = FALSE;
    BOOLEAN bBound = FALSE;
    BOOLEAN bEPRegistered = FALSE;
    static ENDPOINT endpoints[] =
    {
        {"ncacn_np",   "\\\\pipe\\\\srvsvc"},
        {"ncalrpc",    NULL}, // endpoint is fetched from config parameter
        {NULL,         NULL}, // placeholder for ncacn_ip_tcp (if enabled)
        {NULL,         NULL}
    };
    DWORD i = 0;
    PSTR lpcSocketPath = NULL;
    BOOLEAN registerTcpIp = FALSE;

    dwError = SrvSvcConfigGetLpcSocketPath(&lpcSocketPath);
    BAIL_ON_SRVSVC_ERROR(dwError);

    // Fill in the socket path for local procedure calls (ncalrpc)
    while (endpoints[i].protocol) {
        if (lpcSocketPath &&
            LwRtlCStringIsEqual(endpoints[i].protocol,
                                "ncalrpc",
                                TRUE))
        {
            endpoints[i].endpoint = lpcSocketPath;
        }

        i++;
    }

    dwError = SrvSvcConfigGetRegisterTcpIp(&registerTcpIp);
    BAIL_ON_SRVSVC_ERROR(dwError);

    // Append ncacn_ip_tcp endpoint if it's enabled in the configuration
    if (registerTcpIp)
    {
        endpoints[i++].protocol = "ncacn_ip_tcp";
    }

    DCETHREAD_TRY
    {
        rpc_server_register_if (srvsvc_v3_0_s_ifspec,
                                NULL,
                                NULL,
                                (unsigned32*)&dwRpcStatus);
    }
    DCETHREAD_CATCH_ALL(THIS_CATCH)
    {
        if ( dwRpcStatus == RPC_S_OK )
        {
            dwError = dcethread_exc_getstatus (THIS_CATCH);
            if(!dwError)
            {
                dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER;
            }
        }
    }
    DCETHREAD_ENDTRY;

    BAIL_ON_DCE_ERROR(dwError, dwRpcStatus);
    BAIL_ON_SRVSVC_ERROR(dwError);

    bRegistered = TRUE;
    SRVSVC_LOG_INFO("RPC Service registered successfully.");

    DCETHREAD_TRY
    {
        dwError = bind_server(&pServerBinding,
                              srvsvc_v3_0_s_ifspec,
                              endpoints);
    }
    DCETHREAD_CATCH_ALL(THIS_CATCH)
    {
        if(!dwError)
        {
            dwError = dcethread_exc_getstatus (THIS_CATCH);
        }
        if(!dwError)
        {
            dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER;
        }
    }
    DCETHREAD_ENDTRY;

    BAIL_ON_SRVSVC_ERROR(dwError);

    bBound = TRUE;

    DCETHREAD_TRY
    {
        rpc_ep_register(srvsvc_v3_0_s_ifspec,
                        pServerBinding,
                        NULL,
                        (idl_char*)pszServiceName,
                        (unsigned32*)&dwRpcStatus);
    }
    DCETHREAD_CATCH_ALL(THIS_CATCH)
    {
        if ( dwRpcStatus == RPC_S_OK )
        {
            dwError = dcethread_exc_getstatus (THIS_CATCH);
            if(!dwError)
            {
                dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER;
            }
        }
    }
    DCETHREAD_ENDTRY;

    BAIL_ON_DCE_ERROR(dwError, dwRpcStatus);
    BAIL_ON_SRVSVC_ERROR(dwError);

    bEPRegistered = TRUE;
    SRVSVC_LOG_INFO("RPC Endpoint registered successfully.");

    *ppServerBinding = pServerBinding;

cleanup:
    // DCE/RPC runtime makes a copy of ncalrpc socket path internally
    // so it is safe to free it here
    LW_SAFE_FREE_MEMORY(lpcSocketPath);

    return dwError;

error:

    SRVSVC_LOG_ERROR("Failed to register RPC endpoint.  Error Code: [%u]\n", dwError);

    if (bEPRegistered)
    {
        DCETHREAD_TRY
        {
            DWORD tmpStatus = 0;
            rpc_ep_unregister(srvsvc_v3_0_s_ifspec,
                              pServerBinding,
                              NULL,
                              (unsigned32*)&tmpStatus);
        }
        DCETHREAD_CATCH_ALL(THIS_CATCH)
        DCETHREAD_ENDTRY;
    }

    if (bBound) {
        DCETHREAD_TRY
        {
            DWORD tmpStatus = 0;
            rpc_binding_vector_free(&pServerBinding,
                                    (unsigned32*)&tmpStatus);
        }
        DCETHREAD_CATCH_ALL(THIS_CATCH)
        DCETHREAD_ENDTRY;
    }

    if (bRegistered)
    {
        DCETHREAD_TRY
        {
            DWORD tmpStatus = 0;
            rpc_server_unregister_if (srvsvc_v3_0_s_ifspec,
                                      NULL,
                                      (unsigned32*)&tmpStatus);
        }
        DCETHREAD_CATCH_ALL(THIS_CATCH)
        DCETHREAD_ENDTRY;
    }

    *ppServerBinding = NULL;

    goto cleanup;
}
Example #7
0
static
NTSTATUS
PvfsSysRemoveDir(
    PSTR pszDirname
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    DIR *pDir = NULL;
    struct dirent *pDirEntry = NULL;
    struct dirent dirEntry = { 0 };
    PSTR pszPath = NULL;
    PVFS_STAT streamDirStat = { 0 };

    ntError = PvfsSysOpenDir(pszDirname, &pDir);
    BAIL_ON_NT_STATUS(ntError);

    for (ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry);
            pDirEntry;
            ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry))
    {
        /* First check the error return */
        BAIL_ON_NT_STATUS(ntError);

        memset(&streamDirStat, 0, sizeof(PVFS_STAT));
        if (pszPath)
        {
            LwRtlCStringFree(&pszPath);
        }

        ntError = LwRtlCStringAllocatePrintf(
                      &pszPath,
                      "%s/%s",
                      pszDirname,
                      pDirEntry->d_name);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysStat(pszPath, &streamDirStat);
        if (ntError == STATUS_SUCCESS)
        {
            if(S_ISDIR(streamDirStat.s_mode))
            {
                if (!LwRtlCStringIsEqual(pDirEntry->d_name, ".", FALSE) &&
                        !LwRtlCStringIsEqual(pDirEntry->d_name, "..", FALSE))
                {
                    ntError = PvfsSysRemoveDir(pszPath);
                    BAIL_ON_NT_STATUS(ntError);
                }
            }
            else
            {
                ntError = PvfsSysRemove(pszPath);
                BAIL_ON_NT_STATUS(ntError);
            }
        }
        else
        {
            // Squash the error is the stream directory did not exist
            ntError = STATUS_SUCCESS;
        }
    }

    ntError = PvfsSysCloseDir(pDir);
    BAIL_ON_NT_STATUS(ntError);
    pDir = NULL;

    ntError = PvfsSysRemove(pszDirname);
    BAIL_ON_NT_STATUS(ntError);

error:
    if (pszPath)
    {
        LwRtlCStringFree(&pszPath);
    }

    if (pDir)
    {
        PvfsSysCloseDir(pDir);
    }

    return ntError;
}
Example #8
0
NTSTATUS
PvfsRenameCCB(
    IN PPVFS_CCB pCcb,
    IN PPVFS_FILE_NAME pDestFileName
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PVFS_FILE_NAME srcFileName = { 0 };

    ntError = PvfsValidatePathSCB(pCcb->pScb, &pCcb->FileId);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsBuildFileNameFromScb(&srcFileName, pCcb->pScb);
    BAIL_ON_NT_STATUS(ntError);

    if (!PvfsIsDefaultStreamName(&srcFileName) &&
        !PvfsIsDefaultStreamName(pDestFileName))
    {
        // Two named streams
        if (LwRtlCStringIsEqual(
                PvfsGetCStringBaseStreamName(&srcFileName),
                PvfsGetCStringBaseStreamName(pDestFileName),
                FALSE))
        {
            // Both src and dst stream names are the same
            // renaming the underlying file object

            ntError = PvfsRenameFile(pCcb, pDestFileName);
        }
        else if (LwRtlCStringIsEqual(
                     PvfsGetCStringBaseFileName(&srcFileName),
                     PvfsGetCStringBaseFileName(pDestFileName),
                     FALSE))
        {
            // Renaming the named stream, file name stays the same

            ntError = PvfsRenameStream(pCcb, pDestFileName);
        }
        else
        {
            // Don't allow renaming both the file name and stream name at the
            // same time (yet)

            ntError = STATUS_OBJECT_NAME_INVALID;
        }
    }
    else if (PvfsIsDefaultStreamName(&srcFileName) &&
             PvfsIsDefaultStreamName(pDestFileName))
    {
        // Two default streams rename object itself
        ntError = PvfsRenameFile(pCcb, pDestFileName);
    }
    else if (!PvfsIsDefaultStreamName(&srcFileName) &&
             PvfsIsDefaultStreamName(pDestFileName))
    {
        // rename name stream -> default stream
        // A stream on a directory cannot be renamed to the default data stream
        if (!LwRtlCStringIsEqual(
                         PvfsGetCStringBaseFileName(&srcFileName),
                         PvfsGetCStringBaseFileName(pDestFileName),
                         FALSE) || PVFS_IS_DIR(pCcb))
        {
            ntError = STATUS_OBJECT_NAME_INVALID;
        }
        else
        {
            ntError = PvfsRenameStream(pCcb, pDestFileName);
        }
    }
    else
    {
        // disallow rename object->stream as what smbtorture expects
        // TODO:
        // we may want to allow "Renaming" the default data stream
        // it is not a true rename, and it leaves behind a zero-length default data streams
        ntError = STATUS_OBJECT_NAME_INVALID;
    }
    BAIL_ON_NT_STATUS(ntError);

error:
    PvfsDestroyFileName(&srcFileName);

    return ntError;
}