Beispiel #1
0
DWORD
LocalDirEnumMembers(
    IN HANDLE hEnum,
    IN DWORD dwMaxMemberSidCount,
    OUT PDWORD pdwMemberSidCount,
    OUT PSTR** pppszMemberSids
    )
{
    DWORD dwError = 0;
    LOCAL_ENUM_HANDLE pEnum = (LOCAL_ENUM_HANDLE) hEnum;
    PLOCAL_PROVIDER_CONTEXT pContext = (PLOCAL_PROVIDER_CONTEXT) pEnum->hProvider;
    LONG64 llSequenceNumber = 0;
    DWORD dwAllocCount = 0;
    PSTR* ppszMemberSids = NULL;
    DWORD dwIndex = 0;
    PDIRECTORY_ENTRY pEntry = NULL;
    static WCHAR wszAttrNameObjectSID[]      = LOCAL_DIR_ATTR_OBJECT_SID;

    if (pEnum->dwIndex >= pEnum->dwCount)
    {
        dwError = ERROR_NO_MORE_ITEMS;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LocalGetSequenceNumber(
        pContext,
        &llSequenceNumber);
    BAIL_ON_LSA_ERROR(dwError);

    if (llSequenceNumber != pEnum->llSequenceNumber)
    {
        dwError = ERROR_INVALID_DATA;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwAllocCount = dwMaxMemberSidCount;
    if (dwAllocCount > pEnum->dwCount - pEnum->dwIndex)
    {
        dwAllocCount = pEnum->dwCount - pEnum->dwIndex;
    }

    dwError = LwAllocateMemory(sizeof(*ppszMemberSids) * dwAllocCount, OUT_PPVOID(&ppszMemberSids));
    BAIL_ON_LSA_ERROR(dwError);

    for(dwIndex = 0; dwIndex < dwAllocCount; dwIndex++)
    {
        pEntry = &pEnum->pEntries[pEnum->dwIndex++];

        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameObjectSID,
            &ppszMemberSids[dwIndex]);
        BAIL_ON_LSA_ERROR(dwError);
    }

    *pdwMemberSidCount = dwAllocCount;
    *pppszMemberSids = ppszMemberSids;

cleanup:

    return dwError;

error:

    *pdwMemberSidCount = 0;
    *pppszMemberSids = NULL;

    if (ppszMemberSids)
    {
        LwFreeStringArray(ppszMemberSids, dwAllocCount);
    }

    goto cleanup;
}
Beispiel #2
0
static
DWORD
LocalDirQueryMemberOfDN(
    IN HANDLE hProvider,
    IN LSA_FIND_FLAGS FindFlags,
    IN PWSTR pwszDN,
    IN OUT PLW_HASH_TABLE pGroupHash
    )
{
    DWORD dwError = 0;
    PLOCAL_PROVIDER_CONTEXT pContext = (PLOCAL_PROVIDER_CONTEXT)hProvider;
    static WCHAR wszAttrNameObjectSID[] = LOCAL_DIR_ATTR_OBJECT_SID;
    static PWSTR wszMemberAttrs[] =
    {
        wszAttrNameObjectSID,
        NULL
    };
    PDIRECTORY_ENTRY pEntries = NULL;
    DWORD dwNumEntries = 0;
    PSTR pszFilter = NULL;
    PWSTR pwszFilter = NULL;
    DWORD dwIndex = 0;
    PSTR pszGroupSid = NULL;
    PSTR pszPreviousGroupSid = NULL;

    dwError = DirectoryGetMemberships(
        pContext->hDirectory,
        pwszDN,
        wszMemberAttrs,
        &pEntries,
        &dwNumEntries);
    BAIL_ON_LSA_ERROR(dwError);
            
    for (dwIndex = 0; dwIndex < dwNumEntries; dwIndex++)
    {
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            &pEntries[dwIndex],
            wszAttrNameObjectSID,
            &pszGroupSid);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LwHashGetValue(
            pGroupHash,
            pszGroupSid,
            OUT_PPVOID(&pszPreviousGroupSid));
        if (dwError == ERROR_NOT_FOUND)
        {
            dwError = LwHashSetValue(
                pGroupHash,
                pszGroupSid,
                pszGroupSid);
            BAIL_ON_LSA_ERROR(dwError);
            
            dwError = LocalDirQueryMemberOfInternal(
                hProvider,
                FindFlags,
                pszGroupSid,
                pGroupHash);
            pszGroupSid = NULL;
            BAIL_ON_LSA_ERROR(dwError);
        }
        else
        {
            BAIL_ON_LSA_ERROR(dwError);
        }
        
        LW_SAFE_FREE_MEMORY(pszGroupSid);
    }

cleanup:

    LW_SAFE_FREE_MEMORY(pwszFilter);
    LW_SAFE_FREE_MEMORY(pszFilter);
    
    if (pEntries)
    {
        DirectoryFreeEntries(pEntries, dwNumEntries);
    }

    return dwError;

error:

    goto cleanup;
}
Beispiel #3
0
static
DWORD
LocalDirResolveUserObjectPrimaryGroupSid(
    IN HANDLE hProvider,
    IN OUT PLSA_SECURITY_OBJECT pUserObject
    )
{
    DWORD dwError = 0;
    PLOCAL_PROVIDER_CONTEXT pContext = (PLOCAL_PROVIDER_CONTEXT)hProvider;
    static WCHAR wszAttrNameObjectSID[] = LOCAL_DIR_ATTR_OBJECT_SID;
    static PWSTR wszAttrs[] =
    {
        wszAttrNameObjectSID,
        NULL
    };
    PCSTR pszTemplate = LOCAL_DB_DIR_ATTR_GID " = %u";
    PWSTR pwszFilter = NULL;
    PDIRECTORY_ENTRY pEntry = NULL;
    DWORD dwNumEntries = 0;
    
    if (pUserObject->type != LSA_OBJECT_TYPE_USER)
    {
        goto cleanup;
    }

    dwError = DirectoryAllocateWC16StringFilterPrintf(
        &pwszFilter,
        pszTemplate,
        pUserObject->userInfo.gid);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectorySearch(
        pContext->hDirectory,
        NULL,
        0,
        pwszFilter,
        wszAttrs,
        FALSE,
        &pEntry,
        &dwNumEntries);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwNumEntries != 1)
    {
        dwError = LW_ERROR_DATA_ERROR;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LocalMarshalAttrToANSIFromUnicodeString(
        pEntry,
        wszAttrNameObjectSID,
        &pUserObject->userInfo.pszPrimaryGroupSid);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    LW_SAFE_FREE_MEMORY(pwszFilter);

    if (pEntry)
    {
        DirectoryFreeEntries(pEntry, dwNumEntries);
    }

    return dwError;

error:

    goto cleanup;
}
Beispiel #4
0
DWORD
LocalMarshalEntryToSecurityObject(
    PDIRECTORY_ENTRY pEntry,
    PLSA_SECURITY_OBJECT* ppObject
    )
{
    DWORD dwError = 0;
    static WCHAR wszAttrNameObjectClass[]    = LOCAL_DIR_ATTR_OBJECT_CLASS;
    static WCHAR wszAttrNameUID[]            = LOCAL_DIR_ATTR_UID;
    static WCHAR wszAttrNameGID[]            = LOCAL_DIR_ATTR_GID;
    static WCHAR wszAttrNamePrimaryGroup[]   = LOCAL_DIR_ATTR_PRIMARY_GROUP;
    static WCHAR wszAttrNameSamAccountName[] = LOCAL_DIR_ATTR_SAM_ACCOUNT_NAME;
    static WCHAR wszAttrNamePassword[]       = LOCAL_DIR_ATTR_PASSWORD;
    static WCHAR wszAttrNameNTHash[]         = LOCAL_DIR_ATTR_NT_HASH;
    static WCHAR wszAttrNameLMHash[]         = LOCAL_DIR_ATTR_LM_HASH;
    static WCHAR wszAttrNameGecos[]          = LOCAL_DIR_ATTR_GECOS;
    static WCHAR wszAttrNameShell[]          = LOCAL_DIR_ATTR_SHELL;
    static WCHAR wszAttrNameHomedir[]        = LOCAL_DIR_ATTR_HOME_DIR;
    static WCHAR wszAttrNameUPN[]            = LOCAL_DIR_ATTR_USER_PRINCIPAL_NAME;
    static WCHAR wszAttrNameObjectSID[]      = LOCAL_DIR_ATTR_OBJECT_SID;
    static WCHAR wszAttrNameAccountFlags[]   = LOCAL_DIR_ATTR_ACCOUNT_FLAGS;
    static WCHAR wszAttrNameAccountExpiry[]  = LOCAL_DIR_ATTR_ACCOUNT_EXPIRY;
    static WCHAR wszAttrNamePasswdLastSet[]  = LOCAL_DIR_ATTR_PASSWORD_LAST_SET;
    static WCHAR wszAttrNameDN[]             = LOCAL_DIR_ATTR_DISTINGUISHED_NAME;
    static WCHAR wszAttrNameNetBIOSDomain[]  = LOCAL_DIR_ATTR_NETBIOS_NAME;
    PLSA_SECURITY_OBJECT pObject = NULL;
    DWORD  dwObjectClass = 0;
    DWORD  dwAccountFlags = 0;
    LONG64 llAccountExpiry = 0;
    LONG64 llPasswordLastSet = 0;
    DWORD  dwUid = 0;
    DWORD  dwGid = 0;
    BOOLEAN enableUnixIds = TRUE;

    dwError = LocalMarshalAttrToInteger(
                    pEntry,
                    wszAttrNameObjectClass,
                    &dwObjectClass);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateMemory(
        sizeof(*pObject),
        OUT_PPVOID(&pObject));
    BAIL_ON_LSA_ERROR(dwError);

    pObject->bIsLocal = TRUE;

    dwError = LocalCfgGetEnableUnixIds(&enableUnixIds);
    BAIL_ON_LSA_ERROR(dwError);

    pObject->enabled = enableUnixIds;

    switch (dwObjectClass)
    {
    case LOCAL_OBJECT_CLASS_USER:
        pObject->type = LSA_OBJECT_TYPE_USER;

        dwError = LocalMarshalAttrToInteger(
            pEntry,
            wszAttrNameUID,
            &dwUid);
        BAIL_ON_LSA_ERROR(dwError);
        
        pObject->userInfo.uid = (uid_t) dwUid;
        
        dwError = LocalMarshalAttrToInteger(
            pEntry,
            wszAttrNamePrimaryGroup,
            &dwGid);
        BAIL_ON_LSA_ERROR(dwError);
        
        pObject->userInfo.gid = (gid_t) dwGid;
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameSamAccountName,
            &pObject->pszSamAccountName);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNamePassword,
            &pObject->userInfo.pszPasswd);
        if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE)
        {
            dwError = 0;
        }
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameGecos,
            &pObject->userInfo.pszGecos);
        if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE)
        {
            dwError = 0;
        }
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameShell,
            &pObject->userInfo.pszShell);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
                    pEntry,
                    wszAttrNameHomedir,
                    &pObject->userInfo.pszHomedir);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameObjectSID,
            &pObject->pszObjectSid);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameUPN,
            &pObject->userInfo.pszUPN);
        if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE)
        {
            dwError = 0;
        }
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
		    wszAttrNameDN,
		    &pObject->pszDN);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameNetBIOSDomain,
            &pObject->pszNetbiosDomainName);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToInteger(
            pEntry,
            wszAttrNameAccountFlags,
            &dwAccountFlags);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToLargeInteger(
            pEntry,
            wszAttrNameAccountExpiry,
            &llAccountExpiry);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToLargeInteger(
            pEntry,
            wszAttrNamePasswdLastSet,
            &llPasswordLastSet);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LocalMarshalAccountFlagsToSecurityObject(
            pObject,
            dwAccountFlags,
            llPasswordLastSet,
            llAccountExpiry);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwAllocateStringPrintf(
            &pObject->userInfo.pszUnixName,
            "%s%c%s",
            pObject->pszNetbiosDomainName,
            LsaSrvDomainSeparator(),
            pObject->pszSamAccountName);
        BAIL_ON_LSA_ERROR(dwError);

        if (LW_IS_NULL_OR_EMPTY_STR(pObject->userInfo.pszUPN))
        {
            dwError = LwAllocateStringPrintf(
                &pObject->userInfo.pszUPN,
                "%s@%s",
                pObject->pszSamAccountName,
                pObject->pszNetbiosDomainName);
            BAIL_ON_LSA_ERROR(dwError);
            LwStrToUpper(pObject->userInfo.pszUPN + strlen(pObject->pszSamAccountName) + 1);
            
            pObject->userInfo.bIsGeneratedUPN = TRUE;
        }

        dwError = LocalMarshalAttrToOctetStream(
            pEntry,
            wszAttrNameNTHash,
            &pObject->userInfo.pNtHash,
            &pObject->userInfo.dwNtHashLen);
        if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE)
        {
            dwError = 0;
        }
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToOctetStream(
            pEntry,
            wszAttrNameLMHash,
            &pObject->userInfo.pLmHash,
            &pObject->userInfo.dwLmHashLen);
        if (dwError == LW_ERROR_NO_ATTRIBUTE_VALUE)
        {
            dwError = 0;
        }
        BAIL_ON_LSA_ERROR(dwError);
        break;
    case LOCAL_OBJECT_CLASS_GROUP:
        pObject->type = LSA_OBJECT_TYPE_GROUP;

        dwError = LocalMarshalAttrToInteger(
            pEntry,
            wszAttrNameGID,
            &dwGid);
        BAIL_ON_LSA_ERROR(dwError);
        
        pObject->groupInfo.gid = dwGid;
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameSamAccountName,
            &pObject->pszSamAccountName);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
		    wszAttrNameDN,
		    &pObject->pszDN);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameObjectSID,
            &pObject->pszObjectSid);
        BAIL_ON_LSA_ERROR(dwError);
        
        dwError = LocalMarshalAttrToANSIFromUnicodeString(
            pEntry,
            wszAttrNameNetBIOSDomain,
            &pObject->pszNetbiosDomainName);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwAllocateStringPrintf(
            &pObject->groupInfo.pszUnixName,
            "%s%c%s",
            pObject->pszNetbiosDomainName,
            LsaSrvDomainSeparator(),
            pObject->pszSamAccountName);
        BAIL_ON_LSA_ERROR(dwError);
        break;
    default:
        dwError = LW_ERROR_INTERNAL;
        BAIL_ON_LSA_ERROR(dwError);
    }

    *ppObject = pObject;

cleanup:


    return dwError;

error:

    *ppObject = NULL;

    if (pObject)
    {
        LsaUtilFreeSecurityObject(pObject);
    }

    goto cleanup;
}