Пример #1
0
void
LsaFreeGroupModInfo2(
    PLSA_GROUP_MOD_INFO_2 pGroupModInfo
    )
{
    LW_SAFE_FREE_STRING(pGroupModInfo->pszSid);
    LwFreeStringArray(pGroupModInfo->ppszAddMembers, pGroupModInfo->dwAddMembersNum);
    LwFreeStringArray(pGroupModInfo->ppszRemoveMembers, pGroupModInfo->dwRemoveMembersNum);
    LwFreeMemory(pGroupModInfo);
}
Пример #2
0
VOID
AD_FreeConfigContents(
    PLSA_AD_CONFIG pConfig
)
{
    LW_SAFE_FREE_STRING(pConfig->pszHomedirPrefix);
    LW_SAFE_FREE_STRING(pConfig->pszHomedirTemplate);
    LW_SAFE_FREE_STRING(pConfig->pszRemoteHomeDirTemplate);
    LW_SAFE_FREE_STRING(pConfig->pszShell);
    LW_SAFE_FREE_STRING(pConfig->pszSkelDirs);
    LW_SAFE_FREE_MEMORY(pConfig->pszaIgnoreUserNameList);
    LW_SAFE_FREE_MEMORY(pConfig->pszaIgnoreGroupNameList);
    LW_SAFE_FREE_STRING(pConfig->pszUserDomainPrefix);

    if (pConfig->pUnresolvedMemberList)
    {
        LwDLinkedListForEach(
            pConfig->pUnresolvedMemberList,
            &AD_FreeConfigMemberInList,
            NULL);
        LwDLinkedListFree(pConfig->pUnresolvedMemberList);
        pConfig->pUnresolvedMemberList = NULL;
    }

    LwFreeStringArray(
        pConfig->DomainManager.ppszTrustExceptionList,
        pConfig->DomainManager.dwTrustExceptionCount);
    pConfig->DomainManager.ppszTrustExceptionList = NULL;
    pConfig->DomainManager.dwTrustExceptionCount = 0;
}
Пример #3
0
static
DWORD
AD_ConvertMultiStringToStringArray(
    IN PCSTR pszMultiString,
    OUT PSTR** pppszStringArray,
    OUT PDWORD pdwCount
)
{
    DWORD dwError = 0;
    PSTR* ppszStringArray = NULL;
    DWORD dwCount = 0;
    PCSTR pszIter = NULL;
    DWORD dwIndex = 0;

    dwCount = 0;
    for (pszIter = pszMultiString;
            pszIter && *pszIter;
            pszIter += strlen(pszIter) + 1)
    {
        dwCount++;
    }

    if (dwCount)
    {
        dwError = LwAllocateMemory(
                      dwCount * sizeof(*ppszStringArray),
                      OUT_PPVOID(&ppszStringArray));
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwIndex = 0;
    for (pszIter = pszMultiString;
            pszIter && *pszIter;
            pszIter += strlen(pszIter) + 1)
    {
        dwError = LwAllocateString(pszIter, &ppszStringArray[dwIndex]);
        BAIL_ON_LSA_ERROR(dwError);

        dwIndex++;
    }

    LSA_ASSERT(dwIndex == dwCount);

cleanup:

    *pppszStringArray = ppszStringArray;
    *pdwCount = dwCount;

    return dwError;

error:

    LwFreeStringArray(ppszStringArray, dwCount);
    ppszStringArray = NULL;
    dwCount = 0;

    goto cleanup;
}
VOID
LwpsLegacyFreeStringArray(
    IN PSTR* ppszDomainList,
    IN DWORD dwCount
    )
{
    if (ppszDomainList)
    {
        LwFreeStringArray(ppszDomainList, dwCount);
    }
}
Пример #5
0
DWORD
LwDuplicateStringArray(
    PSTR** pppNewStringArray,
    PDWORD pdwNewCount,
    PSTR* ppStringArray,
    DWORD dwCount
    )
{
    DWORD dwError = 0;
    PSTR* ppNewStringArray = NULL;
    DWORD dwNewCount = 0;

    if (dwCount)
    {
        DWORD i = 0;

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

        dwNewCount = dwCount;

        for (i = 0; i < dwCount; i++)
        {
            dwError = LwAllocateString(
                            ppStringArray[i],
                            &ppNewStringArray[i]);
            BAIL_ON_LW_ERROR(dwError);
        }
    }

cleanup:

    *pppNewStringArray = ppNewStringArray;
    if (pdwNewCount)
    {
        *pdwNewCount = dwNewCount;
    }

    return dwError;

error:

    LwFreeStringArray(ppNewStringArray, dwNewCount);
    ppNewStringArray = NULL;
    dwNewCount = 0;

    goto cleanup;
}
Пример #6
0
static
VOID
DestroyQueryListEntry(
    IN OUT PLSA_AD_QUERY_LISTS_ENTRY* ppEntry
    )
{
    PLSA_AD_QUERY_LISTS_ENTRY pEntry = *ppEntry;
    if (pEntry)
    {
        LwFreeStringArray(pEntry->ppszQueryValues, pEntry->dwQueryCount);
        LwFreeMemory(pEntry);
        *ppEntry = NULL;
    }
}
Пример #7
0
DWORD
LsaGetMatchingFilePathsInFolder(
    PCSTR pszDirPath,
    PCSTR pszFileNameRegExp,
    PSTR** pppszHostFilePaths,
    PDWORD pdwNPaths
    )
{
    typedef struct __PATHNODE
    {
        PSTR pszPath;
        struct __PATHNODE *pNext;
    } PATHNODE, *PPATHNODE;

    DWORD dwError = 0;
    DIR* pDir = NULL;
    struct dirent*  pDirEntry = NULL;
    regex_t rx;
    BOOLEAN rxAllocated = FALSE;
    regmatch_t* pResult = NULL;
    size_t nMatch = 1;
    DWORD  dwNPaths = 0;
    DWORD  iPath = 0;
    PSTR*  ppszHostFilePaths = NULL;
    CHAR   szBuf[PATH_MAX+1];
    struct stat statbuf;
    PPATHNODE pPathList = NULL;
    PPATHNODE pPathNode = NULL;
    BOOLEAN bDirExists = FALSE;

    dwError = LsaCheckDirectoryExists(pszDirPath, &bDirExists);
    BAIL_ON_LSA_ERROR(dwError);

    if(!bDirExists) {
        dwError = ERROR_FILE_NOT_FOUND;
        BAIL_ON_LSA_ERROR(dwError);
    }

    if (regcomp(&rx, pszFileNameRegExp, REG_EXTENDED) != 0) {
        dwError = LW_ERROR_REGEX_COMPILE_FAILED;
        BAIL_ON_LSA_ERROR(dwError);
    }
    rxAllocated = TRUE;

    dwError = LwAllocateMemory(sizeof(regmatch_t), (PVOID*)&pResult);
    BAIL_ON_LSA_ERROR(dwError);

    pDir = opendir(pszDirPath);
    if (!pDir) {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LSA_ERROR(dwError);
    }

    while ((pDirEntry = readdir(pDir)) != NULL) {

        int copied = snprintf(
                            szBuf,
                            sizeof(szBuf),
                            "%s/%s",
                            pszDirPath,
                            pDirEntry->d_name);
        if (copied >= sizeof(szBuf))
        {
            //Skip pathnames that are too long
            continue;
        }
        memset(&statbuf, 0, sizeof(struct stat));
        if (lstat(szBuf, &statbuf) < 0) {
            if(errno == ENOENT)
            {
                //This occurs when there is a symbolic link pointing to a
                //location that doesn't exist, because stat looks at the final
                //file, not the link. Since this file doesn't exist anyway,
                //just skip it.
                continue;
            }
            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);
        }

        /*
         * For now, we are searching only for regular files
         * This may be enhanced in the future to support additional
         * file system entry types
         */
        if (((statbuf.st_mode & S_IFMT) == S_IFREG) &&
            (regexec(&rx, pDirEntry->d_name, nMatch, pResult, 0) == 0)) {
            dwNPaths++;

            dwError = LwAllocateMemory(sizeof(PATHNODE), (PVOID*)&pPathNode);
            BAIL_ON_LSA_ERROR(dwError);

            dwError = LwAllocateString(szBuf, &pPathNode->pszPath);
            BAIL_ON_LSA_ERROR(dwError);

            pPathNode->pNext = pPathList;
            pPathList = pPathNode;
            pPathNode = NULL;
        }
    }

    if (pPathList) {
        dwError = LwAllocateMemory(sizeof(PSTR)*dwNPaths,
                                    (PVOID*)&ppszHostFilePaths);
        BAIL_ON_LSA_ERROR(dwError);
        /*
         *  The linked list is in reverse.
         *  Assign values in reverse to get it right
         */
        iPath = dwNPaths-1;
        pPathNode = pPathList;
        while (pPathNode) {
            *(ppszHostFilePaths+iPath) = pPathNode->pszPath;
            pPathNode->pszPath = NULL;
            pPathNode = pPathNode->pNext;
            iPath--;
        }
    }

    *pppszHostFilePaths = ppszHostFilePaths;
    *pdwNPaths = dwNPaths;

cleanup:

    if (pPathNode) {
        LW_SAFE_FREE_STRING(pPathNode->pszPath);
        LwFreeMemory(pPathNode);
    }

    while(pPathList) {
        pPathNode = pPathList;
        pPathList = pPathList->pNext;
        LW_SAFE_FREE_STRING(pPathNode->pszPath);
        LwFreeMemory(pPathNode);
    }

    if (rxAllocated) {
        regfree(&rx);
    }

    LW_SAFE_FREE_MEMORY(pResult);

    if (pDir) {
        closedir(pDir);
    }

    return dwError;

error:

    if (ppszHostFilePaths) {
       LwFreeStringArray(ppszHostFilePaths, dwNPaths);
    }

    goto cleanup;
}
Пример #8
0
DWORD
LwFindFilesInPaths(
    IN PCSTR pszName,
    IN LWFILE_TYPE type,
    IN const PCSTR* ppszSearchPaths,
    OUT PDWORD pdwFoundCount,
    OUT PSTR** pppszFoundPaths
    )
{
    DWORD dwError = 0;
    DWORD dwIndex = 0;
    PSTR pszTestPath = NULL;
    DWORD dwFoundCount = 0;
    PSTR* ppszFoundPaths = NULL;
    PSTR* ppszNewFoundPaths = NULL;
    BOOLEAN bExists = FALSE;

    for (dwIndex = 0; ppszSearchPaths[dwIndex]; dwIndex++)
    {
        LW_SAFE_FREE_STRING(pszTestPath);

        dwError = LwAllocateStringPrintf(
                        &pszTestPath,
                        "%s/%s",
                        ppszSearchPaths[dwIndex],
                        pszName);
        BAIL_ON_LW_ERROR(dwError);

        dwError = LwCheckFileTypeExists(
                        pszTestPath,
                        type,
                        &bExists);
        BAIL_ON_LW_ERROR(dwError);

        if (bExists)
        {
            dwError = LwReallocMemory(
                            ppszFoundPaths,
                            OUT_PPVOID(&ppszNewFoundPaths),
                            (dwFoundCount + 1) * sizeof(ppszFoundPaths[0]));
            BAIL_ON_LW_ERROR(dwError);
            ppszFoundPaths = ppszNewFoundPaths;

            ppszFoundPaths[dwFoundCount] = pszTestPath;
            pszTestPath = NULL;
            dwFoundCount++;
        }
    }

    *pdwFoundCount = dwFoundCount;
    *pppszFoundPaths = ppszFoundPaths;

cleanup:
    return dwError;

error:
    *pdwFoundCount = 0;
    *pppszFoundPaths = NULL;

    if (ppszFoundPaths)
    {
        LwFreeStringArray(
                ppszFoundPaths,
                dwFoundCount);
    }
    goto cleanup;
}
Пример #9
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;
}
Пример #10
0
DWORD
LocalDirQueryMemberOf(
    IN HANDLE hProvider,
    IN LSA_FIND_FLAGS FindFlags,
    IN DWORD dwSidCount,
    IN PSTR* ppszSids,
    OUT PDWORD pdwGroupSidCount,
    OUT PSTR** pppszGroupSids
    )
{
    DWORD dwError = 0;
    DWORD dwIndex = 0;
    PLW_HASH_TABLE   pGroupHash = NULL;
    LW_HASH_ITERATOR hashIterator = {0};
    LW_HASH_ENTRY*   pHashEntry = NULL;
    DWORD dwGroupSidCount = 0;
    PSTR* ppszGroupSids = NULL;

    dwError = LwHashCreate(
                    13,
                    LwHashCaselessStringCompare,
                    LwHashCaselessStringHash,
                    NULL,
                    NULL,
                    &pGroupHash);
    BAIL_ON_LSA_ERROR(dwError);

    for (dwIndex = 0; dwIndex < dwSidCount; dwIndex++)
    {
        dwError = LocalDirQueryMemberOfInternal(
            hProvider,
            FindFlags,
            ppszSids[dwIndex],
            pGroupHash);
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwGroupSidCount = (DWORD) LwHashGetKeyCount(pGroupHash);
    
    if (dwGroupSidCount)
    {
        dwError = LwAllocateMemory(
            sizeof(*ppszGroupSids) * dwGroupSidCount,
            OUT_PPVOID(&ppszGroupSids));
        BAIL_ON_LSA_ERROR(dwError);
    
        dwError = LwHashGetIterator(pGroupHash, &hashIterator);
        BAIL_ON_LSA_ERROR(dwError);
        
        for(dwIndex = 0; (pHashEntry = LwHashNext(&hashIterator)) != NULL; dwIndex++)
        {
            ppszGroupSids[dwIndex] = (PSTR) pHashEntry->pValue;
            pHashEntry->pValue = NULL;
        }
    }

    *pdwGroupSidCount = dwGroupSidCount;
    *pppszGroupSids = ppszGroupSids;

cleanup:

    if (pGroupHash)
    {
        if (LwHashGetIterator(pGroupHash, &hashIterator) == 0)
        {
            while ((pHashEntry = LwHashNext(&hashIterator)))
            {
                LW_SAFE_FREE_MEMORY(pHashEntry->pValue);
            }
        }

        LwHashSafeFree(&pGroupHash);
    }

    return dwError;

error:

    *pdwGroupSidCount = 0;
    *pppszGroupSids = NULL;

    if (ppszGroupSids)
    {
        LwFreeStringArray(ppszGroupSids, dwGroupSidCount);
    }

    goto cleanup;
}
Пример #11
0
static
DWORD
EVTCreateAccessDescriptor(
    PCSTR pszAllowReadTo,
    PCSTR pszAllowWriteTo,
    PCSTR pszAllowDeleteTo,
    PSECURITY_DESCRIPTOR_ABSOLUTE* ppDescriptor,
    PBOOLEAN pbFullyResolved
    )
{
    PSECURITY_DESCRIPTOR_ABSOLUTE pDescriptor = NULL;
    DWORD dwCount = 0;
    PSTR* ppszArray = NULL;
    DWORD dwReadCount = 0;
    DWORD dwWriteCount = 0;
    DWORD dwDeleteCount = 0;
    PSID* ppReadList = NULL;
    PSID* ppWriteList = NULL;
    PSID* ppDeleteList = NULL;
    PACL pDacl = NULL;
    DWORD dwDaclSize = 0;
    PLW_MAP_SECURITY_CONTEXT pContext = NULL;
    DWORD dwError = 0;
    PSID pLocalSystem = NULL;
    PSID pAdministrators = NULL;
    BOOLEAN bFullyResolved = TRUE;

    dwError = LwAllocateWellKnownSid(
                    WinLocalSystemSid,
                    NULL,
                    &pLocalSystem,
                    NULL);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = LwAllocateWellKnownSid(
                    WinBuiltinAdministratorsSid,
                    NULL,
                    &pAdministrators,
                    NULL);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = LwNtStatusToWin32Error(
        LwMapSecurityCreateContext(
                &pContext));
    BAIL_ON_EVT_ERROR(dwError);

    dwError = LwAllocateMemory(
                SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
                (PVOID*)&pDescriptor);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = LwNtStatusToWin32Error(
        RtlCreateSecurityDescriptorAbsolute(
                pDescriptor,
                SECURITY_DESCRIPTOR_REVISION));
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTStringSplit(
                pszAllowReadTo,
                &dwCount,
                &ppszArray);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTNamesToSids(
                pContext,
                dwCount,
                ppszArray,
                &dwReadCount,
                &ppReadList);
    BAIL_ON_EVT_ERROR(dwError);

    if (dwReadCount < dwCount)
    {
        bFullyResolved = FALSE;
    }

    LwFreeStringArray(
        ppszArray,
        dwCount);
    ppszArray = NULL;

    dwError = EVTStringSplit(
                pszAllowWriteTo,
                &dwCount,
                &ppszArray);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTNamesToSids(
                pContext,
                dwCount,
                ppszArray,
                &dwWriteCount,
                &ppWriteList);
    BAIL_ON_EVT_ERROR(dwError);

    if (dwWriteCount < dwCount)
    {
        bFullyResolved = FALSE;
    }

    LwFreeStringArray(
        ppszArray,
        dwCount);
    ppszArray = NULL;

    dwError = EVTStringSplit(
                pszAllowDeleteTo,
                &dwCount,
                &ppszArray);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTNamesToSids(
                pContext,
                dwCount,
                ppszArray,
                &dwDeleteCount,
                &ppDeleteList);
    BAIL_ON_EVT_ERROR(dwError);

    if (dwDeleteCount < dwCount)
    {
        bFullyResolved = FALSE;
    }

    LwFreeStringArray(
        ppszArray,
        dwCount);
    ppszArray = NULL;

    dwDaclSize = ACL_HEADER_SIZE +
        EVTGetAllowAcesSize(dwReadCount, ppReadList) +
        EVTGetAllowAcesSize(dwWriteCount, ppWriteList) +
        EVTGetAllowAcesSize(dwDeleteCount, ppDeleteList);

    dwError = LwAllocateMemory(
        dwDaclSize,
        OUT_PPVOID(&pDacl));
    BAIL_ON_EVT_ERROR(dwError);

    dwError = LwNtStatusToWin32Error(
        RtlCreateAcl(pDacl, dwDaclSize, ACL_REVISION));
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTAddAllowAces(
                pDacl,
                dwReadCount,
                ppReadList,
                EVENTLOG_READ_RECORD);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTAddAllowAces(
                pDacl,
                dwWriteCount,
                ppWriteList,
                EVENTLOG_WRITE_RECORD);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = EVTAddAllowAces(
                pDacl,
                dwWriteCount,
                ppWriteList,
                EVENTLOG_DELETE_RECORD);
    BAIL_ON_EVT_ERROR(dwError);

    dwError = LwNtStatusToWin32Error(
        RtlSetDaclSecurityDescriptor(
            pDescriptor,
            TRUE,
            pDacl,
            FALSE));
    BAIL_ON_EVT_ERROR(dwError);
    pDacl = NULL;

    dwError = LwNtStatusToWin32Error(
        RtlSetOwnerSecurityDescriptor(
            pDescriptor,
            pLocalSystem,
            FALSE));
    BAIL_ON_EVT_ERROR(dwError);
    pLocalSystem = NULL;

    dwError = LwNtStatusToWin32Error(
        RtlSetGroupSecurityDescriptor(
            pDescriptor,
            pAdministrators,
            FALSE));
    BAIL_ON_EVT_ERROR(dwError);
    pAdministrators = NULL;

    *ppDescriptor = pDescriptor;
    if (pbFullyResolved)
    {
        *pbFullyResolved = bFullyResolved;
    }

cleanup:
    if (ppszArray)
    {
        LwFreeStringArray(
            ppszArray,
            dwCount);
    }
    EVTFreeSidArray(
        pContext,
        dwReadCount,
        ppReadList);
    EVTFreeSidArray(
        pContext,
        dwWriteCount,
        ppWriteList);
    EVTFreeSidArray(
        pContext,
        dwDeleteCount,
        ppDeleteList);
    LwMapSecurityFreeContext(&pContext);
    return dwError;

error:
    EVTFreeSecurityDescriptor(pDescriptor);
    *ppDescriptor = NULL;
    if (pbFullyResolved)
    {
        *pbFullyResolved = FALSE;
    }
    LW_SAFE_FREE_MEMORY(pDacl);
    LW_SAFE_FREE_MEMORY(pLocalSystem);
    LW_SAFE_FREE_MEMORY(pAdministrators);
    goto cleanup;
}
Пример #12
0
static
DWORD
EVTStringSplit(
    PCSTR   pszInput,
    PDWORD  pdwCount,
    PSTR**  pppszArray
    )
{
    DWORD  dwError = 0;
    DWORD  dwCount = 0;
    PCSTR  pszStart = NULL;
    PCSTR  pszEnd = NULL;
    PSTR* ppszArray = NULL;
    PSTR pszAdd = NULL;

    for (pszStart = pszInput; *pszStart !=  0; pszStart++)
    {
        if (*pszStart == ',') dwCount++;
    }
    dwCount++;

    dwError = LwAllocateMemory(
                  (dwCount+1)*sizeof(PCSTR),
                  (PVOID *)&ppszArray);

    dwCount = 0;
    pszStart = pszInput;
    while (TRUE)
    {
        pszEnd = strchr(pszStart, ',');
        if ( pszEnd )
        {
            dwError = LwStrndup(
                         pszStart,
                         pszEnd - pszStart,
                         &pszAdd);
            BAIL_ON_EVT_ERROR(dwError);
        }
        else
        {
            dwError = LwAllocateString(
                        pszStart,
                        &pszAdd);
            BAIL_ON_EVT_ERROR(dwError);
        }
        LwStripWhitespace(pszAdd, TRUE, TRUE);
        if (pszAdd[0])
        {
            ppszArray[dwCount++] = pszAdd;
            pszAdd = NULL;
        }
        else
        {
            LW_SAFE_FREE_STRING(pszAdd);
        }

        if (pszEnd)
        {
            pszStart = pszEnd + 1;
        }
        else
        {
            break;
        }
    }

    *pppszArray = ppszArray;
    *pdwCount = dwCount;

cleanup:
    LW_SAFE_FREE_STRING(pszAdd);
    return dwError;

error:
    LwFreeStringArray(
        ppszArray,
        dwCount);
    goto cleanup;
}
Пример #13
0
DWORD
ADLdap_GetObjectGroupMembership(
    IN PAD_PROVIDER_CONTEXT pContext,
    IN PLSA_SECURITY_OBJECT pObject,
    OUT int* piPrimaryGroupIndex,
    OUT size_t* psNumGroupsFound,
    OUT PLSA_SECURITY_OBJECT** pppGroupInfoList
    )
{
    DWORD dwError =  0;
    PLSA_DM_LDAP_CONNECTION pConn = NULL;
    PSTR pszFullDomainName = NULL;
    INT i = 0;
    PLSA_SECURITY_OBJECT* ppGroupInfoList = NULL;
    size_t sNumGroupsFound = 0;
    int    iPrimaryGroupIndex = -1;
    DWORD gcMembershipCount = 0;
    PSTR* ppGcMembershipList = NULL;
    DWORD dcMembershipCount = 0;
    PSTR* ppDcMembershipList = NULL;
    PLW_HASH_TABLE pGroupHash = NULL;
    LSA_TRUST_DIRECTION trustDirection = LSA_TRUST_DIRECTION_UNKNOWN;
    LSA_TRUST_MODE trustMode = LSA_TRUST_MODE_UNKNOWN;
    DWORD index = 0;
    DWORD totalSidCount = 0;
    PSTR* ppTotalSidList = NULL;

    // If we cannot get dn, then we cannot get DN information for this objects, hence BAIL
    if (LW_IS_NULL_OR_EMPTY_STR(pObject->pszDN))
    {
        dwError = LW_ERROR_NO_SUCH_USER;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LwLdapConvertDNToDomain(
                 pObject->pszDN,
                 &pszFullDomainName);
    BAIL_ON_LSA_ERROR(dwError);

    // Note that this function is called only for 2-way trusts.  However,
    // the trust could be an external trust or a forest trust.  We can only
    // query the GC if there is a forest trust.

    dwError = AD_DetermineTrustModeandDomainName(
                    pContext->pState,
                    pszFullDomainName,
                    &trustDirection,
                    &trustMode,
                    NULL,
                    NULL);
    BAIL_ON_LSA_ERROR(dwError);

    // We could only have the DN path for the user if (s)he came from a two way
    // trusted domain or the joined domain.
    LSA_ASSERT(LSA_TRUST_DIRECTION_TWO_WAY == trustDirection ||
            LSA_TRUST_DIRECTION_SELF == trustDirection);

    if (trustMode != LSA_TRUST_MODE_EXTERNAL)
    {
        // Get forest info from domain's GC since there is a forest trust.
        // This will only include universal group information.  (The domain
        // global groups will not include membership info in the GC.)
        dwError = LsaDmLdapOpenGc(
                      pContext,
                      pszFullDomainName,
                      &pConn);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = ADLdap_GetAttributeValuesList(
                        pConn,
                        pObject->pszDN,
                        AD_LDAP_MEMBEROF_TAG,
                        TRUE,
                        TRUE,
                        &gcMembershipCount,
                        &ppGcMembershipList);
        BAIL_ON_LSA_ERROR(dwError);

        LsaDmLdapClose(pConn);
        pConn = NULL;
    }

    dwError = LsaDmLdapOpenDc(
                  pContext,
                  pszFullDomainName,
                  &pConn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADLdap_GetAttributeValuesList(
                    pConn,
                    pObject->pszDN,
                    AD_LDAP_MEMBEROF_TAG,
                    TRUE,
                    TRUE,
                    &dcMembershipCount,
                    &ppDcMembershipList);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwHashCreate(
                    (dcMembershipCount + gcMembershipCount + 1) * 2,
                    LwHashCaselessStringCompare,
                    LwHashCaselessStringHash,
                    ADLdap_FreeHashStringValue,
                    NULL,
                    &pGroupHash);
    BAIL_ON_LSA_ERROR(dwError);

    for (index = 0; index < gcMembershipCount; index++)
    {
        PSTR pSid = ppGcMembershipList[index];
        if (!LwHashExists(pGroupHash, pSid))
        {
            // Set the value of the hash entry as NULL so this string is not
            // freed with the hash.
            dwError = LwHashSetValue(pGroupHash, pSid, NULL);
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    for (index = 0; index < dcMembershipCount; index++)
    {
        PSTR pSid = ppDcMembershipList[index];
        if (!LwHashExists(pGroupHash, pSid))
        {
            // Set the value of the hash entry as NULL so this string is not
            // freed with the hash.
            dwError = LwHashSetValue(pGroupHash, pSid, NULL);
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    if (pObject->type == LSA_OBJECT_TYPE_USER && pObject->userInfo.pszPrimaryGroupSid)
    {
        // Add the pszPrimaryGroupSID entry to the hash
        PSTR pSid = pObject->userInfo.pszPrimaryGroupSid;
        if (!LwHashExists(pGroupHash, pSid))
        {
            // Set the value of the hash entry as NULL so this string is not
            // freed with the hash.
            dwError = LwHashSetValue(pGroupHash, pSid, NULL);
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    // Check if the user came from a domain other than the computer's domain
    if (LSA_TRUST_DIRECTION_TWO_WAY == trustDirection)
    {
        dwError = ADLdap_AddDomainLocalGroups(
                        pContext,
                        pObject,
                        pGroupHash);
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = ADLdap_MoveHashKeysToArray(
                    pGroupHash,
                    &totalSidCount,
                    (PVOID**)(PVOID)&ppTotalSidList);
    BAIL_ON_LSA_ERROR(dwError);
    
    dwError = AD_FindObjectsBySidList(
                    pContext,
                    totalSidCount,
                    ppTotalSidList,
                    &sNumGroupsFound,
                    &ppGroupInfoList);
    BAIL_ON_LSA_ERROR(dwError);

    AD_FilterNullEntries(
            ppGroupInfoList,
            &sNumGroupsFound);

    // Determine primary group index
    if (pObject->type == LSA_OBJECT_TYPE_USER &&
        pObject->userInfo.pszPrimaryGroupSid &&
        ppGroupInfoList &&
        sNumGroupsFound)
    {
        for (i = (INT)sNumGroupsFound - 1; i >= 0; i--)
        {
            if (!strcmp(ppGroupInfoList[i]->pszObjectSid, pObject->userInfo.pszPrimaryGroupSid))
            {
                iPrimaryGroupIndex = i;
                break;
            }
        }
    }

    *psNumGroupsFound = sNumGroupsFound;
    *pppGroupInfoList = ppGroupInfoList;
    *piPrimaryGroupIndex = iPrimaryGroupIndex;

cleanup:
    LwHashSafeFree(&pGroupHash);
    LW_SAFE_FREE_STRING(pszFullDomainName);
    LwFreeStringArray(ppGcMembershipList, gcMembershipCount);
    LwFreeStringArray(ppDcMembershipList, dcMembershipCount);
    // Do not free the string pointers inside. They are borrowed from the
    // hash.
    LW_SAFE_FREE_MEMORY(ppTotalSidList);

    LsaDmLdapClose(pConn);

    return dwError;

error:

    *pppGroupInfoList = NULL;
    *psNumGroupsFound = 0;
    *piPrimaryGroupIndex = -1;

    if ( dwError != LW_ERROR_DOMAIN_IS_OFFLINE )
    {
        LSA_LOG_ERROR("Failed to group memberships of SID=%s. [error code:%u]",
                      pObject->pszObjectSid, dwError);
    }

    ADCacheSafeFreeObjectList((DWORD)sNumGroupsFound, &ppGroupInfoList);

    goto cleanup;
}
Пример #14
0
DWORD
LsaAdBatchBuildQueryForRpc(
    IN PCSTR pszNetbiosDomainName,
    IN LSA_AD_BATCH_QUERY_TYPE QueryType,
    // List of PLSA_AD_BATCH_ITEM
    IN PLSA_LIST_LINKS pFirstLinks,
    IN PLSA_LIST_LINKS pEndLinks,
    OUT PLSA_LIST_LINKS* ppNextLinks,
    IN DWORD dwMaxQueryCount,
    OUT PDWORD pdwQueryCount,
    OUT PSTR** pppszQueryList
    )
{
    DWORD dwError = 0;
    PLSA_LIST_LINKS pLinks = NULL;
    PSTR* ppszQueryList = NULL;
    PLSA_LIST_LINKS pLastLinks = pFirstLinks;
    DWORD dwQueryCount = 0;
    DWORD dwSavedQueryCount = 0;

    pLinks = pFirstLinks;
    for (pLinks = pFirstLinks; pLinks != pEndLinks; pLinks = pLinks->Next)
    {
        PLSA_AD_BATCH_ITEM pBatchItem = LW_STRUCT_FROM_FIELD(pLinks, LSA_AD_BATCH_ITEM, BatchItemListLinks);
        PCSTR pszQueryTerm = NULL;

        switch (QueryType)
        {
            case LSA_AD_BATCH_QUERY_TYPE_BY_SID:
            {
                if (pBatchItem->pszSid)
                {
                    pszQueryTerm = pBatchItem->pszSid;
                }
                else if (QueryType == pBatchItem->QueryTerm.Type)
                {
                    pszQueryTerm = pBatchItem->QueryTerm.pszString;
                }
                break;
            }
            case LSA_AD_BATCH_QUERY_TYPE_BY_NT4:
            {
                if (pBatchItem->pszSamAccountName)
                {
                    pszQueryTerm = pBatchItem->pszSamAccountName;
                }
                else if (QueryType == pBatchItem->QueryTerm.Type)
                {
                    pszQueryTerm = pBatchItem->QueryTerm.pszString;
                }
                break;
            }
            default:
                LSA_ASSERT(FALSE);
                dwError = LW_ERROR_INTERNAL;
                BAIL_ON_LSA_ERROR(dwError);
        }

        if (!LW_IS_NULL_OR_EMPTY_STR(pszQueryTerm))
        {
            DWORD dwNewQueryCount = dwQueryCount + 1;

            if (dwMaxQueryCount && (dwNewQueryCount > dwMaxQueryCount))
            {
                break;
            }
            dwQueryCount = dwNewQueryCount;
        }
    }
    pLastLinks = pLinks;
    dwSavedQueryCount = dwQueryCount;

    if (dwQueryCount < 1)
    {
        goto cleanup;
    }

    dwError = LwAllocateMemory(dwQueryCount*sizeof(*ppszQueryList), (PVOID*)&ppszQueryList);
    BAIL_ON_LSA_ERROR(dwError);

    dwQueryCount = 0;
    // Loop until we reach last links.
    for (pLinks = pFirstLinks; pLinks != pLastLinks; pLinks = pLinks->Next)
    {
        PLSA_AD_BATCH_ITEM pBatchItem = LW_STRUCT_FROM_FIELD(pLinks, LSA_AD_BATCH_ITEM, BatchItemListLinks);

        if (IsSetFlag(pBatchItem->Flags, LSA_AD_BATCH_ITEM_FLAG_ALLOCATED_MATCH_TERM))
        {
            LW_SAFE_FREE_STRING(pBatchItem->pszQueryMatchTerm);
            ClearFlag(pBatchItem->Flags, LSA_AD_BATCH_ITEM_FLAG_ALLOCATED_MATCH_TERM);
        }

        switch (QueryType)
        {
            case LSA_AD_BATCH_QUERY_TYPE_BY_SID:
            {
                PCSTR pszUseSid = NULL;
                if (pBatchItem->pszSid)
                {
                    pszUseSid = pBatchItem->pszSid;
                }
                else if (QueryType == pBatchItem->QueryTerm.Type)
                {
                    pszUseSid = pBatchItem->QueryTerm.pszString;
                }
                // We might not have a SID if we failed to find a pseudo.
                if (pszUseSid)
                {
                    dwError = LwAllocateString(pszUseSid,
                                                &ppszQueryList[dwQueryCount++]);
                    BAIL_ON_LSA_ERROR(dwError);
                    pBatchItem->pszQueryMatchTerm = (PSTR)pszUseSid;
                }
                break;
            }

            case LSA_AD_BATCH_QUERY_TYPE_BY_NT4:
            {
                PCSTR pszUseSamAccountName = NULL;
                if (pBatchItem->pszSamAccountName)
                {
                    pszUseSamAccountName = pBatchItem->pszSamAccountName;
                }
                else if (QueryType == pBatchItem->QueryTerm.Type)
                {
                    pszUseSamAccountName = pBatchItem->QueryTerm.pszString;
                }
                if (pszUseSamAccountName)
                {
                    dwError = LwAllocateStringPrintf(
                                    &ppszQueryList[dwQueryCount++],
                                    "%s\\%s",
                                    pszNetbiosDomainName,
                                    pszUseSamAccountName);
                    BAIL_ON_LSA_ERROR(dwError);
                    pBatchItem->pszQueryMatchTerm = (PSTR)pszUseSamAccountName;
                }
                break;
            }
            default:
                LSA_ASSERT(FALSE);
                dwError = LW_ERROR_INTERNAL;
                BAIL_ON_LSA_ERROR(dwError);
        }
    }

    assert(dwSavedQueryCount == dwQueryCount);

cleanup:
    // We handle error here instead of error label
    // because there is a goto cleanup above.
    if (dwError)
    {
        LwFreeStringArray(ppszQueryList, dwSavedQueryCount);
        ppszQueryList = NULL;
        dwQueryCount = 0;
        dwSavedQueryCount = 0;
        pLastLinks = pFirstLinks;
    }

    *pppszQueryList = ppszQueryList;
    *pdwQueryCount = dwQueryCount;
    *ppNextLinks = pLastLinks;

    return dwError;

error:
    // Do not actually handle any errors here.
    goto cleanup;
}
Пример #15
0
// Give an attribute name "pszAttributeName"
// Return all the values of the attribute for a given DN "pszDN"
// The number of values can be more than 1500 since "ranging" is handled correctly in the routine
// Now accept whether to do an extended DN search and whether to parse result to get Sids
DWORD
ADLdap_GetAttributeValuesList(
    IN PLSA_DM_LDAP_CONNECTION pConn,
    IN PCSTR pszDN,
    IN PCSTR pszAttributeName,
    IN BOOLEAN bDoExtDnSearch,
    IN BOOLEAN bDoSidParsing,
    OUT PDWORD pdwTotalCount,
    OUT PSTR** pppszValues
    )
{
    DWORD dwError = 0;
    // Do not free "szAttributeList"
    PSTR szAttributeList[2] = {NULL,NULL};
    PSTR* ppszValuesTotal = NULL;
    PSTR* ppszValues = NULL;
    LDAPMessage* pMessage = NULL;
    DWORD dwCount = 0;
    DWORD dwTotalCount = 0;
    PLW_DLINKED_LIST pList = NULL;
    PLW_DLINKED_LIST pNode = NULL;
    PLSA_AD_QUERY_LISTS_ENTRY pEntry = NULL;
    PSTR pszRangeAttr = NULL;
    LDAP* pLd = NULL;
    BerElement* pBer = NULL;
    PSTR pszRetrievedAttr = NULL;
    //Do Not free "pszRetrievedRangeAttr"
    PSTR pszRetrievedRangeAttr = NULL;
    BOOLEAN bIsEnd = FALSE;
    DWORD iValues = 0;
    DWORD iValuesTotal = 0;
    PSTR pszAttributeRangedName = NULL;
    HANDLE hDirectory = NULL;

    BAIL_ON_INVALID_STRING(pszAttributeName);
    szAttributeList[0] = (PSTR)pszAttributeName;

    for (;;)
    {
        if (pMessage)
        {
            ldap_msgfree(pMessage);
            pMessage = NULL;
        }

        if (!bDoExtDnSearch && bDoSidParsing)
        {
            dwError = LW_ERROR_INVALID_PARAMETER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        if (bDoExtDnSearch)
        {
            dwError = LsaDmLdapDirectoryExtendedDNSearch(
                            pConn,
                            pszDN,
                            "(objectClass=*)",
                            szAttributeList,
                            LDAP_SCOPE_BASE,
                            &hDirectory,
                            &pMessage);
            BAIL_ON_LSA_ERROR(dwError);
        }
        else
        {
            dwError = LsaDmLdapDirectorySearch(
                            pConn,
                            pszDN,
                            LDAP_SCOPE_BASE,
                            "(objectClass=*)",
                            szAttributeList,
                            &hDirectory,
                            &pMessage);
            BAIL_ON_LSA_ERROR(dwError);
        }
        pLd = LwLdapGetSession(hDirectory);

        dwError = LwLdapGetStringsWithExtDnResult(
                        hDirectory,
                        pMessage,
                        pszAttributeName,
                        bDoSidParsing,
                        &ppszValues,
                        &dwCount);
        BAIL_ON_LSA_ERROR(dwError);

        if (ppszValues && dwCount)
        {
            if (pList)
            {
                // This is the case where we started out getting
                // ranged info but the info became non-ranged.
                // We might actually want to allow this to handle
                // a case where the membership list is trimmed
                // while we are enumerating.
                dwError = LW_ERROR_LDAP_ERROR;
                BAIL_ON_LSA_ERROR(dwError);
            }

            dwTotalCount = dwCount;
            ppszValuesTotal = ppszValues;

            dwCount = 0;
            ppszValues = NULL;

            break;
        }

        if (pszRetrievedAttr)
        {
            ldap_memfree(pszRetrievedAttr);
            pszRetrievedAttr = NULL;
        }

        if (pBer)
        {
             ber_free(pBer, 0);
        }

        LW_SAFE_FREE_STRING(pszAttributeRangedName);

        dwError = LwAllocateStringPrintf(
                      &pszAttributeRangedName,
                      "%s;Range=",
                      pszAttributeName);
        BAIL_ON_LSA_ERROR(dwError);

        pszRetrievedAttr = ldap_first_attribute(pLd, pMessage, &pBer);
        while (pszRetrievedAttr)
        {
            if (!strncasecmp(pszRetrievedAttr, pszAttributeRangedName, strlen(pszAttributeRangedName)))
            {
                pszRetrievedRangeAttr = pszRetrievedAttr;
                break;
            }
            ldap_memfree(pszRetrievedAttr);
            pszRetrievedAttr = NULL;

            pszRetrievedAttr = ldap_next_attribute(pLd, pMessage, pBer);
        }

        if (!pszRetrievedRangeAttr)
        {
            // This happens when we have an group with no members,
            break;
        }

        if ('*' == pszRetrievedRangeAttr[strlen(pszRetrievedRangeAttr)-1])
        {
            bIsEnd = TRUE;
        }

        dwError = LwLdapGetStringsWithExtDnResult(
                        hDirectory,
                        pMessage,
                        pszRetrievedRangeAttr,
                        bDoSidParsing,
                        &ppszValues,
                        &dwCount);
        BAIL_ON_LSA_ERROR(dwError);

        dwTotalCount += dwCount;

        dwError = CreateQueryListEntry(
                        &pEntry,
                        dwCount,
                        ppszValues);
        BAIL_ON_LSA_ERROR(dwError);
        ppszValues = NULL;
        dwCount = 0;

        dwError = LwDLinkedListPrepend(&pList, pEntry);
        BAIL_ON_LSA_ERROR(dwError);
        pEntry = NULL;

        if (bIsEnd)
        {
            break;
        }

        LW_SAFE_FREE_STRING(pszRangeAttr);

        dwError = LwAllocateStringPrintf(
                        &pszRangeAttr,
                        "%s%u-*",
                        pszAttributeRangedName,
                        dwTotalCount);
        BAIL_ON_LSA_ERROR(dwError);

        szAttributeList[0] = pszRangeAttr;
    }

    if (pList && !ppszValuesTotal)
    {
        dwError = LwAllocateMemory(
                        sizeof(*ppszValuesTotal) * dwTotalCount,
                        (PVOID*)&ppszValuesTotal);
        BAIL_ON_LSA_ERROR(dwError);

        for (pNode = pList; pNode; pNode = pNode->pNext)
        {
            PLSA_AD_QUERY_LISTS_ENTRY pEntry = (PLSA_AD_QUERY_LISTS_ENTRY)pNode->pItem;

            for (iValues = 0; iValues < pEntry->dwQueryCount; iValues++)
            {
                ppszValuesTotal[iValuesTotal] = pEntry->ppszQueryValues[iValues];
                pEntry->ppszQueryValues[iValues] = NULL;
                iValuesTotal++;
            }
        }
    }

    *pdwTotalCount = dwTotalCount;
    *pppszValues = ppszValuesTotal;

cleanup:
    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    if (pszRetrievedAttr)
    {
        ldap_memfree(pszRetrievedAttr);
    }

    if (pBer)
    {
        ber_free(pBer, 0);
    }

    LwFreeStringArray(ppszValues, dwCount);
    DestroyQueryListEntry(&pEntry);
    LW_SAFE_FREE_STRING(pszAttributeRangedName);
    LW_SAFE_FREE_STRING(pszRangeAttr);

    for (pNode = pList; pNode; pNode = pNode->pNext)
    {
        PLSA_AD_QUERY_LISTS_ENTRY pEntry = (PLSA_AD_QUERY_LISTS_ENTRY)pNode->pItem;
        DestroyQueryListEntry(&pEntry);
    }
    LwDLinkedListFree(pList);

    return dwError;

error:
    LwFreeStringArray(ppszValuesTotal, iValuesTotal);

    *pdwTotalCount = 0;
    *pppszValues = NULL;

    goto cleanup;
}
Пример #16
0
DWORD
ADGetConfigurationMode(
    IN PLSA_DM_LDAP_CONNECTION pConn,
    PCSTR  pszDN,
    ADConfigurationMode* pADConfMode
    )
{
    DWORD dwError = 0;
    LDAP *pLd = NULL;
    PSTR szAttributeList[] = {AD_LDAP_DESCRIPTION_TAG, NULL};
    LDAPMessage *pMessage = NULL;
    DWORD dwCount = 0;
    ADConfigurationMode adConfMode = NonSchemaMode;
    HANDLE hDirectory = NULL;

    PSTR* ppszValues = NULL;
    DWORD dwNumValues = 0;
    DWORD i = 0;

    BAIL_ON_INVALID_POINTER(pConn);

    dwError = LsaDmLdapDirectorySearch(
                    pConn,
                    pszDN,
                    LDAP_SCOPE_BASE,
                    "(objectClass=*)",
                    szAttributeList,
                    &hDirectory,
                    &pMessage);
    if (dwError == LW_ERROR_LDAP_NO_SUCH_OBJECT){
        dwError = LW_ERROR_INCOMPATIBLE_MODES_BETWEEN_TRUSTEDDOMAINS;
    }
    BAIL_ON_LSA_ERROR(dwError);

    pLd = LwLdapGetSession(hDirectory);

    dwCount = ldap_count_entries(
                pLd,
                pMessage
                );
    if (dwCount < 0) {
        dwError = LW_ERROR_LDAP_ERROR;
    } else if (dwCount == 0) {
        dwError = LW_ERROR_NO_SUCH_CELL;
    } else if (dwCount > 1) {
        dwError = LW_ERROR_INTERNAL;
    }

    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwLdapGetStrings(
                    hDirectory,
                    pMessage,
                    AD_LDAP_DESCRIPTION_TAG,
                    &ppszValues,
                    &dwNumValues);
    BAIL_ON_LSA_ERROR(dwError);

    for (i = 0; i < dwNumValues; i++)
    {
        if (!strncasecmp(ppszValues[i], "use2307Attrs=", sizeof("use2307Attrs=")-1))
        {
           PSTR pszValue = ppszValues[i] + sizeof("use2307Attrs=") - 1;
           if (!LW_IS_NULL_OR_EMPTY_STR(pszValue) && !strcasecmp(pszValue, "true")) {
              adConfMode = SchemaMode;
              break;
           }
        }
    }

    *pADConfMode = adConfMode;

cleanup:

    if (pMessage) {
        ldap_msgfree(pMessage);
    }

    if (ppszValues) {
        LwFreeStringArray(ppszValues, dwNumValues);
    }

    return dwError;

error:

    *pADConfMode = UnknownMode;

    goto cleanup;
}
Пример #17
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;
}
Пример #18
0
// Must return at least one of NT4 or SID.
// Can optionally return alias as well.
DWORD
ADUnprovPlugin_QueryById(
    IN PLSA_AD_PROVIDER_STATE pState,
    IN BOOLEAN bIsUser,
    IN DWORD dwId,
    OUT PSTR* ppszSid,
    OUT PSTR* ppszAlias
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PSTR* ppszDomainNames = NULL;
    DWORD dwDomainCount = 0;
    DWORD i = 0;

    // lsass unprovisioned mode converts a group/user uid/gid to objectSid/name with the same algorithm

    dwError = ADUnprovPlugin_QueryByIdWithDomainName(
                    pState,
                    bIsUser,
                    dwId,
                    pState->pProviderData->szDomain,
                    ppszSid,
                    ppszAlias);
    if (LW_ERROR_NO_SUCH_OBJECT == dwError ||
        LW_ERROR_NO_SUCH_DOMAIN == dwError)
    {
        dwError = 0;
    }
    BAIL_ON_LSA_ERROR(dwError);


    if (!LW_IS_NULL_OR_EMPTY_STR(*ppszSid))
        goto cleanup;

    dwError = LsaDmEnumDomainNames(
                  pState->hDmState,
                  NULL,
                  NULL,
                  &ppszDomainNames,
                  &dwDomainCount);
    BAIL_ON_LSA_ERROR(dwError);

    for (i = 0; i < dwDomainCount; i++)
    {
        dwError = ADUnprovPlugin_QueryByIdWithDomainName(
                        pState,
                        bIsUser,
                        dwId,
                        ppszDomainNames[i],
                        ppszSid,
                        ppszAlias);
        if (LW_ERROR_NO_SUCH_OBJECT == dwError ||
            LW_ERROR_NO_SUCH_DOMAIN == dwError)
        {
            dwError = 0;
            continue;
        }
        BAIL_ON_LSA_ERROR(dwError);

        if (!LW_IS_NULL_OR_EMPTY_STR(*ppszSid))
            goto cleanup;
    }

cleanup:
    if (dwError)
    {
        *ppszSid = NULL;
        *ppszAlias = NULL;
    }

    LwFreeStringArray(ppszDomainNames, dwDomainCount);

    return dwError;

error:
    goto cleanup;
}
Пример #19
0
DWORD
ADLdap_GetGroupMembers(
    IN PAD_PROVIDER_CONTEXT pContext,
    IN PCSTR pszDomainName,
    IN PCSTR pszSid,
    OUT size_t* psCount,
    OUT PLSA_SECURITY_OBJECT** pppResults
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    DWORD dwSidCount = 0;
    PSTR pszDnsDomainName = NULL;
    PLSA_SECURITY_OBJECT pGroupObj = NULL;
    PLSA_SECURITY_OBJECT* ppResults = NULL;
    PSTR *ppszLDAPValues = NULL;
    size_t sFoundCount = 0;
    PLSA_DM_LDAP_CONNECTION pConn = NULL;

    dwError = AD_FindObjectBySid(
                    pContext,
                    pszSid,
                    &pGroupObj);
    BAIL_ON_LSA_ERROR(dwError);

    if (pGroupObj->type != LSA_OBJECT_TYPE_GROUP)
    {
        dwError = LW_ERROR_DATA_ERROR;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LsaDmWrapGetDomainName(
                  pContext->pState->hDmState,
                  pszDomainName,
                  &pszDnsDomainName,
                  NULL);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LsaDmLdapOpenDc(
                  pContext,
                  pszDnsDomainName,
                  &pConn);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADLdap_GetAttributeValuesList(
                    pConn,
                    pGroupObj->pszDN,
                    AD_LDAP_MEMBER_TAG,
                    TRUE,
                    TRUE,
                    &dwSidCount,
                    &ppszLDAPValues);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = AD_FindObjectsBySidList(
                 pContext,
                 dwSidCount,
                 ppszLDAPValues,
                 &sFoundCount,
                 &ppResults);
    BAIL_ON_LSA_ERROR(dwError);

    *psCount = sFoundCount;
    *pppResults = ppResults;

cleanup:
    LW_SAFE_FREE_STRING(pszDnsDomainName);
    ADCacheSafeFreeObject(&pGroupObj);
    LwFreeStringArray(ppszLDAPValues, dwSidCount);
    LsaDmLdapClose(pConn);

    return dwError;

error:
    *psCount = 0;
    *pppResults = NULL;

    LSA_LOG_ERROR("Failed to find group's members of objectSid=%s. [error code:%u]",
                  LSA_SAFE_LOG_STRING(pszSid), dwError);

    ADCacheSafeFreeObjectList((DWORD)sFoundCount, &ppResults);
    goto cleanup;
}
Пример #20
0
BOOLEAN FindSshAndConfig(
        PCSTR pSshOrSshd,
        PSTR *ppSshBinary,
        PSTR *ppSshConfig,
        LWException **ppExc)
{
    DWORD ceError = ERROR_SUCCESS;
    /* Mac OS X stores the configuration in /etc */
    /* CSW ssh on Solaris uses /opt/csw/etc/ssh */
    const PCSTR ppSshConfigPaths[] = {
        "/etc/ssh",
        "/opt/ssh/etc",
        "/usr/local/etc",
        "/etc",
        "/etc/openssh",
        "/usr/openssh/etc",
        "/opt/csw/etc/ssh",
        NULL
    };
    DWORD foundConfigCount = 0;
    PSTR* ppFoundConfigs = NULL;

    /* Solaris Sparc 10 stores sshd in /usr/lib/ssh */
    /* Experian says their sshd is at /usr/openssh/sbin/sshd */
    /* CSW ssh on Solaris uses /opt/csw/sbin/sshd */
    const PCSTR ppSshBinaryPaths[] = {
        "/usr/sbin",
        "/opt/ssh/sbin",
        "/usr/local/sbin",
        "/usr/bin",
        "/opt/ssh/bin",
        "/usr/local/bin",
        "/usr/lib/ssh",
        "/usr/openssh/sbin",
        "/usr/openssh/bin",
        "/opt/csw/sbin",
        "/opt/csw/bin",
        "/opt/ssh/hpux64/sbin",
        NULL
    };
    DWORD foundBinaryCount = 0;
    PSTR* ppFoundBinaries = NULL;
    PSTR pConfigFilename = NULL;
    PSTR pBinaryFilename = NULL;
    PSTR pFoundConfigList = NULL;
    PSTR pFoundBinaryList = NULL;
    DWORD index = 0;

    *ppSshBinary = NULL;
    *ppSshConfig = NULL;

    LW_CLEANUP_CTERR(ppExc, CTAllocateStringPrintf(
        &pConfigFilename, "%s_config", pSshOrSshd));
    LW_CLEANUP_CTERR(ppExc, CTAllocateStringPrintf(
        &pBinaryFilename, "%s", pSshOrSshd));

    ceError = LwFindFilesInPaths(
                    pConfigFilename,
                    LWFILE_REGULAR,
                    ppSshConfigPaths,
                    &foundConfigCount,
                    &ppFoundConfigs);
    LW_CLEANUP_CTERR(ppExc, ceError);

    ceError = LwRemoveDuplicateInodes(
                    &foundConfigCount,
                    ppFoundConfigs);
    LW_CLEANUP_CTERR(ppExc, ceError);

    ceError = LwFindFilesInPaths(
                    pBinaryFilename,
                    LWFILE_REGULAR,
                    ppSshBinaryPaths,
                    &foundBinaryCount,
                    &ppFoundBinaries);
    LW_CLEANUP_CTERR(ppExc, ceError);

    ceError = LwRemoveDuplicateInodes(
                    &foundBinaryCount,
                    ppFoundBinaries);
    LW_CLEANUP_CTERR(ppExc, ceError);

    // Ssh version A.04.40.005 on HP-UX Itanimum has these paths:
    //  /opt/ssh/hpux64/sbin/sshd (ELF-64 IA64)
    //  /opt/ssh/sbin/sshd (ELF-32 IA64)
    //  /usr/sbin/sshd (symlink to /opt/ssh/hpux64/sbin/sshd)
    //
    // Ssh version A.04.30.007 on HP-UX Itanimum has these paths:
    //  /opt/ssh/hpux64/sbin/sshd (ELF-64 IA64)
    //  /opt/ssh/sbin/sshd (ELF-32 IA64)
    //  /usr/sbin/sshd (symlink to /opt/ssh/sbin/sshd)
    //
    // Both files point to the same config path. An exception must exist for
    // this case since the inodes are different for the two architectures.
    //
    // The symlink at /usr/sbin/sshd wins the duplication removal process. So
    // if it is found, the other path must be removed.
    
    for (index = 0; index < foundBinaryCount; index++)
    {
        if (!strcmp(ppFoundBinaries[index], "/usr/sbin/sshd"))
        {
            // Remove /opt/ssh/sbin/sshd or /opt/ssh/hpux64/sbin/sshd if they
            // are in the list
            for (index = 0; index < foundBinaryCount; index++)
            {
                if (!strcmp(ppFoundBinaries[index], "/opt/ssh/sbin/sshd") ||
                    !strcmp(ppFoundBinaries[index],
                        "/opt/ssh/hpux64/sbin/sshd"))
                {
                    LW_SAFE_FREE_STRING(ppFoundBinaries[index]);
                    memmove(&ppFoundBinaries[index],
                            &ppFoundBinaries[index+1],
                            (foundBinaryCount - index - 1) *
                                sizeof(ppFoundBinaries[index]));
                    foundBinaryCount--;
                    break;
                }
            }
            break;
        }
    }

    if ((foundConfigCount | foundBinaryCount) > 0 && foundConfigCount != foundBinaryCount)
    {
        ceError = CombinePaths(
                        foundConfigCount,
                        ppFoundConfigs,
                        &pFoundConfigList);
        LW_CLEANUP_CTERR(ppExc, ceError);

        ceError = CombinePaths(
                        foundBinaryCount,
                        ppFoundBinaries,
                        &pFoundBinaryList);
        LW_CLEANUP_CTERR(ppExc, ceError);

        if ((foundConfigCount | foundBinaryCount) == 1)
        {
            ceError = ERROR_FILE_NOT_FOUND;
        }
        else
        {
            ceError = ERROR_DUPLICATE_SERVICE_NAME;
        }

        LW_RAISE_EX(ppExc, ceError,
                "Unable to find ssh binary",
"A %s config file was at %s, and a %s binary file was found at %s. Exactly one config file and one binary must exist on the system in a standard location. Uninstall any unused copies of ssh.",
                pSshOrSshd,
                pFoundConfigList,
                pSshOrSshd,
                pFoundBinaryList);
    }

    if (foundConfigCount == 1)
    {
        DJ_LOG_INFO("Found config file %s", ppFoundConfigs[0]);
        *ppSshConfig = ppFoundConfigs[0];
        ppFoundConfigs[0] = NULL;
    }
    if (foundBinaryCount == 1)
    {
        DJ_LOG_INFO("Found binary %s", ppFoundBinaries[0]);
        *ppSshBinary = ppFoundBinaries[0];
        ppFoundBinaries[0] = NULL;
    }

cleanup:
    if (ppFoundConfigs)
    {
        LwFreeStringArray(
                ppFoundConfigs,
                foundConfigCount);
    }
    if (ppFoundBinaries)
    {
        LwFreeStringArray(
                ppFoundBinaries,
                foundBinaryCount);
    }
    LW_SAFE_FREE_STRING(pConfigFilename);
    LW_SAFE_FREE_STRING(pBinaryFilename);
    LW_SAFE_FREE_STRING(pFoundConfigList);
    LW_SAFE_FREE_STRING(pFoundBinaryList);
    return (foundConfigCount == 1);
}
Пример #21
0
static
DWORD
LsaGetGroupsForUserBySid(
    IN HANDLE hLsaConnection,
    IN PCSTR pszSid,
    IN LSA_FIND_FLAGS FindFlags,
    IN DWORD dwGroupInfoLevel,
    OUT PDWORD pdwGroupsFound,
    OUT PVOID** pppGroupInfoList
    )
{
    DWORD dwError = 0;
    DWORD dwGroupSidCount = 0;
    PSTR* ppszGroupSids = 0;
    LSA_QUERY_LIST QueryList;
    PLSA_SECURITY_OBJECT* ppObjects = NULL;
    DWORD dwObjectsUsed = 0;
    DWORD dwInfoCount = 0;
    PVOID* ppGroupInfo = NULL;

    dwError = LsaQueryMemberOf(
        hLsaConnection,
        NULL,
        FindFlags,
        1,
        (PSTR*) &pszSid,
        &dwGroupSidCount,
        &ppszGroupSids);
    BAIL_ON_LSA_ERROR(dwError);

    if (dwGroupSidCount == 0)
    {
        *pdwGroupsFound = 0;
        *pppGroupInfoList = NULL;
    }
    else
    {
        QueryList.ppszStrings = (PCSTR*) ppszGroupSids;
        
        dwError = LsaFindObjects(
            hLsaConnection,
            NULL,
            FindFlags,
            LSA_OBJECT_TYPE_GROUP,
            LSA_QUERY_TYPE_BY_SID,
            dwGroupSidCount,
            QueryList,
            &ppObjects);
        BAIL_ON_LSA_ERROR(dwError);

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

        dwError = LsaMarshalGroupInfoList(
            hLsaConnection,
            FindFlags,
            dwGroupSidCount,
            ppObjects,
            dwGroupInfoLevel,
            dwGroupSidCount,
            ppGroupInfo,
            &dwObjectsUsed,
            &dwInfoCount);
        BAIL_ON_LSA_ERROR(dwError);

        if (dwInfoCount == 0)
        {
             *pdwGroupsFound = 0;
             *pppGroupInfoList = NULL;

             LW_SAFE_FREE_MEMORY(ppObjects);
        }
        else
        {
            *pdwGroupsFound = dwInfoCount;
            *pppGroupInfoList = ppGroupInfo;
        }
    }

cleanup:

    if (ppObjects)
    {
        LsaUtilFreeSecurityObjectList(dwGroupSidCount, ppObjects);
    }

    if (ppszGroupSids)
    {
        LwFreeStringArray(ppszGroupSids, dwGroupSidCount);
    }

    return dwError;

error:

    *pdwGroupsFound = 0;
    *pppGroupInfoList = NULL;

    if (ppGroupInfo)
    {
        LsaFreeGroupInfoList(dwGroupInfoLevel, ppGroupInfo, dwInfoCount);
    }

    goto cleanup;
}