Пример #1
0
LW_NTSTATUS
LwRtlSvcmLoadEmbedded(
    LW_IN LW_PCWSTR pServiceName,
    LW_IN LW_SVCM_MODULE_ENTRY_FUNCTION Entry,
    LW_OUT PLW_SVCM_INSTANCE* ppInstance
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_SVCM_INSTANCE pInstance = NULL;

    status = InitPool();
    GCOS(status);

    status = LW_RTL_ALLOCATE_AUTO(&pInstance);
    GCOS(status);

    LW_RTL_LOG_DEBUG("Loading embedded service: %s", pServiceName);

    status = LwRtlSvcmInitializeInstance(pInstance, pServiceName, "<embedded>", Entry);
    GCOS(status);

cleanup:

    if (!NT_SUCCESS(status))
    {
        LwRtlSvcmUnload(pInstance);
        pInstance = NULL;
    }

    *ppInstance = pInstance;

    return status;
}
Пример #2
0
DWORD
LwKrb5SetThreadDefaultCachePath(
    IN PCSTR pszCachePath,
    OUT PSTR* ppszPreviousCachePath
    )
{
    DWORD dwError       = 0;
    DWORD dwMajorStatus = 0;
    DWORD dwMinorStatus = 0;
    PSTR  pszOrigCachePath = NULL;

    // Set the default for gss
    dwMajorStatus = gss_krb5_ccache_name(
                            (OM_uint32 *)&dwMinorStatus,
                            pszCachePath,
                            (ppszPreviousCachePath) ? (const char**)&pszOrigCachePath : NULL);
    BAIL_ON_GSS_ERROR(dwError, dwMajorStatus, dwMinorStatus);

    LW_RTL_LOG_DEBUG("Switched gss krb5 credentials path from %s to %s",
            LW_SAFE_LOG_STRING(pszOrigCachePath),
            LW_SAFE_LOG_STRING(pszCachePath));

    if (ppszPreviousCachePath) {
        if (!LW_IS_NULL_OR_EMPTY_STR(pszOrigCachePath)) {
            dwError = LwAllocateString(pszOrigCachePath, ppszPreviousCachePath);
            BAIL_ON_LW_ERROR(dwError);
        } else {
            *ppszPreviousCachePath = NULL;
        }
    }

cleanup:

    return dwError;

error:

    if (ppszPreviousCachePath) {
        *ppszPreviousCachePath = NULL;
    }

    goto cleanup;
}
Пример #3
0
LW_NTSTATUS
LwRtlSvcmLoadModule(
    LW_IN LW_PCWSTR pServiceName,
    LW_IN LW_PCWSTR pModulePath,
    LW_OUT PLW_SVCM_INSTANCE* ppInstance
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_SVCM_INSTANCE pInstance = NULL;
    PSTR pModulePathA = NULL;
    LW_SVCM_MODULE_ENTRY_FUNCTION Entry = NULL;
    PSTR pEntryName = NULL;
    PSTR pBareName = NULL;
    PSTR pFinalSlash = NULL;
    PSTR pFinalDot = NULL;

    status = InitPool();
    GCOS(status);

    status = LwRtlCStringAllocateFromWC16String(&pModulePathA, pModulePath);
    GCOS(status);

    pFinalSlash = strrchr(pModulePathA, '/');
    pFinalDot = strrchr(pModulePathA, '.');

    if (!pFinalSlash)
    {
        pFinalSlash = pModulePathA;
    }
    else
    {
        pFinalSlash++;
    }

    if (!pFinalDot)
    {
        pFinalDot = pModulePathA + strlen(pModulePathA);
    }

    status = LW_RTL_ALLOCATE(&pBareName, CHAR, (pFinalDot - pFinalSlash) + 1);
    GCOS(status);

    memcpy(pBareName, pFinalSlash, pFinalDot - pFinalSlash);

    status = LwRtlCStringAllocatePrintf(&pEntryName, "_LwSvcmEntry_%s", pBareName);
    GCOS(status);

    status = LW_RTL_ALLOCATE_AUTO(&pInstance);
    GCOS(status);

    LW_RTL_LOG_DEBUG("Loading service module: %s", pModulePathA);

    (void) dlerror();
    pInstance->pDlHandle = dlopen(pModulePathA, RTLD_LOCAL | RTLD_NOW);

    if (!pInstance->pDlHandle)
    {
        LW_RTL_LOG_ERROR(
            "Could not load service module '%s': %s",
            pModulePathA,
            dlerror());

        status = LwErrnoToNtStatus(errno);
        GCOS(status);
    }

    (void) dlerror();
    Entry = dlsym(pInstance->pDlHandle, pEntryName);

    if (!Entry)
    {
        LW_RTL_LOG_ERROR(
            "Could not load entry point from service module '%s': %s",
            pModulePathA,
            dlerror());

        status = LwErrnoToNtStatus(errno);
        if (!status)
        {
            status = STATUS_BAD_DLL_ENTRYPOINT;
        }
        GCOS(status);
    }

    status = LwRtlSvcmInitializeInstance(pInstance, pServiceName, pModulePathA, Entry);
    GCOS(status);

cleanup:

    RTL_FREE(&pModulePathA);
    RTL_FREE(&pBareName);
    RTL_FREE(&pEntryName);

    if (!NT_SUCCESS(status))
    {
        LwRtlSvcmUnload(pInstance);
        pInstance = NULL;
    }

    *ppInstance = pInstance;

    return status;
}
Пример #4
0
// This utility function parse a ldap result in the format of
// <GUID=xxxxxxxx>;<SID=yyyyyyyyy>;distinguishedName (hexadecimal)
// It also handles the case when AD object does not have a SID,
// Hence, <GUID=xxxxxxxx>;distinguishedName
DWORD
LwLdapParseExtendedDNResult(
    IN PCSTR pszExtDnResult,
    OUT PSTR* ppszSid
    )
{
    DWORD dwError = 0;
    PCSTR pszSidHex = NULL;
    PCSTR pszCurrExtDnResult = pszExtDnResult;
    DWORD dwSidLength = 0;
    PSTR pszSid = NULL;
    UCHAR* pucSIDByteArr = NULL;
    DWORD dwSIDByteCount = 0;
    PLW_SECURITY_IDENTIFIER pSID = NULL;

    LW_BAIL_ON_INVALID_STRING(pszCurrExtDnResult);

    if (strncasecmp(pszCurrExtDnResult, "<GUID=", sizeof("<GUID=")-1))
    {
        dwError = LW_ERROR_LDAP_ERROR;
        LW_RTL_LOG_ERROR("Failed to find extended DN entry '%s' GUID part. [error code:%d]",
                       pszExtDnResult, dwError);
        BAIL_ON_LW_ERROR(dwError);
    }

    while (*pszCurrExtDnResult != ';')
    {
        if (*pszCurrExtDnResult == '\0')
        {
            dwError = LW_ERROR_INVALID_PARAMETER;
            BAIL_ON_LW_ERROR(dwError);
        }
        pszCurrExtDnResult++;
    }
    pszCurrExtDnResult++;

    if (strncasecmp(pszCurrExtDnResult, "<SID=", sizeof("<SID=")-1))
    {
        LW_RTL_LOG_DEBUG("The extended DN entry '%s' has no SID part.", pszExtDnResult);
        goto cleanup;
    }

    pszSidHex = pszCurrExtDnResult + sizeof("<SID=") - 1;

    while (*(pszSidHex+dwSidLength) != '>')
    {
        if (*(pszSidHex+dwSidLength) == '\0')
        {
            dwError = LW_ERROR_INVALID_PARAMETER;
            BAIL_ON_LW_ERROR(dwError);
        }
        ++dwSidLength;
    }

    if (*(pszSidHex+dwSidLength+1) != ';')
    {
        dwError = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_LW_ERROR(dwError);
    }

    dwError = LwHexStrToByteArray(
                 pszSidHex,
                 &dwSidLength,
                 &pucSIDByteArr,
                 &dwSIDByteCount);
    BAIL_ON_LW_ERROR(dwError);

    dwError = LwAllocSecurityIdentifierFromBinary(
                 pucSIDByteArr,
                 dwSIDByteCount,
                 &pSID);
    BAIL_ON_LW_ERROR(dwError);

    dwError = LwGetSecurityIdentifierString(
                 pSID,
                 &pszSid);
    BAIL_ON_LW_ERROR(dwError);

cleanup:
    if (dwError)
    {
        LW_SAFE_FREE_STRING(pszSid);
    }
    *ppszSid = pszSid;

    LW_SAFE_FREE_MEMORY(pucSIDByteArr);
    if (pSID)
    {
        LwFreeSecurityIdentifier(pSID);
    }

    return dwError;

error:
    // Do not actually handle any error here,
    // Do it in the cleanup, since there is a 'goto cleanup'

    goto cleanup;
}
Пример #5
0
DWORD
LwLdapPingTcp(
    PCSTR pszHostAddress,
    DWORD dwTimeoutSeconds
    )
{
    DWORD dwError = 0;
    int sysRet = 0;
    int fd = -1;
    struct in_addr addr;
    struct sockaddr_in socketAddress;
    struct timeval timeout;
    fd_set fds;
    int socketError;
#ifdef GETSOCKNAME_TAKES_SOCKLEN_T
    socklen_t socketErrorLength = 0;
#else
    int socketErrorLength = 0;
#endif

    addr.s_addr = inet_addr(pszHostAddress);
    if (addr.s_addr == INADDR_NONE)
    {
        LW_RTL_LOG_ERROR("Could not convert address'%s' to in_addr", pszHostAddress);
        dwError = LW_ERROR_DNS_RESOLUTION_FAILED;
        BAIL_ON_LW_ERROR(dwError);
    }

    socketAddress.sin_family = AF_INET;
    socketAddress.sin_port = htons(389);
    socketAddress.sin_addr = addr;

    fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LW_ERROR(dwError);
    }

    sysRet = fcntl(fd, F_SETFL, O_NONBLOCK);
    if (sysRet < 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LW_ERROR(dwError);
    }

    sysRet = connect(fd, (struct sockaddr *)&socketAddress, sizeof(socketAddress));
    {
        dwError = LwMapErrnoToLwError(errno);
        // We typically expect EINPROGRESS
        dwError = (LW_ERROR_ERRNO_EINPROGRESS == dwError) ? 0 : dwError;
        BAIL_ON_LW_ERROR(dwError);
    }

    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    timeout.tv_sec = dwTimeoutSeconds;
    timeout.tv_usec = 0;

    sysRet = select(fd + 1, NULL, &fds, NULL, &timeout);
    if (sysRet < 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LW_ERROR(dwError);
    }

    switch (sysRet)
    {
        case 0:
            // We timed out
            LW_RTL_LOG_DEBUG("Timed out connecting to '%s'", pszHostAddress);
            // ISSUE-2008/09/16-dalmeida -- Technically, not a "domain"...
            dwError = LW_ERROR_DOMAIN_IS_OFFLINE;
            BAIL_ON_LW_ERROR(dwError);
            break;
        case 1:
            // Normal case
            break;
        default:
            // This should never happen.
            LW_RTL_LOG_DEBUG("Unexpected number of file descriptors returned (%d)", sysRet);
            dwError = LW_ERROR_INVALID_PARAMETER;
            BAIL_ON_LW_ERROR(dwError);
            break;
    }

    if (!FD_ISSET(fd, &fds))
    {
        // ISSUE-2008/07/15-dalmeida -- Suitable error code?
        dwError = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_LW_ERROR(dwError);
    }

    socketError = 0;
    socketErrorLength = sizeof(socketError);
    sysRet = getsockopt(fd, SOL_SOCKET, SO_ERROR, &socketError,
                        &socketErrorLength);
    if (sysRet < 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LW_ERROR(dwError);
    }

    if (socketErrorLength != sizeof(socketError))
    {
        dwError = LW_ERROR_ERRNO_EMSGSIZE;
        BAIL_ON_LW_ERROR(dwError);
    }

    if (socketError)
    {
        dwError = LwMapErrnoToLwError(socketError);
        BAIL_ON_LW_ERROR(dwError);
    }

error:
    if (fd != -1)
    {
        close(fd);
    }

    return dwError;
}