Пример #1
0
void
ADCacheSafeFreeObjectList(
        size_t sCount,
        PLSA_SECURITY_OBJECT** pppObjectList)
{
    if (*pppObjectList != NULL)
    {
        size_t sIndex;
        for (sIndex = 0; sIndex < sCount; sIndex++)
        {
            ADCacheSafeFreeObject(&(*pppObjectList)[sIndex]);
        }
        LW_SAFE_FREE_MEMORY(*pppObjectList);
    }
}
Пример #2
0
DWORD
AD_GroupExpansionDataGetNextGroupToExpand(
    IN PLSA_AD_GROUP_EXPANSION_DATA pExpansionData,
    OUT PLSA_SECURITY_OBJECT* ppGroupToExpand,
    OUT PDWORD pdwGroupToExpandDepth
    )
{
    DWORD dwError = 0;
    PLSA_SECURITY_OBJECT pGroupToExpand = NULL;
    DWORD dwGroupToExpandDepth = 0;
    const LW_HASH_ENTRY* pHashEntry = NULL;

    dwError = pExpansionData->dwLastError;
    BAIL_ON_LSA_ERROR(dwError);

    if (pExpansionData->pGroupsToExpand->sCount < 1)
    {
        // Nothing to return
        goto cleanup;
    }

    if (pExpansionData->bIsIteratorInitialized)
    {
        pHashEntry = LwHashNext(&pExpansionData->GroupsToExpandIterator);
    }

    if (!pHashEntry)
    {
        // Either the iterator is not initialized or we
        // reached the end of the hash table and need to start over.
        dwError = LwHashGetIterator(
                    pExpansionData->pGroupsToExpand,
                    &pExpansionData->GroupsToExpandIterator);
        BAIL_ON_LSA_ERROR(dwError);

        pExpansionData->bIsIteratorInitialized = TRUE;

        pHashEntry = LwHashNext(&pExpansionData->GroupsToExpandIterator);
        if (!pHashEntry)
        {
            dwError = LW_ERROR_INTERNAL;
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    pGroupToExpand = (PLSA_SECURITY_OBJECT) pHashEntry->pKey;
    dwGroupToExpandDepth = (size_t) pHashEntry->pValue;
    dwGroupToExpandDepth++;

    // Move the object to the expanded list.  Note that the object is
    // not necessarily expanded yet, but we must remove it from
    // the "to expand" list.  It does not hurt to track it in the
    // "expanded" list.

    dwError = LwHashSetValue(pExpansionData->pExpandedGroups,
                              pGroupToExpand,
                              (PVOID)(size_t)dwGroupToExpandDepth);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwHashRemoveKey(pExpansionData->pGroupsToExpand, pGroupToExpand);
    if (dwError)
    {
        LSA_LOG_DEBUG("ASSERT: cannot fail");
    }
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    *ppGroupToExpand = pGroupToExpand;
    *pdwGroupToExpandDepth = dwGroupToExpandDepth;

    return dwError;

error:
    ADCacheSafeFreeObject(&pGroupToExpand);
    dwGroupToExpandDepth = 0;

    if (dwError && !pExpansionData->dwLastError)
    {
        pExpansionData->dwLastError = dwError;
    }
    goto cleanup;
}
Пример #3
0
DWORD
AD_GroupExpansionDataAddExpansionResults(
    IN PLSA_AD_GROUP_EXPANSION_DATA pExpansionData,
    IN DWORD dwExpandedGroupDepth,
    IN OUT size_t* psMembersCount,
    IN OUT PLSA_SECURITY_OBJECT** pppMembers
    )
{
    DWORD dwError = 0;
    size_t sMembersCount = *psMembersCount;
    PLSA_SECURITY_OBJECT* ppMembers = *pppMembers;

    dwError = pExpansionData->dwLastError;
    BAIL_ON_LSA_ERROR(dwError);

    if (dwExpandedGroupDepth > pExpansionData->dwMaxDepth)
    {
        // This should never happen
        dwError = LW_ERROR_INTERNAL;
        BAIL_ON_LSA_ERROR(dwError);
    }

    if ((sMembersCount + pExpansionData->pUsers->sCount) * 2 >
            pExpansionData->pUsers->sTableSize)
    {
        dwError = LwHashResize(
                        pExpansionData->pUsers,
                        (sMembersCount +
                             pExpansionData->pUsers->sCount + 10) * 3);
        BAIL_ON_LSA_ERROR(dwError);
    }

    if ((sMembersCount + pExpansionData->pGroupsToExpand->sCount) * 2 >
            pExpansionData->pGroupsToExpand->sTableSize)
    {
        dwError = LwHashResize(
                        pExpansionData->pGroupsToExpand,
                        (sMembersCount +
                             pExpansionData->pGroupsToExpand->sCount + 10) * 3);
        BAIL_ON_LSA_ERROR(dwError);
    }

    for (; sMembersCount > 0; sMembersCount--)
    {
        PLSA_SECURITY_OBJECT pCurrentMember = ppMembers[sMembersCount-1];

        if (!pCurrentMember)
        {
            continue;
        }

        if (pCurrentMember->type == LSA_OBJECT_TYPE_USER)
        {
            if (!LwHashExists(pExpansionData->pUsers,
                               ppMembers[sMembersCount-1]))
            {
                dwError = LwHashSetValue(
                    pExpansionData->pUsers,
                    ppMembers[sMembersCount-1],
                    (PVOID)(size_t)dwExpandedGroupDepth);
                BAIL_ON_LSA_ERROR(dwError);
                ppMembers[sMembersCount-1] = NULL;
            }
            else
            {
                ADCacheSafeFreeObject(&ppMembers[sMembersCount-1]);
            }
        }
        else if (pCurrentMember->type == LSA_OBJECT_TYPE_GROUP)
        {
            if (dwExpandedGroupDepth >= pExpansionData->dwMaxDepth)
            {
                pExpansionData->bDiscardedDueToDepth = TRUE;
                ADCacheSafeFreeObject(&ppMembers[sMembersCount-1]);
            }
            else if (LwHashExists(pExpansionData->pExpandedGroups,
                                   pCurrentMember) ||
                     LwHashExists(pExpansionData->pGroupsToExpand,
                                   pCurrentMember))
            {
                ADCacheSafeFreeObject(&ppMembers[sMembersCount-1]);
            }
            else
            {
                dwError = LwHashSetValue(
                            pExpansionData->pGroupsToExpand,
                            ppMembers[sMembersCount-1],
                            (PVOID)(size_t)dwExpandedGroupDepth);
                BAIL_ON_LSA_ERROR(dwError);
                ppMembers[sMembersCount-1] = NULL;
            }
        }
        else
        {
            // some other kind of object -- should not happen
            ADCacheSafeFreeObject(&ppMembers[sMembersCount-1]);
        }
    }

cleanup:
    if (ppMembers && (sMembersCount == 0))
    {
        ADCacheSafeFreeObjectList(sMembersCount, &ppMembers);
    }
    *psMembersCount = sMembersCount;
    *pppMembers = ppMembers;
    return dwError;

error:
    ADCacheSafeFreeObjectList(sMembersCount, &ppMembers);
    if (dwError && !pExpansionData->dwLastError)
    {
        pExpansionData->dwLastError = dwError;
    }
    goto cleanup;
}
Пример #4
0
DWORD
LsaAdBatchMarshal(
    IN PLSA_AD_PROVIDER_STATE pState,
    IN PCSTR pszDnsDomainName,
    IN PCSTR pszNetbiosDomainName,
    IN OUT PLSA_AD_BATCH_ITEM pItem,
    OUT PLSA_SECURITY_OBJECT* ppObject
    )
{
    DWORD dwError = 0;
    PAD_PROVIDER_DATA pProviderData = pState->pProviderData;
    PLSA_SECURITY_OBJECT pObject = NULL;

    // To marshal, the following conditions to be satisfied:
    //
    // 1) Object must have user or group type.
    // 2) Object must have real information.
    if ((LSA_AD_BATCH_OBJECT_TYPE_UNDEFINED == pItem->ObjectType) ||
        !IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_REAL))
    {
        PCSTR pszType = NULL;
        BOOLEAN bIsString = FALSE;
        PCSTR pszString = NULL;
        DWORD dwId = 0;

        LsaAdBatchQueryTermDebugInfo(
                &pItem->QueryTerm,
                &pszType,
                &bIsString,
                &pszString,
                &dwId);
        if (bIsString)
        {
            LSA_LOG_VERBOSE("Did not find object by %s '%s'", pszType, pszString);
        }
        else
        {
            LSA_LOG_VERBOSE("Did not find object by %s %u", pszType, dwId);
        }
        dwError = 0;
        goto cleanup;
    }

    if (!IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_HAVE_PSEUDO) &&
        !LsaAdBatchIsUnprovisionedMode(pProviderData))
    {
        SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED);
    }

#if 0
    // Disable in svn commit r45217
    // Fix regression that could cause NULL objects to be returned by LsaEnumObjects():
    // Don't filter out disabled objects when enumerating in the AD provider - If we
    // ever do filter out objects, don't leave NULLs in the array
    //
    // This code also has to be disabled for to support returning non-provisioned objects
    // (computers, users, ...) that need an access token for use in Likewise-CIFS

    if (IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED) &&
        (pItem->ObjectType != LSA_AD_BATCH_OBJECT_TYPE_GROUP))
    {
        // Skip any disabled non-groups.
        LSA_LOG_VERBOSE("Skipping disabled object (sid = %s, name = %s\\%s)",
                LSA_SAFE_LOG_STRING(pItem->pszSid),
                LSA_SAFE_LOG_STRING(pszNetbiosDomainName),
                LSA_SAFE_LOG_STRING(pItem->pszSamAccountName));
        dwError = 0;
        goto cleanup;
    }
#endif

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

    pObject->version.qwDbId = -1;

    pObject->enabled = !IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED);

    // Transfer the data
    LSA_XFER_STRING(pItem->pszSid, pObject->pszObjectSid);
    LSA_XFER_STRING(pItem->pszSamAccountName, pObject->pszSamAccountName);
    LSA_XFER_STRING(pItem->pszDn, pObject->pszDN);

    dwError = LwAllocateString(
                    pszNetbiosDomainName,
                    &pObject->pszNetbiosDomainName);
    BAIL_ON_LSA_ERROR(dwError);

    switch (pItem->ObjectType)
    {
        case LSA_AD_BATCH_OBJECT_TYPE_USER:
            pObject->type = LSA_OBJECT_TYPE_USER;
            dwError = LsaAdBatchMarshalUserInfo(
                            pState,
                            &pItem->UserInfo,
                            &pObject->userInfo,
                            pszDnsDomainName,
                            pObject->pszNetbiosDomainName,
                            pObject->pszSamAccountName,
                            pObject->pszObjectSid);
            BAIL_ON_LSA_ERROR(dwError);

            pObject->userInfo.bIsAccountInfoKnown =
                IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_ACCOUNT_INFO_KNOWN);
            break;

        case LSA_AD_BATCH_OBJECT_TYPE_GROUP:
            pObject->type = LSA_OBJECT_TYPE_GROUP;
            dwError = LsaAdBatchMarshalGroupInfo(
                            pProviderData,
                            &pItem->GroupInfo,
                            &pObject->groupInfo,
                            pszDnsDomainName,
                            pObject->pszNetbiosDomainName,
                            pObject->pszSamAccountName,
                            pObject->pszObjectSid);
            BAIL_ON_LSA_ERROR(dwError);
            break;

        default:
            LSA_ASSERT(FALSE);
            dwError = LW_ERROR_INTERNAL;
            BAIL_ON_LSA_ERROR(dwError);
    }

cleanup:
    *ppObject = pObject;
    return dwError;

error:
    if (pObject)
    {
        ADCacheSafeFreeObject(&pObject);
    }
    goto cleanup;
}
Пример #5
0
DWORD
ADCacheDuplicateObject(
    OUT PLSA_SECURITY_OBJECT* ppDest,
    IN PLSA_SECURITY_OBJECT pSrc
    )
{
    DWORD dwError = 0;
    PLSA_SECURITY_OBJECT pDest = NULL;

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

    pDest->version = pSrc->version;

    dwError = LwAllocateString(
                    pSrc->pszObjectSid,
                    &pDest->pszObjectSid);
    BAIL_ON_LSA_ERROR(dwError);

    pDest->enabled = pSrc->enabled;

    dwError = LwAllocateString(
                    pSrc->pszNetbiosDomainName,
                    &pDest->pszNetbiosDomainName);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                    pSrc->pszSamAccountName,
                    &pDest->pszSamAccountName);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwStrDupOrNull(
                    pSrc->pszDN,
                    &pDest->pszDN);
    BAIL_ON_LSA_ERROR(dwError);

    pDest->type = pSrc->type;

    if (pDest->type == LSA_OBJECT_TYPE_USER)
    {
        pDest->userInfo.uid = pSrc->userInfo.uid;
        pDest->userInfo.gid = pSrc->userInfo.gid;

        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszPrimaryGroupSid,
                        &pDest->userInfo.pszPrimaryGroupSid);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszUPN,
                        &pDest->userInfo.pszUPN);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszAliasName,
                        &pDest->userInfo.pszAliasName);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszUnixName,
                        &pDest->userInfo.pszUnixName);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszPasswd,
                        &pDest->userInfo.pszPasswd);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszGecos,
                        &pDest->userInfo.pszGecos);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszShell,
                        &pDest->userInfo.pszShell);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszHomedir,
                        &pDest->userInfo.pszHomedir);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszWindowsHomeFolder,
                        &pDest->userInfo.pszWindowsHomeFolder);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszLocalWindowsHomeFolder,
                        &pDest->userInfo.pszLocalWindowsHomeFolder);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwStrDupOrNull(
                        pSrc->userInfo.pszDisplayName,
                        &pDest->userInfo.pszDisplayName);
        BAIL_ON_LSA_ERROR(dwError);

        pDest->userInfo.qwPwdLastSet = pSrc->userInfo.qwPwdLastSet;
        pDest->userInfo.qwPwdExpires = pSrc->userInfo.qwPwdExpires;
        pDest->userInfo.qwAccountExpires = pSrc->userInfo.qwAccountExpires;

        pDest->userInfo.bIsGeneratedUPN = pSrc->userInfo.bIsGeneratedUPN;
        pDest->userInfo.bIsAccountInfoKnown = pSrc->userInfo.bIsAccountInfoKnown;
        pDest->userInfo.bPasswordExpired = pSrc->userInfo.bPasswordExpired;
        pDest->userInfo.bPasswordNeverExpires = pSrc->userInfo.bPasswordNeverExpires;
        pDest->userInfo.bPromptPasswordChange = pSrc->userInfo.bPromptPasswordChange;
        pDest->userInfo.bUserCanChangePassword = pSrc->userInfo.bUserCanChangePassword;
        pDest->userInfo.bAccountDisabled = pSrc->userInfo.bAccountDisabled;
        pDest->userInfo.bAccountExpired = pSrc->userInfo.bAccountExpired;
        pDest->userInfo.bAccountLocked = pSrc->userInfo.bAccountLocked;
    }
    else if (pDest->type == LSA_OBJECT_TYPE_GROUP)
    {
        pDest->groupInfo.gid = pSrc->groupInfo.gid;

        dwError = LwStrDupOrNull(
                        pSrc->groupInfo.pszAliasName,
                        &pDest->groupInfo.pszAliasName);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->groupInfo.pszUnixName,
                        &pDest->groupInfo.pszUnixName);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwStrDupOrNull(
                        pSrc->groupInfo.pszPasswd,
                        &pDest->groupInfo.pszPasswd);
        BAIL_ON_LSA_ERROR(dwError);
    }

    *ppDest = pDest;

cleanup:
    return dwError;

error:
    ADCacheSafeFreeObject(&pDest);
    *ppDest = NULL;
    goto cleanup;
}
Пример #6
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;
}