Exemple #1
0
DWORD
NtlmClientExportSecurityContext(
    IN PNTLM_CONTEXT_HANDLE phContext,
    IN DWORD fFlags,
    OUT PSecBuffer pPackedContext
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;

    BAIL_ON_INVALID_POINTER(phContext);

    dwError = NtlmTransactExportSecurityContext(
        *phContext,
        fFlags,
        pPackedContext);
    BAIL_ON_LSA_ERROR(dwError);

error:
    return(dwError);
}
Exemple #2
0
DWORD
LocalCheckForModifyAccess(
    HANDLE hProvider
    )
{
    DWORD dwError = 0;
    BOOLEAN bIsAdmin = FALSE;

    dwError = LocalCheckIsAdministrator(hProvider, &bIsAdmin);
    BAIL_ON_LSA_ERROR(dwError);

    if (!bIsAdmin)
    {
        dwError = LW_ERROR_ACCESS_DENIED;
    }

error:

    return dwError;
}
static
DWORD
ParseArgs(
    int argc,
    char *argv[],
    PSTR *ppszSid
    )
{
    DWORD dwError = 0;
    PSTR pszSid = NULL;

    if (argc < 2) {
        dwError = LW_ERROR_INVALID_PARAMETER;
        ShowUsage();
        exit(1);
    }

    if (strcmp(argv[1], "--help") == 0 ||
        strcmp(argv[1], "-h") == 0)
    {
        ShowUsage();
        exit(0);
    }

    dwError = LwAllocateString(argv[1], &pszSid);
    BAIL_ON_LSA_ERROR(dwError);

    *ppszSid = pszSid;

cleanup:
    return dwError;

error:
    if (pszSid) {
        LW_SAFE_FREE_STRING(pszSid);
    }

    *ppszSid = NULL;

    goto cleanup;
}
Exemple #4
0
DWORD
LsaTraceUnsetFlag(
    DWORD dwTraceFlag
    )
{
    DWORD dwError = 0;

    if (!gpTraceFlags)
    {
        dwError = LW_ERROR_TRACE_NOT_INITIALIZED;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LsaBitVectorUnsetBit(
                    gpTraceFlags,
                    dwTraceFlag);

error:

    return dwError;
}
static
DWORD
ParseTraceFlag(
    PCSTR  pszArg,
    PDWORD pdwTraceFlag
    )
{
    DWORD dwError = 0;
    DWORD dwTraceFlag = 0;

    if (!strcasecmp(pszArg, LSA_TRACE_FLAG_USER_GROUP_QUERIES_TEXT))
    {
       dwTraceFlag = LSA_TRACE_FLAG_USER_GROUP_QUERIES;
    }
    else if (!strcasecmp(pszArg, LSA_TRACE_FLAG_AUTHENTICATION_TEXT))
    {
       dwTraceFlag = LSA_TRACE_FLAG_AUTHENTICATION;
    }
    else if (!strcasecmp(pszArg, LSA_TRACE_FLAG_USER_GROUP_ADMINISTRATION_TEXT))
    {
       dwTraceFlag = LSA_TRACE_FLAG_USER_GROUP_ADMINISTRATION;
    }
    else
    {
       dwError = LW_ERROR_INVALID_PARAMETER;
       BAIL_ON_LSA_ERROR(dwError);
    }

    *pdwTraceFlag = dwTraceFlag;

cleanup:

    return dwError;

error:

    *pdwTraceFlag = 0;

    goto cleanup;
}
Exemple #6
0
DWORD
LsaCheckDirectoryExists(
    PCSTR pszPath,
    PBOOLEAN pbDirExists
    )
{
    DWORD dwError = 0;

    struct stat statbuf;

    while (1) {

        memset(&statbuf, 0, sizeof(struct stat));

        if (stat(pszPath, &statbuf) < 0) {

            if (errno == EINTR) {
                continue;
            }
            else if (errno == ENOENT || errno == ENOTDIR) {
                *pbDirExists = FALSE;
                break;
            }
            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);

        }

        /*
           The path exists. Is it a directory?
         */

        *pbDirExists = (((statbuf.st_mode & S_IFMT) == S_IFDIR) ? TRUE : FALSE);
        break;
    }

error:

    return dwError;
}
DWORD
ADNonSchemaKeywordGetString(
    PSTR *ppszValues,
    DWORD dwNumValues,
    PCSTR pszAttributeName,
    PSTR *ppszResult
    )
{
    DWORD dwError = 0;
    size_t i;
    size_t sNameLen = strlen(pszAttributeName);
    PSTR pszResult = NULL;

    for (i = 0; i < dwNumValues; i++)
    {
        PCSTR pszValue = ppszValues[i];

        // Look for ldap values which are in the form <attributename>=<value>
        if (!strncasecmp(pszValue, pszAttributeName, sNameLen) &&
                pszValue[sNameLen] == '=')
        {
            dwError = LwAllocateString(
                        pszValue + sNameLen + 1,
                        &pszResult);
            BAIL_ON_LSA_ERROR(dwError);
            break;
        }
    }

    *ppszResult = pszResult;

cleanup:
    return dwError;

error:
    *ppszResult = NULL;
    LW_SAFE_FREE_STRING(pszResult);

    goto cleanup;
}
Exemple #8
0
static
DWORD
SetQueryType(
    LSA_QUERY_TYPE type
    )
{
    DWORD dwError = 0;

    if (gState.QueryType != LSA_QUERY_TYPE_UNDEFINED)
    {
        dwError = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_LSA_ERROR(dwError);
    }
    else
    {
        gState.QueryType = type;
    }

error:

    return dwError;
}
Exemple #9
0
DWORD
LsaDataBlobCopy(
    PLSA_DATA_BLOB *ppDst,
    PLSA_DATA_BLOB pSrc
    )
{
    DWORD dwError = LW_ERROR_INTERNAL;

    BAIL_ON_INVALID_POINTER(ppDst);
    BAIL_ON_INVALID_POINTER(pSrc);

    dwError = LsaDataBlobStore(ppDst,
                               pSrc->dwLen,
                               pSrc->pData);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    return dwError;
    
error:
    goto cleanup;    
}
Exemple #10
0
static
DWORD
LocalCfgSetDefaultLoginShell(
    PLOCAL_CONFIG pConfig,
    PCSTR          pszName,
    PCSTR          pszValue
    )
{
    DWORD dwError = 0;

    PSTR pszLoginShell = NULL;

    if (LW_IS_NULL_OR_EMPTY_STR(pszValue))
    {
        goto error;
    }

    if (access(pszValue, X_OK) != 0)
    {
        LSA_LOG_ERROR("Invalid login shell [%s]", pszValue);
        goto error;
    }

    dwError = LwAllocateString(pszValue, &pszLoginShell);
    BAIL_ON_LSA_ERROR(dwError);

    LW_SAFE_FREE_STRING(pConfig->pszLoginShell);

    pConfig->pszLoginShell = pszLoginShell;
    pszLoginShell = NULL;

cleanup:
    return dwError;

error:
    LW_SAFE_FREE_STRING(pszLoginShell);

    goto cleanup;
}
NTSTATUS
LsaSrvAddPrivilegesToAccount(
    /* [in] */ handle_t hBinding,
    /* [in] */ LSAR_ACCOUNT_HANDLE hAccount,
    /* [in] */ PPRIVILEGE_SET pPrivileges
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD err = ERROR_SUCCESS;
    PLSAR_ACCOUNT_CONTEXT pAccountCtx = (PLSAR_ACCOUNT_CONTEXT)hAccount;
    PPOLICY_CONTEXT pPolicyCtx = NULL;

    BAIL_ON_INVALID_PTR(hAccount);
    BAIL_ON_INVALID_PTR(pPrivileges);

    if (pAccountCtx->Type != LsaContextAccount)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pPolicyCtx = pAccountCtx->pPolicyCtx;

    err = LsaSrvPrivsAddPrivilegesToAccount(
                        NULL,
                        pPolicyCtx->pUserToken,
                        pAccountCtx->pAccountContext,
                        pPrivileges);
    BAIL_ON_LSA_ERROR(err);

error:
    if (ntStatus == STATUS_SUCCESS &&
        err != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(err);
    }

    return ntStatus;
}
DWORD
LsaValidateGroupName(
    PCSTR pszName
    )
{
    DWORD dwError = 0;
    size_t sNameLen = 0;

    sNameLen = strlen(pszName);
    if (sNameLen > LSA_MAX_GROUP_NAME_LENGTH || sNameLen == 0)
    {
        dwError = LW_ERROR_INVALID_GROUP_NAME;
        BAIL_ON_LSA_ERROR(dwError);
    }

cleanup:
    return dwError;

error:

    goto cleanup;
}
DWORD
SamDbBuildDirectoryContext(
    PSAMDB_OBJECTCLASS_TO_ATTR_MAP_INFO pObjectClassAttrMaps,
    DWORD                               dwNumObjectClassAttrMaps,
    PSAM_DB_ATTR_LOOKUP                 pAttrLookup,
    PSAM_DIRECTORY_CONTEXT*             ppDirContext
    )
{
    DWORD dwError = 0;
    PSAM_DIRECTORY_CONTEXT pDirContext = NULL;

    dwError = DirectoryAllocateMemory(
                    sizeof(SAM_DIRECTORY_CONTEXT),
                    (PVOID*)&pDirContext);
    BAIL_ON_SAMDB_ERROR(dwError);

    pDirContext->pObjectClassAttrMaps = pObjectClassAttrMaps;
    pDirContext->dwNumObjectClassAttrMaps = dwNumObjectClassAttrMaps;
    pDirContext->pAttrLookup = pAttrLookup;

    dwError = SamDbAcquireDbContext(&pDirContext->pDbContext);
    BAIL_ON_LSA_ERROR(dwError);

    *ppDirContext = pDirContext;

cleanup:
    return dwError;

error:
    if (pDirContext)
    {
        SamDbFreeDirectoryContext(pDirContext);
    }

    *ppDirContext = NULL;

    goto cleanup;
}
Exemple #14
0
DWORD
LsaRemoveFile(
    PCSTR pszPath
    )
{
    DWORD dwError = 0;

    while (1) {
        if (unlink(pszPath) < 0) {
            if (errno == EINTR) {
                continue;
            }
            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);
        } else {
            break;
        }
    }

error:

    return dwError;
}
Exemple #15
0
static
DWORD
LsaAdBatchMarshalGroupInfo(
    IN PAD_PROVIDER_DATA pProviderData,
    IN OUT PLSA_AD_BATCH_ITEM_GROUP_INFO pGroupInfo,
    OUT PLSA_SECURITY_OBJECT_GROUP_INFO pObjectGroupInfo,
    IN PCSTR pszDnsDomainName,
    IN PCSTR pszNetbiosDomainName,
    IN PCSTR pszSamAccountName,
    IN PCSTR pszSid
    )
{
    DWORD dwError = 0;

    if (LsaAdBatchIsUnprovisionedMode(pProviderData))
    {
        dwError = LsaAdBatchMarshalUnprovisionedGroup(
                        pProviderData,
                        pGroupInfo,
                        pszDnsDomainName,
                        pszNetbiosDomainName,
                        pszSamAccountName,
                        pszSid);
        BAIL_ON_LSA_ERROR(dwError);
    }

    pObjectGroupInfo->gid = pGroupInfo->gid;

    LSA_XFER_STRING(pGroupInfo->pszAlias, pObjectGroupInfo->pszAliasName);
    LSA_XFER_STRING(pGroupInfo->pszPasswd, pObjectGroupInfo->pszPasswd);

cleanup:
    return dwError;

error:
    goto cleanup;
}
Exemple #16
0
DWORD
ADGetDomainQualifiedString(
    PCSTR pszNetBIOSDomainName,
    PCSTR pszName,
    PSTR* ppszQualifiedName
    )
{
    DWORD dwError = 0;
    PSTR  pszQualifiedName = NULL;

    dwError = LwAllocateStringPrintf(
                    &pszQualifiedName,
                    "%s%c%s",
                    pszNetBIOSDomainName,
                    LsaSrvDomainSeparator(),
                    pszName);
    BAIL_ON_LSA_ERROR(dwError);

    LwStrnToUpper(pszQualifiedName, strlen(pszNetBIOSDomainName));

    LwStrToLower(pszQualifiedName + strlen(pszNetBIOSDomainName) + 1);

    *ppszQualifiedName = pszQualifiedName;

cleanup:

    return dwError;

error:

    *ppszQualifiedName = NULL;

    LW_SAFE_FREE_STRING(pszQualifiedName);

    goto cleanup;
}
Exemple #17
0
DWORD
LsaChangePermissions(
    PCSTR pszPath,
    mode_t dwFileMode
    )
{
    DWORD dwError = 0;

    while (1) {
        if (chmod(pszPath, dwFileMode) < 0) {
            if (errno == EINTR) {
                continue;
            }
            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);
        } else {
            break;
        }
    }

error:

    return dwError;
}
Exemple #18
0
DWORD
LsaDataBlobStore(
    PLSA_DATA_BLOB *ppBlob,
    DWORD dwSize,
    const PBYTE pBuffer
    )
{
    DWORD dwError = LW_ERROR_INTERNAL;

    BAIL_ON_INVALID_POINTER(ppBlob);

    dwError = LsaDataBlobAllocate(ppBlob, dwSize);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwSize > 0) {        
        memcpy((*ppBlob)->pData, pBuffer, dwSize);
    }
    
cleanup:
    return dwError;
    
error:
    goto cleanup;    
}
Exemple #19
0
DWORD
LsaPcacheGetMachinePasswordInfoW(
    IN LSA_MACHINEPWD_CACHE_HANDLE pPcache,
    OUT PLSA_MACHINE_PASSWORD_INFO_W* ppPasswordInfo
    )
{
    DWORD dwError = 0;
    BOOLEAN bInLock = FALSE;
    PLSA_MACHINE_PASSWORD_INFO_W pPasswordInfo = NULL;

    dwError = LsaPcachepEnsurePasswordInfoAndLock(pPcache);
    BAIL_ON_LSA_ERROR(dwError);
    bInLock = TRUE;

    pPasswordInfo = &pPcache->pEntry->PasswordInfoW;
    LwInterlockedIncrement(&pPcache->pEntry->RefCount);

error:
    if (bInLock)
    {
        PTHREAD_CALL_MUST_SUCCEED(pthread_rwlock_unlock(pPcache->pStateLock));
    }

    if (dwError)
    {
        if (pPasswordInfo)
        {
            LsaPcacheReleaseMachinePasswordInfoW(pPasswordInfo);
            pPasswordInfo = NULL;
        }
    }

    *ppPasswordInfo = pPasswordInfo;

    return dwError;
}
static
DWORD
ValidateParameters(
    PCSTR pszName
    )
{
    DWORD dwError = 0;

    BAIL_ON_INVALID_STRING(pszName);

    if (strlen(pszName) > 15)
    {
        fprintf(stdout, "Machine name can have up to 15 characters\n");

        dwError = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_LSA_ERROR(dwError);
    }

cleanup:
    return dwError;

error:
    goto cleanup;
}
Exemple #21
0
static
DWORD
LsaSrvAuthProviderAllocateProviderList(
    PLSA_AUTH_PROVIDER *ppProviderList
    )
{
    DWORD dwError = 0;
    PSTR pszLoadOrder = NULL; // Multistring
    PCSTR pszProvider = NULL;
    PSTR pszProviderKey = NULL;
    PLSA_AUTH_PROVIDER pProvider = NULL;
    PLSA_AUTH_PROVIDER pProviderList = NULL;

    dwError = LsaSrvAuthProviderRegGetLoadOrder(&pszLoadOrder);
    BAIL_ON_LSA_ERROR(dwError);

    if (!pszLoadOrder)
    {
        /* We should only get here if there is some problem with the
         * registry -- can't access it, the key isn't there, ...
         * -- so we will try a default set of providers.
         */
        LSA_LOG_ERROR("Problem accessing provider configuration in registry. Trying compiled defaults [ActiveDirectory, Local].");

        dwError = LsaSrvAllocateProvider(
                    LSA_PROVIDER_TAG_AD,
                    LSA_PROVIDER_PATH_AD,
                    &pProvider);
        BAIL_ON_LSA_ERROR(dwError);

        if (pProvider)
        {
            LsaSrvAppendAuthProviderList(&pProviderList, pProvider);
            pProvider = NULL;
        }

        dwError = LsaSrvAllocateProvider(
                    LSA_PROVIDER_TAG_LOCAL,
                    LSA_PROVIDER_PATH_LOCAL,
                    &pProvider);
        BAIL_ON_LSA_ERROR(dwError);

        if (pProvider)
        {
            LsaSrvAppendAuthProviderList(&pProviderList, pProvider);
            pProvider = NULL;
        }
    }
    else
    {
        pszProvider = pszLoadOrder;
        while ( pszProvider != NULL && *pszProvider != '\0' )
        {
            dwError = LwAllocateStringPrintf(
                        &pszProviderKey,
                        "Services\\lsass\\Parameters\\Providers\\%s",
                        pszProvider);
            BAIL_ON_LSA_ERROR(dwError);

            dwError = LsaSrvAuthLoadProvider(
                        pszProvider,
                        pszProviderKey,
                        &pProvider);
            BAIL_ON_LSA_ERROR(dwError);

            if (pProvider)
            {
                LsaSrvAppendAuthProviderList(&pProviderList, pProvider);
                pProvider = NULL;
            }

            LW_SAFE_FREE_STRING(pszProviderKey);
            pszProvider = pszProvider + strlen(pszProvider) + 1;
        }
    }

cleanup:

    *ppProviderList = pProviderList;

    LW_SAFE_FREE_MEMORY(pszLoadOrder);
    LW_SAFE_FREE_STRING(pszProviderKey);

    return dwError;

error:

    LsaSrvFreeAuthProviderList(pProviderList);
    pProviderList = NULL;

    goto cleanup;
}
Exemple #22
0
DWORD
LsaSrvInitAuthProviders(
    IN OPTIONAL PLSA_STATIC_PROVIDER pStaticProviders
    )
{
    DWORD dwError = 0;
    PLSA_AUTH_PROVIDER pUninitializedProviderList = NULL;
    PLSA_AUTH_PROVIDER pProviderList = NULL;
    PLSA_AUTH_PROVIDER pProvider = NULL;
    BOOLEAN bInLock = FALSE;

    dwError = LsaSrvAuthProviderAllocateProviderList(
                &pUninitializedProviderList);
    BAIL_ON_LSA_ERROR(dwError);

    while(pUninitializedProviderList)
    {
        pProvider = pUninitializedProviderList;
        pUninitializedProviderList = pUninitializedProviderList->pNext;
        pProvider->pNext = NULL;

        dwError = LsaSrvInitAuthProvider(pProvider, pStaticProviders);
        if (dwError)
        {
            LSA_LOG_ERROR("Failed to load provider '%s' from '%s' - error %u (%s)",
                LSA_SAFE_LOG_STRING(pProvider->pszId),
                LSA_SAFE_LOG_STRING(pProvider->pszProviderLibpath),
                dwError,
                LwWin32ExtErrorToName(dwError));

            LsaSrvFreeAuthProvider(pProvider);
            pProvider = NULL;
            dwError = 0;
        }
        else
        {
            LsaSrvAppendAuthProviderList(&pProviderList, pProvider);
            pProvider = NULL;
        }
    }

    ENTER_AUTH_PROVIDER_LIST_WRITER_LOCK(bInLock);

    LsaSrvFreeAuthProviderList(gpAuthProviderList);

    gpAuthProviderList = pProviderList;
    pProviderList = NULL;

    LEAVE_AUTH_PROVIDER_LIST_WRITER_LOCK(bInLock);

cleanup:

    if (pUninitializedProviderList)
    {
        LsaSrvFreeAuthProviderList(pUninitializedProviderList);
    }

    return dwError;

error:

    if (pProviderList) {
        LsaSrvFreeAuthProviderList(pProviderList);
    }

    goto cleanup;
}
Exemple #23
0
static
DWORD
LsaSrvAuthLoadProvider(
    PCSTR   pszProviderName,
    PCSTR   pszProviderKey,
    PLSA_AUTH_PROVIDER *ppProvider
    )
{
    DWORD dwError = 0;
    PSTR pszId = NULL;
    PSTR pszPath = NULL;
    PLSA_AUTH_PROVIDER pProvider = NULL;

    LWREG_CONFIG_ITEM Config[] =
    {
        {
           "Id",
           FALSE,
           LwRegTypeString,
           0,
           MAXDWORD,
           NULL,
           &pszId,
           NULL
        },
        {
           "Path",
           FALSE,
           LwRegTypeString,
           0,
           MAXDWORD,
           NULL,
           &pszPath,
           NULL
        },
    };
    dwError = RegProcessConfig(
                pszProviderKey,
                pszProviderKey,
                Config,
                sizeof(Config)/sizeof(Config[0]));
    BAIL_ON_LSA_ERROR(dwError);

    if (LW_IS_NULL_OR_EMPTY_STR(pszId))
    {
        goto error;
    }
    if (LW_IS_NULL_OR_EMPTY_STR(pszPath))
    {
        goto error;
    }

    dwError = LsaSrvAllocateProvider(pszId, pszPath, &pProvider);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:

    *ppProvider = pProvider;

    LW_SAFE_FREE_STRING(pszId);
    LW_SAFE_FREE_STRING(pszPath);

    return dwError;

error:

    if (pProvider)
    {
        LsaSrvFreeAuthProvider(pProvider);
        pProvider = NULL;
    }

    goto cleanup;
}
int
set_machine_sid_main(
    int argc,
    char* argv[]
    )
{
    DWORD dwError = 0;
    PSTR pszMachineSid = NULL;
    size_t dwErrorBufferSize = 0;
    BOOLEAN bPrintOrigError = TRUE;

    if (geteuid() != 0) {
        fprintf(stderr, "This program requires super-user privileges.\n");
        dwError = LW_ERROR_ACCESS_DENIED;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = ParseArgs(argc, argv,
                        &pszMachineSid);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ValidateParameters(pszMachineSid);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = SetMachineSid(pszMachineSid);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    if (pszMachineSid) {
        LW_SAFE_FREE_STRING(pszMachineSid);
    }

    return dwError;

error:

    dwError = MapErrorCode(dwError);

    dwErrorBufferSize = LwGetErrorString(dwError, NULL, 0);

    if (dwErrorBufferSize > 0)
    {
        DWORD dwError2 = 0;
        PSTR  pszErrorBuffer = NULL;

        dwError2 = LwAllocateMemory(
                     dwErrorBufferSize,
                     (PVOID*)&pszErrorBuffer);

        if (!dwError2)
        {
            DWORD dwLen = 0;

            dwLen = LwGetErrorString(dwError,
                                      pszErrorBuffer,
                                      dwErrorBufferSize);
            if ((dwLen == dwErrorBufferSize) &&
                !LW_IS_NULL_OR_EMPTY_STR(pszErrorBuffer))
            {
                fprintf(stderr,
                        "Failed to modify SID.  Error code %u (%s).\n%s\n",
                        dwError,
                        LW_PRINTF_STRING(LwWin32ExtErrorToName(dwError)),
                        pszErrorBuffer);
                bPrintOrigError = FALSE;
            }
        }

        LW_SAFE_FREE_STRING(pszErrorBuffer);
    }

    if (bPrintOrigError)
    {
        fprintf(stderr,
                "Failed to modify SID.  Error code %u (%s).\n",
                dwError,
                LW_PRINTF_STRING(LwWin32ExtErrorToName(dwError)));
    }

    goto cleanup;
}
Exemple #25
0
DWORD
LsaSrvInitAuthProvider(
    IN PLSA_AUTH_PROVIDER pProvider,
    IN OPTIONAL PLSA_STATIC_PROVIDER pStaticProviders
    )
{
    DWORD dwError = 0;
    PFNINITIALIZEPROVIDER pfnInitProvider = NULL;
    PCSTR pszError = NULL;
    PSTR pszProviderLibpath = NULL;
    int i = 0;

    if (pStaticProviders)
    {
        /* First look for a static provider entry with the given name */
        for (i = 0; pStaticProviders[i].pszId; i++)
        {
            if (!strcmp(pStaticProviders[i].pszId, pProvider->pszId))
            {
                pfnInitProvider = pStaticProviders[i].pInitialize;
                LSA_LOG_DEBUG("Provider %s loaded from static list", pProvider->pszId);
                break;
            }
        }
    }

    if (!pfnInitProvider)
    {
        /* Try to load the provider dynamically */
        if (LW_IS_NULL_OR_EMPTY_STR(pProvider->pszProviderLibpath))
        {
            dwError = LW_ERROR_INVALID_AUTH_PROVIDER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        pszProviderLibpath = pProvider->pszProviderLibpath;

        dlerror();
        pProvider->pLibHandle = dlopen(pszProviderLibpath, RTLD_NOW | RTLD_LOCAL);
        if (!pProvider->pLibHandle)
        {
            LSA_LOG_ERROR("Failed to open auth provider at path '%s'", pszProviderLibpath);

            pszError = dlerror();
            if (!LW_IS_NULL_OR_EMPTY_STR(pszError))
            {
                LSA_LOG_ERROR("%s", pszError);
            }

            dwError = LW_ERROR_INVALID_AUTH_PROVIDER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        dlerror();
        pfnInitProvider = (PFNINITIALIZEPROVIDER) dlsym(
            pProvider->pLibHandle,
            LSA_SYMBOL_NAME_INITIALIZE_PROVIDER);
        if (!pfnInitProvider)
        {
            LSA_LOG_ERROR("Ignoring invalid auth provider at path '%s'", pszProviderLibpath);

            pszError = dlerror();
            if (!LW_IS_NULL_OR_EMPTY_STR(pszError))
            {
                LSA_LOG_ERROR("%s", pszError);
            }

            dwError = LW_ERROR_INVALID_AUTH_PROVIDER;
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    dwError = pfnInitProvider(
                    &pProvider->pszName,
                    &pProvider->pFnTable);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LsaSrvValidateProvider(pProvider);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:

    return dwError;

error:

    goto cleanup;
}
Exemple #26
0
DWORD
AD_InitializeConfig(
    PLSA_AD_CONFIG pConfig
)
{
    DWORD dwError = 0;

    memset(pConfig, 0, sizeof(LSA_AD_CONFIG));

    pConfig->bAssumeDefaultDomain = FALSE;
    pConfig->bCreateHomeDir   = TRUE;
    pConfig->bCreateK5Login   = TRUE;
    pConfig->bLDAPSignAndSeal = FALSE;
    pConfig->bSyncSystemTime  = TRUE;
    pConfig->dwCacheEntryExpirySecs   = AD_CACHE_ENTRY_EXPIRY_DEFAULT_SECS;
    pConfig->dwCacheSizeCap           = 0;
    pConfig->dwMachinePasswordSyncLifetime = AD_MACHINE_PASSWORD_SYNC_DEFAULT_SECS;
    pConfig->dwUmask          = AD_DEFAULT_UMASK;

    pConfig->bEnableEventLog = FALSE;
    pConfig->bShouldLogNetworkConnectionEvents = TRUE;
    pConfig->bRefreshUserCreds = TRUE;
    pConfig->CellSupport = AD_CELL_SUPPORT_UNPROVISIONED;
    pConfig->CacheBackend = AD_CACHE_IN_MEMORY;
    pConfig->bTrimUserMembershipEnabled = TRUE;
    pConfig->bNssGroupMembersCacheOnlyEnabled = TRUE;
    pConfig->bNssUserMembershipCacheOnlyEnabled = FALSE;
    pConfig->bNssEnumerationEnabled = FALSE;

    pConfig->DomainManager.dwCheckDomainOnlineSeconds = 5 * LSA_SECONDS_IN_MINUTE;
    pConfig->DomainManager.dwUnknownDomainCacheTimeoutSeconds = 1 * LSA_SECONDS_IN_HOUR;
    pConfig->DomainManager.bIgnoreAllTrusts = FALSE;
    pConfig->DomainManager.ppszTrustExceptionList = NULL;
    pConfig->DomainManager.dwTrustExceptionCount = 0;

    pConfig->bMultiTenancyEnabled = FALSE;
    pConfig->bAddDomainToLocalGroupsEnabled = FALSE;

    dwError = LwAllocateString(
                  AD_DEFAULT_SHELL,
                  &pConfig->pszShell);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                  AD_DEFAULT_HOMEDIR_PREFIX,
                  &pConfig->pszHomedirPrefix);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                  AD_DEFAULT_HOMEDIR_TEMPLATE,
                  &pConfig->pszHomedirTemplate);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                  "",
                  &pConfig->pszRemoteHomeDirTemplate);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                  AD_DEFAULT_SKELDIRS,
                  &pConfig->pszSkelDirs);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:

    return dwError;

error:

    AD_FreeConfigContents(pConfig);

    goto cleanup;
}
Exemple #27
0
DWORD
LsaSrvGetPamConfig(
    IN HANDLE hServer,
    OUT PLSA_PAM_CONFIG *ppPamConfig
    )
{
    DWORD dwError = 0;
    LSA_PAM_CONFIG PamConfig = { 0 };
    PLSA_PAM_CONFIG pPamConfig = NULL;
    PSTR pszSmartCardServices = NULL;
    PSTR pszSmartCardPromptGecos = NULL;
    DWORD dwSmartCardServicesSize = 0;
    DWORD dwSmartCardPromptGecosSize = 0;
    DWORD dwCount;

    const PCSTR LogLevels[] = 
    {
        "disabled",
        "always",
        "error",
        "warning",
        "info",
        "verbose",
        "debug"
    };

    LWREG_CONFIG_ITEM ConfigDescription[] =
    {
        {
            "LogLevel",
            TRUE,
            LwRegTypeEnum,
            LSA_PAM_LOG_LEVEL_DISABLED,
            LSA_PAM_LOG_LEVEL_DEBUG,
            LogLevels,
            &PamConfig.dwLogLevel,
            NULL
        },
        {
            "DisplayMOTD",
            TRUE,
            LwRegTypeBoolean,
            0,
            0,
            NULL,
            &PamConfig.bLsaPamDisplayMOTD,
            NULL
        },
        {
            "UserNotAllowedError",
            TRUE,
            LwRegTypeString,
            0,
            0,
            NULL,
            &PamConfig.pszAccessDeniedMessage,
            NULL
        },
        {
            "SmartCardServices",
            TRUE,
            LwRegTypeMultiString,
            0,
            0,
            NULL,
            &pszSmartCardServices,
            &dwSmartCardServicesSize
        },
        {
            "SmartCardPromptGecos",
            TRUE,
            LwRegTypeMultiString,
            0,
            0,
            NULL,
            &pszSmartCardPromptGecos,
            &dwSmartCardPromptGecosSize
        },
        {
            "ActiveDirectoryPasswordPrompt",
            TRUE,
            LwRegTypeString,
            0,
            0,
            NULL,
            &PamConfig.pszActiveDirectoryPasswordPrompt,
            NULL
        },
        {
            
            "LocalPasswordPrompt",
            TRUE,
            LwRegTypeString,
            0,
            0,
            NULL,
            &PamConfig.pszLocalPasswordPrompt,
            NULL                                                            
        },
          {
            
            "OtherPasswordPrompt",
            TRUE,
            LwRegTypeString,
            0,
            0,
            NULL,
            &PamConfig.pszOtherPasswordPrompt,
            NULL                                                            
        },
        
    };

    dwError = LwAllocateMemory(
                sizeof(LSA_PAM_CONFIG),
                OUT_PPVOID(&pPamConfig));
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LsaUtilInitializePamConfig(&PamConfig);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = RegProcessConfig(
                "Services\\lsass\\Parameters\\PAM",
                "Policy\\Services\\lsass\\Parameters\\PAM",
                ConfigDescription,
                sizeof(ConfigDescription)/sizeof(ConfigDescription[0]));
    BAIL_ON_LSA_ERROR(dwError);

    dwError = RegByteArrayToMultiStrsA(
            (PBYTE) pszSmartCardServices,
            dwSmartCardServicesSize,
            &PamConfig.ppszSmartCardServices);
    BAIL_ON_LSA_ERROR(dwError);

    dwCount = 0;
    while (PamConfig.ppszSmartCardServices[dwCount] != NULL)
    {
         ++dwCount;
    }
    PamConfig.dwNumSmartCardServices = dwCount;

    dwError = RegByteArrayToMultiStrsA(
            (PBYTE) pszSmartCardPromptGecos,
            dwSmartCardPromptGecosSize,
            &PamConfig.ppszSmartCardPromptGecos);
    BAIL_ON_LSA_ERROR(dwError);

    dwCount = 0;
    while (PamConfig.ppszSmartCardPromptGecos[dwCount] != NULL)
    {
         ++dwCount;
    }
    PamConfig.dwNumSmartCardPromptGecos = dwCount;

    *pPamConfig = PamConfig;
    memset(&PamConfig, 0, sizeof(LSA_PAM_CONFIG));

cleanup:
    LW_SAFE_FREE_STRING(pszSmartCardServices);
    LW_SAFE_FREE_STRING(pszSmartCardPromptGecos);

    *ppPamConfig = pPamConfig;

    return dwError;

error:
    if (pPamConfig)
    {
        LsaUtilFreePamConfigContents(pPamConfig);
        LW_SAFE_FREE_MEMORY(pPamConfig);
    }
    LsaUtilFreePamConfigContents(&PamConfig);

    goto cleanup;
}
Exemple #28
0
DWORD
AD_ReadRegistry(
    IN OPTIONAL PCSTR pszDomainName,
    OUT PLSA_AD_CONFIG pConfig
)
{
    DWORD dwError = 0;
    PSTR pszDomainKey = NULL;
    PSTR pszDomainPolicyKey = NULL;
    PSTR pszUmask = NULL;
    PSTR pszUnresolvedMemberList = NULL;
    DWORD dwMachinePasswordSyncLifetime = 0;
    PSTR pszExcludeTrustsListMultiString = NULL;
    PSTR pszIncludeTrustsListMultiString = NULL;
    LSA_AD_CONFIG StagingConfig;

    const PCSTR CellSupport[] = {
        "unprovisioned"
    };

    const PCSTR CacheBackend[] =
    {
        "sqlite",
        "memory"
    };

    LWREG_CONFIG_ITEM ADConfigDescription[] =
    {
        {
            "HomeDirUmask",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &pszUmask,
            NULL
        },
        {
            "RequireMembershipOf",
            TRUE,
            LwRegTypeMultiString,
            0,
            MAXDWORD,
            NULL,
            &pszUnresolvedMemberList,
            NULL
        },
        {
            "LoginShellTemplate",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszShell,
            NULL
        },
        {
            "HomeDirTemplate",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszHomedirTemplate,
            NULL
        },
        {
            "RemoteHomeDirTemplate",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszRemoteHomeDirTemplate,
            NULL
        },
        {
            "UserDomainPrefix",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszUserDomainPrefix
        },
        {
            "MachinePasswordLifespan",
            TRUE,
            LwRegTypeDword,
            0,  /* Valid range is 0 or [AD_MACHINE_PASSWORD_SYNC_MINIMUM_SECS,*/
            MAXDWORD, /* AD_MACHINE_PASSWORD_SYNC_MAXIMUM_SECS] */
            NULL,
            &dwMachinePasswordSyncLifetime,
            NULL
        },
        {
            "CacheEntryExpiry",
            TRUE,
            LwRegTypeDword,
            AD_CACHE_ENTRY_EXPIRY_MINIMUM_SECS,
            AD_CACHE_ENTRY_EXPIRY_MAXIMUM_SECS,
            NULL,
            &StagingConfig.dwCacheEntryExpirySecs,
            NULL
        },
        {
            "MemoryCacheSizeCap",
            TRUE,
            LwRegTypeDword,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.dwCacheSizeCap,
            NULL
        },
        {
            "LdapSignAndSeal",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bLDAPSignAndSeal,
            NULL
        },
        {
            "AssumeDefaultDomain",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bAssumeDefaultDomain,
            NULL
        },
        {
            "SyncSystemTime",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bSyncSystemTime,
            NULL
        },
        {
            "LogNetworkConnectionEvents",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bShouldLogNetworkConnectionEvents,
            NULL
        },
        {
            "CreateK5Login",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bCreateK5Login,
            NULL
        },
        {
            "CreateHomeDir",
            TRUE,
            LwRegTypeBoolean,
            0,
            -1,
            NULL,
            &StagingConfig.bCreateHomeDir,
            NULL
        },
        {
            "SkeletonDirs",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszSkelDirs,
            NULL
        },
        {
            "HomeDirPrefix",
            TRUE,
            LwRegTypeString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszHomedirPrefix,
            NULL
        },
        {
            "RefreshUserCredentials",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bRefreshUserCreds,
            NULL
        },
        {
            "TrimUserMembership",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bTrimUserMembershipEnabled,
            NULL
        },
        {
            "CellSupport",
            TRUE,
            LwRegTypeEnum,
            AD_CELL_SUPPORT_UNPROVISIONED,
            AD_CELL_SUPPORT_UNPROVISIONED,
            CellSupport,
            &StagingConfig.CellSupport,
            NULL
        },
        {
            "CacheType",
            TRUE,
            LwRegTypeEnum,
            AD_CACHE_SQLITE,
            AD_CACHE_IN_MEMORY,
            CacheBackend,
            &StagingConfig.CacheBackend,
            NULL
        },
        {
            "NssGroupMembersQueryCacheOnly",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bNssGroupMembersCacheOnlyEnabled,
            NULL
        },
        {
            "NssUserMembershipQueryCacheOnly",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bNssUserMembershipCacheOnlyEnabled,
            NULL
        },
        {
            "NssEnumerationEnabled",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bNssEnumerationEnabled,
            NULL
        },
        {
            "DomainManagerCheckDomainOnlineInterval",
            TRUE,
            LwRegTypeDword,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.DomainManager.dwCheckDomainOnlineSeconds,
            NULL
        },
        {
            "DomainManagerUnknownDomainCacheTimeout",
            TRUE,
            LwRegTypeDword,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.DomainManager.dwUnknownDomainCacheTimeoutSeconds,
            NULL
        },
        {
            "DomainManagerIgnoreAllTrusts",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.DomainManager.bIgnoreAllTrusts,
            NULL
        },
        {
            "DomainManagerExcludeTrustsList",
            TRUE,
            LwRegTypeMultiString,
            0,
            MAXDWORD,
            NULL,
            &pszExcludeTrustsListMultiString,
            NULL
        },
        {
            "DomainManagerIncludeTrustsList",
            TRUE,
            LwRegTypeMultiString,
            0,
            MAXDWORD,
            NULL,
            &pszIncludeTrustsListMultiString,
            NULL
        },
        {
            "IgnoreUserNameList",
            TRUE,
            LwRegTypeMultiString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszaIgnoreUserNameList,
            NULL
        },
        {
            "IgnoreGroupNameList",
            TRUE,
            LwRegTypeMultiString,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.pszaIgnoreGroupNameList,
            NULL
        },
        {
            "MultiTenancyEnabled",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bMultiTenancyEnabled,
            NULL
        },
        {
            "AddDomainToLocalGroupsEnabled",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bAddDomainToLocalGroupsEnabled,
            NULL
        }
    };

    LWREG_CONFIG_ITEM LsaConfigDescription[] =
    {
        {
            "EnableEventlog",
            TRUE,
            LwRegTypeBoolean,
            0,
            MAXDWORD,
            NULL,
            &StagingConfig.bEnableEventLog,
            NULL
        }
    };

    dwError = AD_InitializeConfig(&StagingConfig);
    BAIL_ON_LSA_ERROR(dwError);

    dwMachinePasswordSyncLifetime = AD_MACHINE_PASSWORD_SYNC_DEFAULT_SECS;

    dwError = RegProcessConfig(
                  AD_PROVIDER_REGKEY,
                  AD_PROVIDER_POLICY_REGKEY,
                  ADConfigDescription,
                  sizeof(ADConfigDescription)/sizeof(ADConfigDescription[0]));
    BAIL_ON_LSA_ERROR(dwError);

    if (pszDomainName)
    {
        dwError = LwAllocateStringPrintf(
                      &pszDomainKey,
                      "%s\\%s",
                      AD_PROVIDER_DOMAINJOIN_REGKEY,
                      pszDomainName);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwAllocateStringPrintf(
                      &pszDomainPolicyKey,
                      "%s\\%s",
                      AD_PROVIDER_POLICY_DOMAINJOIN_REGKEY,
                      pszDomainName);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = RegProcessConfig(
                      pszDomainKey,
                      pszDomainPolicyKey,
                      ADConfigDescription,
                      sizeof(ADConfigDescription)/sizeof(ADConfigDescription[0]));
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = RegProcessConfig(
                  "Services\\lsass\\Parameters",
                  "Policy\\Services\\lsass\\Parameters",
                  LsaConfigDescription,
                  sizeof(LsaConfigDescription)/sizeof(LsaConfigDescription[0]));
    BAIL_ON_LSA_ERROR(dwError);

    AD_SetConfig_Umask(
        &StagingConfig,
        "HomeDirUmask",
        pszUmask);

    AD_SetConfig_RequireMembershipOf(
        &StagingConfig,
        "RequireMembershipOf",
        pszUnresolvedMemberList);

    AD_SetConfig_MachinePasswordLifespan(
        &StagingConfig,
        "MachinePasswordLifespan",
        dwMachinePasswordSyncLifetime);

    AD_SetConfig_DomainManager_TrustExceptionList(
        &StagingConfig,
        (StagingConfig.DomainManager.bIgnoreAllTrusts ?
         pszIncludeTrustsListMultiString :
         pszExcludeTrustsListMultiString));

    AD_TransferConfigContents(&StagingConfig, pConfig);

cleanup:
    LW_SAFE_FREE_STRING(pszDomainKey);
    LW_SAFE_FREE_STRING(pszDomainPolicyKey);
    LW_SAFE_FREE_STRING(pszUmask);
    LW_SAFE_FREE_STRING(pszUnresolvedMemberList);
    LW_SAFE_FREE_STRING(pszExcludeTrustsListMultiString);
    LW_SAFE_FREE_STRING(pszIncludeTrustsListMultiString);

    AD_FreeConfigContents(&StagingConfig);

    return dwError;

error:
    AD_FreeConfigContents(pConfig);
    goto cleanup;
}
Exemple #29
0
DWORD
AD_GetMemberLists(
    IN PLSA_AD_PROVIDER_STATE pState,
    PSTR** pppszMembers,
    PDWORD pdwNumMembers,
    PLW_HASH_TABLE* ppAllowedMemberList
)
{
    DWORD dwError = 0;
    BOOLEAN bInLock = FALSE;
    DWORD dwNumMembers = 0;
    PLW_DLINKED_LIST pIter = NULL;
    PSTR* ppszMembers = NULL;
    PLW_HASH_TABLE pAllowedMemberList = NULL;

    ENTER_AD_CONFIG_RW_READER_LOCK(bInLock, pState);

    for (pIter = pState->config.pUnresolvedMemberList; pIter; pIter = pIter->pNext)
    {
        dwNumMembers++;
    }

    if (dwNumMembers)
    {
        DWORD iMember = 0;

        dwError = LwAllocateMemory(
                      dwNumMembers * sizeof(PSTR),
                      (PVOID*)&ppszMembers);
        BAIL_ON_LSA_ERROR(dwError);

        for (pIter = pState->config.pUnresolvedMemberList;
                pIter;
                pIter = pIter->pNext, iMember++)
        {
            dwError = LwAllocateString(
                          (PSTR)pIter->pItem,
                          &ppszMembers[iMember]);
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    if (pState->pAllowedSIDs)
    {
        dwError = LwHashCopy(
                      pState->pAllowedSIDs,
                      &pAllowedMemberList);
        BAIL_ON_LSA_ERROR(dwError);
    }

    *pppszMembers = ppszMembers;
    *pdwNumMembers = dwNumMembers;
    *ppAllowedMemberList = pAllowedMemberList;

cleanup:

    LEAVE_AD_CONFIG_RW_READER_LOCK(bInLock, pState);

    return dwError;

error:

    if (ppszMembers)
    {
        LwFreeStringArray(ppszMembers, dwNumMembers);
    }

    *pppszMembers = NULL;
    *pdwNumMembers = 0;
    *ppAllowedMemberList = NULL;

    LwHashSafeFree(&pAllowedMemberList);

    goto cleanup;
}
Exemple #30
0
DWORD
AD_AddAllowedMember(
    IN PLSA_AD_PROVIDER_STATE pState,
    IN PCSTR               pszSID,
    IN PSTR                pszMember,
    IN OUT PLW_HASH_TABLE *ppAllowedMemberList
)
{
    DWORD dwError = 0;
    BOOLEAN bInLock = FALSE;
    PSTR  pszValue = NULL;
    PSTR  pszSIDCopy = NULL;
    PSTR  pszMemberCopy = NULL;
    PLW_HASH_TABLE pAllowedMemberList = *ppAllowedMemberList;

    ENTER_AD_CONFIG_RW_WRITER_LOCK(bInLock, pState);

    if (!pState->pAllowedSIDs)
    {
        dwError = LwHashCreate(
                      11,
                      LwHashCaselessStringCompare,
                      LwHashCaselessStringHash,
                      AD_FreeHashStringKeyValue,
                      AD_CopyHashStringKeyValue,
                      &pState->pAllowedSIDs);
        BAIL_ON_LSA_ERROR(dwError);
    }

    if (!pAllowedMemberList)
    {
        dwError = LwHashCreate(
                      11,
                      LwHashCaselessStringCompare,
                      LwHashCaselessStringHash,
                      AD_FreeHashStringKeyValue,
                      AD_CopyHashStringKeyValue,
                      &pAllowedMemberList);
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LwAllocateString(
                  pszSID,
                  &pszSIDCopy);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                  pszMember,
                  &pszMemberCopy);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwHashSetValue(
                  pAllowedMemberList,
                  pszSIDCopy,
                  pszMemberCopy);
    BAIL_ON_LSA_ERROR(dwError);

    pszSIDCopy = NULL;
    pszMemberCopy = NULL;

    if ( AD_IsInMembersList_InLock(pState, pszMember) )
    {
        dwError = LwHashGetValue(
                      pState->pAllowedSIDs,
                      pszSID,
                      (PVOID*)&pszValue);
        if (dwError == ERROR_NOT_FOUND)
        {
            dwError = LwAllocateString(
                          pszSID,
                          &pszSIDCopy);
            BAIL_ON_LSA_ERROR(dwError);

            dwError = LwAllocateString(
                          pszMember,
                          &pszMemberCopy);
            BAIL_ON_LSA_ERROR(dwError);

            dwError = LwHashSetValue(
                          pState->pAllowedSIDs,
                          pszSIDCopy,
                          pszMemberCopy);
            BAIL_ON_LSA_ERROR(dwError);

            pszSIDCopy = NULL;
            pszMemberCopy = NULL;
        }

        AD_DeleteFromMembersList_InLock(pState, pszMember);
    }

    *ppAllowedMemberList = pAllowedMemberList;

cleanup:

    LW_SAFE_FREE_STRING(pszSIDCopy);
    LW_SAFE_FREE_STRING(pszMemberCopy);

    LEAVE_AD_CONFIG_RW_WRITER_LOCK(bInLock, pState);

    return dwError;

error:

    if ( ! *ppAllowedMemberList )
    {
        LwHashSafeFree(&pAllowedMemberList);
    }

    goto cleanup;
}