Example #1
0
long
LWIAttrValDataQuery::QueryComputerListInformation(LWIQuery* pQuery, char* pszAttribute, char* pszPattern)
{
    long macError = eDSNoErr;
    LWIAttrLookup::Index_t attrIndex = LWIAttrLookup::idx_unknown;

    attrIndex = LWIAttrLookup::GetIndex(pszAttribute);
    switch (attrIndex)
    {
        case LWIAttrLookup::idx_kDSNAttrRecordName:
            macError = pQuery->QueryComputerListInformationByName(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        case LWIAttrLookup::idx_kDSNAttrComputers:
            if (!strcmp(pszPattern, "localhost"))
            {
                macError = pQuery->QueryComputerListInformationByName(kDSRecordsAll);
                GOTO_CLEANUP_ON_MACERROR(macError);
                break;
            }
        default:
#ifdef SHOW_DEBUG_SPEW
            LOG("Unsupported attribute index for group - %d", attrIndex);
#endif
            macError = eDSNoErr;
            break;
    }

cleanup:

    return macError;
}
Example #2
0
long
LWIAttrValDataQuery::QueryGroupInformation(LWIQuery* pQuery, char* pszAttribute, char* pszPattern)
{
    long macError = eDSNoErr;
    LWIAttrLookup::Index_t attrIndex = LWIAttrLookup::idx_unknown;

    attrIndex = LWIAttrLookup::GetIndex(pszAttribute);
    switch (attrIndex)
    {
        case LWIAttrLookup::idx_kDSNAttrRecordName:
        case LWIAttrLookup::idx_kDS1AttrDistinguishedName:
            macError = pQuery->QueryGroupInformationByName(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        case LWIAttrLookup::idx_kDSNAttrGroupMembership:
            macError = pQuery->QueryGroupsForUserByName(pszPattern);
            break;
        case LWIAttrLookup::idx_kDSNAttrGroupMembers:
        {
            uid_t uid;
            macError = ExtractUIDFromGeneratedUID(pszPattern, uid);
            GOTO_CLEANUP_ON_MACERROR(macError);

            macError = pQuery->QueryGroupsForUserById(uid);
            GOTO_CLEANUP_ON_MACERROR(macError);

            break;
        }
        case LWIAttrLookup::idx_kDS1AttrPrimaryGroupID:
        {
            gid_t gid = atoi(pszPattern);
            macError = pQuery->QueryGroupInformationById(gid);
            GOTO_CLEANUP_ON_MACERROR(macError);

            break;
        }
        case LWIAttrLookup::idx_kDS1AttrGeneratedUID:
            macError = pQuery->QueryGroupInformationByGeneratedUID(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        default:
#ifdef SHOW_DEBUG_SPEW
            LOG("Unsupported attribute index for group - %d", attrIndex);
#endif
            macError = eDSNoErr;
            break;
    }

cleanup:

    return macError;
}
long
LWIRecTypeLookup::GetVector(tDataListPtr List, PLWIBITVECTOR* ppVector)
{
    int macError = eDSNoErr;
    PLWIBITVECTOR pResult = NULL;
    tDataNodePtr pDataNode = NULL;
    int nNodes = 0;
    Index_t value = idx_unknown;

    macError = LWIMakeBitVector(idx_sentinel, &pResult);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (List != NULL)
    {
       nNodes = dsDataListGetNodeCount(List);

       for (int iNode = 0; iNode < nNodes; iNode++)
       {
           macError = dsDataListGetNodeAlloc(0,
                                             List,
                                             iNode+1,
                                             &pDataNode);
           GOTO_CLEANUP_ON_MACERROR(macError);
           value = GetIndex(pDataNode->fBufferData);
           if (value)
           {
              LWI_BITVECTOR_SET(pResult, value);
           }

           dsDataNodeDeAllocate(NULL, pDataNode);
           pDataNode = NULL;
       }
    }

    *ppVector = pResult;
    pResult = NULL;

cleanup:

    if (pResult)
    {
        LWIFreeBitVector(pResult);
    }

    if (pDataNode)
    {
        dsDataNodeDeAllocate(0, pDataNode);
    }

    return macError;
}
long
LWIRecTypeLookup::GetVector(const char* Item, PLWIBITVECTOR* ppVector)
{
    int macError = eDSNoErr;
    PLWIBITVECTOR pResult = NULL;
    Index_t value = idx_unknown;

    macError = LWIMakeBitVector(idx_sentinel, &pResult);
    GOTO_CLEANUP_ON_MACERROR(macError);

    value = GetIndex(Item);
    if (value)
    {
        LWI_BITVECTOR_SET(pResult, value);
    }

    *ppVector = pResult;
    pResult = NULL;

cleanup:

    if (pResult)
    {
        LWIFreeBitVector(pResult);
    }

    return macError;
}
long LWIRecTypeLookup::Initialize()
{
    long macError = eDSNoErr;

    _dictionary = CFDictionaryCreateMutable(NULL,
                                            0,
                                            &kCFCopyStringDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
    if (!_dictionary)
    {
        macError = eDSAllocationFailed;
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    _INIT_KEY(kDSStdRecordTypeUsers, idx_kDSStdRecordTypeUsers);
    _INIT_KEY(kDSStdRecordTypeGroups, idx_kDSStdRecordTypeGroups);
    _INIT_KEY(kDSStdRecordTypeComputerLists, idx_kDSStdRecordTypeComputerLists);
    _INIT_KEY(kDSStdRecordTypeComputerGroups, idx_kDSStdRecordTypeComputerGroups);
    _INIT_KEY(kDSStdRecordTypeComputers, idx_kDSStdRecordTypeComputers);

cleanup:

    if (macError)
    {
        Cleanup();
    }

    return macError;
}
Example #6
0
static long GetDomainJoinState(PSTR* ppszDomain)
{
    long macError = eDSNoErr;
    PSTR pszDomain = NULL;

    macError = GetCurrentDomain(&pszDomain);
    if (macError)
    {
        // ISSUE-2008/10/07-dalmeida -- Assume not joined?
        macError = eDSNoErr;
    }
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (pszDomain)
    {
        LwStrToUpper(pszDomain);
    }

cleanup:
    if (macError)
    {
        LW_SAFE_FREE_STRING(pszDomain);
        pszDomain = NULL;
    }

    *ppszDomain = pszDomain;

    return macError;
}
long
LWIRecordListQuery::GetRecordEntry(sGetRecordEntry* pGetRecordEntry)
{
    long macError = eDSNoErr;

    LOG_ENTER("fType = %d, fResult = %d, fInNodeRef = %d, fInOutDataBuff = @%p  { len = %d, size = %d }, fInRecEntryIndex = %d, fOutAttrListRef = @%p, fOutRecEntryPtr = @%p",
              pGetRecordEntry->fType,
              pGetRecordEntry->fResult,
              pGetRecordEntry->fInNodeRef,
              pGetRecordEntry->fInOutDataBuff,
              pGetRecordEntry->fInOutDataBuff->fBufferLength,
              pGetRecordEntry->fInOutDataBuff->fBufferSize,
              pGetRecordEntry->fInRecEntryIndex,
              pGetRecordEntry->fOutAttrListRef,
              pGetRecordEntry->fOutRecEntryPtr);

    macError = eNotYetImplemented;
    GOTO_CLEANUP_ON_MACERROR(macError);

cleanup:

    LOG_LEAVE("fInOutDataBuff => { length = %d, size = %d } --> %d",
              pGetRecordEntry->fInOutDataBuff->fBufferLength,
              pGetRecordEntry->fInOutDataBuff->fBufferSize,
              macError);

    return macError;
}
Example #8
0
static
long UnregisterGPONode(
        PCSTR pszDomain,
        PCSTR pszGPOName
	)
{
    long macError = eDSNoErr;
    tDataListPtr nodeNameList = NULL;
    char szChildNodeName[1024];

	if (!pszDomain)
	{
        macError = eDSEmptyParameter;
		GOTO_CLEANUP_ON_MACERROR( macError );
    }

    /* Build up node names for each child node found */
    nodeNameList = dsDataListAllocate(0);
    if ( !nodeNameList )
    {
        macError = eDSAllocationFailed;
        GOTO_CLEANUP_ON_MACERROR( macError );
    }

    memset(szChildNodeName, 0, sizeof(szChildNodeName));
    strcpy(szChildNodeName, PLUGIN_ROOT_PATH);
    strcat(szChildNodeName, "/");
    strcat(szChildNodeName, pszDomain);
    strcat(szChildNodeName, "/");
    strcat(szChildNodeName, pszGPOName);

    macError = dsBuildListFromPathAlloc(0, nodeNameList, szChildNodeName, "/");
    GOTO_CLEANUP_ON_MACERROR( macError );

    macError = DSUnregisterNode(GlobalState.Signature, nodeNameList);

cleanup:

    if (nodeNameList)
    {
        dsDataListDeallocate(0, nodeNameList);
        free(nodeNameList);
    }

    return macError;
}
Example #9
0
static long UpdateGPONodes(
        PCSTR pszDomain,
        const PGROUP_POLICY_OBJECT pCurrentGPOs
    )
{
    long macError = eDSNoErr;
    PGROUP_POLICY_OBJECT pDeletedGPOs = NULL;
    PGROUP_POLICY_OBJECT pNewGPOs = NULL;
    PGROUP_POLICY_OBJECT pTemp = NULL;

    macError = GPAComputeDeletedList(
            pCurrentGPOs,
            GlobalState.pGPOs,
            &pDeletedGPOs);
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = GPAComputeDeletedList(
            GlobalState.pGPOs,
            pCurrentGPOs,
            &pNewGPOs);
    GOTO_CLEANUP_ON_MACERROR(macError);

    pTemp = pDeletedGPOs;
    while (pTemp)
    {
        LOG("Removing GPO directory node (%s)", pTemp->pszDisplayName);
        UnregisterGPONode(GlobalState.pszRealm, pTemp->pszDisplayName);
        pTemp = pTemp->pNext;
    }

    pTemp = pNewGPOs;
    while (pTemp)
    {
        LOG("Adding GPO directory node (%s)", pTemp->pszDisplayName);
        RegisterGPONode(pszDomain, pTemp->pszDisplayName);
        pTemp = pTemp->pNext;
    }

cleanup:

    GPA_SAFE_FREE_GPO_LIST(pDeletedGPOs);
    GPA_SAFE_FREE_GPO_LIST(pNewGPOs);

    return macError;
}
Example #10
0
long
LWIAttrValDataQuery::QueryComputerInformation(LWIQuery* pQuery, char* pszAttribute, char* pszPattern)
{
    long macError = eDSNoErr;
    LWIAttrLookup::Index_t attrIndex = LWIAttrLookup::idx_unknown;

    attrIndex = LWIAttrLookup::GetIndex(pszAttribute);
    switch (attrIndex)
    {
        case LWIAttrLookup::idx_kDSNAttrRecordName:
            macError = pQuery->QueryComputerInformationByName(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        case LWIAttrLookup::idx_kDS1AttrENetAddress:
            macError = pQuery->QueryComputerInformationByENetAddress(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        case LWIAttrLookup::idx_kDSNAttrIPAddress:
            macError = pQuery->QueryComputerInformationByIPAddress(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        case LWIAttrLookup::idx_kDS1AttrGeneratedUID:
            macError = pQuery->QueryComputerInformationByGeneratedUID(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        default:
#ifdef SHOW_DEBUG_SPEW
            LOG("Unsupported attribute index for group - %d", attrIndex);
#endif
            macError = eDSNoErr;
            break;
    }

cleanup:

    return macError;
}
Example #11
0
static long GetGPONodes(
        PCSTR pszDomain,
        PGROUP_POLICY_OBJECT *ppCurrentGPOs,
        PBOOLEAN pbOffline
    )
{
    long macError = eDSNoErr;
    PGROUP_POLICY_OBJECT pCurrentGPOs = NULL;
    BOOLEAN bOffline = false;

    if (pszDomain)
    {
        macError = EnumWorkgroupManagerEnabledGPOs(pszDomain, &pCurrentGPOs);
        if (macError == eDSReceiveFailed ||
                macError == eDSBogusServer ||
                macError == eDSSendFailed ||
            macError == eDSAuthMasterUnreachable)
        {
            LOG("EnumWorkgroupManagerEnableGPOs failed %d, treating as okay", macError);
            bOffline = true;
            macError = eDSNoErr;
        }
        else if (macError)
        {
            LOG("EnumWorkgroupManagerEnableGPOs failed unexpectedly (error = %d)", macError);
            GOTO_CLEANUP_ON_MACERROR(macError);
        }
    }

    *pbOffline = bOffline;
    *ppCurrentGPOs = pCurrentGPOs;
    pCurrentGPOs = NULL;

cleanup:

    GPA_SAFE_FREE_GPO_LIST(pCurrentGPOs);

    return macError;
}
long
LWIRecordListQuery::ReleaseContinueData(IN OUT sReleaseContinueData* pReleaseContinueData)
{
    long macError = eDSNoErr;
    LWIQuery* pQuery = NULL;

    LOG_ENTER("fType = %d, fResult = %d, fInNodeRef = %d, "
              "fInContinueData = %d",
              pReleaseContinueData->fType,
              pReleaseContinueData->fResult,
              pReleaseContinueData->fInDirReference,
              pReleaseContinueData->fInContinueData);

    if ((UInt32)pReleaseContinueData->fInContinueData == SPECIAL_DS_CONTINUE_HANDLE)
    {
        // Special continue handle value, no actual cached query for this one.
        goto cleanup;
    }

    macError = GetQueryFromContextList(pReleaseContinueData->fInContinueData, &pQuery);
    if (macError == eDSNoErr && pQuery)
    {
        /* This is our continue value that we used. Free the pQuery object. */
        pQuery->Release();
    }
    else
    {
        macError = eDSInvalidContinueData;
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

cleanup:

    LOG_LEAVE("fInContinueData = %d, macError = %d",
              pReleaseContinueData->fInContinueData,
              macError);

    return macError;
}
long
LWIRecordListQuery::Test(
    IN const char* DsPath,
    IN tDataListPtr RecNameList,
    IN tDirPatternMatch PatternMatch,
    IN tDataListPtr RecTypeList,
    IN tDataListPtr AttribTypeList,
    IN dsBool AttribInfoOnly,
    IN unsigned long Size
    )
{
    long macError = eDSNoErr;
    tDirReference dirRef = 0;
    tDirNodeReference dirNode = 0;
    tDataListPtr dirNodeName = NULL;
    tDataBufferPtr pData = NULL;
    UInt32 outCount;
    tContextData continueData = NULL;

    LOG_ENTER("");

    macError = dsOpenDirService( &dirRef );
    GOTO_CLEANUP_ON_MACERROR( macError );

    pData = dsDataBufferAllocate(dirRef, Size);
    if (!pData)
    {
        macError = eDSAllocationFailed;
        GOTO_CLEANUP();
    }

    dirNodeName = dsBuildFromPath( dirRef, DsPath, "/" );
    if (!dirNodeName)
    {
        macError = eDSAllocationFailed;
        GOTO_CLEANUP();
    }

    macError = dsOpenDirNode( dirRef, dirNodeName, &dirNode );
    GOTO_CLEANUP_ON_MACERROR( macError );

    macError = dsGetRecordList( dirNode,
                                pData,
                                RecNameList,
                                PatternMatch,
                                RecTypeList,
                                AttribTypeList,
                                AttribInfoOnly,
                                &outCount,
                                &continueData);
    GOTO_CLEANUP_ON_MACERROR( macError );

    LOG("Got %d records", outCount);

    if (pData->fBufferLength > 0)
    {
        LOG_BUFFER(pData->fBufferData, pData->fBufferLength);
    }

cleanup:

    if ( pData )
    {
        dsDataBufferDeAllocate( dirRef, pData );
    }

    if ( dirNodeName )
    {
        dsDataListDeallocate( dirRef, dirNodeName );
    }

    if ( dirNode )
    {
        dsCloseDirNode( dirNode );
    }

    if ( dirRef )
    {
        dsCloseDirService( dirRef );
    }

    LOG_LEAVE("--> %d", macError);

    return macError;
}
Example #14
0
/*
 * This must be called between GS_ACQUIRE_EXCLUSIVE() and GS_RELEASE().
 */
static long Activate(void)
{
    long macError = eDSNoErr;
    tDataListPtr nodeNameList = NULL;
    BOOLEAN bIsStarted = FALSE;

    LOG_ENTER("");

    LOG("Verify that LSASS service is operational");
    GlobalState.IsStartupComplete = false;

    // Verify that startup has completed successfully for lsass service.
    GetLsaStatus(&bIsStarted);
    if (bIsStarted)
    {
        LOG("LSASS service is operational");
        GlobalState.IsStartupComplete = true;
    }

    if ( !GlobalState.DsRoot )
    {
        macError = dsOpenDirService( &GlobalState.DsRoot );
        GOTO_CLEANUP_ON_MACERROR( macError );
    }

    if ( !GlobalState.NodeNameList )
    {
        nodeNameList = dsDataListAllocate(0);
        if ( !nodeNameList )
        {
            macError = eDSAllocationFailed;
            GOTO_CLEANUP_ON_MACERROR( macError );
        }

        macError = dsBuildListFromPathAlloc(0, nodeNameList, PLUGIN_ROOT_PATH, "/");
        GOTO_CLEANUP_ON_MACERROR( macError );

        macError = DSRegisterNode(GlobalState.Signature, nodeNameList, kDirNodeType);
        GOTO_CLEANUP_ON_MACERROR( macError );

        GlobalState.NodeNameList = nodeNameList;
        nodeNameList = NULL;
    }

    if ( !GlobalState.NodeDictionary )
    {
        GlobalState.NodeDictionary = CFDictionaryCreateMutable(NULL, 0,
                &kCFCopyStringDictionaryKeyCallBacks,
                &kCFTypeDictionaryValueCallBacks);
    }

cleanup:
    if (nodeNameList)
    {
        dsDataListDeallocate(0, nodeNameList);
        free(nodeNameList);
    }

    if (macError)
    {
        long localMacError = Deactivate();
        if (localMacError)
        {
            LOG_ERROR("Unexpected error: %d", localMacError);
        }
    }

    LOG_LEAVE("--> %d", macError);
    return macError;
}
Example #15
0
long
CreateLWIComputer(
    PCSTR szName,
    PCSTR szShortname,
    PCSTR szComment,
    PCSTR szGUID,
    PCSTR szEthernetID,
    PCSTR szIPaddress,
    PCSTR szKeyword,
	PMCXVALUE pMCXValues,
    PLWICOMPUTER* ppLWIComputer
    )
{
    long macError = eDSNoErr;
    PLWICOMPUTER pComputer = NULL;

    macError = LwAllocateMemory(sizeof(LWICOMPUTER), (PVOID*)&pComputer);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (szName)
    {
        macError = LwAllocateString(szName, &pComputer->name);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (szShortname)
    {
        macError = LwAllocateString(szShortname, &pComputer->shortname);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (szComment)
    {
        macError = LwAllocateString(szComment, &pComputer->comment);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (szGUID)
    {
        macError = LwAllocateString(szGUID, &pComputer->guid);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (szEthernetID)
    {
        macError = LwAllocateString(szEthernetID, &pComputer->ethernetID);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (szIPaddress)
    {
        macError = LwAllocateString(szIPaddress, &pComputer->IPaddress);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (szKeyword)
    {
        macError = LwAllocateMemory(sizeof(pComputer->keywords[0]) * 2, (PVOID*)&pComputer->keywords);
        GOTO_CLEANUP_ON_MACERROR(macError);

        macError = LwAllocateString(szKeyword, &pComputer->keywords[0]);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pMCXValues)
    {
        macError = CopyMCXValueList(pMCXValues, &pComputer->pMCXValues);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    *ppLWIComputer = pComputer;
    pComputer = NULL;

cleanup:

    if (pComputer)
    {
        FreeLWIComputer(pComputer);
    }

    return macError;
}
Example #16
0
static long RefreshGPONodes(void)
{
    long macError = eDSNoErr;
    PGROUP_POLICY_OBJECT pCurrentGPOs = NULL;
    PGROUP_POLICY_OBJECT pDeletedGPOs = NULL;
    PGROUP_POLICY_OBJECT pNewGPOs = NULL;
    PGROUP_POLICY_OBJECT pTemp = NULL;
    PSTR pszDomain = NULL;
    bool isAcquired = false;

    macError = GetDomainJoinState(&pszDomain);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (pszDomain)
    {
        if (pszDomain && GlobalState.pszRealm &&
            strcmp(pszDomain, GlobalState.pszRealm))
        {
            LOG("Unexpected domain name change: '%s' -> '%s'",
                pszDomain, GlobalState.pszRealm);
            // ISSUE-2008/10/07-dalmeida -- To support this, we would
            // need to unregister all nodes.
            macError = eDSOperationFailed;
            GOTO_CLEANUP_ON_MACERROR(macError);
        }

        macError = EnumWorkgroupManagerEnabledGPOs(pszDomain, &pCurrentGPOs);
        if (macError == eDSReceiveFailed ||
            macError == eDSBogusServer ||
            macError == eDSSendFailed ||
            macError == eDSAuthMasterUnreachable)
        {
            LOG("EnumWorkgroupManagerEnableGPOs failed %d, treating as okay", macError);
            GlobalState.fDomainControllerNotAvailable = true;
            GlobalState.OfflineTimerCount = 1;
            macError = eDSNoErr;
        }

        if (macError)
        {
            LOG("EnumWorkgroupManagerEnableGPOs failed unexpectedly (error = %d)", macError);
            GOTO_CLEANUP_ON_MACERROR(macError);
        }
    }

    GS_ACQUIRE_SHARED();
    pthread_mutex_lock(&GlobalState.PeriodicTaskMutex);
    isAcquired = true;

    macError = GPAComputeDeletedList(pCurrentGPOs, GlobalState.pGPOs, &pDeletedGPOs);
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = GPAComputeDeletedList(GlobalState.pGPOs, pCurrentGPOs, &pNewGPOs);
    GOTO_CLEANUP_ON_MACERROR(macError);

    pTemp = pDeletedGPOs;
    while (pTemp)
    {
        LOG("Removing GPO directory node (%s)", pTemp->pszDisplayName);
        UnregisterGPONode(GlobalState.pszRealm, pTemp->pszDisplayName);
        pTemp = pTemp->pNext;
    }

    pTemp = pNewGPOs;
    while (pTemp)
    {
        LOG("Adding GPO directory node (%s)", pTemp->pszDisplayName);
        RegisterGPONode(pszDomain, pTemp->pszDisplayName);
        pTemp = pTemp->pNext;
    }

    GPA_SAFE_FREE_GPO_LIST(GlobalState.pGPOs);
    GlobalState.pGPOs = pCurrentGPOs;
    pCurrentGPOs = NULL;

    GlobalState.IsJoinedToAD = pszDomain ? true : false;
    LW_SAFE_FREE_STRING(GlobalState.pszRealm);
    GlobalState.pszRealm = pszDomain;
    pszDomain = NULL;

cleanup:

    if (isAcquired)
    {
        pthread_mutex_unlock(&GlobalState.PeriodicTaskMutex);
        GS_RELEASE();
    }

    GPA_SAFE_FREE_GPO_LIST(pCurrentGPOs);
    GPA_SAFE_FREE_GPO_LIST(pDeletedGPOs);
    GPA_SAFE_FREE_GPO_LIST(pNewGPOs);
    LW_SAFE_FREE_STRING(pszDomain);

    return macError;
}
Example #17
0
long PlugInShell_PeriodicTask(void)
{
    long macError = eDSNoErr;
    bool isAcquired = false;
    BOOLEAN bMergeModeMCX = FALSE;
    BOOLEAN bEnableForceHomedirOnStartupDisk = FALSE;
    BOOLEAN bUseADUNCForHomeLocation = FALSE;
    BOOLEAN bAdminListChanged = FALSE;
    PSTR pszUNCProtocolForHomeLocation = NULL;
    PSTR pszAllowAdministrationBy = NULL;
    BOOLEAN bMergeAdmins = FALSE;
    BOOLEAN bIsStarted = FALSE;
    LWE_DS_FLAGS NewFlags = LWE_DS_FLAG_NO_OPTIONS_SET;
    PVOID pAllowAdminCheckData = NULL;
    PNETADAPTERINFO pTempNetInfo = NULL;

    // No enter/leave logging since function is called every 30 seconds
    // or so (on Mac OS X 10.4.7).

    GS_VERIFY_INITIALIZED(macError);

    GS_ACQUIRE_SHARED();
    pthread_mutex_lock(&GlobalState.PeriodicTaskMutex);
    isAcquired = true;

    if (!GlobalState.pNetAdapterList)
    {
        /* Get the network adpater details - We only care about the ENetAddress info */
        macError = LWGetNetAdapterList(true, &GlobalState.pNetAdapterList);
        GOTO_CLEANUP_ON_MACERROR(macError);

        pTempNetInfo = GlobalState.pNetAdapterList;
        while (pTempNetInfo)
        {
            LOG("Finally found a valid ethernet  network adapter...");
            LOG("  Name: %s", pTempNetInfo->pszName);
            LOG("  ENet: %s", pTempNetInfo->pszENetAddress ? pTempNetInfo->pszENetAddress : "----");
            LOG("  IP: %s", pTempNetInfo->pszIPAddress ? pTempNetInfo->pszIPAddress : "----");
            LOG("  Up: %s", pTempNetInfo->IsUp ? "yes" : "no");
            LOG("  Running: %s", pTempNetInfo->IsRunning ? "yes" : "no");
            pTempNetInfo = pTempNetInfo->pNext;
        }
    }

    if (GlobalState.IsStartupComplete == false)
    {
        // Re-verify that startup has completed successfully for lsass service.
        LOG("Re-verify that LSASS service is operational");
        GetLsaStatus(&bIsStarted);
        if (bIsStarted)
        {
            LOG("LSASS service is now operational");
            GlobalState.IsStartupComplete = true;
        }
    }

    macError = GetConfigurationSettings(&bMergeModeMCX,
                                        &bEnableForceHomedirOnStartupDisk,
                                        &bUseADUNCForHomeLocation,
                                        &pszUNCProtocolForHomeLocation,
                                        &pszAllowAdministrationBy,
                                        &bMergeAdmins);
    GOTO_CLEANUP_ON_MACERROR(macError);

    /* Make sure to preserve the flag that tells us this is Leopard or not */
    if (GlobalState.Flags & LWE_DS_FLAG_IS_LEOPARD)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_IS_LEOPARD;;
    }

    /* Make sure to preserve the flag that tells us this is Snow Leopard or not */
    if (GlobalState.Flags & LWE_DS_FLAG_IS_SNOW_LEOPARD)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_IS_SNOW_LEOPARD;;
    }

    /* See if MCX setting aggregation feature is to be supported */
    if (bMergeModeMCX)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_MERGE_MODE_MCX;
        if (GlobalState.Flags & LWE_DS_FLAG_MERGE_MODE_MCX == 0)
        {
            LOG("Merge mode MCX is now enabled. Settings from multiple Group Policy Objects will be merged for the AD user accounts at logon.");
        }
    }

    /* See if Force Home Directory On Startup Disk feature is to be supported */
    if (bEnableForceHomedirOnStartupDisk)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_FORCE_LOCAL_HOME_DIRECTORY_ON_STARTUP_DISK;
        if (GlobalState.Flags & LWE_DS_FLAG_FORCE_LOCAL_HOME_DIRECTORY_ON_STARTUP_DISK == 0)
        {
            LOG("Force Home Directory On Startup Disk is now enabled.");
        }
    }

    /* See if Use AD UNC for Home Location - SMB feature is to be supported */
    if (bUseADUNCForHomeLocation)
    {
        if (pszUNCProtocolForHomeLocation && !strcmp(pszUNCProtocolForHomeLocation, "smb"))
        {
            NewFlags = NewFlags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_SMB;
        }
        else if (pszUNCProtocolForHomeLocation && !strcmp(pszUNCProtocolForHomeLocation, "afp"))
        {
            /* See if Use AD UNC for Home Location - AFP feature is to be supported */
            NewFlags = NewFlags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_AFP;
        }
        else
        {
            NewFlags = NewFlags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_SMB;
        }
    }

    if (pszAllowAdministrationBy)
    {
        if (GlobalState.pszCurrentAllowedAdminsList)
        {
            if (strcmp(GlobalState.pszCurrentAllowedAdminsList, pszAllowAdministrationBy))
            {
                // Setting changed from one value to another
                bAdminListChanged = true;
            }

            // Release the former cached list
            LW_SAFE_FREE_STRING(GlobalState.pszCurrentAllowedAdminsList);
        }
        else
        {
            // Former empty value is to be updated to new
            bAdminListChanged = true;
        }

        // Now replace cached list
        GlobalState.pszCurrentAllowedAdminsList = pszAllowAdministrationBy;
        pszAllowAdministrationBy = NULL;

        if (bAdminListChanged)
        {
            macError = GetAccessCheckData(GlobalState.pszCurrentAllowedAdminsList, &pAllowAdminCheckData);
            if (macError)
            {
                if (macError == eDSAuthUnknownUser)
                {
                    LOG("GetAccessCheckData(%s) failed with error: eDSAuthUnknownUser. AD user accounts will not be added to admin group (GID:80), since the list provided is incorrectly specified. This error suggests that you have a user or group that is not recognized by Likewise authentication daemon. Recommend checking that system administrator has enabled the items here in the Likewise cell that applies to this computer.", GlobalState.pszCurrentAllowedAdminsList);
                }
                else
                {
                    LOG("Failed to GetAllowData(%s) with error: %d", GlobalState.pszCurrentAllowedAdminsList, macError);
                }

                LW_SAFE_FREE_STRING(GlobalState.pszCurrentAllowedAdminsList);
                GlobalState.pszCurrentAllowedAdminsList = NULL;
                pAllowAdminCheckData = NULL;
                macError = eDSNoErr;
            }
            else
            {
                LOG("AllowAdministrationBy updated to (%s)", GlobalState.pszCurrentAllowedAdminsList);
            }
        }
    }
    else
    {
        if (GlobalState.pszCurrentAllowedAdminsList)
        {
            // Former value being set to empty
            bAdminListChanged = true;
            LW_SAFE_FREE_STRING(GlobalState.pszCurrentAllowedAdminsList);
            GlobalState.pszCurrentAllowedAdminsList = NULL;
            LOG("AllowAdministrationBy updated to (not set)");
        }
    }

    /* See if Merge Admins feature is to be supported */
    if (bMergeAdmins)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_DONT_REMOVE_LOCAL_ADMINS;
        if (GlobalState.Flags & LWE_DS_FLAG_DONT_REMOVE_LOCAL_ADMINS == 0)
        {
            LOG("Option to override allow-administration-by with local computer changes to the admin group is now enabled.");
        }
    }

    if (bAdminListChanged)
    {
        /* Now update the GlobalState to reflect new pAllowAdminCheckData */
        GS_ACQUIRE_EXCLUSIVE_ADMIN_ACCESS_LIST();

        if (GlobalState.pAllowAdminCheckData)
        {
            FreeAccessCheckData(GlobalState.pAllowAdminCheckData);
            GlobalState.pAllowAdminCheckData = NULL;
        }

        if (pAllowAdminCheckData)
        {
            GlobalState.pAllowAdminCheckData = pAllowAdminCheckData;
            pAllowAdminCheckData = NULL;
        }

        GS_RELEASE_ADMIN_ACCESS_LIST();
    }

    /* Now update the GlobalState to reflect new flags */
    GlobalState.Flags = NewFlags;

    if (GlobalState.fDomainControllerNotAvailable &&
        (GlobalState.OfflineTimerCount < 5))
    {
        GlobalState.OfflineTimerCount++;
        macError = eDSNoErr;
        goto cleanup;
    }

    GlobalState.fDomainControllerNotAvailable = false;
    GlobalState.OfflineTimerCount = 0;

    if (isAcquired)
    {
        pthread_mutex_unlock(&GlobalState.PeriodicTaskMutex);
        GS_RELEASE();
        isAcquired = false;
    }

    macError = RefreshGPONodes();
    if (macError)
    {
        LOG("Encountered error %d from refresh GPO nodes", macError);
        macError = eDSNoErr;
    }

cleanup:

    if (pszUNCProtocolForHomeLocation)
    {
        LW_SAFE_FREE_STRING(pszUNCProtocolForHomeLocation);
    }

    if (pszAllowAdministrationBy)
    {
        LW_SAFE_FREE_STRING(pszAllowAdministrationBy);
    }

    if (isAcquired)
    {
        pthread_mutex_unlock(&GlobalState.PeriodicTaskMutex);
        GS_RELEASE();
    }

    return macError;
}
Example #18
0
long PlugInShell_SetPluginState(const unsigned long inNewState)
{
    long macError = eDSNoErr;
    bool isAcquired = false;

    LOG_ENTER("inNewState = 0x%08x (%s)", inNewState, StateToString(inNewState));

    if (FlagOn(inNewState, ~(kActive | kInactive)))
    {
        LOG("Ignoring unexpected state flags: 0x%08x", FlagOn(inNewState, ~(kActive | kInactive)));
    }

    if (!FlagOn(inNewState, kActive | kInactive))
    {
        // Nothing to do.
        LOG("Nothing to do because inactive/active flags are not specified.");
        macError = eDSNoErr;
        GOTO_CLEANUP();
    }

    if (FlagOn(inNewState, kActive) && FlagOn(inNewState, kInactive))
    {
        LOG_ERROR("Cannot set active and inactive at the same time.");
        macError = ePlugInError;
        GOTO_CLEANUP();
    }

    GS_ACQUIRE_EXCLUSIVE();
    isAcquired = true;

    GS_VERIFY_INITIALIZED(macError);

    LOG("Current State = 0x%08x", GlobalState.PluginState);

    if ( (FlagOn(inNewState, kActive | kInactive) == FlagOn(GlobalState.PluginState, kActive | kInactive)) )
    {
        // Nothing to do.
        LOG("Nothing to do because the state matches");
        macError = eDSNoErr;
        GOTO_CLEANUP();
    }

    if ( FlagOn(inNewState, kActive) )
    {
        LOG("Activating");
        macError = Activate();
        GOTO_CLEANUP_ON_MACERROR(macError);

        SetFlag(GlobalState.PluginState, kActive);
        ClearFlag(GlobalState.PluginState, kInactive);
    }
    else if ( FlagOn(inNewState, kInactive) )
    {
        LOG("De-activating");
        macError = Deactivate();
        GOTO_CLEANUP_ON_MACERROR(macError);

        ClearFlag(GlobalState.PluginState, kActive);
        SetFlag(GlobalState.PluginState, kInactive);
    }
    else
    {
        // This should never happen.
        LOG_ERROR("Benign unexpected code path.");
        macError = eDSNoErr;
    }

cleanup:

    if (isAcquired)
    {
        LOG("Final State = 0x%08x", GlobalState.PluginState);
        GS_RELEASE();
    }

    LOG_LEAVE("--> %d", macError);
    return macError;
}
Example #19
0
long
CreateLWIUser(
    PCSTR pszName,
    PCSTR pszDisplayName,
    PCSTR pszNameAsQueried,
    PCSTR pszPassword,
    PCSTR pszClass,
    PCSTR pszGecos,
    PCSTR pszNFSHomeDirectory,
    PCSTR pszHomeDirectory,
    PCSTR pszOrigNFSHomeDirectory,
    PCSTR pszOrigHomeDirectory,
    PCSTR pszShell,
    uid_t uid,
    gid_t gid,
    PMCXVALUE pMCXValues,
    PAD_USER_ATTRIBUTES padUserADInfo,
    PLWIUSER* ppLWIUser
    )
{
    long macError = eDSNoErr;
    PLWIUSER pUser = NULL;
    
    macError = LwAllocateMemory(sizeof(LWIUSER), (PVOID*)&pUser);
    GOTO_CLEANUP_ON_MACERROR(macError);
    
    if (pszName)
    {
        macError = LwAllocateString(pszName, &pUser->pw_name);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pszDisplayName)
    {
        macError = LwAllocateString(pszDisplayName, &pUser->pw_display_name);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pszNameAsQueried)
    {
        macError = LwAllocateString(pszNameAsQueried, &pUser->pw_name_as_queried);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }
    
    if (pszPassword)
    {
        macError = LwAllocateString(pszPassword, &pUser->pw_passwd);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }
    
    if (pszClass)
    {
        macError = LwAllocateString(pszClass, &pUser->pw_class);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }
    
    if (pszGecos)
    {
        macError = LwAllocateString(pszGecos, &pUser->pw_gecos);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (!pszNFSHomeDirectory && pszHomeDirectory && *pszHomeDirectory)
    {
        macError = LwAllocateString(pszHomeDirectory, &pUser->pw_nfs_home_dir);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }
    else if (pszNFSHomeDirectory)
    {
        macError = LwAllocateString(pszNFSHomeDirectory, &pUser->pw_nfs_home_dir);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pszHomeDirectory)
    {
        macError = LwAllocateString(pszHomeDirectory, &pUser->pw_home_dir);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pszOrigNFSHomeDirectory)
    {
        macError = LwAllocateString(pszOrigNFSHomeDirectory, &pUser->pw_orig_nfs_home_dir);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pszOrigHomeDirectory)
    {
        macError = LwAllocateString(pszOrigHomeDirectory, &pUser->pw_orig_home_dir);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pszShell)
    {
        macError = LwAllocateString(pszShell, &pUser->pw_shell);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (pMCXValues)
    {
        macError = CopyMCXValueList(pMCXValues, &pUser->pMCXValues);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }
    
    if (padUserADInfo)
    {
        macError = CopyADUserInfo(padUserADInfo, &pUser->padUserInfo);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    pUser->pw_uid = uid;
    pUser->pw_gid = gid;
    
    *ppLWIUser = pUser;
    pUser = NULL;

cleanup:

    FreeLWIUser(pUser);
    
    return macError;
}
Example #20
0
long
LWIAttrValDataQuery::QueryComputerGroupInformation(LWIQuery* pQuery, char* pszAttribute, char* pszPattern)
{
    long macError = eDSNoErr;
    LWIAttrLookup::Index_t attrIndex = LWIAttrLookup::idx_unknown;
    PSTR pszHostname = NULL;
 
    macError = GetDnsHostName(&pszHostname);
    GOTO_CLEANUP_ON_MACERROR(macError);

    attrIndex = LWIAttrLookup::GetIndex(pszAttribute);
    switch (attrIndex)
    {
        case LWIAttrLookup::idx_kDSNAttrRecordName:
            macError = pQuery->QueryComputerGroupInformationByName(pszPattern);
            GOTO_CLEANUP_ON_MACERROR(macError);
            break;
        case LWIAttrLookup::idx_kDSNAttrComputers:
            if (!strcmp(pszPattern, "localhost") ||
                !strcmp(pszPattern, pszHostname) )
            {
                macError = pQuery->QueryComputerGroupInformationByName(kDSRecordsAll);
                GOTO_CLEANUP_ON_MACERROR(macError);
                break;
            }
            else
            {
                LOG("Got request to search for %s as a (Computers) attribute for ComputerGroup objects, currently not supported and therefore ignoring",
                    pszPattern);
                break;
            }
        case LWIAttrLookup::idx_kDSNAttrGroupMembership:
            if (!strcmp(pszPattern, "localhost") ||
                !strcmp(pszPattern, pszHostname))
            {
                macError = pQuery->QueryComputerGroupInformationByName(kDSRecordsAll);
                GOTO_CLEANUP_ON_MACERROR(macError);
                break;
            }
            else
            {
                LOG("Got request to search for %s as a GroupMembership) attribute for ComputerGroup objects, currently not supported and therefore ignoring",
                    pszPattern);
                break;
            }
        default:
#ifdef SHOW_DEBUG_SPEW
            LOG("Unsupported attribute index for group - %d", attrIndex);
#endif
            macError = eDSNoErr;
            break;
    }

cleanup:

    if (pszHostname)
    {
        LW_SAFE_FREE_STRING(pszHostname);
    }

    return macError;
}
Example #21
0
long PlugInShell_Initialize(void)
{
    long macError = eDSNoErr;
    bool gotUnameInfo = false;
    PSTR pszVersion = NULL;
    PCSTR pszVersionName = NULL;
    bool isUnsupported = false;
    PNETADAPTERINFO pTempNetInfo = NULL;
    struct utsname info;
    BOOLEAN bMergeModeMCX = FALSE;
    BOOLEAN bEnableForceHomedirOnStartupDisk = FALSE;
    BOOLEAN bUseADUNCForHomeLocation = FALSE;
    PSTR pszUNCProtocolForHomeLocation = NULL;
    PSTR pszAllowAdministrationBy = NULL;
    BOOLEAN bMergeAdmins = FALSE;
    PVOID pAllowAdminCheckData = NULL;
    DWORD dwCacheLifeTime = 10;

    memset(info.sysname, 0, sizeof(info.sysname));
    memset(info.nodename, 0, sizeof(info.nodename));
    memset(info.release, 0, sizeof(info.release));
    memset(info.version, 0, sizeof(info.version));
    memset(info.machine, 0, sizeof(info.machine));

    LOG_ENTER("");
    LOG("Current State = 0x%08x", GlobalState.PluginState);

    //
    // We expect to be called exactly once, except if we fail to initialize.
    // When that happens, we can get called again several times to try to
    // initialize successfully.
    //

    if (GlobalState.IsInitialized)
    {
        LOG("Plug-in already initialized");
        GOTO_CLEANUP();
    }

    /* Clear all values for GlobalState */
    GlobalState.IsInitialized = false;
    GlobalState.PluginState = kUnknownState;
    GlobalState.IsJoinedToAD = false;
    GlobalState.Flags = LWE_DS_FLAG_NO_OPTIONS_SET;
    GlobalState.NodeNameList = NULL;
    GlobalState.pGPOs = NULL;
    GlobalState.pszRealm = NULL;
    macError = InitializeContextList();
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (uname(&info))
    {
        gotUnameInfo = false;

        macError = LWCaptureOutput((char*)"sw_vers -productVersion", &pszVersion);
        GOTO_CLEANUP_ON_MACERROR(macError);

        if (strstr(pszVersion, "10.4.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags & (~LWE_DS_FLAG_IS_LEOPARD);
            GlobalState.Flags = GlobalState.Flags & (~LWE_DS_FLAG_IS_SNOW_LEOPARD);
            pszVersionName = MAC_OS_X_VERSION_NAME_10_4;
        }
        else if (strstr(pszVersion, "10.5.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_5;
        }
        else if (strstr(pszVersion, "10.6.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_SNOW_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_6;
        }
        else if (strstr(pszVersion, "10.7.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_SNOW_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_7;
        }
        else if (strstr(pszVersion, "10.8.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_SNOW_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_8;
        }
        else if (strstr(pszVersion, "10.9.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_MAVERICKS;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_9;
        }
        else if (strstr(pszVersion, "10.10.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_YOSEMITE;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_10;
        }
        else
        {
            isUnsupported = true;
        }
    }
    else
    {
        gotUnameInfo = true;

        macError = LwAllocateString(info.release, &pszVersion);
        GOTO_CLEANUP_ON_MACERROR(macError);

        if (strstr(pszVersion, "8.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags & ~LWE_DS_FLAG_IS_LEOPARD;
            GlobalState.Flags = GlobalState.Flags & ~LWE_DS_FLAG_IS_SNOW_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_4;
        }
        else if (strstr(pszVersion, "9.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_5;
        }
        else if (strstr(pszVersion, "10.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_SNOW_LEOPARD;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_6;
        }
        else if (strstr(pszVersion, "11.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_LION;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_7;
        }
        else if (strstr(pszVersion, "12.") == pszVersion)
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_MOUNTAIN_LION;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_8;
        } else if (strstr(pszVersion, "13.") == pszVersion) {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_MAVERICKS;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_9;
        } else if (strstr(pszVersion, "14.") == pszVersion) {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_IS_YOSEMITE;
            pszVersionName = MAC_OS_X_VERSION_NAME_10_10;
        } else {
            isUnsupported = true;
        }
    }
    if (isUnsupported)
    {
        pszVersionName = "unsupported";
    }
    LOG("Starting up PBIS - Active directory DS plug-in, detected %s Mac OS X %s(%s)",
            pszVersionName, gotUnameInfo ? "kernel " : "", pszVersion);
    if (isUnsupported)
    {
        macError = ePlugInFailedToInitialize;
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    /* Get the network adpater details - We only care about the ENetAddress info */
    macError = LWGetNetAdapterList(true, &GlobalState.pNetAdapterList);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (!GlobalState.pNetAdapterList)
    {
        LOG("Could not find an ethernet network adapter, will retry later. Computer settings maybe not be applied till one is found.");
    }

    pTempNetInfo = GlobalState.pNetAdapterList;
    while (pTempNetInfo)
    {
        LOG("Found network adapter...");
        LOG("  Name: %s", pTempNetInfo->pszName);
        LOG("  ENet: %s", pTempNetInfo->pszENetAddress ? pTempNetInfo->pszENetAddress : "----");
        LOG("  IP: %s", pTempNetInfo->pszIPAddress ? pTempNetInfo->pszIPAddress : "----");
        LOG("  Up: %s", pTempNetInfo->IsUp ? "yes" : "no");
        LOG("  Running: %s", pTempNetInfo->IsRunning ? "yes" : "no");
        pTempNetInfo = pTempNetInfo->pNext;
    }

    macError = GetConfigurationSettings(&bMergeModeMCX,
            &bEnableForceHomedirOnStartupDisk,
            &bUseADUNCForHomeLocation,
            &pszUNCProtocolForHomeLocation,
            &pszAllowAdministrationBy,
            &bMergeAdmins,
            &dwCacheLifeTime);
    GOTO_CLEANUP_ON_MACERROR(macError);

    /* See if MCX setting aggregation feature is to be supported */
    if (bMergeModeMCX)
    {
        GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_MERGE_MODE_MCX;
        LOG("Merge mode MCX is enabled. Settings from multiple Group Policy Objects will be merged for the AD user accounts at logon.");
    }

    /* See if Force Home Directory On Startup Disk feature is to be supported */
    if (bEnableForceHomedirOnStartupDisk)
    {
        GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_FORCE_LOCAL_HOME_DIRECTORY_ON_STARTUP_DISK;
        LOG("Force Home Directory On Startup Disk is enabled.");
    }

    /* See if Use AD UNC for Home Location - SMB feature is to be supported */
    if (bUseADUNCForHomeLocation)
    {
        if (pszUNCProtocolForHomeLocation && !strcmp(pszUNCProtocolForHomeLocation, "smb"))
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_SMB;
            LOG("Use AD UNC for Home Location - SMB is enabled.");
        }
        else if (pszUNCProtocolForHomeLocation && !strcmp(pszUNCProtocolForHomeLocation, "afp"))
        {
            /* See if Use AD UNC for Home Location - AFP feature is to be supported */
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_AFP;
            LOG("Use AD UNC for Home Location - AFP is enabled.");
        }
        else
        {
            GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_SMB;
            LOG("Use AD UNC for Home Location - defaulting to SMB protocol.");
        }
    }

    if (pszAllowAdministrationBy)
    {
        macError = GetAccessCheckData(pszAllowAdministrationBy, &pAllowAdminCheckData);
        if (macError)
        {
            if (macError == eDSAuthUnknownUser)
            {
                LOG("GetAccessCheckData(%s) failed with error: eDSAuthUnknownUser. AD user accounts will not be added to admin group (GID:80), since the list provided is incorrectly specified. This error suggests that you have a user or group that is not recognized by PBIS authentication daemon. Recommend checking that system administrator has enabled the items here in the PBIS cell that applies to this computer.", pszAllowAdministrationBy);
            }
            else
            {
                LOG("Failed to GetAccessCheckData(%s) with error: %d", pszAllowAdministrationBy, macError);
            }

            macError = eDSNoErr;
        }
        else
        {
            LOG("AllowAdministrationBy configured to: %s", pszAllowAdministrationBy);
            if (GlobalState.pAllowAdminCheckData)
            {
                FreeAccessCheckData(GlobalState.pAllowAdminCheckData);
            }

            GlobalState.pAllowAdminCheckData = pAllowAdminCheckData;
            pAllowAdminCheckData = NULL;
        }
    }

    /* See if Merge Admins feature is to be supported */
    if (bMergeAdmins)
    {
        GlobalState.Flags = GlobalState.Flags | LWE_DS_FLAG_DONT_REMOVE_LOCAL_ADMINS;
        LOG("Option to override allow-administration-by with local computer changes to the admin group is enabled.");
    }

    LWIQuery::SetCacheLifeTime(dwCacheLifeTime);

    if (pthread_rwlock_init(&GlobalState.Lock, NULL) < 0)
    {
        int libcError = errno;
        LOG_ERROR("Failied to init lock: %s (%d)", strerror(libcError), libcError);
        macError = ePlugInInitError;
        GOTO_CLEANUP();
    }
    GlobalState.IsLockInitialized = true;

    macError = LWIAttrLookup::Initialize();
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = LWIRecTypeLookup::Initialize();
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = LWIDirNodeQuery::Initialize();
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = LWIRecordQuery::Initialize();
    GOTO_CLEANUP_ON_MACERROR(macError);

    LWICRC::Initialize();

    // Allow WGM policy options to define Login/Logoff Hook scripts. We do this to automatically support settings
    // we get from group policies.
    macError = SetupMCXLoginScriptsSupport();
    GOTO_CLEANUP_ON_MACERROR(macError);

    GlobalState.IsInitialized = true;
    GlobalState.PluginState = kInitialized | kInactive;

    //
    // If we supported custom calls while not active, we would need to create a
    // node for that here.
    //

cleanup:

    if (pszVersion)
    {
        LwFreeMemory(pszVersion);
    }

    if (pszUNCProtocolForHomeLocation)
    {
        LW_SAFE_FREE_STRING(pszUNCProtocolForHomeLocation);
    }

    if (pszAllowAdministrationBy)
    {
        LW_SAFE_FREE_STRING(pszUNCProtocolForHomeLocation);
    }

    if (pAllowAdminCheckData)
    {
        FreeAccessCheckData(pAllowAdminCheckData);
    }

    if (macError)
    {
        // This is the only error code allowed in the failure case.
        macError = ePlugInInitError;

        PlugInShell_Shutdown();
        GlobalState.PluginState = kFailedToInit | kInactive;
    }

    LOG("Final State = 0x%08x", GlobalState.PluginState);

    LOG_LEAVE("--> %d", macError);

    return macError;
}
Example #22
0
long
LWIAttrValDataQuery::Run(sDoAttrValueSearchWithData* pAttrValueSearchWithData, LWE_DS_FLAGS Flags, PNETADAPTERINFO pNetAdapterList)
{
    long macError = eDSNoErr;
    long macError_userQuery = eDSNoErr;
    long macError_groupQuery = eDSNoErr;
    unsigned long bytesWritten = 0;
    unsigned long nRecordsWritten = 0;
    unsigned long TotalRecords = 0;
    LWIQuery* pQuery = NULL;
    int recordTypeCount;
    int recordAttributeCount;
    bool isWithData = (kDoAttributeValueSearchWithData == pAttrValueSearchWithData->fType);
    tContextData HandleId = 0;
 
    LOG_ENTER("LWIAttrValDataQuery::Run - fType = %d, fResult = %d, fInNodeRef = %d, fInAttrType = %s, fInPattMatchType = 0x%04X, fInPatt2Match = %s, fInAttrInfoOnly = %s, fIOContinueData = %d, fOutDataBuff => { size = %d }",
              pAttrValueSearchWithData->fType,
              pAttrValueSearchWithData->fResult,
              pAttrValueSearchWithData->fInNodeRef,
              pAttrValueSearchWithData->fInAttrType->fBufferData,
              pAttrValueSearchWithData->fInPattMatchType,
              pAttrValueSearchWithData->fInPatt2Match->fBufferData,
              BOOL_STRING(isWithData && pAttrValueSearchWithData->fInAttrInfoOnly),
              pAttrValueSearchWithData->fIOContinueData,
              pAttrValueSearchWithData->fOutDataBuff->fBufferSize);

    recordTypeCount = dsDataListGetNodeCount(pAttrValueSearchWithData->fInRecTypeList);
    recordAttributeCount = isWithData ? dsDataListGetNodeCount(pAttrValueSearchWithData->fInAttrTypeRequestList) : 0;

    LOG_PARAM("fInRecTypeList.count = %d, fInAttrTypeRequestList.count = %d",
              recordTypeCount,
              recordAttributeCount);

    if (pAttrValueSearchWithData->fIOContinueData != 0)
    {
        macError = GetQueryFromContextList(pAttrValueSearchWithData->fIOContinueData, &pQuery);
        if (macError == eDSNoErr)
        {
            LOG("Already processed this query, handling IO continuation for result record data");
            goto HandleResponse;
        }
    }

    macError = LWIQuery::Create(!isWithData || !pAttrValueSearchWithData->fInAttrInfoOnly,
                                true, // The query results will support fIOContinue (split large results over many calls)
                                pAttrValueSearchWithData->fInNodeRef,
                                Flags,
                                pNetAdapterList,
                                &pQuery);
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = LWIRecTypeLookup::GetVector(pAttrValueSearchWithData->fInRecTypeList, &pQuery->_recTypeSet);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (isWithData)
    {
        macError = LWIAttrLookup::GetVector(pAttrValueSearchWithData->fInAttrTypeRequestList, &pQuery->_attributeSet);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }
    else
    {
        macError = LWIAttrLookup::GetVector(kDSAttributesAll, &pQuery->_attributeSet);
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    // We support only exact (including case-insensitive) matches
    switch (pAttrValueSearchWithData->fInPattMatchType)
    {
        case eDSExact:
        case eDSiExact:
            // These are fine
            break;

        default:
            LOG("Unsupported pattern match type: 0x%04X", pAttrValueSearchWithData->fInPattMatchType);
            macError = eDSRecordNotFound;
            GOTO_CLEANUP_ON_MACERROR(macError);
    }

    macError = eDSInvalidRecordType;

    if (pQuery->ShouldQueryUserInformation())
    {
        macError_userQuery = QueryUserInformation(pQuery,
                                                  pAttrValueSearchWithData->fInAttrType->fBufferData,
                                                  pAttrValueSearchWithData->fInPatt2Match->fBufferData);
        if (macError_userQuery != eDSNoErr)
        {
            LOG("User query failed [Error: %d]", macError_userQuery);
        }
    }

    if (pQuery->ShouldQueryGroupInformation())
    {
        macError_groupQuery = QueryGroupInformation(pQuery,
                                                    pAttrValueSearchWithData->fInAttrType->fBufferData,
                                                    pAttrValueSearchWithData->fInPatt2Match->fBufferData);
        if (macError_groupQuery != eDSNoErr)
        {
            LOG("Group query failed [Error: %d]", macError_groupQuery);
        }
    }
    
    if (pQuery->ShouldQueryComputerListInformation())
    {
        macError_groupQuery = QueryComputerListInformation(pQuery,
                                                           pAttrValueSearchWithData->fInAttrType->fBufferData,
                                                           pAttrValueSearchWithData->fInPatt2Match->fBufferData);
        if (macError_groupQuery != eDSNoErr)
        {
            LOG("Computer List query failed [Error: %d]", macError_groupQuery);
        }
    }

    if (pQuery->ShouldQueryComputerGroupInformation())
    {
        macError_groupQuery = QueryComputerGroupInformation(pQuery,
                                                            pAttrValueSearchWithData->fInAttrType->fBufferData,
                                                            pAttrValueSearchWithData->fInPatt2Match->fBufferData);
        if (macError_groupQuery != eDSNoErr)
        {
            LOG("Computer Group query failed [Error: %d]", macError_groupQuery);
        }
    }

    if (pQuery->ShouldQueryComputerInformation())
    {
        macError_groupQuery = QueryComputerInformation(pQuery,
                                                       pAttrValueSearchWithData->fInAttrType->fBufferData,
                                                       pAttrValueSearchWithData->fInPatt2Match->fBufferData);
        if (macError_groupQuery != eDSNoErr)
        {
            LOG("Computer query failed [Error: %d]", macError_groupQuery);
        }
    }

    // If both queries failed, it is a problem
    if ((macError_userQuery != eDSNoErr) && (macError_groupQuery != eDSNoErr))
    {
       macError = (pQuery->ShouldQueryUserInformation() ? macError_userQuery : macError_groupQuery);
       GOTO_CLEANUP_ON_MACERROR(macError);
    }
    else
       macError = eDSNoErr;

HandleResponse:

    // Write the results
    macError = pQuery->WriteResponse(pAttrValueSearchWithData->fOutDataBuff->fBufferData,
                                     pAttrValueSearchWithData->fOutDataBuff->fBufferSize,
                                     bytesWritten,
                                     nRecordsWritten,
                                     TotalRecords);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (TotalRecords > nRecordsWritten)
    {
        macError = AddQueryToContextList(pQuery, &HandleId);
        GOTO_CLEANUP_ON_MACERROR(macError);

        pQuery = NULL;
  
        pAttrValueSearchWithData->fIOContinueData = HandleId;
    }
    else
    {
        pAttrValueSearchWithData->fIOContinueData = 0;
    }

    pAttrValueSearchWithData->fOutDataBuff->fBufferLength = bytesWritten;
    pAttrValueSearchWithData->fOutMatchRecordCount = nRecordsWritten;

    if ( bytesWritten > 0 )
    {
#ifdef SHOW_ALL_DEBUG_SPEW
        LOG_BUFFER(pAttrValueSearchWithData->fOutDataBuff->fBufferData, bytesWritten);
#endif
    }

cleanup:

    if (pQuery)
    {
        delete pQuery;
    }

    LOG_LEAVE("fOutMatchRecordCount = %d, fIOContinueData = %d --> %d", pAttrValueSearchWithData->fOutMatchRecordCount, pAttrValueSearchWithData->fIOContinueData, macError);

    return macError;
}
Example #23
0
long PlugInShell_PeriodicTask(void)
{
    long macError = eDSNoErr;
    bool isAcquired = false;
    BOOLEAN bMergeModeMCX = FALSE;
    BOOLEAN bEnableForceHomedirOnStartupDisk = FALSE;
    BOOLEAN bUseADUNCForHomeLocation = FALSE;
    BOOLEAN bAdminListChanged = FALSE;
    PSTR pszUNCProtocolForHomeLocation = NULL;
    PSTR pszAllowAdministrationBy = NULL;
    BOOLEAN bMergeAdmins = FALSE;
    BOOLEAN bIsStarted = FALSE;
    LWE_DS_FLAGS NewFlags = LWE_DS_FLAG_NO_OPTIONS_SET;
    PVOID pAllowAdminCheckData = NULL;
    PNETADAPTERINFO pTempNetInfo = NULL;
    DWORD dwCacheLifeTime = 10;
    PGROUP_POLICY_OBJECT pCurrentGPOs = NULL;
    PSTR pszDomain = NULL;
    BOOLEAN bOffline = false;
    static int offlineTimerCount = 0;
    static PSTR pszCurrentAllowedAdminsList = NULL;

    // No enter/leave logging since function is called every 30 seconds
    // or so (on Mac OS X 10.4.7).
    //

    // Get some information that might take a while before locking
    // GlobalState.
    macError = GetConfigurationSettings(&bMergeModeMCX,
            &bEnableForceHomedirOnStartupDisk,
            &bUseADUNCForHomeLocation,
            &pszUNCProtocolForHomeLocation,
            &pszAllowAdministrationBy,
            &bMergeAdmins,
            &dwCacheLifeTime);
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = GetDomainJoinState(&pszDomain);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (offlineTimerCount)
    {
        if (offlineTimerCount < 5)
        {
            ++offlineTimerCount;
        }
        else
        {
            offlineTimerCount = 0;
        }
    }

    if (offlineTimerCount == 0)
    {
        macError = GetGPONodes(pszDomain, &pCurrentGPOs, &bOffline);
        GOTO_CLEANUP_ON_MACERROR(macError);

        if (bOffline)
        {
            offlineTimerCount = 1;
        }
    }

    if (pszAllowAdministrationBy)
    {
        if (pszCurrentAllowedAdminsList)
        {
            if (strcmp(pszCurrentAllowedAdminsList, pszAllowAdministrationBy))
            {
                // Setting changed from one value to another
                bAdminListChanged = true;

                // Release the former cached list
                LW_SAFE_FREE_STRING(pszCurrentAllowedAdminsList);
                pszCurrentAllowedAdminsList = pszAllowAdministrationBy;
                pszAllowAdministrationBy = NULL;
            }
        }
        else
        {
            // Former empty value is to be updated to new
            bAdminListChanged = true;
            pszCurrentAllowedAdminsList = pszAllowAdministrationBy;
            pszAllowAdministrationBy = NULL;
        }

        if (bAdminListChanged)
        {
            macError = GetAccessCheckData(pszCurrentAllowedAdminsList, &pAllowAdminCheckData);
            if (macError)
            {
                if (macError == eDSAuthUnknownUser)
                {
                    LOG("GetAccessCheckData(%s) failed with error: eDSAuthUnknownUser. AD user accounts will not be added to admin group (GID:80), since the list provided is incorrectly specified. This error suggests that you have a user or group that is not recognized by PBIS authentication daemon. Recommend checking that system administrator has enabled the items here in the PBIS cell that applies to this computer.", pszCurrentAllowedAdminsList);
                }
                else
                {
                    LOG("Failed to GetAllowData(%s) with error: %d", pszCurrentAllowedAdminsList, macError);
                }

                LW_SAFE_FREE_STRING(pszCurrentAllowedAdminsList);
                pszCurrentAllowedAdminsList = NULL;
                pAllowAdminCheckData = NULL;
                macError = eDSNoErr;
            }
            else
            {
                LOG("AllowAdministrationBy updated to (%s)", pszCurrentAllowedAdminsList);
            }
        }
    }
    else
    {
        if (pszCurrentAllowedAdminsList)
        {
            // Former value being set to empty
            bAdminListChanged = true;
            LW_SAFE_FREE_STRING(pszCurrentAllowedAdminsList);
            pszCurrentAllowedAdminsList = NULL;
            LOG("AllowAdministrationBy updated to (not set)");
        }
    }

    GS_ACQUIRE_EXCLUSIVE();
    isAcquired = true;

    GS_VERIFY_INITIALIZED(macError);

    if (pszDomain && GlobalState.pszRealm &&
        strcmp(pszDomain, GlobalState.pszRealm))
    {
        LOG("Unexpected domain name change: '%s' -> '%s'",
                pszDomain, GlobalState.pszRealm);
        // ISSUE-2008/10/07-dalmeida -- To support this, we would
        // need to unregister all nodes.
        macError = eDSOperationFailed;
        GOTO_CLEANUP_ON_MACERROR(macError);
    }

    if (!GlobalState.pNetAdapterList)
    {
        /* Get the network adpater details - We only care about the ENetAddress info */
        macError = LWGetNetAdapterList(true, &GlobalState.pNetAdapterList);
        GOTO_CLEANUP_ON_MACERROR(macError);

        pTempNetInfo = GlobalState.pNetAdapterList;
        while (pTempNetInfo)
        {
            LOG("Finally found a valid ethernet  network adapter...");
            LOG("  Name: %s", pTempNetInfo->pszName);
            LOG("  ENet: %s", pTempNetInfo->pszENetAddress ? pTempNetInfo->pszENetAddress : "----");
            LOG("  IP: %s", pTempNetInfo->pszIPAddress ? pTempNetInfo->pszIPAddress : "----");
            LOG("  Up: %s", pTempNetInfo->IsUp ? "yes" : "no");
            LOG("  Running: %s", pTempNetInfo->IsRunning ? "yes" : "no");
            pTempNetInfo = pTempNetInfo->pNext;
        }
    }

    if (GlobalState.IsStartupComplete == false)
    {
        // Re-verify that startup has completed successfully for lsass service.
        LOG("Re-verify that LSASS service is operational");
        GetLsaStatus(&bIsStarted);
        if (bIsStarted)
        {
            LOG("LSASS service is now operational");
            GlobalState.IsStartupComplete = true;
        }
    }

    /* Make sure to preserve the flag that tells us this is Leopard or not */
    if (GlobalState.Flags & LWE_DS_FLAG_IS_LEOPARD)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_IS_LEOPARD;;
    }

    /* Make sure to preserve the flag that tells us this is Snow Leopard or not */
    if (GlobalState.Flags & LWE_DS_FLAG_IS_SNOW_LEOPARD)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_IS_SNOW_LEOPARD;;
    }

    /* See if MCX setting aggregation feature is to be supported */
    if (bMergeModeMCX)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_MERGE_MODE_MCX;
        if (GlobalState.Flags & LWE_DS_FLAG_MERGE_MODE_MCX == 0)
        {
            LOG("Merge mode MCX is now enabled. Settings from multiple Group Policy Objects will be merged for the AD user accounts at logon.");
        }
    }

    /* See if Force Home Directory On Startup Disk feature is to be supported */
    if (bEnableForceHomedirOnStartupDisk)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_FORCE_LOCAL_HOME_DIRECTORY_ON_STARTUP_DISK;
        if (GlobalState.Flags & LWE_DS_FLAG_FORCE_LOCAL_HOME_DIRECTORY_ON_STARTUP_DISK == 0)
        {
            LOG("Force Home Directory On Startup Disk is now enabled.");
        }
    }

    /* See if Use AD UNC for Home Location - SMB feature is to be supported */
    if (bUseADUNCForHomeLocation)
    {
        if (pszUNCProtocolForHomeLocation && !strcmp(pszUNCProtocolForHomeLocation, "smb"))
        {
            NewFlags = NewFlags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_SMB;
        }
        else if (pszUNCProtocolForHomeLocation && !strcmp(pszUNCProtocolForHomeLocation, "afp"))
        {
            /* See if Use AD UNC for Home Location - AFP feature is to be supported */
            NewFlags = NewFlags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_AFP;
        }
        else
        {
            NewFlags = NewFlags | LWE_DS_FLAG_USE_AD_UNC_FOR_HOME_LOCATION_SMB;
        }
    }
    /* See if Merge Admins feature is to be supported */
    if (bMergeAdmins)
    {
        NewFlags = NewFlags | LWE_DS_FLAG_DONT_REMOVE_LOCAL_ADMINS;
        if (GlobalState.Flags & LWE_DS_FLAG_DONT_REMOVE_LOCAL_ADMINS == 0)
        {
            LOG("Option to override allow-administration-by with local computer changes to the admin group is now enabled.");
        }
    }

    if (bAdminListChanged)
    {
        /* Now update the GlobalState to reflect new pAllowAdminCheckData */
        if (GlobalState.pAllowAdminCheckData)
        {
            FreeAccessCheckData(GlobalState.pAllowAdminCheckData);
            GlobalState.pAllowAdminCheckData = NULL;
        }

        if (pAllowAdminCheckData)
        {
            GlobalState.pAllowAdminCheckData = pAllowAdminCheckData;
            pAllowAdminCheckData = NULL;
        }
    }

    LWIQuery::SetCacheLifeTime(dwCacheLifeTime);

    /* Now update the GlobalState to reflect new flags */
    GlobalState.Flags = NewFlags;

    if (offlineTimerCount == 0)
    {
        macError = UpdateGPONodes(pszDomain, pCurrentGPOs);
        if (macError)
        {
            LOG("Encountered error %d while updating GPO nodes", macError);
            macError = eDSNoErr;
        }
    }

    GPA_SAFE_FREE_GPO_LIST(GlobalState.pGPOs);
    GlobalState.pGPOs = pCurrentGPOs;
    pCurrentGPOs = NULL;

    GlobalState.IsJoinedToAD = pszDomain ? true : false;
    LW_SAFE_FREE_STRING(GlobalState.pszRealm);
    GlobalState.pszRealm = pszDomain;
    pszDomain = NULL;

cleanup:

    if (isAcquired)
    {
        GS_RELEASE();
    }

    if (pAllowAdminCheckData)
    {
        FreeAccessCheckData(pAllowAdminCheckData);
    }

    LW_SAFE_FREE_STRING(pszUNCProtocolForHomeLocation);
    LW_SAFE_FREE_STRING(pszAllowAdministrationBy);
    LW_SAFE_FREE_STRING(pszDomain);
    GPA_SAFE_FREE_GPO_LIST(pCurrentGPOs);


    return macError;
}
long
LWIRecordListQuery::Run(IN OUT sGetRecordList* pGetRecordList, LWE_DS_FLAGS Flags, PNETADAPTERINFO pNetAdapterList)
{
    long macError = eDSNoErr;
    long macError_userQuery = eDSNoErr;
    long macError_groupQuery = eDSNoErr;
    long macError_computerQuery = eDSNoErr;
    long macError_computergroupQuery = eDSNoErr;
    long macError_computerlistQuery = eDSNoErr;
    tDataNodePtr pDataNode = NULL;
    const char* szNames = NULL;
    unsigned long bytesWritten = 0;
    unsigned long nRecordsWritten = 0;
    unsigned long TotalRecords = 0;
    LWIQuery* pQuery = NULL;
    int iter = 0;
    int resultCount = 0;
    int recordNameCount;
    int recordTypeCount;
    int recordAttributeCount;
    tContextData HandleId = 0;

    LOG_ENTER("LWIRecordListQuery::Run - fType = %d, fResult = %d, fInNodeRef = %d, "
              "fInDataBuf = @%p { len = %d, size = %d }, fInPatternMatch = 0x%04X, "
              "fIOContinueData = %d",
              pGetRecordList->fType,
              pGetRecordList->fResult,
              pGetRecordList->fInNodeRef,
              pGetRecordList->fInDataBuff,
              pGetRecordList->fInDataBuff->fBufferLength,
              pGetRecordList->fInDataBuff->fBufferSize,
              pGetRecordList->fInPatternMatch,
              pGetRecordList->fIOContinueData);

    recordNameCount = dsDataListGetNodeCount(pGetRecordList->fInRecNameList);
    recordTypeCount = dsDataListGetNodeCount(pGetRecordList->fInRecTypeList);
    recordAttributeCount = dsDataListGetNodeCount(pGetRecordList->fInAttribTypeList);

    LOG_PARAM("fInRecNameList.count = %d, fInRecTypeList.count = %d, "
              "fInAttribTypeList.count = %d",
              recordNameCount,
              recordTypeCount,
              recordAttributeCount);

    /* Initialize the out parameters in case we return with error */
    pGetRecordList->fInDataBuff->fBufferLength = 0;
    pGetRecordList->fOutRecEntryCount = 0;

    if ((UInt32)pGetRecordList->fIOContinueData != 0 &&
        (UInt32)pGetRecordList->fIOContinueData != SPECIAL_DS_CONTINUE_HANDLE)
    {
        macError = GetQueryFromContextList(pGetRecordList->fIOContinueData, &pQuery);
        if (macError == eDSNoErr)
        {
            LOG("Already processed this query, handling IO continuation for result record data");
            goto HandleResponse;
        }
    }

    macError = LWIQuery::Create(!pGetRecordList->fInAttribInfoOnly,
                                true, // The query results will support fIOContinue (split large results over many calls)
                                pGetRecordList->fInNodeRef,
                                Flags,
                                pNetAdapterList,
                                &pQuery);
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = LWIRecTypeLookup::GetVector(pGetRecordList->fInRecTypeList, &pQuery->_recTypeSet);
    GOTO_CLEANUP_ON_MACERROR(macError);

    macError = LWIAttrLookup::GetVector(pGetRecordList->fInAttribTypeList, &pQuery->_attributeSet);
    GOTO_CLEANUP_ON_MACERROR(macError);

    for (iter = 0; iter < recordNameCount; iter++)
    {
        macError = dsDataListGetNodeAlloc( pGetRecordList->fInNodeRef,
                                           pGetRecordList->fInRecNameList,
                                           iter+1,
                                           &pDataNode );
        GOTO_CLEANUP_ON_MACERROR( macError );
        szNames = pDataNode->fBufferData;

        macError = eDSInvalidRecordType;

        if (pQuery->ShouldQueryUserInformation())
        {
            macError_userQuery = pQuery->QueryUserInformationByName(szNames);
            if (macError_userQuery != eDSNoErr)
            {
               LOG("User query failed [Error: %d]", macError_userQuery);
            }
            else
            {
                resultCount++;
            }
        }

        if (pQuery->ShouldQueryGroupInformation())
        {
            macError_groupQuery = pQuery->QueryGroupInformationByName(szNames);
            if (macError_groupQuery != eDSNoErr)
            {
               LOG("Group query failed [Error: %d]", macError_groupQuery);
            }
            else
            {
                resultCount++;
            }
        }

        if (pQuery->ShouldQueryComputerInformation())
        {
            macError_computerQuery = pQuery->QueryComputerInformationByName(szNames);
            if (macError_computerQuery != eDSNoErr)
            {
               LOG("Computer query failed [Error: %d]", macError_computerQuery);
            }
            else
            {
                resultCount++;
            }
        }

        if (pQuery->ShouldQueryComputerGroupInformation())
        {
            macError_computergroupQuery = pQuery->QueryComputerGroupInformationByName(szNames);
            if (macError_computergroupQuery != eDSNoErr)
            {
               LOG("Computer group query failed [Error: %d]", macError_computergroupQuery);
            }
            else
            {
                resultCount++;
            }
        }

        if (pQuery->ShouldQueryComputerListInformation())
        {
            macError_computerlistQuery = pQuery->QueryComputerListInformationByName(szNames);
            if (macError_computerlistQuery != eDSNoErr)
            {
               LOG("Computer list query failed [Error: %d]", macError_computerlistQuery);
            }
            else
            {
                resultCount++;
            }
        }

        dsDataNodeDeAllocate(NULL, pDataNode);
        pDataNode = NULL;
    }

    // If both queries failed, it is a problem
    if (resultCount == 0 &&
        (macError_userQuery != eDSNoErr) &&
        (macError_groupQuery != eDSNoErr) &&
        (macError_computerQuery != eDSNoErr) &&
        (macError_computergroupQuery != eDSNoErr) &&
        (macError_computerlistQuery != eDSNoErr))
    {
       macError = (pQuery->ShouldQueryUserInformation() ? macError_userQuery : macError_groupQuery);
       GOTO_CLEANUP_ON_MACERROR(macError);
    }
    else
       macError = eDSNoErr;

HandleResponse:

    // Write the results
    macError = pQuery->WriteResponse(pGetRecordList->fInDataBuff->fBufferData,
                                     pGetRecordList->fInDataBuff->fBufferSize,
                                     bytesWritten,
                                     nRecordsWritten,
                                     TotalRecords);
    GOTO_CLEANUP_ON_MACERROR(macError);

    if (TotalRecords > nRecordsWritten)
    {
        macError = AddQueryToContextList(pQuery, &HandleId);
        GOTO_CLEANUP_ON_MACERROR(macError);

        pQuery = NULL;

        pGetRecordList->fIOContinueData = HandleId;
    }
    else
    {
        pGetRecordList->fIOContinueData = 0;
    }

    pGetRecordList->fInDataBuff->fBufferLength = bytesWritten;
    pGetRecordList->fOutRecEntryCount = nRecordsWritten;

    if ( bytesWritten > 0 )
    {
#ifdef SHOW_ALL_DEBUG_SPEW
        LOG_BUFFER(pGetRecordList->fInDataBuff->fBufferData, bytesWritten);
#endif
    }

cleanup:

    if (pDataNode)
    {
        dsDataNodeDeAllocate(0, pDataNode);
    }

    if (pQuery)
    {
        delete pQuery;
    }

    if (macError == eDSBufferTooSmall)
    {
        pGetRecordList->fIOContinueData = (tContextData)SPECIAL_DS_CONTINUE_HANDLE;
    }

    LOG_LEAVE("fOutRecEntryCount = %d, fInDataBuff = { length = %d, size = %d }, fIOContinueData = %d, macError = %d",
              pGetRecordList->fOutRecEntryCount,
              pGetRecordList->fInDataBuff->fBufferLength,
              pGetRecordList->fInDataBuff->fBufferSize,
              pGetRecordList->fIOContinueData,
              macError);

    return macError;
}