コード例 #1
0
NTSTATUS
SamrSrvLookupDomain(
    /* [in] */ handle_t hBinding,
    /* [in] */ CONNECT_HANDLE hConn,
    /* [in] */ UNICODE_STRING *domain_name,
    /* [out] */ SID **ppSid
    )
{
    CHAR szDnToken[] = "DC";
    wchar_t wszFilter[] = L"%ws=%u AND %ws=\'%ws\'";
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = 0;
    PCONNECT_CONTEXT pConnCtx = NULL;
    PWSTR pwszBase = NULL;
    WCHAR wszAttrObjectClass[] = DS_ATTR_OBJECT_CLASS;
    WCHAR wszAttrDomain[] = DS_ATTR_DOMAIN;
    WCHAR wszAttrObjectSID[] = DS_ATTR_OBJECT_SID;
    DWORD dwObjectClass = DS_OBJECT_CLASS_DOMAIN;
    WCHAR wszBuiltinDomainName[] = SAMR_BUILTIN_DOMAIN_NAME;
    PWSTR pwszDomainName = NULL;
    DWORD dwBaseLen = 0;
    DWORD dwScope = 0;
    PWSTR pwszFilter = NULL;
    DWORD dwFilterLen = 0;
    PWSTR wszAttributes[2];
    PDIRECTORY_ENTRY pEntries = NULL;
    DWORD dwCount = 0;
    PDIRECTORY_ATTRIBUTE pAttr = NULL;
    PATTRIBUTE_VALUE pAttrVal = NULL;
    PSID pDomainSid = NULL;

    BAIL_ON_INVALID_PARAMETER(ppSid);
    BAIL_ON_INVALID_PARAMETER(domain_name);

    memset(wszAttributes, 0, sizeof(wszAttributes));

    pConnCtx = (PCONNECT_CONTEXT)hConn;

    if (pConnCtx == NULL || pConnCtx->Type != SamrContextConnect)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    ntStatus = SamrSrvGetFromUnicodeString(&pwszDomainName,
                                           domain_name);
    BAIL_ON_NO_MEMORY(pwszDomainName);

    if (!wc16scasecmp(pwszDomainName, wszBuiltinDomainName))
    {
        dwObjectClass = DS_OBJECT_CLASS_BUILTIN_DOMAIN;
    }

    dwBaseLen = domain_name->MaximumLength +
                ((sizeof(szDnToken) + 2) * sizeof(WCHAR));

    dwFilterLen = (sizeof(wszAttrObjectClass) - 1) +
                  10 +
                  (sizeof(wszAttrDomain) - 1) +
                  domain_name->Length +
                  sizeof(wszFilter);

    ntStatus = SamrSrvAllocateMemory(OUT_PPVOID(&pwszFilter),
                                     dwFilterLen);
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    if (sw16printfw(pwszFilter, dwFilterLen/sizeof(WCHAR), wszFilter,
                    wszAttrObjectClass, dwObjectClass,
                    wszAttrDomain, pwszDomainName) < 0)
    {
        ntStatus = LwErrnoToNtStatus(errno);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    wszAttributes[0] = wszAttrObjectSID;
    wszAttributes[1] = NULL;

    dwError = DirectorySearch(pConnCtx->hDirectory,
                              pwszBase,
                              dwScope,
                              pwszFilter,
                              wszAttributes,
                              FALSE,
                              &pEntries,
                              &dwCount);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwCount == 1) {
        dwError = DirectoryGetEntryAttributeSingle(pEntries,
                                                   &pAttr);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = DirectoryGetAttributeValue(pAttr, &pAttrVal);
        BAIL_ON_LSA_ERROR(dwError);

        if (pAttrVal->Type == DIRECTORY_ATTR_TYPE_UNICODE_STRING) {
            ntStatus = SamrSrvAllocateSidFromWC16String(
                            &pDomainSid,
                            pAttrVal->data.pwszStringValue);
            BAIL_ON_NTSTATUS_ERROR(ntStatus);

        } else {
            ntStatus = STATUS_INTERNAL_ERROR;
            BAIL_ON_NTSTATUS_ERROR(ntStatus);
        }

    } else if (dwCount == 0) {
        ntStatus = STATUS_NO_SUCH_DOMAIN;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);

    } else {
        ntStatus = STATUS_INTERNAL_ERROR;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    *ppSid = pDomainSid;

cleanup:
    if (pwszBase) {
        SamrSrvFreeMemory(pwszBase);
    }

    if (pwszDomainName) {
        SamrSrvFreeMemory(pwszDomainName);
    }

    if (pwszFilter) {
        SamrSrvFreeMemory(pwszFilter);
    }

    if (pEntries) {
        DirectoryFreeEntries(pEntries, dwCount);
    }

    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    if (pDomainSid) {
        SamrSrvFreeMemory(&pDomainSid);
    }

    *ppSid = NULL;
    goto cleanup;
}
コード例 #2
0
NTSTATUS
SamrSrvQueryAliasInfo(
    /* [in] */ handle_t hBinding,
    /* [in] */ ACCOUNT_HANDLE hAlias,
    /* [in] */ UINT16 level,
    /* [out] */ AliasInfo **info
    )
{
    PCSTR filterFormat = "%s=%Q";
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = 0;
    PACCOUNT_CONTEXT pAcctCtx = NULL;
    PDOMAIN_CONTEXT pDomCtx = NULL;
    PCONNECT_CONTEXT pConnCtx = NULL;
    PWSTR pwszBase = NULL;
    WCHAR wszAttrDn[] = DS_ATTR_DISTINGUISHED_NAME;
    WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME;
    WCHAR wszAttrDescription[] = DS_ATTR_DESCRIPTION;
    CHAR szAttrDn[] = DS_ATTR_DISTINGUISHED_NAME;
    DWORD dwScope = 0;
    PSTR pszDn = NULL;
    PWSTR pwszFilter = NULL;
    PDIRECTORY_ENTRY pEntry = NULL;
    DWORD dwEntriesNum = 0;
    PDIRECTORY_ENTRY pMemberEntry = NULL;
    DWORD dwNumMembers = 0;
    AliasInfo *pAliasInfo = NULL;

    PWSTR wszAttributesLevel1[] = {
        wszAttrSamAccountName,
        wszAttrDescription,
        NULL
    };

    PWSTR wszAttributesLevel2[] = {
        wszAttrSamAccountName,
        NULL
    };

    PWSTR wszAttributesLevel3[] = {
        wszAttrDescription,
        NULL
    };

    PWSTR *pwszAttributes[] = {
        wszAttributesLevel1,
        wszAttributesLevel2,
        wszAttributesLevel3
    };

    PWSTR wszMemberAttributes[] = {
        wszAttrDn,
        NULL
    };

    pAcctCtx = (PACCOUNT_CONTEXT)hAlias;

    if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    if (!(pAcctCtx->dwAccessGranted & ALIAS_ACCESS_LOOKUP_INFO))
    {
        ntStatus = STATUS_ACCESS_DENIED;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    pDomCtx  = pAcctCtx->pDomCtx;
    pConnCtx = pDomCtx->pConnCtx;

    pwszBase = pDomCtx->pwszDn;

    dwError = LwWc16sToMbs(pAcctCtx->pwszDn,
                           &pszDn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectoryAllocateWC16StringFilterPrintf(
                            &pwszFilter,
                            filterFormat,
                            szAttrDn, pszDn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectorySearch(pConnCtx->hDirectory,
                              pwszBase,
                              dwScope,
                              pwszFilter,
                              pwszAttributes[level - 1],
                              FALSE,
                              &pEntry,
                              &dwEntriesNum);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwEntriesNum == 0)
    {
        ntStatus = STATUS_INVALID_HANDLE;

    }
    else if (dwEntriesNum > 1)
    {
        ntStatus = STATUS_INTERNAL_ERROR;
    }

    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    if (level == ALIAS_INFO_ALL)
    {
        dwError = DirectoryGetGroupMembers(pConnCtx->hDirectory,
                                           pAcctCtx->pwszDn,
                                           wszMemberAttributes,
                                           &pMemberEntry,
                                           &dwNumMembers);
        BAIL_ON_LSA_ERROR(dwError);
    }

    ntStatus = SamrSrvAllocateMemory((void**)&pAliasInfo,
                                     sizeof(*pAliasInfo));
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    switch (level)
    {
    case ALIAS_INFO_ALL:
        ntStatus = SamrFillAliasInfo1(pEntry, dwNumMembers, pAliasInfo);
        break;

    case ALIAS_INFO_NAME:
        ntStatus = SamrFillAliasInfo2(pEntry, pAliasInfo);
        break;

    case ALIAS_INFO_DESCRIPTION:
        ntStatus = SamrFillAliasInfo3(pEntry, pAliasInfo);
        break;

    default:
        ntStatus = STATUS_INVALID_INFO_CLASS;
    }
    
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    *info = pAliasInfo;
    
cleanup:
    LW_SAFE_FREE_MEMORY(pszDn);
    LW_SAFE_FREE_MEMORY(pwszFilter);

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

    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    if (pAliasInfo)
    {
        SamrSrvFreeMemory(pAliasInfo);
    }

    *info = NULL;
    goto cleanup;
}
コード例 #3
0
NTSTATUS
SamrSrvQuerySecurity(
    IN  handle_t                          hBinding,
    IN  void                             *hObject,
    IN  DWORD                             dwSecurityInfo,
    OUT PSAMR_SECURITY_DESCRIPTOR_BUFFER *ppSecDescBuf
    )
{
    PCSTR filterFormat = "%s=%Q";
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PSAMR_GENERIC_CONTEXT pCtx = (PSAMR_GENERIC_CONTEXT)hObject;
    PDOMAIN_CONTEXT pDomCtx = NULL;
    PACCOUNT_CONTEXT pAcctCtx = NULL;
    PWSTR pwszDn = NULL;
    HANDLE hDirectory = NULL;
    PWSTR pwszBaseDn = NULL;
    DWORD dwScope = 0;
    WCHAR wszAttrSecDesc[] = DS_ATTR_SECURITY_DESCRIPTOR;
    CHAR szAttrDn[] = DS_ATTR_DISTINGUISHED_NAME;
    PSTR pszDn = NULL;
    PWSTR pwszFilter = NULL;
    PDIRECTORY_ENTRY pEntries = NULL;
    DWORD dwNumEntries = 0;
    PDIRECTORY_ENTRY pObjectEntry = NULL;
    POCTET_STRING pSecDescBlob = NULL;
    PSAMR_SECURITY_DESCRIPTOR_BUFFER pSecDescBuf = NULL;

    PWSTR wszAttributes[] = {
        wszAttrSecDesc,
        NULL
    };

    /*
     * Only querying security descriptor on an account is allowed
     */
    if (pCtx->Type == SamrContextAccount)
    {
        pAcctCtx    = (PACCOUNT_CONTEXT)hObject;
        pDomCtx     = pAcctCtx->pDomCtx;
        pwszDn      = pAcctCtx->pwszDn;
        hDirectory  = pDomCtx->pConnCtx->hDirectory;
    }
    else if (pCtx->Type == SamrContextConnect ||
             pCtx->Type == SamrContextDomain)
    {
        ntStatus = STATUS_ACCESS_DENIED;
    }
    else
    {
        ntStatus = STATUS_INVALID_HANDLE;
    }
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    /*
     * 1) READ_CONTROL right is required to read a security descriptor
     * 2) Querying SACL part of the SD is not permitted over rpc
     */
    if (!(pAcctCtx->dwAccessGranted & READ_CONTROL) ||
        dwSecurityInfo & SACL_SECURITY_INFORMATION)
    {
        ntStatus = STATUS_ACCESS_DENIED;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    dwError = LwWc16sToMbs(pwszDn, &pszDn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectoryAllocateWC16StringFilterPrintf(
                              &pwszFilter,
                              filterFormat,
                              szAttrDn, pszDn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectorySearch(hDirectory,
                              pwszBaseDn,
                              dwScope,
                              pwszFilter,
                              wszAttributes,
                              FALSE,
                              &pEntries,
                              &dwNumEntries);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwNumEntries == 0)
    {
        ntStatus = STATUS_INVALID_HANDLE;
    }
    else if (dwNumEntries > 1)
    {
        ntStatus = STATUS_INTERNAL_ERROR;
    }
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    pObjectEntry = &(pEntries[0]);

    dwError = DirectoryGetEntryAttrValueByName(
                              pObjectEntry,
                              wszAttrSecDesc,
                              DIRECTORY_ATTR_TYPE_NT_SECURITY_DESCRIPTOR,
                              &pSecDescBlob);
    BAIL_ON_LSA_ERROR(dwError);

    ntStatus = SamrSrvAllocateSecDescBuffer(
                              &pSecDescBuf,
                              (SECURITY_INFORMATION)dwSecurityInfo,
                              pSecDescBlob);
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    *ppSecDescBuf = pSecDescBuf;

cleanup:
    if (pEntries)
    {
        DirectoryFreeEntries(pEntries, dwNumEntries);
    }

    LW_SAFE_FREE_MEMORY(pszDn);
    LW_SAFE_FREE_MEMORY(pwszFilter);

    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    if (pSecDescBuf)
    {
        if (pSecDescBuf->pBuffer)
        {
            SamrSrvFreeMemory(pSecDescBuf->pBuffer);
        }

        SamrSrvFreeMemory(pSecDescBuf);
    }

    *ppSecDescBuf = NULL;

    goto cleanup;
}
コード例 #4
0
NTSTATUS
SamrSrvGetMembersInAlias(
    IN  handle_t        hBinding,
    IN  ACCOUNT_HANDLE  hAlias,
    OUT SID_ARRAY      *pSids
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = 0;
    PACCOUNT_CONTEXT pAcctCtx = NULL;
    PCONNECT_CONTEXT pConnCtx = NULL;
    HANDLE hDirectory = NULL;
    PWSTR pwszAliasDn = NULL;
    WCHAR wszAttrObjectSid[] = DS_ATTR_OBJECT_SID;
    PDIRECTORY_ENTRY pMemberEntries;
    DWORD dwMembersNum = 0;
    DWORD i = 0;
    PWSTR pwszMemberSid = NULL;
    PSID pMemberSid = NULL;
    SID_ARRAY Sids = {0};

    PWSTR wszAttributes[] = {
        wszAttrObjectSid,
        NULL
    };

    pAcctCtx = (PACCOUNT_CONTEXT)hAlias;

    if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    if (!(pAcctCtx->dwAccessGranted & ALIAS_ACCESS_GET_MEMBERS))
    {
        ntStatus = STATUS_ACCESS_DENIED;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    pConnCtx    = (PCONNECT_CONTEXT)pAcctCtx->pDomCtx->pConnCtx;
    hDirectory  = pConnCtx->hDirectory;
    pwszAliasDn = pAcctCtx->pwszDn;

    dwError = DirectoryGetGroupMembers(hDirectory,
                                       pwszAliasDn,
                                       wszAttributes,
                                       &pMemberEntries,
                                       &dwMembersNum);
    BAIL_ON_LSA_ERROR(dwError);

    Sids.dwNumSids = dwMembersNum;
    ntStatus = SamrSrvAllocateMemory((PVOID*)&Sids.pSids,
                                   sizeof(*Sids.pSids) * Sids.dwNumSids);
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    for (i = 0; i < dwMembersNum; i++)
    {
        PDIRECTORY_ENTRY pEntry = &(pMemberEntries[i]);

        dwError = DirectoryGetEntryAttrValueByName(
                                    pEntry,
                                    wszAttrObjectSid,
                                    DIRECTORY_ATTR_TYPE_UNICODE_STRING,
                                    &pwszMemberSid);
        BAIL_ON_LSA_ERROR(dwError);

        ntStatus = SamrSrvAllocateSidFromWC16String(
                                    &pMemberSid,
                                    pwszMemberSid);
        BAIL_ON_NTSTATUS_ERROR(ntStatus);

        Sids.pSids[i].pSid = pMemberSid;
    }

    pSids->dwNumSids = Sids.dwNumSids;
    pSids->pSids     = Sids.pSids;

cleanup:
    if (pMemberEntries)
    {
        DirectoryFreeEntries(pMemberEntries, dwMembersNum);
    }

    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    for (i = 0; i < dwMembersNum; i++)
    {
        SamrSrvFreeMemory(Sids.pSids[i].pSid);
    }
    SamrSrvFreeMemory(Sids.pSids);

    memset(pSids, 0, sizeof(*pSids));
    goto cleanup;
}
コード例 #5
0
NTSTATUS
SamrSrvEnumDomainAccounts(
    IN  handle_t          hBinding,
    IN  DOMAIN_HANDLE     hDomain,
    IN OUT PDWORD         pdwResume,
    IN  DWORD             dwObjectClass,
    IN  DWORD             dwFlagsFilter,
    IN  DWORD             dwMaxSize,
    OUT RID_NAME_ARRAY  **ppNames,
    OUT UINT32           *pdwNumEntries
    )
{
    wchar_t wszFilterFmt[] = L"%ws=%u AND %ws='%ws'";
    NTSTATUS ntStatus = STATUS_SUCCESS;
    NTSTATUS ntEnumStatus = STATUS_SUCCESS;
    DWORD dwError = 0;
    PDOMAIN_CONTEXT pDomCtx = NULL;
    PCONNECT_CONTEXT pConnCtx = NULL;
    PWSTR pwszBase = NULL;
    WCHAR wszAttrObjectClass[] = DS_ATTR_OBJECT_CLASS;
    WCHAR wszAttrDomainName[] = DS_ATTR_DOMAIN;
    WCHAR wszAttrAccountFlags[] = DS_ATTR_ACCOUNT_FLAGS;
    WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME;
    WCHAR wszAttrObjectSid[] = DS_ATTR_OBJECT_SID;
    DWORD dwScope = 0;
    PWSTR pwszFilter = NULL;
    size_t sDomainNameLen = 0;
    PWSTR pwszDomainName = NULL;
    DWORD dwFilterLen = 0;
    PDIRECTORY_ENTRY pEntries = NULL;
    PDIRECTORY_ENTRY pEntry = NULL;
    DWORD dwNumEntries = 0;
    DWORD dwTotalSize = 0;
    DWORD dwSize = 0;
    DWORD i = 0;
    DWORD dwCount = 0;
    DWORD dwNumEntriesReturned = 0;
    DWORD dwResume = 0;
    DWORD dwAccountFlags = 0;
    size_t sNameLen = 0;
    PWSTR pwszName = NULL;
    PWSTR pwszSid = NULL;
    PSID pSid = NULL;
    DWORD dwRid = 0;
    RID_NAME_ARRAY *pNames = NULL;
    RID_NAME *pName = NULL;
    DWORD dwNewResumeIdx = 0;

    PWSTR wszAttributes[] = {
        wszAttrSamAccountName,
        wszAttrObjectSid,
        wszAttrAccountFlags,
        NULL
    };

    BAIL_ON_INVALID_PTR(hDomain);
    BAIL_ON_INVALID_PTR(pdwResume);
    BAIL_ON_INVALID_PTR(ppNames);
    BAIL_ON_INVALID_PTR(pdwNumEntries);

    pDomCtx  = (PDOMAIN_CONTEXT)hDomain;
    dwResume = *pdwResume;

    if (pDomCtx == NULL || pDomCtx->Type != SamrContextDomain)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    if (!(pDomCtx->dwAccessGranted & DOMAIN_ACCESS_ENUM_ACCOUNTS))
    {
        ntStatus = STATUS_ACCESS_DENIED;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    pConnCtx       = pDomCtx->pConnCtx;
    pwszBase       = pDomCtx->pwszDn;
    pwszDomainName = pDomCtx->pwszDomainName;

    dwError = LwWc16sLen(pwszDomainName, &sDomainNameLen);
    BAIL_ON_LSA_ERROR(dwError);

    dwFilterLen = ((sizeof(wszAttrObjectClass)/sizeof(WCHAR)) - 1) +
                  10 +
                  ((sizeof(wszAttrDomainName)/sizeof(WCHAR)) - 1) +
                  (sDomainNameLen + 1) +
                  (sizeof(wszFilterFmt)/sizeof(wszFilterFmt[0]));

    dwError = LwAllocateMemory(dwFilterLen * sizeof(pwszFilter[0]),
                               OUT_PPVOID(&pwszFilter));
    BAIL_ON_LSA_ERROR(dwError);

    if (sw16printfw(pwszFilter, dwFilterLen, wszFilterFmt,
                    wszAttrObjectClass,
                    dwObjectClass,
                    wszAttrDomainName,
                    pwszDomainName) < 0)
    {
        ntStatus = LwErrnoToNtStatus(errno);
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    dwError = DirectorySearch(pConnCtx->hDirectory,
                              pwszBase,
                              dwScope,
                              pwszFilter,
                              wszAttributes,
                              FALSE,
                              &pEntries,
                              &dwNumEntries);
    BAIL_ON_LSA_ERROR(dwError);

    ntStatus = SamrSrvAllocateMemory(OUT_PPVOID(&pNames),
                                     sizeof(*pNames));
    BAIL_ON_NTSTATUS_ERROR(ntStatus);


    if (dwResume >= dwNumEntries)
    {
        ntEnumStatus = STATUS_NO_MORE_ENTRIES;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    dwTotalSize += sizeof(pNames->dwCount);

    for (i = 0; i + dwResume < dwNumEntries; i++)
    {
        pEntry = &(pEntries[i + dwResume]);

        dwError = DirectoryGetEntryAttrValueByName(
                                     pEntry,
                                     wszAttrSamAccountName,
                                     DIRECTORY_ATTR_TYPE_UNICODE_STRING,
                                     &pwszName);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = DirectoryGetEntryAttrValueByName(
                                     pEntry,
                                     wszAttrAccountFlags,
                                     DIRECTORY_ATTR_TYPE_INTEGER,
                                     &dwAccountFlags);
        BAIL_ON_LSA_ERROR(dwError);

        dwSize = 0;

        if (dwFlagsFilter &&
            !(dwAccountFlags & dwFlagsFilter))
        {
            continue;
        }

        dwError = LwWc16sLen(pwszName, &sNameLen);
        BAIL_ON_LSA_ERROR(dwError);

        dwSize += sizeof(UINT32);
        dwSize += sNameLen * sizeof(pwszName[0]);
        dwSize += 2 * sizeof(UINT16);

        dwTotalSize += dwSize;
        dwCount++;

        if (dwTotalSize > dwMaxSize)
        {
            dwTotalSize -= dwSize;
            dwCount--;

            ntEnumStatus = STATUS_MORE_ENTRIES;
            break;
        }
    }

    /*
     * At least one entry is returned regardless of declared
     * max response size
     */
    dwNumEntriesReturned = (dwSize > 0 && dwCount == 0) ? 1 : dwCount;

    pNames->dwCount = dwNumEntriesReturned;
    ntStatus = SamrSrvAllocateMemory(
                           OUT_PPVOID(&pNames->pEntries),
                           sizeof(pNames->pEntries[0]) * pNames->dwCount);
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    for (i = 0, dwCount = 0;
         dwCount < dwNumEntriesReturned && i + dwResume < dwNumEntries;
         i++)
    {
        pEntry = &(pEntries[i + dwResume]);

        dwError = DirectoryGetEntryAttrValueByName(pEntry,
                                                   wszAttrObjectSid,
                                                   DIRECTORY_ATTR_TYPE_UNICODE_STRING,
                                                   &pwszSid);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = DirectoryGetEntryAttrValueByName(pEntry,
                                                   wszAttrSamAccountName,
                                                   DIRECTORY_ATTR_TYPE_UNICODE_STRING,
                                                   &pwszName);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = DirectoryGetEntryAttrValueByName(pEntry,
                                                   wszAttrAccountFlags,
                                                   DIRECTORY_ATTR_TYPE_INTEGER,
                                                   &dwAccountFlags);
        BAIL_ON_LSA_ERROR(dwError);

        dwNewResumeIdx = i + dwResume + 1;

        if (dwFlagsFilter &&
            !(dwAccountFlags & dwFlagsFilter))
        {
            continue;
        }

        pName = &(pNames->pEntries[dwCount++]);

        ntStatus = RtlAllocateSidFromWC16String(&pSid, pwszSid);
        BAIL_ON_NTSTATUS_ERROR(ntStatus);

        dwRid        = pSid->SubAuthority[pSid->SubAuthorityCount - 1];
        pName->dwRid = (UINT32)dwRid;
        
        ntStatus = SamrSrvInitUnicodeString(&pName->Name,
                                            pwszName);
        BAIL_ON_NTSTATUS_ERROR(ntStatus);

        RTL_FREE(&pSid);
    }

    *pdwResume      = dwNewResumeIdx;
    *pdwNumEntries  = dwNumEntriesReturned;
    *ppNames        = pNames;

cleanup:
    LW_SAFE_FREE_MEMORY(pwszFilter);
    RTL_FREE(&pSid);

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

    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    if (ntStatus == STATUS_SUCCESS &&
        ntEnumStatus != STATUS_SUCCESS)
    {
        ntStatus = ntEnumStatus;
    }

    return ntStatus;

error:
    if (pNames)
    {
        for (i = 0; i < pNames->dwCount; i++)
        {
            SamrSrvFreeUnicodeString(&(pNames->pEntries[i].Name));
        }
        SamrSrvFreeMemory(pNames->pEntries);
        SamrSrvFreeMemory(pNames);
    }

    *pdwResume      = 0;
    *pdwNumEntries  = 0;
    *ppNames        = NULL;
    goto cleanup;
}
コード例 #6
0
NTSTATUS
SamrSrvQueryUserInfo(
    /* [in] */ handle_t hBinding,
    /* [in] */ ACCOUNT_HANDLE hUser,
    /* [in] */ UINT16 level,
    /* [out] */ UserInfo **info
    )
{
    PCSTR filterFormat = "%s=%Q";
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = 0;
    PACCOUNT_CONTEXT pAcctCtx = NULL;
    PDOMAIN_CONTEXT pDomCtx = NULL;
    PCONNECT_CONTEXT pConnCtx = NULL;
    PWSTR pwszBase = NULL;
    WCHAR wszAttrObjectSid[] = DS_ATTR_OBJECT_SID;
    WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME;
    WCHAR wszAttrFullName[] = DS_ATTR_FULL_NAME;
    WCHAR wszAttrPrimaryGroup[] = DS_ATTR_PRIMARY_GROUP;
    WCHAR wszAttrDescription[] = DS_ATTR_DESCRIPTION;
    WCHAR wszAttrComment[] = DS_ATTR_COMMENT;
    WCHAR wszAttrCountryCode[] = DS_ATTR_COUNTRY_CODE;
    WCHAR wszAttrCodePage[] = DS_ATTR_CODE_PAGE;
    WCHAR wszAttrHomeDirectory[] = DS_ATTR_HOME_DIR;
    WCHAR wszAttrHomeDrive[] = DS_ATTR_HOME_DRIVE;
    WCHAR wszAttrLogonScript[] = DS_ATTR_LOGON_SCRIPT;
    WCHAR wszAttrProfilePath[] = DS_ATTR_PROFILE_PATH;
    WCHAR wszAttrWorkstations[]= DS_ATTR_WORKSTATIONS;
    WCHAR wszAttrParameters[] = DS_ATTR_PARAMETERS;
    WCHAR wszAttrLastLogon[] = DS_ATTR_LAST_LOGON;
    WCHAR wszAttrLastLogoff[] = DS_ATTR_LAST_LOGOFF;
    WCHAR wszAttrPasswordLastSet[] = DS_ATTR_PASSWORD_LAST_SET;
    WCHAR wszAttrAllowPasswordChange[] = DS_ATTR_ALLOW_PASSWORD_CHANGE;
    WCHAR wszAttrForcePasswordChange[] = DS_ATTR_FORCE_PASSWORD_CHANGE;
    WCHAR wszAttrLogonHours[] = DS_ATTR_LOGON_HOURS;
    WCHAR wszAttrBadPasswordCount[] = DS_ATTR_BAD_PASSWORD_COUNT;
    WCHAR wszAttrLogonCount[] = DS_ATTR_LOGON_COUNT;
    WCHAR wszAttrAccountFlags[] = DS_ATTR_ACCOUNT_FLAGS;
    WCHAR wszAttrAccountExpiry[] = DS_ATTR_ACCOUNT_EXPIRY;
    WCHAR wszAttrLmHash[] = DS_ATTR_LM_HASH;
    WCHAR wszAttrNtHash[] = DS_ATTR_NT_HASH;
    CHAR szAttrDn[] = DS_ATTR_DISTINGUISHED_NAME;
    DWORD dwScope = 0;
    PSTR pszDn = NULL;
    PWSTR pwszFilter = NULL;
    PDIRECTORY_ENTRY pEntry = NULL;
    DWORD dwEntriesNum = 0;
    UserInfo *pUserInfo = NULL;

    PWSTR wszAttributesLevel1[] = {
        wszAttrSamAccountName,
        wszAttrFullName,
        wszAttrPrimaryGroup,
        wszAttrDescription,
        wszAttrComment,
        NULL
    };

    PWSTR wszAttributesLevel2[] = {
        wszAttrComment,
        wszAttrCountryCode,
        wszAttrCodePage,
        NULL
    };

    PWSTR wszAttributesLevel3[] = {
        wszAttrSamAccountName,
        wszAttrFullName,
        wszAttrObjectSid,
        wszAttrPrimaryGroup,
        wszAttrHomeDirectory,
        wszAttrHomeDrive,
        wszAttrLogonScript,
        wszAttrProfilePath,
        wszAttrWorkstations,
        wszAttrLastLogon,
        wszAttrLastLogoff,
        wszAttrPasswordLastSet,
        wszAttrAllowPasswordChange,
        wszAttrForcePasswordChange,
        wszAttrLogonHours,
        wszAttrBadPasswordCount,
        wszAttrLogonCount,
        wszAttrAccountFlags,
        NULL
    };

    PWSTR wszAttributesLevel4[] = {
        wszAttrLogonHours,
        NULL
    };

    PWSTR wszAttributesLevel5[] = {
        wszAttrSamAccountName,
        wszAttrFullName,
        wszAttrObjectSid,
        wszAttrPrimaryGroup,
        wszAttrHomeDirectory,
        wszAttrHomeDrive,
        wszAttrLogonScript,
        wszAttrProfilePath,
        wszAttrDescription,
        wszAttrWorkstations,
        wszAttrLastLogon,
        wszAttrLastLogoff,
        wszAttrLogonHours,
        wszAttrBadPasswordCount,
        wszAttrLogonCount,
        wszAttrPasswordLastSet,
        wszAttrAccountExpiry,
        wszAttrAccountFlags,
        NULL
    };

    PWSTR wszAttributesLevel6[] = {
        wszAttrSamAccountName,
        wszAttrFullName,
        NULL
    };

    PWSTR wszAttributesLevel7[] = {
        wszAttrSamAccountName,
        NULL
    };

    PWSTR wszAttributesLevel8[] = {
        wszAttrFullName,
        NULL
    };

    PWSTR wszAttributesLevel9[] = {
        wszAttrPrimaryGroup,
        NULL
    };

    PWSTR wszAttributesLevel10[] = {
        wszAttrHomeDirectory,
        wszAttrHomeDrive,
        NULL
    };

    PWSTR wszAttributesLevel11[] = {
        wszAttrLogonScript,
        NULL
    };

    PWSTR wszAttributesLevel12[] = {
        wszAttrProfilePath,
        NULL
    };

    PWSTR wszAttributesLevel13[] = {
        wszAttrDescription,
        NULL
    };

    PWSTR wszAttributesLevel14[] = {
        wszAttrWorkstations,
        NULL
    };

    PWSTR wszAttributesLevel16[] = {
        wszAttrAccountFlags,
        NULL
    };

    PWSTR wszAttributesLevel17[] = {
        wszAttrAccountExpiry,
        NULL
    };

    PWSTR wszAttributesLevel20[] = {
        wszAttrParameters,
        NULL
    };

    PWSTR wszAttributesLevel21[] = {
        wszAttrLastLogon,
        wszAttrLastLogoff,
        wszAttrPasswordLastSet,
        wszAttrAccountExpiry,
        wszAttrAllowPasswordChange,
        wszAttrForcePasswordChange,
        wszAttrSamAccountName,
        wszAttrFullName,
        wszAttrHomeDirectory,
        wszAttrHomeDrive,
        wszAttrLogonScript,
        wszAttrProfilePath,
        wszAttrDescription,
        wszAttrWorkstations,
        wszAttrComment,
        wszAttrParameters,
        wszAttrObjectSid,
        wszAttrPrimaryGroup,
        wszAttrAccountFlags,
        wszAttrLogonHours,
        wszAttrBadPasswordCount,
        wszAttrLogonCount,
        wszAttrCountryCode,
        wszAttrCodePage,
        wszAttrLmHash,
        wszAttrNtHash,
        NULL
    };

    PWSTR *pwszAttributes[] = {
        wszAttributesLevel1,
        wszAttributesLevel2,
        wszAttributesLevel3,
        wszAttributesLevel4,
        wszAttributesLevel5,
        wszAttributesLevel6,
        wszAttributesLevel7,
        wszAttributesLevel8,
        wszAttributesLevel9,
        wszAttributesLevel10,
        wszAttributesLevel11,
        wszAttributesLevel12,
        wszAttributesLevel13,
        wszAttributesLevel14,
        NULL,
        wszAttributesLevel16,
        wszAttributesLevel17,
        NULL,
        NULL,
        wszAttributesLevel20,
        wszAttributesLevel21
    };

    pAcctCtx = (PACCOUNT_CONTEXT)hUser;

    if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    switch (level)
    {
    case 15:
    case 18:
    case 19:
        ntStatus = STATUS_INVALID_INFO_CLASS;
        break;

    default:
        ntStatus = STATUS_SUCCESS;
    }
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    pDomCtx  = pAcctCtx->pDomCtx;
    pConnCtx = pDomCtx->pConnCtx;

    pwszBase = pDomCtx->pwszDn;

    dwError = LwWc16sToMbs(pAcctCtx->pwszDn,
                           &pszDn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectoryAllocateWC16StringFilterPrintf(
                              &pwszFilter,
                              filterFormat,
                              szAttrDn, pszDn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = DirectorySearch(pConnCtx->hDirectory,
                              pwszBase,
                              dwScope,
                              pwszFilter,
                              pwszAttributes[level - 1],
                              FALSE,
                              &pEntry,
                              &dwEntriesNum);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwEntriesNum == 0)
    {
        ntStatus = STATUS_INVALID_HANDLE;

    }
    else if (dwEntriesNum > 1)
    {
        ntStatus = STATUS_INTERNAL_ERROR;
    }

    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    ntStatus = SamrSrvAllocateMemory((void**)&pUserInfo,
                                     sizeof(*pUserInfo));
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    switch (level)
    {
    case 1:
    case 6:
    case 7:
    case 8:
    case 13:
        if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_NAME_ETC) ||
            !(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES))
        {
            ntStatus = STATUS_ACCESS_DENIED;
            BAIL_ON_NTSTATUS_ERROR(ntStatus);
        }
        break;

    case 2:
        if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_LOCALE) ||
            !(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES))
        {
            ntStatus = STATUS_ACCESS_DENIED;
            BAIL_ON_NTSTATUS_ERROR(ntStatus);
        }
        break;

    case 4:
    case 5:
    case 10:
    case 11:
    case 12:
    case 14:
    case 17:
        if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_LOGONINFO) ||
            !(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES))
        {
            ntStatus = STATUS_ACCESS_DENIED;
            BAIL_ON_NTSTATUS_ERROR(ntStatus);
        }
        break;

    case 3:
    case 9:
    case 16:
    case 20:
    case 21:
        if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES))
        {
            ntStatus = STATUS_ACCESS_DENIED;
            BAIL_ON_NTSTATUS_ERROR(ntStatus);
        }
        break;
    }

    switch (level) {
    case 1:
        ntStatus = SamrFillUserInfo1(pEntry, pUserInfo);
        break;

    case 2:
        ntStatus = SamrFillUserInfo2(pEntry, pUserInfo);
        break;

    case 3:
        ntStatus = SamrFillUserInfo3(pAcctCtx, pEntry, pUserInfo);
        break;

    case 4:
        ntStatus = SamrFillUserInfo4(pEntry, pUserInfo);
        break;

    case 5:
        ntStatus = SamrFillUserInfo5(pEntry, pUserInfo);
        break;

    case 6:
        ntStatus = SamrFillUserInfo6(pEntry, pUserInfo);
        break;

    case 7:
        ntStatus = SamrFillUserInfo7(pEntry, pUserInfo);
        break;

    case 8:
        ntStatus = SamrFillUserInfo8(pEntry, pUserInfo);
        break;

    case 9:
        ntStatus = SamrFillUserInfo9(pEntry, pUserInfo);
        break;

    case 10:
        ntStatus = SamrFillUserInfo10(pEntry, pUserInfo);
        break;

    case 11:
        ntStatus = SamrFillUserInfo11(pEntry, pUserInfo);
        break;

    case 12:
        ntStatus = SamrFillUserInfo12(pEntry, pUserInfo);
        break;

    case 13:
        ntStatus = SamrFillUserInfo13(pEntry, pUserInfo);
        break;

    case 14:
        ntStatus = SamrFillUserInfo14(pEntry, pUserInfo);
        break;

    case 16:
        ntStatus = SamrFillUserInfo16(pEntry, pUserInfo);
        break;

    case 17:
        ntStatus = SamrFillUserInfo17(pEntry, pUserInfo);
        break;

    case 20:
        ntStatus = SamrFillUserInfo20(pEntry, pUserInfo);
        break;

    case 21:
        ntStatus = SamrFillUserInfo21(pAcctCtx, pEntry, pUserInfo);
        break;

    default:
        ntStatus = STATUS_INVALID_INFO_CLASS;
    }
    
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    *info = pUserInfo;
    
cleanup:
    LW_SAFE_FREE_MEMORY(pszDn);
    LW_SAFE_FREE_MEMORY(pwszFilter);

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

    return ntStatus;

error:
    if (pUserInfo) {
        SamrSrvFreeMemory(pUserInfo);
    }

    *info = NULL;
    goto cleanup;
}
コード例 #7
0
NTSTATUS
SamrSrvCreateDomAlias(
    /* [in] */ handle_t hBinding,
    /* [in] */ DOMAIN_HANDLE hDomain,
    /* [in] */ UNICODE_STRING *pAliasName,
    /* [in] */ UINT32 dwAccessMask,
    /* [out] */ ACCOUNT_HANDLE *phAlias,
    /* [out] */ UINT32 *pdwRid
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDOMAIN_CONTEXT pDomCtx = NULL;
    PWSTR pwszAliasName = NULL;
    UNICODE_STRING Name = {0};
    UINT32 ulAccessGranted = 0;

    pDomCtx = (PDOMAIN_CONTEXT)hDomain;

    if (pDomCtx == NULL || pDomCtx->Type != SamrContextDomain)
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    if (!(pDomCtx->dwAccessGranted & DOMAIN_ACCESS_CREATE_ALIAS))
    {
        ntStatus = STATUS_ACCESS_DENIED;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

    ntStatus = SamrSrvGetFromUnicodeString(&pwszAliasName,
                                           pAliasName);
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    ntStatus = SamrSrvInitUnicodeStringEx(&Name,
                                          pwszAliasName);
    BAIL_ON_NTSTATUS_ERROR(ntStatus);

    ntStatus = SamrSrvCreateAccount(hBinding,
                                    hDomain,
                                    &Name,
                                    DS_OBJECT_CLASS_LOCAL_GROUP,
                                    0,
                                    dwAccessMask,
                                    phAlias,
                                    &ulAccessGranted,
                                    pdwRid);
    if (ntStatus == STATUS_USER_EXISTS)
    {
        ntStatus = STATUS_ALIAS_EXISTS;
        BAIL_ON_NTSTATUS_ERROR(ntStatus);
    }

cleanup:
    if (pwszAliasName)
    {
        SamrSrvFreeMemory(pwszAliasName);
    }

    SamrSrvFreeUnicodeStringEx(&Name);

    return ntStatus;

error:
    *phAlias = NULL;
    *pdwRid  = 0;
    goto cleanup;
}