Пример #1
0
static
NTSTATUS
ValidateModuleTable(
    PLW_SVCM_MODULE pTable,
    PCSTR pPath
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    if (!pTable)
    {
        LW_RTL_LOG_ERROR(
            "Service module '%s' did not provide a function table",
            pPath);
        status = STATUS_BAD_DLL_ENTRYPOINT;
        GCOS(status);
    }

    if (pTable->Size < sizeof(*pTable) ||
        !pTable->Init || !pTable->Destroy ||
        !pTable->Start || !pTable->Stop)
    {
        LW_RTL_LOG_ERROR(
            "Service module '%s' has a bogus function table",
            pPath);
        status = STATUS_BAD_DLL_ENTRYPOINT;
        GCOS(status);
    }

    cleanup:

    return status;
}
Пример #2
0
static
DWORD
LsaPstorepInitializePlugin(
    OUT PLSA_PSTORE_PLUGIN_INFO PluginInfo,
    IN PCSTR PluginName
    )
{
    DWORD dwError = 0;
    int EE = 0;
    LSA_PSTORE_PLUGIN_INITIALIZE_FUNCTION initFunction = NULL;

    dwError = LwNtStatusToWin32Error(LwRtlCStringDuplicate(&PluginInfo->Name, PluginName));
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepGetPluginPath(PluginInfo->Name, &PluginInfo->Path);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);
    
    dwError = LsaPstorepOpenPlugin(
                    PluginInfo->Path,
                    LSA_PSTORE_PLUGIN_INITIALIZE_FUNCTION_NAME,
                    &PluginInfo->LibraryHandle,
                    OUT_PPVOID(&initFunction));
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = initFunction(LSA_PSTORE_PLUGIN_VERSION,
                           PluginInfo->Name,
                           &PluginInfo->Dispatch,
                           &PluginInfo->Context);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    if (!PluginInfo->Dispatch)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin %s is missing a dispatch table",
                         PluginInfo->Name);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }

    if (!PluginInfo->Dispatch->Cleanup)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin %s is missing the Cleanup function",
                         PluginInfo->Name);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }

    LW_RTL_LOG_VERBOSE("Loaded LSA pstore plugin %s from %s",
                       PluginInfo->Name, PluginInfo->Path);

cleanup:
    if (dwError)
    {
        LsaPstorepCleanupPlugin(PluginInfo);
    }

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Пример #3
0
DWORD
LwLdapBindDirectorySasl(
    LDAP *ld,
    PCSTR pszServerName,
    BOOLEAN bSeal
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;

    // Do not attempt to canonicalize the server
    // name which isn't necessary since we used
    // the server's FQDN or address.

    dwError = ldap_set_option(
                  ld,
                  LDAP_OPT_X_SASL_NOCANON,
                  LDAP_OPT_ON);
    BAIL_ON_LDAP_ERROR(dwError);

    // ssf=1 is sign, ssf>1 is seal.  By default
    // it will use the maximum available ssf level
    // so setting minssf isn't strictly necessary.
    // Setting minssf guarantees an error if it
    // cannot provide the minimum level.

    if (bSeal)
    {
        dwError = ldap_set_option(
                      ld,
                      LDAP_OPT_X_SASL_SECPROPS,
                      (void *)"minssf=2");
        BAIL_ON_LDAP_ERROR(dwError);
    }
    else
    {
        dwError = ldap_set_option(
                      ld,
                      LDAP_OPT_X_SASL_SECPROPS,
                      (void *)"minssf=1,maxssf=1");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    dwError = ldap_sasl_interactive_bind_s(
                  ld,
                  NULL,
                  "GSS-SPNEGO",
                  NULL,
                  NULL,
                  LDAP_SASL_QUIET,
                  LwLdapGssSpnegoInteract,
                  (void *)pszServerName);
    if (dwError != 0) {
        LW_RTL_LOG_ERROR("ldap_sasl_interactive_bind_s failed with error code %d", dwError);
        BAIL_ON_LDAP_ERROR(dwError);
    }

error:

    return dwError;
}
Пример #4
0
DWORD
LwLdapBindDirectoryAnonymous(
    HANDLE hDirectory
    )
{
    DWORD dwError = 0;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

    LW_BAIL_ON_INVALID_HANDLE(hDirectory);

    dwError = ldap_bind_s(
                    pDirectory->ld,
                    NULL,
                    NULL,
                    LDAP_AUTH_SIMPLE);
    BAIL_ON_LDAP_ERROR(dwError);

cleanup:

    return dwError;

error:

    LW_RTL_LOG_ERROR("Failed on LDAP simple bind (Error code: %u)", dwError);

    if(pDirectory->ld != NULL)
    {
        ldap_unbind_s(pDirectory->ld);
        pDirectory->ld = NULL;
    }

    goto cleanup;
}
Пример #5
0
LW_DWORD
LwMapHErrnoToLwError(
    LW_IN LW_DWORD dwHErrno
    )
{
    switch(dwHErrno)
    {
        case 0:
            return LW_ERROR_SUCCESS;
        case HOST_NOT_FOUND:
            return WSAHOST_NOT_FOUND;
        case NO_DATA:
#if defined(NO_ADDRESS) && NO_DATA != NO_ADDRESS
        case NO_ADDRESS:
#endif
            return WSANO_DATA;
        case NO_RECOVERY:
            return WSANO_RECOVERY;
        case TRY_AGAIN:
            return WSATRY_AGAIN;
        default:
            LW_RTL_LOG_ERROR("Unable to map h_errno %d", dwHErrno);
            return LW_ERROR_UNKNOWN;
    }
}
Пример #6
0
static
NTSTATUS
LwRtlSvcmInitializeInstance(
    PLW_SVCM_INSTANCE pInstance,
    PCWSTR pServiceName,
    PCSTR pModuleName,
    LW_SVCM_MODULE_ENTRY_FUNCTION Entry
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    pInstance->pTable = Entry();

    status = ValidateModuleTable(pInstance->pTable, pModuleName);
    GCOS(status);

    status = pInstance->pTable->Init(pServiceName, pInstance);
    if (status)
    {
        LW_RTL_LOG_ERROR(
            "Could not initialize service module '%s': %s (0x%lx)",
            pModuleName,
            LwNtStatusToName(status),
            (unsigned long) status);
    }
    GCOS(status);

cleanup:

    return status;
}
Пример #7
0
DWORD
LwMapLwmsgStatusToLwError(
    LWMsgStatus status
    )
{
    switch (status)
    {
        case LWMSG_STATUS_SUCCESS:
            return LW_ERROR_SUCCESS;
        case LWMSG_STATUS_ERROR:
            return LW_ERROR_INTERNAL;
        case LWMSG_STATUS_MEMORY:
        case LWMSG_STATUS_RESOURCE_LIMIT:
            return LW_ERROR_OUT_OF_MEMORY;
        case LWMSG_STATUS_MALFORMED:
        case LWMSG_STATUS_OVERFLOW:
        case LWMSG_STATUS_UNDERFLOW:
        case LWMSG_STATUS_EOF:
            return LW_ERROR_INVALID_MESSAGE;
        case LWMSG_STATUS_INVALID_PARAMETER:
            return LW_ERROR_INVALID_PARAMETER;
        case LWMSG_STATUS_INVALID_STATE:
            return LW_ERROR_INVALID_PARAMETER;
        case LWMSG_STATUS_UNIMPLEMENTED:
            return LW_ERROR_NOT_IMPLEMENTED;
        case LWMSG_STATUS_SYSTEM:
            return LW_ERROR_INTERNAL;
        case LWMSG_STATUS_TIMEOUT:
            return LW_ERROR_ERRNO_ETIMEDOUT;
        case LWMSG_STATUS_SECURITY:
            return LW_ERROR_ACCESS_DENIED;
        case LWMSG_STATUS_CANCELLED:
            return LW_ERROR_INTERRUPTED;
        case LWMSG_STATUS_FILE_NOT_FOUND:
            return ERROR_FILE_NOT_FOUND;
        case LWMSG_STATUS_CONNECTION_REFUSED:
            return LW_ERROR_ERRNO_ECONNREFUSED;
        case LWMSG_STATUS_PEER_RESET:
            return LW_ERROR_ERRNO_ECONNRESET;
        case LWMSG_STATUS_PEER_ABORT:
            return LW_ERROR_ERRNO_ECONNABORTED;
        case LWMSG_STATUS_PEER_CLOSE:
        case LWMSG_STATUS_SESSION_LOST:
            return LW_ERROR_ERRNO_EPIPE;
        case LWMSG_STATUS_INVALID_HANDLE:
            return ERROR_INVALID_HANDLE;
        default:
            LW_RTL_LOG_ERROR("Unable to map lwmsg status %d", status);
            return LW_ERROR_INTERNAL;
    }
}
Пример #8
0
DWORD
InstallLwiCompat(
    PCSTR pSmbdPath
    )
{
    DWORD error = 0;
    PSTR pSambaDir = NULL;
    PSTR pLwiCompat = NULL;
    PCSTR pLikewiseLwiCompat = LIBDIR "/" LWICOMPAT_FILENAME;

    error = GetIdmapDir(
                pSmbdPath,
                &pSambaDir);
    BAIL_ON_LSA_ERROR(error);

    error = LwAllocateStringPrintf(
            &pLwiCompat,
            "%s/%s",
            pSambaDir,
            LWICOMPAT_FILENAME
            );
    BAIL_ON_LSA_ERROR(error);

    if (unlink(pLwiCompat) < 0)
    {
        if (errno != ENOENT)
        {
            error = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(error);   
        }
    }

    if (symlink(pLikewiseLwiCompat, pLwiCompat) < 0)
    {
        error = LwMapErrnoToLwError(errno);
        if (error == ERROR_FILE_NOT_FOUND)
        {
            LW_RTL_LOG_ERROR("Cannot access idmap directory %s. Please ensure you have winbind installed", pSambaDir);
        }
        BAIL_ON_LSA_ERROR(error);   
    }

    LW_RTL_LOG_INFO("Linked idmapper %s to %s", pLwiCompat, pLikewiseLwiCompat);

cleanup:
    LW_SAFE_FREE_STRING(pSambaDir);
    LW_SAFE_FREE_STRING(pLwiCompat);
    return error;
}
Пример #9
0
static
PVOID
EventThread(
    PVOID pContext
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    status = EventLoop((PEPOLL_THREAD) pContext);
    if (!NT_SUCCESS(status))
    {
        LW_RTL_LOG_ERROR(
            "Task thread exiting with fatal error: %s (0x%x)",
            LwNtStatusToName(status),
            status);
        abort();
    }

    return NULL;
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
0
DWORD
LwMapErrnoToLwError(
    DWORD dwErrno
    )
{
    switch(dwErrno)
    {
        case 0:
            return LW_ERROR_SUCCESS;
        case EPERM:
            return ERROR_ACCESS_DENIED;
        case ENOENT:
            return ERROR_FILE_NOT_FOUND;
        case ESRCH:
            return LW_ERROR_NO_SUCH_PROCESS;
        case EINTR:
            return LW_ERROR_INTERRUPTED;
        case EIO:
            return LW_ERROR_GENERIC_IO;
        case ENXIO:
            return LW_ERROR_ERRNO_ENXIO;
        case E2BIG:
            return LW_ERROR_ERRNO_E2BIG;
        case ENOEXEC:
            return LW_ERROR_ERRNO_ENOEXEC;
        case EBADF:
            return LW_ERROR_INVALID_HANDLE;
        case ECHILD:
            return LW_ERROR_ERRNO_ECHILD;
        case EAGAIN:
#if EWOULDBLOCK != EAGAIN
        case EWOULDBLOCK:
#endif
            return LW_ERROR_ERRNO_EAGAIN;
        case ENOMEM:
            return LW_ERROR_OUT_OF_MEMORY;
        case EACCES:
            return LW_ERROR_ACCESS_DENIED;
        case EFAULT:
            return LW_ERROR_ERRNO_EFAULT;
        case ENOTBLK:
            return LW_ERROR_ERRNO_ENOTBLK;
        case EBUSY:
            return LW_ERROR_ERRNO_EBUSY;
        case EEXIST:
            return LW_ERROR_ERRNO_EEXIST;
        case EXDEV:
            return LW_ERROR_ERRNO_EXDEV;
        case ENODEV:
            return LW_ERROR_ERRNO_ENODEV;
        case ENOTDIR:
            return LW_ERROR_ERRNO_ENOTDIR;
        case EISDIR:
            return LW_ERROR_ERRNO_EISDIR;
        case EINVAL:
            return LW_ERROR_INVALID_PARAMETER;
        case ENFILE:
            return LW_ERROR_ERRNO_ENFILE;
        case EMFILE:
            return LW_ERROR_ERRNO_EMFILE;
        case ENOTTY:
            return LW_ERROR_ERRNO_ENOTTY;
        case ETXTBSY:
            return LW_ERROR_ERRNO_ETXTBSY;
        case EFBIG:
            return LW_ERROR_ERRNO_EFBIG;
        case ENOSPC:
            return LW_ERROR_ERRNO_ENOSPC;
        case ESPIPE:
            return LW_ERROR_ERRNO_ESPIPE;
        case EROFS:
            return LW_ERROR_ERRNO_EROFS;
        case EMLINK:
            return LW_ERROR_ERRNO_EMLINK;
        case EPIPE:
            return LW_ERROR_ERRNO_EPIPE;
        case EDOM:
            return LW_ERROR_ERRNO_EDOM;
        case ERANGE:
            return LW_ERROR_ERRNO_ERANGE;
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
        case EDEADLOCK:
#endif
        case EDEADLK:
            return LW_ERROR_ERRNO_EDEADLOCK;
        case ENAMETOOLONG:
            return LW_ERROR_ERRNO_ENAMETOOLONG;
        case ENOLCK:
            return LW_ERROR_ERRNO_ENOLCK;
        case ENOSYS:
            return LW_ERROR_NOT_SUPPORTED;
#if ENOTEMPTY != EEXIST
        case ENOTEMPTY:
            return LW_ERROR_ERRNO_ENOTEMPTY;
#endif
        case ELOOP:
            return LW_ERROR_ERRNO_ELOOP;
        case ENOMSG:
            return LW_ERROR_ERRNO_ENOMSG;
        case EIDRM:
            return LW_ERROR_ERRNO_EIDRM;
#ifdef ECHRNG
        case ECHRNG:
            return LW_ERROR_ERRNO_ECHRNG;
#endif
#ifdef EL2NSYNC
        case EL2NSYNC:
            return LW_ERROR_ERRNO_EL2NSYNC;
#endif
#ifdef EL3HLT
        case EL3HLT:
            return LW_ERROR_ERRNO_EL3HLT;
#endif
#ifdef EL3RST
        case EL3RST:
            return LW_ERROR_ERRNO_EL3RST;
#endif
#ifdef ELNRNG
        case ELNRNG:
            return LW_ERROR_ERRNO_ELNRNG;
#endif
#ifdef EUNATCH
        case EUNATCH:
            return LW_ERROR_ERRNO_EUNATCH;
#endif
#ifdef ENOCSI
        case ENOCSI:
            return LW_ERROR_ERRNO_ENOCSI;
#endif
#ifdef EL2HLT
        case EL2HLT:
            return LW_ERROR_ERRNO_EL2HLT;
#endif
#ifdef EBADE
        case EBADE:
            return LW_ERROR_ERRNO_EBADE;
#endif
#ifdef EBADR
        case EBADR:
            return LW_ERROR_ERRNO_EBADR;
#endif
#ifdef EXFULL
        case EXFULL:
            return LW_ERROR_ERRNO_EXFULL;
#endif
#ifdef ENOANO
        case ENOANO:
            return LW_ERROR_ERRNO_ENOANO;
#endif
#ifdef EBADRQC
        case EBADRQC:
            return LW_ERROR_ERRNO_EBADRQC;
#endif
#ifdef EBADSLT
        case EBADSLT:
            return LW_ERROR_ERRNO_EBADSLT;
#endif
#ifdef EBFONT
        case EBFONT:
            return LW_ERROR_ERRNO_EBFONT;
#endif
#ifdef ENOSTR
        case ENOSTR:
            return LW_ERROR_ERRNO_ENOSTR;
#endif
#ifdef ENODATA
        case ENODATA:
            return LW_ERROR_ERRNO_ENODATA;
#endif
#ifdef ETIME
        case ETIME:
            return LW_ERROR_ERRNO_ETIME;
#endif
#ifdef ENOSR
        case ENOSR:
            return LW_ERROR_ERRNO_ENOSR;
#endif
#ifdef ENONET
        case ENONET:
            return LW_ERROR_ERRNO_ENONET;
#endif
#ifdef ENOPKG
        case ENOPKG:
            return LW_ERROR_ERRNO_ENOPKG;
#endif
        case EREMOTE:
            return LW_ERROR_ERRNO_EREMOTE;
        case ENOLINK:
            return LW_ERROR_ERRNO_ENOLINK;
#ifdef EADV
        case EADV:
            return LW_ERROR_ERRNO_EADV;
#endif
#ifdef ESRMNT
        case ESRMNT:
            return LW_ERROR_ERRNO_ESRMNT;
#endif
#ifdef ECOMM
        case ECOMM:
            return LW_ERROR_ERRNO_ECOMM;
#endif
        case EPROTO:
            return LW_ERROR_ERRNO_EPROTO;
        case EMULTIHOP:
            return LW_ERROR_ERRNO_EMULTIHOP;
#ifdef EDOTDOT
        case EDOTDOT:
            return LW_ERROR_ERRNO_EDOTDOT;
#endif
        case EBADMSG:
            return LW_ERROR_ERRNO_EBADMSG;
        case EOVERFLOW:
            return LW_ERROR_ERRNO_EOVERFLOW;
#ifdef ENOTUNIQ
        case ENOTUNIQ:
            return LW_ERROR_ERRNO_ENOTUNIQ;
#endif
#ifdef EBADFD
        case EBADFD:
            return LW_ERROR_ERRNO_EBADFD;
#endif
#ifdef EREMCHG
        case EREMCHG:
            return LW_ERROR_ERRNO_EREMCHG;
#endif
#ifdef ELIBACC
        case ELIBACC:
            return LW_ERROR_ERRNO_ELIBACC;
#endif
#ifdef ELIBBAD
        case ELIBBAD:
            return LW_ERROR_ERRNO_ELIBBAD;
#endif
#ifdef ELIBSCN
        case ELIBSCN:
            return LW_ERROR_ERRNO_ELIBSCN;
#endif
#ifdef ELIBMAX
        case ELIBMAX:
            return LW_ERROR_ERRNO_ELIBMAX;
#endif
#ifdef ELIBEXEC
        case ELIBEXEC:
            return LW_ERROR_ERRNO_ELIBEXEC;
#endif
        case EILSEQ:
            return LW_ERROR_ERRNO_EILSEQ;
#ifdef ERESTART
        case ERESTART:
            return LW_ERROR_ERRNO_ERESTART;
#endif
#ifdef ESTRPIPE
        case ESTRPIPE:
            return LW_ERROR_ERRNO_ESTRPIPE;
#endif
        case EUSERS:
            return LW_ERROR_ERRNO_EUSERS;
        case ENOTSOCK:
            return LW_ERROR_ERRNO_ENOTSOCK;
        case EDESTADDRREQ:
            return LW_ERROR_ERRNO_EDESTADDRREQ;
        case EMSGSIZE:
            return LW_ERROR_ERRNO_EMSGSIZE;
        case EPROTOTYPE:
            return LW_ERROR_ERRNO_EPROTOTYPE;
        case ENOPROTOOPT:
            return LW_ERROR_ERRNO_ENOPROTOOPT;
        case EPROTONOSUPPORT:
            return LW_ERROR_ERRNO_EPROTONOSUPPORT;
        case ESOCKTNOSUPPORT:
            return LW_ERROR_ERRNO_ESOCKTNOSUPPORT;
        case EOPNOTSUPP:
            return LW_ERROR_ERRNO_EOPNOTSUPP;
        case EPFNOSUPPORT:
            return LW_ERROR_ERRNO_EPFNOSUPPORT;
        case EAFNOSUPPORT:
            return LW_ERROR_ERRNO_EAFNOSUPPORT;
        case EADDRINUSE:
            return LW_ERROR_ERRNO_EADDRINUSE;
        case EADDRNOTAVAIL:
            return LW_ERROR_ERRNO_EADDRNOTAVAIL;
        case ENETDOWN:
            return LW_ERROR_ERRNO_ENETDOWN;
        case ENETUNREACH:
            return LW_ERROR_ERRNO_ENETUNREACH;
        case ENETRESET:
            return LW_ERROR_ERRNO_ENETRESET;
        case ECONNABORTED:
            return LW_ERROR_ERRNO_ECONNABORTED;
        case ECONNRESET:
            return LW_ERROR_ERRNO_ECONNRESET;
        case ENOBUFS:
            return LW_ERROR_ERRNO_ENOBUFS;
        case EISCONN:
            return LW_ERROR_ERRNO_EISCONN;
        case ENOTCONN:
            return LW_ERROR_ERRNO_ENOTCONN;
        case ESHUTDOWN:
            return LW_ERROR_ERRNO_ESHUTDOWN;
        case ETOOMANYREFS:
            return LW_ERROR_ERRNO_ETOOMANYREFS;
        case ETIMEDOUT:
            return LW_ERROR_ERRNO_ETIMEDOUT;
        case ECONNREFUSED:
            return LW_ERROR_ERRNO_ECONNREFUSED;
        case EHOSTDOWN:
            return LW_ERROR_ERRNO_EHOSTDOWN;
        case EHOSTUNREACH:
            return LW_ERROR_ERRNO_EHOSTUNREACH;
        case EALREADY:
            return LW_ERROR_ERRNO_EALREADY;
        case EINPROGRESS:
            return LW_ERROR_ERRNO_EINPROGRESS;
        case ESTALE:
            return LW_ERROR_ERRNO_ESTALE;
#ifdef EUCLEAN
        case EUCLEAN:
            return LW_ERROR_ERRNO_EUCLEAN;
#endif
#ifdef ENOTNAM
        case ENOTNAM:
            return LW_ERROR_ERRNO_ENOTNAM;
#endif
#ifdef ENAVAIL
        case ENAVAIL:
            return LW_ERROR_ERRNO_ENAVAIL;
#endif
#ifdef EISNAM
        case EISNAM:
            return LW_ERROR_ERRNO_EISNAM;
#endif
#ifdef EREMOTEIO
        case EREMOTEIO:
            return LW_ERROR_ERRNO_EREMOTEIO;
#endif
        case EDQUOT:
            return LW_ERROR_ERRNO_EDQUOT;
#ifdef ENOMEDIUM
        case ENOMEDIUM:
            return LW_ERROR_ERRNO_ENOMEDIUM;
#endif
#ifdef EMEDIUMTYPE
        case EMEDIUMTYPE:
            return LW_ERROR_ERRNO_EMEDIUMTYPE;
#endif
        case ECANCELED:
            return LW_ERROR_ERRNO_ECANCELED;
        default:
            LW_RTL_LOG_ERROR("Unable to map errno %d", dwErrno);
            return LW_ERROR_UNKNOWN;
    }
}
Пример #13
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;
}
Пример #14
0
DWORD
LwMapLdapErrorToLwError(
    DWORD dwErr
    )
{
    switch(dwErr)
    {
        case LDAP_SUCCESS:
            return LW_ERROR_SUCCESS;
        case LDAP_SERVER_DOWN:
            return LW_ERROR_LDAP_SERVER_DOWN;
        case LDAP_LOCAL_ERROR:
            return LW_ERROR_LDAP_LOCAL_ERROR;
        case LDAP_ENCODING_ERROR:
            return LW_ERROR_LDAP_ENCODING_ERROR;
        case LDAP_DECODING_ERROR:
            return LW_ERROR_LDAP_DECODING_ERROR;
        case LDAP_TIMEOUT:
            return LW_ERROR_LDAP_TIMEOUT;
        case LDAP_AUTH_UNKNOWN:
            return LW_ERROR_LDAP_AUTH_UNKNOWN;
        case LDAP_FILTER_ERROR:
            return LW_ERROR_LDAP_FILTER_ERROR;
        case LDAP_USER_CANCELLED:
            return LW_ERROR_LDAP_USER_CANCELLED;
        case LDAP_PARAM_ERROR:
            return LW_ERROR_LDAP_PARAM_ERROR;
        case LDAP_NO_MEMORY:
            return LW_ERROR_LDAP_NO_MEMORY;
        case LDAP_CONNECT_ERROR:
            return LW_ERROR_LDAP_CONNECT_ERROR;
        case LDAP_NOT_SUPPORTED:
            return LW_ERROR_LDAP_NOT_SUPPORTED;
        case LDAP_CONTROL_NOT_FOUND:
            return LW_ERROR_LDAP_CONTROL_NOT_FOUND;
        case LDAP_NO_RESULTS_RETURNED:
            return LW_ERROR_LDAP_NO_RESULTS_RETURNED;
        case LDAP_MORE_RESULTS_TO_RETURN:
            return LW_ERROR_LDAP_MORE_RESULTS_TO_RETURN;
        case LDAP_CLIENT_LOOP:
            return LW_ERROR_LDAP_CLIENT_LOOP;
        case LDAP_REFERRAL_LIMIT_EXCEEDED:
            return LW_ERROR_LDAP_REFERRAL_LIMIT_EXCEEDED;
        case LDAP_OPERATIONS_ERROR:
            return LW_ERROR_LDAP_OPERATIONS_ERROR;
        case LDAP_PROTOCOL_ERROR:
            return LW_ERROR_LDAP_PROTOCOL_ERROR;
        case LDAP_TIMELIMIT_EXCEEDED:
            return LW_ERROR_LDAP_TIMELIMIT_EXCEEDED;
        case LDAP_SIZELIMIT_EXCEEDED:
            return LW_ERROR_LDAP_SIZELIMIT_EXCEEDED;
        case LDAP_COMPARE_FALSE:
            return LW_ERROR_LDAP_COMPARE_FALSE;
        case LDAP_COMPARE_TRUE:
            return LW_ERROR_LDAP_COMPARE_TRUE;
        case LDAP_STRONG_AUTH_NOT_SUPPORTED:
            return LW_ERROR_LDAP_STRONG_AUTH_NOT_SUPPORTED;
        case LDAP_STRONG_AUTH_REQUIRED:
            return LW_ERROR_LDAP_STRONG_AUTH_REQUIRED;
        case LDAP_PARTIAL_RESULTS:
            return LW_ERROR_LDAP_PARTIAL_RESULTS;
        case LDAP_NO_SUCH_ATTRIBUTE:
            return LW_ERROR_LDAP_NO_SUCH_ATTRIBUTE;
        case LDAP_UNDEFINED_TYPE:
            return LW_ERROR_LDAP_UNDEFINED_TYPE;
        case LDAP_INAPPROPRIATE_MATCHING:
            return LW_ERROR_LDAP_INAPPROPRIATE_MATCHING;
        case LDAP_CONSTRAINT_VIOLATION:
            return LW_ERROR_LDAP_CONSTRAINT_VIOLATION;
        case LDAP_TYPE_OR_VALUE_EXISTS:
            return LW_ERROR_LDAP_TYPE_OR_VALUE_EXISTS;
        case LDAP_INVALID_SYNTAX:
            return LW_ERROR_LDAP_INVALID_SYNTAX;
        case LDAP_NO_SUCH_OBJECT:
            return LW_ERROR_LDAP_NO_SUCH_OBJECT;
        case LDAP_ALIAS_PROBLEM:
            return LW_ERROR_LDAP_ALIAS_PROBLEM;
        case LDAP_INVALID_DN_SYNTAX:
            return LW_ERROR_LDAP_INVALID_DN_SYNTAX;
        case LDAP_IS_LEAF:
            return LW_ERROR_LDAP_IS_LEAF;
        case LDAP_ALIAS_DEREF_PROBLEM:
            return LW_ERROR_LDAP_ALIAS_DEREF_PROBLEM;
        case LDAP_REFERRAL:
            return LW_ERROR_LDAP_REFERRAL;
        case LDAP_ADMINLIMIT_EXCEEDED:
            return LW_ERROR_LDAP_ADMINLIMIT_EXCEEDED;
        case LDAP_UNAVAILABLE_CRITICAL_EXTENSION:
            return LW_ERROR_LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
        case LDAP_CONFIDENTIALITY_REQUIRED:
            return LW_ERROR_LDAP_CONFIDENTIALITY_REQUIRED;
        case LDAP_SASL_BIND_IN_PROGRESS:
            return LW_ERROR_LDAP_SASL_BIND_IN_PROGRESS;
        case LDAP_X_PROXY_AUTHZ_FAILURE:
            return LW_ERROR_LDAP_X_PROXY_AUTHZ_FAILURE;
        case LDAP_INAPPROPRIATE_AUTH:
            return LW_ERROR_LDAP_INAPPROPRIATE_AUTH;
        case LDAP_INVALID_CREDENTIALS:
            return LW_ERROR_LDAP_INVALID_CREDENTIALS;
        case LDAP_INSUFFICIENT_ACCESS:
            return LW_ERROR_LDAP_INSUFFICIENT_ACCESS;
        case LDAP_BUSY:
            return LW_ERROR_LDAP_BUSY;
        case LDAP_UNAVAILABLE:
            return LW_ERROR_LDAP_UNAVAILABLE;
        case LDAP_UNWILLING_TO_PERFORM:
            return LW_ERROR_LDAP_UNWILLING_TO_PERFORM;
        case LDAP_LOOP_DETECT:
            return LW_ERROR_LDAP_LOOP_DETECT;
        case LDAP_NAMING_VIOLATION:
            return LW_ERROR_LDAP_NAMING_VIOLATION;
        case LDAP_OBJECT_CLASS_VIOLATION:
            return LW_ERROR_LDAP_OBJECT_CLASS_VIOLATION;
        case LDAP_NOT_ALLOWED_ON_NONLEAF:
            return LW_ERROR_LDAP_NOT_ALLOWED_ON_NONLEAF;
        case LDAP_NOT_ALLOWED_ON_RDN:
            return LW_ERROR_LDAP_NOT_ALLOWED_ON_RDN;
        case LDAP_ALREADY_EXISTS:
            return LW_ERROR_LDAP_ALREADY_EXISTS;
        case LDAP_NO_OBJECT_CLASS_MODS:
            return LW_ERROR_LDAP_NO_OBJECT_CLASS_MODS;
        case LDAP_RESULTS_TOO_LARGE:
            return LW_ERROR_LDAP_RESULTS_TOO_LARGE;
        case LDAP_AFFECTS_MULTIPLE_DSAS:
            return LW_ERROR_LDAP_AFFECTS_MULTIPLE_DSAS;
        case LDAP_CUP_RESOURCES_EXHAUSTED:
            return LW_ERROR_LDAP_CUP_RESOURCES_EXHAUSTED;
        case LDAP_CUP_SECURITY_VIOLATION:
            return LW_ERROR_LDAP_CUP_SECURITY_VIOLATION;
        case LDAP_CUP_INVALID_DATA:
            return LW_ERROR_LDAP_CUP_INVALID_DATA;
        case LDAP_CUP_UNSUPPORTED_SCHEME:
            return LW_ERROR_LDAP_CUP_UNSUPPORTED_SCHEME;
        case LDAP_CUP_RELOAD_REQUIRED:
            return LW_ERROR_LDAP_CUP_RELOAD_REQUIRED;
        case LDAP_CANCELLED:
            return LW_ERROR_LDAP_CANCELLED;
        case LDAP_NO_SUCH_OPERATION:
            return LW_ERROR_LDAP_NO_SUCH_OPERATION;
        case LDAP_TOO_LATE:
            return LW_ERROR_LDAP_TOO_LATE;
        case LDAP_CANNOT_CANCEL:
            return LW_ERROR_LDAP_CANNOT_CANCEL;
        case LDAP_ASSERTION_FAILED:
            return LW_ERROR_LDAP_ASSERTION_FAILED;
        default:
            LW_RTL_LOG_ERROR("Unable to map ldap error %d", dwErr);
            return LW_ERROR_UNKNOWN;
    }
}
Пример #15
0
DWORD
LwLdapOpenDirectoryServerSingleAttempt(
    IN PCSTR pszServerAddress,
    IN PCSTR pszServerName,
    IN DWORD dwTimeoutSec,
    IN DWORD dwFlags,
    OUT PLW_LDAP_DIRECTORY_CONTEXT* ppDirectory
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    LDAP * ld = NULL;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    int rc = LDAP_VERSION3;
    DWORD dwPort = 389;
    struct timeval timeout = {0};
    BOOLEAN bLdapSeal = FALSE;

    timeout.tv_sec = dwTimeoutSec;

    LW_BAIL_ON_INVALID_STRING(pszServerName);
    LW_BAIL_ON_INVALID_STRING(pszServerAddress);

    if (dwFlags & LW_LDAP_OPT_GLOBAL_CATALOG)
    {
       dwPort = 3268;
    }

    // This creates the ld without immediately connecting to the server.
    // That way a connection timeout can be set first.
    ld = (LDAP *)ldap_init(pszServerAddress, dwPort);
    if (!ld) {
        dwError = LwMapErrnoToLwError(errno);
        LW_RTL_LOG_ERROR("Failed to open LDAP connection to domain controller");
        BAIL_ON_LW_ERROR(dwError);
        LW_RTL_LOG_ERROR("Failed to get errno for failed open LDAP connection");
        dwError = LW_ERROR_LDAP_ERROR;
        BAIL_ON_LW_ERROR(dwError);
    }

    dwError = ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
    BAIL_ON_LDAP_ERROR(dwError);

    dwError = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &rc);
    if (dwError) {
        LW_RTL_LOG_ERROR("Failed to set LDAP option protocol version");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    dwError = ldap_set_option( ld, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);
    if (dwError) {
        LW_RTL_LOG_ERROR("Failed to set LDAP option to not follow referrals");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    /* This tells ldap to retry when select returns with EINTR */
    dwError = ldap_set_option( ld, LDAP_OPT_RESTART, (void *)LDAP_OPT_ON);
    if (dwError) {
        LW_RTL_LOG_ERROR("Failed to set LDAP option to auto retry ");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    if (dwFlags & LW_LDAP_OPT_SIGN_AND_SEAL)
    {
        bLdapSeal = TRUE;
    }

    dwError = LwAllocateMemory(sizeof(*pDirectory), OUT_PPVOID(&pDirectory));
    BAIL_ON_LW_ERROR(dwError);

    pDirectory->ld = ld;
    ld = NULL;

    if (dwFlags & LW_LDAP_OPT_ANNONYMOUS)
    {
        dwError = LwLdapBindDirectoryAnonymous((HANDLE)pDirectory);
    }
    else
    {
        dwError = LwLdapBindDirectory(
                      (HANDLE)pDirectory,
                      pszServerName,
                      bLdapSeal);
    }
    // The above functions return -1 when a connection times out.
    if (dwError == (DWORD)-1)
    {
        dwError = ETIMEDOUT;
    }
    BAIL_ON_LW_ERROR(dwError);

    *ppDirectory = pDirectory;

cleanup:

    return(dwError);

error:

    if (pDirectory)
    {
        LwLdapCloseDirectory(pDirectory);
    }
    if (ld)
    {
        ldap_unbind_s(ld);
    }

    *ppDirectory = (HANDLE)NULL;

    goto cleanup;
}
Пример #16
0
DWORD
LwLdapDirectorySearch(
    HANDLE hDirectory,
    PCSTR  pszObjectDN,
    int    scope,
    PCSTR  pszQuery,
    PSTR*  ppszAttributeList,
    LDAPMessage** ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    struct timeval timeout = {0};
    LDAPMessage* pMessage = NULL;

    timeout.tv_sec = 15;
    timeout.tv_usec = 0;

    dwError = ldap_search_st(pDirectory->ld,
                             pszObjectDN,
                             scope,
                             pszQuery,
                             ppszAttributeList,
                             0,
                             &timeout,
                             &pMessage);
    if (dwError) {
        if (dwError == LDAP_NO_SUCH_OBJECT) {
            LW_RTL_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
            BAIL_ON_LDAP_ERROR(dwError);
        }
        if (dwError == LDAP_REFERRAL) {
            LW_RTL_LOG_ERROR("Caught LDAP_REFERRAL Error on ldap search");
            LW_RTL_LOG_ERROR("LDAP Search Info: DN: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszObjectDN) ? "<null>" : pszObjectDN);
            LW_RTL_LOG_ERROR("LDAP Search Info: scope: [%d]", scope);
            LW_RTL_LOG_ERROR("LDAP Search Info: query: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszQuery) ? "<null>" : pszQuery);
            if (ppszAttributeList) {
                size_t i;
                for (i = 0; ppszAttributeList[i] != NULL; i++) {
                    LW_RTL_LOG_ERROR("LDAP Search Info: attribute: [%s]", ppszAttributeList[i]);
                }
            }
            else {
                LW_RTL_LOG_ERROR("Error: LDAP Search Info: no attributes were specified");
            }
        }
        BAIL_ON_LDAP_ERROR(dwError);
    }

    *ppMessage = pMessage;

cleanup:

    return(dwError);

error:

    *ppMessage = NULL;

    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    goto cleanup;
}
Пример #17
0
DWORD
SynchronizePassword(
    PCSTR pSmbdPath
    )
{
    DWORD error = 0;
    PSTR pSecretsPath = NULL;
    LW_HANDLE hLsa = NULL;
    PLSA_MACHINE_PASSWORD_INFO_A pPasswordInfo = NULL;
    PLSA_PSTORE_PLUGIN_DISPATCH pDispatch = NULL;
    PLSA_PSTORE_PLUGIN_CONTEXT pContext = NULL;
    HANDLE hReg = NULL;

    error = LwRegOpenServer(&hReg);
    BAIL_ON_LSA_ERROR(error);

    error = GetSecretsPath(
        pSmbdPath,
        &pSecretsPath);
    BAIL_ON_LSA_ERROR(error);

    error = RegUtilAddKey(
                hReg,
                LSA_PSTORE_REG_ROOT_KEY_PATH,
                NULL,
                LSA_PSTORE_REG_ROOT_KEY_RELATIVE_PATH_PLUGINS "\\" PLUGIN_NAME);
    BAIL_ON_LSA_ERROR(error);

    error = RegUtilSetValue(
                hReg,
                LSA_PSTORE_REG_ROOT_KEY_PATH,
                NULL,
                LSA_PSTORE_REG_ROOT_KEY_RELATIVE_PATH_PLUGINS "\\" PLUGIN_NAME,
                "SecretsPath",
                REG_SZ,
                pSecretsPath,
                strlen(pSecretsPath));
    BAIL_ON_LSA_ERROR(error);

    error = RegUtilSetValue(
                hReg,
                HKEY_THIS_MACHINE,
                NULL,
                LSA_PSTORE_REG_ROOT_KEY_RELATIVE_PATH_PLUGINS "\\" PLUGIN_NAME,
                "Path",
                REG_SZ,
                PLUGIN_PATH,
                strlen(PLUGIN_PATH));
    BAIL_ON_LSA_ERROR(error);

    error = AddSambaLoadPath(hReg);
    BAIL_ON_LSA_ERROR(error);

    error = LsaOpenServer(
        &hLsa);
    if (error)
    {
        LW_RTL_LOG_ERROR("Unable to contact lsassd");
    }
    BAIL_ON_LSA_ERROR(error);

    error = LsaAdGetMachinePasswordInfo(
        hLsa,
        NULL,
        &pPasswordInfo);
    if (error == NERR_SetupNotJoined)
    {
        LW_RTL_LOG_ERROR("Unable to write machine password in secrets.tdb because PowerBroker Identity Services is not joined. The password will be written to secrets.tdb on the next successful join attempt");
        error = 0;
    }
    else
    {
        BAIL_ON_LSA_ERROR(error);

        error = LsaPstorePluginInitializeContext(
                    LSA_PSTORE_PLUGIN_VERSION,
                    PLUGIN_NAME,
                    &pDispatch,
                    &pContext);
        BAIL_ON_LSA_ERROR(error);

        error = pDispatch->SetPasswordInfoA(
                    pContext,
                    pPasswordInfo);
        BAIL_ON_LSA_ERROR(error);
    }

cleanup:
    LW_SAFE_FREE_STRING(pSecretsPath);
    if (hLsa != NULL)
    {
        LsaCloseServer(hLsa);
    }
    if (hReg != NULL)
    {
        LwRegCloseServer(hReg);
    }
    if (pPasswordInfo != NULL)
    {
        LsaAdFreeMachinePasswordInfo(pPasswordInfo);
    }
    if (pContext)
    {
        pDispatch->Cleanup(pContext);
    }
    return error;
}
Пример #18
0
static
DWORD
LwGssGetSingleErrorMessage(
    OUT PSTR* ppszErrorMessage,
    IN OM_uint32 Status,
    IN BOOLEAN IsMajor
    )
{
    DWORD dwError = 0;
    PSTR pszErrorMessage = NULL;
    OM_uint32 majorStatus = 0;
    OM_uint32 minorStatus = 0;
    gss_buffer_desc message = GSS_C_EMPTY_BUFFER;
    OM_uint32 messageContext = 0;
    int statusType = IsMajor ? GSS_C_GSS_CODE : GSS_C_MECH_CODE;

    do {
        majorStatus = gss_display_status(
                            &minorStatus,
                            Status,
                            statusType,
                            GSS_C_NULL_OID,
                            &messageContext,
                            &message);
        if (majorStatus != GSS_S_COMPLETE)
        {
            LW_RTL_LOG_ERROR("Call to gss_display_status() failed with "
                         "majorStatus = 0x%08x, minorStatus = 0x%08x",
                         majorStatus, minorStatus);

            dwError = ERROR_INTERNAL_ERROR;
            BAIL_ON_LW_ERROR(dwError);
        }

        if (!pszErrorMessage)
        {
            dwError = LwAllocateString((PSTR)message.value, &pszErrorMessage);
            BAIL_ON_LW_ERROR(dwError);
        }
        else
        {
            PSTR pszNewErrorMessage = NULL;

            dwError = LwAllocateStringPrintf(&pszNewErrorMessage,
                                             "%s; %s",
                                             pszErrorMessage,
                                             (PSTR)message.value);
            BAIL_ON_LW_ERROR(dwError);

            LW_SAFE_FREE_STRING(pszErrorMessage);
            pszErrorMessage = pszNewErrorMessage;
        }

        majorStatus = gss_release_buffer(&minorStatus, &message);
    } while (messageContext);

error:
    if (dwError)
    {
        LW_SAFE_FREE_STRING(pszErrorMessage);
    }

    if (message.value)
    {
        majorStatus = gss_release_buffer(&minorStatus, &message);
    }

    *ppszErrorMessage = pszErrorMessage;

    return dwError;
}
Пример #19
0
DWORD
GetSecretsPath(
    PCSTR pSmbdPath,
    PSTR* ppPath
    )
{
    DWORD error = 0;
    PSTR pCommandLine = NULL;
    PCSTR ppArgs[] = {
        "/bin/sh",
        "-c",
        NULL,
        NULL
    };
    PSTR pSambaPrivateDir = NULL;
    PSTR pPath = NULL;
    struct stat statBuf = { 0 };

    // Look for secrets.tdb in the statedir (Ubuntu 10.10 is like this)
    error = LwAllocateStringPrintf(
            &pCommandLine,
            "%s -b | grep STATEDIR:",
            pSmbdPath
            );
    BAIL_ON_LSA_ERROR(error);

    ppArgs[2] = pCommandLine;

    error = CaptureOutputWithStderr(
                "/bin/sh",
                ppArgs,
                &pSambaPrivateDir,
                NULL);
    if (error == ERROR_BAD_COMMAND)
    {
        pSambaPrivateDir = NULL;
        error = ERROR_BAD_COMMAND;
    }
    else
    {
        if (strstr(pSambaPrivateDir, ": "))
        {
            char *pValueStart = strstr(pSambaPrivateDir, ": ") + 2;
            memmove(
                    pSambaPrivateDir,
                    pValueStart,
                    strlen(pSambaPrivateDir) -
                        (pValueStart - pSambaPrivateDir) + 1);
        }

        LwStripWhitespace(
                pSambaPrivateDir,
                TRUE,
                TRUE);

        error = LwAllocateStringPrintf(
                &pPath,
                "%s/secrets.tdb",
                pSambaPrivateDir
                );
        BAIL_ON_LSA_ERROR(error);
        
        // Verify the path exists
        if (stat(pPath, &statBuf) < 0)
        {
            if (errno == ENOENT)
            {
                // Try the private dir instead
                LW_SAFE_FREE_STRING(pSambaPrivateDir);
                LW_SAFE_FREE_STRING(pPath);
            }
            else
            {
                LW_RTL_LOG_ERROR("Cannot find secrets.tdb at %s",
                        pPath);
                error = LwMapErrnoToLwError(errno);
                BAIL_ON_LSA_ERROR(error);   
            }
        }
    }

    if (pPath == NULL)
    {
        // This version of smbd is older than 3.5, or the distro vendor decided
        // to put the file in the private dir (Fedora 14 is like that).
        LW_SAFE_FREE_STRING(pCommandLine);

        error = LwAllocateStringPrintf(
                &pCommandLine,
                "%s -b | grep PRIVATE_DIR:",
                pSmbdPath
                );
        BAIL_ON_LSA_ERROR(error);

        ppArgs[2] = pCommandLine;

        error = CaptureOutputWithStderr(
                    "/bin/sh",
                    ppArgs,
                    &pSambaPrivateDir,
                    NULL);
        BAIL_ON_LSA_ERROR(error);

        LwStripWhitespace(
                pSambaPrivateDir,
                TRUE,
                TRUE);

        if (strstr(pSambaPrivateDir, ": "))
        {
            char *pValueStart = strstr(pSambaPrivateDir, ": ") + 2;
            memmove(
                    pSambaPrivateDir,
                    pValueStart,
                    strlen(pSambaPrivateDir) -
                        (pValueStart - pSambaPrivateDir) + 1);
        }

        error = LwAllocateStringPrintf(
                &pPath,
                "%s/secrets.tdb",
                pSambaPrivateDir
                );
        BAIL_ON_LSA_ERROR(error);
    }

cleanup:
    *ppPath = pPath;
    LW_SAFE_FREE_STRING(pCommandLine);
    LW_SAFE_FREE_STRING(pSambaPrivateDir);
    return error;
}
Пример #20
0
static
DWORD
LsaPstorepCallPlugin(
    IN PCSTR Operation,
    IN LSA_PSTORE_CALL_PLUGIN_CALLBACK Callback,
    IN PLSA_PSTORE_CALL_PLUGIN_ARGS Arguments
    )
{
    DWORD dwError = 0;
    int EE = 0;
    LSA_PSTORE_PLUGIN_INFO pluginInfo = { 0 };
    PSTR* pluginNames = 0;
    DWORD pluginCount = 0;
    DWORD i = 0;
    PCSTR method = NULL;

    dwError = LsaPstorepGetPluginNames(&pluginNames, &pluginCount);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    for (i = 0; i < pluginCount; i++)
    {
        LsaPstorepCleanupPlugin(&pluginInfo);

        dwError = LsaPstorepInitializePlugin(&pluginInfo, pluginNames[i]);
        if (dwError)
        {
            LW_RTL_LOG_ERROR("Failed to load plugin %s with error = %u (%s)",
                    pluginNames[i], dwError,
                    LW_RTL_LOG_SAFE_STRING(LwWin32ExtErrorToName(dwError)));
            dwError = 0;
            continue;
        }

        dwError = Callback(
                        pluginInfo.Name,
                        pluginInfo.Dispatch,
                        pluginInfo.Context,
                        Arguments,
                        &method);
        if (dwError)
        {
            if (method)
            {
                LW_RTL_LOG_ERROR(
                        "Failed %s operation on plugin %s "
                        "while calling %s method with error = %u (%s)",
                        LW_RTL_LOG_SAFE_STRING(Operation), pluginNames[i],
                        method, dwError,
                        LW_RTL_LOG_SAFE_STRING(LwWin32ExtErrorToName(dwError)));
            }
            else
            {
                LW_RTL_LOG_ERROR(
                        "Failed %s operation on plugin %s "
                        "with error = %u (%s)",
                        LW_RTL_LOG_SAFE_STRING(Operation), pluginNames[i],
                        dwError,
                        LW_RTL_LOG_SAFE_STRING(LwWin32ExtErrorToName(dwError)));
            }
            dwError = 0;
            continue;
        }
    }

cleanup:
    LsaPstorepCleanupPlugin(&pluginInfo);

    LSA_PSTORE_FREE_STRING_ARRAY_A(&pluginNames, &pluginCount);

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Пример #21
0
int
main(
    int argc,
    char *argv[]
    )
{
    enum
    {
        UNSET,
        SHOW_HELP,
        CHECK_VERSION,
        INSTALL,
        UNINSTALL
    } mode = UNSET;
    PCSTR pSmbdPath = NULL;
    PSTR pFoundSmbdPath = NULL;
    DWORD error = 0;
    DWORD argIndex = 0;
    LW_RTL_LOG_LEVEL logLevel = LW_RTL_LOG_LEVEL_ERROR;
    PCSTR pErrorSymbol = NULL;
    PSTR pVersion = NULL;
    BOOLEAN smbdExists = FALSE;
    BOOLEAN force = FALSE;

    for (argIndex = 1; argIndex < argc; argIndex++)
    {
        if (!strcmp(argv[argIndex], "--check-version"))
        {
            if (mode == UNSET)
            {
                mode = CHECK_VERSION;
            }
            else
            {
                mode = SHOW_HELP;
            }
        }
        else if (!strcmp(argv[argIndex], "--install"))
        {
            if (mode == UNSET)
            {
                mode = INSTALL;
            }
            else
            {
                mode = SHOW_HELP;
            }
        }
        else if (!strcmp(argv[argIndex], "--uninstall"))
        {
            if (mode == UNSET)
            {
                mode = UNINSTALL;
            }
            else
            {
                mode = SHOW_HELP;
            }
        }
        else if (!strcmp(argv[argIndex], "--force"))
        {
            if (mode == INSTALL || mode== UNINSTALL)
            {
                force = TRUE;
            }
            else
            {
                mode = SHOW_HELP;
            }
        }
        else if (!strcmp(argv[argIndex], "--loglevel"))
        {
            argIndex++;
            if (argIndex >= argc)
            {
                error = ERROR_INVALID_PARAMETER;
                BAIL_ON_LSA_ERROR(error);
            }
            if (!strcmp(argv[argIndex], "error"))
            {
                logLevel = LW_RTL_LOG_LEVEL_ERROR;
            }
            else if (!strcmp(argv[argIndex], "warning"))
            {
                logLevel = LW_RTL_LOG_LEVEL_WARNING;
            }
            else if (!strcmp(argv[argIndex], "info"))
            {
                logLevel = LW_RTL_LOG_LEVEL_INFO;
            }
            else if (!strcmp(argv[argIndex], "verbose"))
            {
                logLevel = LW_RTL_LOG_LEVEL_VERBOSE;
            }
            else if (!strcmp(argv[argIndex], "debug"))
            {
                logLevel = LW_RTL_LOG_LEVEL_DEBUG;
            }
            else
            {
                error = ERROR_INVALID_PARAMETER;
                BAIL_ON_LSA_ERROR(error);
            }
        }
        else if (argIndex == argc - 1)
        {
            pSmbdPath = argv[argIndex];
        }
        else
        {
            mode = SHOW_HELP;
        }
    }

    if (mode == UNSET || mode == SHOW_HELP)
    {
        ShowUsage(argv[0]);
        goto cleanup;
    }

    LwRtlLogSetCallback(LogCallback, NULL);
    LwRtlLogSetLevel(logLevel);

    if (pSmbdPath == NULL)
    {
        PCSTR pSearchPath = "/usr/sbin:/usr/local/sbin:/usr/local/samba/sbin:/opt/csw/samba/sbin:/opt/sfw/samba/sbin:/opt/csw/bin:/usr/local/bin";
        error = FindFileInPath(
                        "smbd",
                        pSearchPath,
                        &pFoundSmbdPath);
        if (error == ERROR_FILE_NOT_FOUND)
        {
            LW_RTL_LOG_ERROR("The smbd file could not be automatically found on your system. The search path was '%s'. Pass the correct location as the last argument to this program.", pSearchPath);
        }
        BAIL_ON_LSA_ERROR(error);
        pSmbdPath = pFoundSmbdPath;
    }

    error = LwCheckFileTypeExists(
                pSmbdPath,
                LWFILE_REGULAR,
                &smbdExists);
    BAIL_ON_LSA_ERROR(error);
    
    if (!smbdExists)
    {
        error = LwCheckFileTypeExists(
                    pSmbdPath,
                    LWFILE_SYMLINK,
                    &smbdExists);
        BAIL_ON_LSA_ERROR(error);
    }

    if (!smbdExists)
    {
        LW_RTL_LOG_ERROR("Smbd file not found at path '%s'", pSmbdPath);
    }

    error = CheckSambaVersion(pSmbdPath, &pVersion);
    if (force == FALSE) 
    {
       BAIL_ON_LSA_ERROR(error);
    }
 
    if (mode == CHECK_VERSION)
    {
        fprintf(stderr, "Samba version supported\n");
    }
    else if (mode == INSTALL)
    {
        if (geteuid() != 0)
        {
            fprintf(stderr, "Please use the root account to install the Samba interop libraries\n");
            goto cleanup;
        }

        error = InstallWbclient(pSmbdPath);
        BAIL_ON_LSA_ERROR(error);

        if (pVersion && strncmp(pVersion, "3.0.", sizeof("3.0.") - 1) == 0)
        {
            // Only Samba 3.0.x needs this
            error = InstallLwiCompat(pSmbdPath);
            BAIL_ON_LSA_ERROR(error);
        }

        error = SynchronizePassword(
                    pSmbdPath);
        BAIL_ON_LSA_ERROR(error);

        fprintf(stderr, "Install successful\n");
    }
    else if (mode == UNINSTALL)
    {
        if (geteuid() != 0)
        {
            fprintf(stderr, "Please use the root account to uninstall the Samba interop libraries\n");
            goto cleanup;
        }

        error = UninstallWbclient(pSmbdPath);
        BAIL_ON_LSA_ERROR(error);

        error = UninstallLwiCompat(pSmbdPath);
        BAIL_ON_LSA_ERROR(error);

        error = DeletePassword(
                    pSmbdPath);
        BAIL_ON_LSA_ERROR(error);

        fprintf(stderr, "Uninstall successful\n");
    }
    else
    {
        fprintf(stderr, "Uninstall mode not implemented\n");
        error = ERROR_INVALID_PARAMETER;
        BAIL_ON_LSA_ERROR(error);
    }

cleanup:
    LW_SAFE_FREE_STRING(pFoundSmbdPath);
    LW_SAFE_FREE_STRING(pVersion);

    if (error)
    {
        pErrorSymbol = LwWin32ErrorToName(error);
        if (pErrorSymbol != NULL)
        {
            fprintf(stderr, "Error: %s\n", pErrorSymbol);
        }
        else
        {
            fprintf(stderr, "Unknown error\n");
        }
    }
    return error;
}
Пример #22
0
DWORD
DeletePassword(
    PCSTR pSmbdPath
    )
{
    DWORD error = 0;
    PLSA_PSTORE_PLUGIN_DISPATCH pDispatch = NULL;
    PLSA_PSTORE_PLUGIN_CONTEXT pContext = NULL;
    PSTR pSecretsPath = NULL;
    LW_HANDLE hLsa = NULL;
    PLSA_MACHINE_ACCOUNT_INFO_A pAccountInfo = NULL;
    HANDLE hReg = NULL;

    error = LwRegOpenServer(&hReg);
    BAIL_ON_LSA_ERROR(error);

    // Even though this was set during the install process, we'll try setting
    // it again. This way if the user calls uninstall without calling install
    // first, they won't get an error.
    error = GetSecretsPath(
        pSmbdPath,
        &pSecretsPath);
    BAIL_ON_LSA_ERROR(error);

    error = LsaOpenServer(
        &hLsa);
    if (error)
    {
        LW_RTL_LOG_ERROR("Unable to contact lsassd");
    }
    BAIL_ON_LSA_ERROR(error);

    error = LsaAdGetMachineAccountInfo(
        hLsa,
        NULL,
        &pAccountInfo);
    BAIL_ON_LSA_ERROR(error);

    error = RegUtilAddKey(
                hReg,
                LSA_PSTORE_REG_ROOT_KEY_PATH,
                NULL,
                LSA_PSTORE_REG_ROOT_KEY_RELATIVE_PATH_PLUGINS "\\" PLUGIN_NAME);
    BAIL_ON_LSA_ERROR(error);

    error = RegUtilSetValue(
                hReg,
                LSA_PSTORE_REG_ROOT_KEY_PATH,
                NULL,
                LSA_PSTORE_REG_ROOT_KEY_RELATIVE_PATH_PLUGINS "\\" PLUGIN_NAME,
                "SecretsPath",
                REG_SZ,
                pSecretsPath,
                strlen(pSecretsPath));
    BAIL_ON_LSA_ERROR(error);

    error = RemoveSambaLoadPath(hReg);
    BAIL_ON_LSA_ERROR(error);

    error = LsaPstorePluginInitializeContext(
                LSA_PSTORE_PLUGIN_VERSION,
                PLUGIN_NAME,
                &pDispatch,
                &pContext);
    BAIL_ON_LSA_ERROR(error);

    error = pDispatch->DeletePasswordInfoA(
                pContext,
                pAccountInfo);
    BAIL_ON_LSA_ERROR(error);

cleanup:
    if (pContext)
    {
        pDispatch->Cleanup(pContext);
    }
    if (hReg != NULL)
    {
        LwRegCloseServer(hReg);
    }
    if (hLsa != NULL)
    {
        LsaCloseServer(hLsa);
    }
    if (pAccountInfo != NULL)
    {
        LsaAdFreeMachineAccountInfo(pAccountInfo);
    }
    return error;
}
Пример #23
0
static
DWORD
LsaPstorepGetPluginPath(
    IN PCSTR pszName,
    OUT PSTR* ppszPath
    )
{
    DWORD dwError = 0;
    int EE = 0;
    HANDLE registryConnection = NULL;
    HKEY keyHandle = NULL;
    PSTR pszKeyPath = NULL;
    PSTR pszPath = NULL;

    dwError = LwNtStatusToWin32Error(LwRtlCStringAllocatePrintf(
                    &pszKeyPath,
                    "%s\\%s",
                    LSA_PSTORE_REG_KEY_PATH_PLUGINS,
                    pszName));
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenServer(&registryConnection);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenKeyExA(
                    registryConnection,
                    NULL,
                    pszKeyPath,
                    0,
                    GENERIC_READ,
                    &keyHandle);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin '%s' is missing its configuration registry key '%s'",
                pszName, pszKeyPath);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetStringA(
                    registryConnection,
                    keyHandle,
                    LSA_PSTORE_REG_VALUE_NAME_PLUGINS_PATH,
                    &pszPath);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin '%s' is missing the '%s' configuration value from its configuration registry key '%s'",
                pszName, LSA_PSTORE_REG_VALUE_NAME_PLUGINS_PATH, pszKeyPath);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

cleanup:
    if (dwError)
    {
        LSA_PSTORE_FREE(&pszPath);
    }

    if (keyHandle)
    {
        LwRegCloseKey(registryConnection, keyHandle);
    }

    if (registryConnection)
    {
        LwRegCloseServer(registryConnection);
    }

    LSA_PSTORE_FREE(&pszKeyPath);

    *ppszPath = pszPath;

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Пример #24
0
DWORD
LwLdapOpenDirectoryServer(
    IN PCSTR pszServerAddress,
    IN PCSTR pszServerName,
    IN DWORD dwFlags,
    OUT PHANDLE phDirectory
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    DWORD dwAttempt = 0;
    struct timespec sleepTime;
    DWORD dwTimeoutSec = 15;

    LW_BAIL_ON_INVALID_STRING(pszServerName);
    LW_BAIL_ON_INVALID_STRING(pszServerAddress);

    for (dwAttempt = 1; dwAttempt <= 3; dwAttempt++)
    {
        // dwTimeoutSec controls how long openldap will wait for the connection
        // to be established. For the first attempt, this is set to 15 seconds
        // (which is the same amount of time netlogon will wait to get the dc
        // name). The second attempt halves the value to 7 seconds. The third
        // attempt halves it again to 3 seconds.
        dwError = LwLdapOpenDirectoryServerSingleAttempt(
                        pszServerAddress,
                        pszServerName,
                        dwTimeoutSec,
                        dwFlags,
                        &pDirectory);
        if (dwError == ETIMEDOUT)
        {
            LW_ASSERT(pDirectory == NULL);
            LW_RTL_LOG_ERROR("The ldap connection to %s was disconnected. This was attempt #%d",
                    pszServerAddress,
                    dwAttempt);
            dwTimeoutSec /= 2;

            // This is the amount of time to sleep before trying to reconnect
            // again. It is: .1 seconds * dwAttempt
            sleepTime.tv_sec = 0;
            sleepTime.tv_nsec = dwAttempt * 100000000;
            while (nanosleep(&sleepTime, &sleepTime) == -1)
            {
                if (errno != EINTR)
                {
                    dwError = LwMapErrnoToLwError(errno);
                    BAIL_ON_LW_ERROR(dwError);
                }
            }
            continue;
        }
        BAIL_ON_LW_ERROR(dwError);
        break;
    }

    *phDirectory = (HANDLE)pDirectory;

cleanup:

    return(dwError);

error:

    if (pDirectory)
    {
        LwLdapCloseDirectory(pDirectory);
    }

    *phDirectory = (HANDLE)NULL;

    goto cleanup;
}
Пример #25
0
DWORD
CheckSambaVersion(
    PCSTR pSmbdPath,
    PSTR *ppVersion
    )
{
    DWORD error = 0;
    PCSTR ppArgs[] = {
        pSmbdPath,
        "-V",
        0
    };
    PSTR pVersionString = NULL;

    error = CaptureOutputWithStderr(
                pSmbdPath,
                ppArgs,
                &pVersionString,
                NULL);
    BAIL_ON_LSA_ERROR(error);

    if (!strncmp(pVersionString, "Version ", sizeof("Version ") -1))
    {
        memmove(
                pVersionString,
                pVersionString + (sizeof("Version ") - 1),
                strlen(pVersionString) - (sizeof("Version ") - 1) + 1);
    }
    LwStripWhitespace(
            pVersionString,
            TRUE,
            TRUE);

    LW_RTL_LOG_ERROR("Found smbd version %s", pVersionString);

    if (!strncmp(pVersionString, "3.2.", sizeof("3.2.") - 1))
    {
    }
    else if (!strncmp(pVersionString, "3.4.", sizeof("3.4.") - 1))
    {
    }
    else if (!strncmp(pVersionString, "3.5.", sizeof("3.5.") - 1))
    {
    }
    else if (!strncmp(pVersionString, "3.6.", sizeof("3.6.") - 1))
    {
    }
    else if (!strncmp(pVersionString, "3.0.", sizeof("3.0.") - 1))
    {
        int build = 0;
        sscanf(pVersionString, "3.0.%d.", &build);

        if (build < 25)
        {
            LW_RTL_LOG_ERROR("Unsupported smbd version %s", pVersionString);
            error = ERROR_PRODUCT_VERSION;
            BAIL_ON_LSA_ERROR(error);
        }
    }
    else if (!strncmp(pVersionString, "4.", sizeof("4.") - 1))
    {
    }
    else
    {
        LW_RTL_LOG_ERROR("Unsupported smbd version %s", pVersionString);
        error = ERROR_PRODUCT_VERSION;
        BAIL_ON_LSA_ERROR(error);
    }


cleanup:
    if (error)
    {
        LW_SAFE_FREE_STRING(pVersionString);
    }
    *ppVersion = pVersionString;
    return error;
}
Пример #26
0
DWORD
LwLdapDirectorySearchEx(
    HANDLE hDirectory,
    PCSTR  pszObjectDN,
    int    scope,
    PCSTR  pszQuery,
    PSTR*  ppszAttributeList,
    LDAPControl** ppServerControls,
    DWORD  dwNumMaxEntries,
    LDAPMessage** ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    struct timeval timeout = {0};
    LDAPMessage* pMessage = NULL;

    // Set timeout to 60 seconds to be able to deal with large group
    // Instead of bailing on errors
    timeout.tv_sec = 60;
    timeout.tv_usec = 0;

    dwError = ldap_search_ext_s(
                    pDirectory->ld,
                    pszObjectDN,
                    scope,
                    pszQuery,
                    ppszAttributeList,
                    0,
                    ppServerControls,
                    NULL,
                    &timeout,
                    dwNumMaxEntries,
                    &pMessage);
    if (dwError) {
        if (dwError == LDAP_NO_SUCH_OBJECT) {
            LW_RTL_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
            BAIL_ON_LDAP_ERROR(dwError);
        }
        if (dwError == LDAP_REFERRAL) {
            LW_RTL_LOG_ERROR("Caught LDAP_REFERRAL Error on ldap search");
            LW_RTL_LOG_ERROR("LDAP Search Info: DN: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszObjectDN) ? "<null>" : pszObjectDN);
            LW_RTL_LOG_ERROR("LDAP Search Info: scope: [%d]", scope);
            LW_RTL_LOG_ERROR("LDAP Search Info: query: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszQuery) ? "<null>" : pszQuery);
            if (ppszAttributeList) {
                size_t i;
                for (i = 0; ppszAttributeList[i] != NULL; i++) {
                    LW_RTL_LOG_ERROR("LDAP Search Info: attribute: [%s]", ppszAttributeList[i]);
                }
            }
            else {
                LW_RTL_LOG_ERROR("Error: LDAP Search Info: no attributes were specified");
            }
        }
        BAIL_ON_LDAP_ERROR(dwError);
    }

    *ppMessage = pMessage;

cleanup:

    return(dwError);

error:

    *ppMessage = NULL;

    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    goto cleanup;
}
Пример #27
0
DWORD
UninstallWbclient(
    PCSTR pSmbdPath
    )
{
    DWORD error = 0;
    PSTR pSambaDir = NULL;
    PSTR pWbClient = NULL;
    PSTR pWbClientOriginal = NULL;
    PCSTR pLikewiseWbClient = LIBDIR "/" WBCLIENT_FILENAME;
    char pBuffer[1024] = { 0 };
    struct stat statBuf = { 0 };

    error = GetWbclientDir(
                pSmbdPath,
                &pSambaDir);
    BAIL_ON_LSA_ERROR(error);

    error = LwAllocateStringPrintf(
            &pWbClient,
            "%s/%s",
            pSambaDir,
            WBCLIENT_FILENAME
            );
    BAIL_ON_LSA_ERROR(error);

    if (readlink(pWbClient, pBuffer, sizeof(pBuffer)) < 0)
    {
        switch(errno)
        {
            // File does not exist
            case ENOENT:
            // Not a symbolic link
            case EINVAL:
                pBuffer[0] = 0;
                break;
            default:
                error = LwMapErrnoToLwError(errno);
                BAIL_ON_LSA_ERROR(error);
        }
    }
    pBuffer[sizeof(pBuffer) - 1] = 0;

    if (strcmp(pBuffer, pLikewiseWbClient))
    {
        LW_RTL_LOG_INFO("Path %s is not a symbolic link or does not point to %s", pWbClient, pLikewiseWbClient);
        // Already configured
        goto cleanup;
    }

    error = LwAllocateStringPrintf(
            &pWbClientOriginal,
            "%s.lwidentity.orig",
            pWbClient
            );
    BAIL_ON_LSA_ERROR(error);

    if (unlink(pWbClient) < 0)
    {
        error = LwMapErrnoToLwError(errno);
        BAIL_ON_LSA_ERROR(error);   
    }

    if (stat(pWbClientOriginal, &statBuf) < 0)
    {
        if (errno == ENOENT)
        {
            // This is probably Samba 3.0.x, and it did not have an original
            // libwbclient.so.
        }
        else
        {
            LW_RTL_LOG_ERROR("Cannot find original wbclient library at %s",
                    pWbClientOriginal);
            error = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(error);   
        }
    }
    else
    {
        if (symlink(pWbClientOriginal, pWbClient) < 0)
        {
            error = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(error);   
        }

        LW_RTL_LOG_INFO("Linked %s to %s", pWbClient, pLikewiseWbClient);
    }

cleanup:
    LW_SAFE_FREE_STRING(pSambaDir);
    LW_SAFE_FREE_STRING(pWbClient);
    LW_SAFE_FREE_STRING(pWbClientOriginal);
    return error;
}
Пример #28
0
NTSTATUS
RtlCreateAccessToken(
    OUT PACCESS_TOKEN* AccessToken,
    IN PTOKEN_USER User,
    IN PTOKEN_GROUPS Groups,
    IN PTOKEN_PRIVILEGES Privileges,
    IN PTOKEN_OWNER Owner,
    IN PTOKEN_PRIMARY_GROUP PrimaryGroup,
    IN PTOKEN_DEFAULT_DACL DefaultDacl,
    IN OPTIONAL PTOKEN_UNIX Unix
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int unixError = 0;
    ULONG requiredSize = 0;
    PACCESS_TOKEN token = NULL;
    ULONG i = 0;
    ULONG size = 0;
    PVOID location = NULL;

    if (!User || !User->User.Sid ||
        !Groups ||
        !Owner ||
        !PrimaryGroup ||
        !DefaultDacl)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    if (!RtlValidSid(User->User.Sid) ||
        (Owner->Owner && !RtlValidSid(Owner->Owner)) ||
        (PrimaryGroup->PrimaryGroup && !RtlValidSid(PrimaryGroup->PrimaryGroup)))
    {
        status = STATUS_INVALID_SID;
        GOTO_CLEANUP();
    }

    // No user attributes currently exist.
    if (User->User.Attributes != 0)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    for (i = 0; i < Groups->GroupCount; i++)
    {
        // TODO-Perhaps validate Group attributes
        if (!Groups->Groups[i].Sid)
        {
            status = STATUS_INVALID_PARAMETER;
            GOTO_CLEANUP();
        }
        if (!RtlValidSid(Groups->Groups[i].Sid))
        {
            status = STATUS_INVALID_SID;
            GOTO_CLEANUP();
        }
    }

    if (DefaultDacl->DefaultDacl &&
        !RtlValidAcl(DefaultDacl->DefaultDacl, NULL))
    {
        status = STATUS_INVALID_ACL;
        GOTO_CLEANUP();
    }

    // Compute size required

    requiredSize = sizeof(*token);

    size = RtlLengthSid(User->User.Sid);
    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    if (Owner->Owner)
    {
        size = RtlLengthSid(Owner->Owner);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        size = RtlLengthSid(PrimaryGroup->PrimaryGroup);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (DefaultDacl->DefaultDacl)
    {
        status = RtlSafeAddULONG(&requiredSize, requiredSize,
                                 DefaultDacl->DefaultDacl->AclSize);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size, sizeof(Groups->Groups[0]), Groups->GroupCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    for (i = 0; i < Groups->GroupCount; i++)
    {
        size = RtlLengthSid(Groups->Groups[i].Sid);

        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size,
                                  sizeof(Privileges->Privileges[0]),
                                  Privileges->PrivilegeCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RTL_ALLOCATE(&token, ACCESS_TOKEN, requiredSize);
    GOTO_CLEANUP_ON_STATUS(status);

    location = LW_PTR_ADD(token, sizeof(*token));

    // Initialize

    token->ReferenceCount = 1;
    token->Flags = 0;
    unixError = pthread_rwlock_init(&token->RwLock, NULL);
    if (unixError)
    {
        LW_RTL_LOG_ERROR("Failed to init rwlock in access token "
                         "(error = %d).", unixError);
        status = LwErrnoToNtStatus(unixError);
        GOTO_CLEANUP();
    }
    token->pRwLock = &token->RwLock;

    token->User.Attributes = User->User.Attributes;
    token->User.Sid = (PSID) location;
    location = RtlpAppendData(location,
                              User->User.Sid,
                              RtlLengthSid(User->User.Sid));

    token->GroupCount = Groups->GroupCount;
    token->Groups = (PSID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(location, sizeof(Groups->Groups[0]) * Groups->GroupCount);
    for (i = 0; i < Groups->GroupCount; i++)
    {
        token->Groups[i].Attributes = Groups->Groups[i].Attributes;
        token->Groups[i].Sid = (PSID) location;
        location = RtlpAppendData(location,
                                  Groups->Groups[i].Sid,
                                  RtlLengthSid(Groups->Groups[i].Sid));
    }

    token->PrivilegeCount = Privileges->PrivilegeCount;
    token->Privileges = (PLUID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(
                location,
                sizeof(Privileges->Privileges[0]) * Privileges->PrivilegeCount);
    memcpy(token->Privileges,
           Privileges->Privileges,
           sizeof(token->Privileges[0]) * token->PrivilegeCount);

    if (Owner->Owner)
    {
        token->Owner = (PSID) location;
        location = RtlpAppendData(location,
                                  Owner->Owner,
                                  RtlLengthSid(Owner->Owner));
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        token->PrimaryGroup = (PSID) location;
        location = RtlpAppendData(location,
                                  PrimaryGroup->PrimaryGroup,
                                  RtlLengthSid(PrimaryGroup->PrimaryGroup));
    }

    if (DefaultDacl->DefaultDacl)
    {
        token->DefaultDacl = (PACL) location;
        location = RtlpAppendData(location,
                                  DefaultDacl->DefaultDacl,
                                  DefaultDacl->DefaultDacl->AclSize);
    }

    if (Unix)
    {
        SetFlag(token->Flags, ACCESS_TOKEN_FLAG_UNIX_PRESENT);
        token->Uid = Unix->Uid;
        token->Gid = Unix->Gid;
        token->Umask = Unix->Umask;
    }

    if (location != LW_PTR_ADD(token, requiredSize))
    {
        status = STATUS_ASSERTION_FAILURE;
        GOTO_CLEANUP();
    }

    status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(status))
    {
        RtlReleaseAccessToken(&token);
    }

    *AccessToken = token;

    return status;
}