Пример #1
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;
}
Пример #2
0
// ---------------------------------------------------------------------------
// * PlugInShell_ProcessRequest
//
//  inData      : A pointer to a data structure representing the current
//                server call.
//
//  This routine is called continuiously throughout the operation of the
//  Directory Services process.
// ---------------------------------------------------------------------------
long
PlugInShell_ProcessRequest(void *inData)
{
    long macError = eDSNoErr;    
    bool isAcquired = false;
    sHeader * pMsgHdr = (sHeader *)inData;
    unsigned long msgType = pMsgHdr ? pMsgHdr->fType : 0;

    LOG_ENTER("inData = @%p => { fType = %lu (%s) }", inData, msgType, TypeToString(msgType));

    if (!inData)
    {
        macError = eDSNullParameter;
        GOTO_CLEANUP();
    }

    GS_ACQUIRE_SHARED();
    isAcquired = true;
    
    GS_VERIFY_INITIALIZED(macError);

    //
    // We currently do not handle anything while not "active".
    //
    if ( !FlagOn(GlobalState.PluginState, kActive) )
    {
        macError = ePlugInNotActive;
        GOTO_CLEANUP();
    }
    
    //
    // We also do not handle anything while not "startup complete".
    //
    if (GlobalState.IsStartupComplete == false &&
            msgType != kDoPlugInCustomCall &&
            msgType != kServerRunLoop &&
        msgType != kKerberosMutex)
    {
        GS_RELEASE();
        GS_ACQUIRE_EXCLUSIVE();

        if (GlobalState.IsStartupComplete == false)
        {
            BOOLEAN bIsStarted;

            LOG("Re-verify that LSASS service is operational");
            GetLsaStatus(&bIsStarted);
            if (bIsStarted)
            {
                LOG("LSASS service is now operational");
                GlobalState.IsStartupComplete = true;
            }
            else
            {
                if (msgType == kOpenDirNode)
                {
                    /*
                     * Apple says kOpenDirNode should return
                     * eDSOpenNodeFailed if we're offline.
                     */
                    macError = eDSOpenNodeFailed;
                }
                else
                {
                    macError = ePlugInNotActive;
                }

                LOG("Startup of dependent services not complete, therefore network accounts are offline");
                GOTO_CLEANUP();
            }
        }

        GS_RELEASE();
        GS_ACQUIRE_SHARED();
    }

    // ISSUE-2007/05/30-dalmeida -- We should use r/w locks instead so that
    // we can behave sensibly when someone tries to de-activate the plug-in
    // while we are processing something...

    try
    {
        switch ( msgType )
        {
            case kHandleNetworkTransition:
                LOG("Got Network Transition change notice");
                macError = eDSNoErr;
                break;

            case kHandleSystemWillSleep:
                LOG("Got Handle System Will Sleep notice");
                macError = eDSNoErr;
                break;

            case kHandleSystemWillPowerOn:
                LOG("Got Handle System Will Power On notice");
                macError = eDSNoErr;
                break;

            case kOpenDirNode:
                LOG("Start of directory node query");
            macError = LWIDirNodeQuery::Open((sOpenDirNode *)inData);
                break;

            case kDoDirNodeAuth:
            macError = LWIDirNodeQuery::DoDirNodeAuth((sDoDirNodeAuth *)inData,
                                                       GlobalState.IsJoinedToAD,
                                                       GlobalState.pAllowAdminCheckData,
                                                       GlobalState.Flags);
                break;

            case kCloseDirNode:
            macError = LWIDirNodeQuery::Close((sCloseDirNode *)inData);
                break;

            case kGetDirNodeInfo:
            macError = LWIDirNodeQuery::GetInfo((sGetDirNodeInfo *)inData,
                                                GlobalState.Flags,
                                                GlobalState.pNetAdapterList);
                break;

            case kGetAttributeEntry:
            macError = LWIDirNodeQuery::GetAttributeEntry((sGetAttributeEntry *)inData);
                break;

            case kGetRecordEntry:
            macError = LWIDirNodeQuery::GetAttributeEntry((sGetAttributeEntry *)inData);
                break;

            case kGetAttributeValue:
            macError = LWIDirNodeQuery::GetAttributeValue((sGetAttributeValue *)inData);
                break;

            case kCloseAttributeValueList:
            macError = LWIDirNodeQuery::CloseValueList((sCloseAttributeValueList *)inData);
                break;

            case kCloseAttributeList:
            macError = LWIDirNodeQuery::CloseAttributeList((sCloseAttributeList *)inData);
                break;

            case kGetRecordList:
            macError = LWIRecordListQuery::Run((sGetRecordList *)inData, GlobalState.Flags, GlobalState.pNetAdapterList);
                break;

            case kReleaseContinueData:
            macError = LWIRecordListQuery::ReleaseContinueData((sReleaseContinueData *)inData);
                break;

            case kDoAttributeValueSearch:
            case kDoAttributeValueSearchWithData:
            macError = LWIAttrValDataQuery::Run((sDoAttrValueSearchWithData *)inData, GlobalState.Flags, GlobalState.pNetAdapterList);
                break;

            case kDoMultipleAttributeValueSearch:
            case kDoMultipleAttributeValueSearchWithData:
            macError = LWIAttrValDataQuery::Run((sDoMultiAttrValueSearchWithData *)inData, GlobalState.Flags, GlobalState.pNetAdapterList);
                break;

            case kOpenRecord:
                LOG("Start of record query");
            macError = LWIRecordQuery::Open((sOpenRecord*)inData, GlobalState.Flags, GlobalState.pNetAdapterList);
                break;

            case kGetRecordReferenceInfo:
            macError = LWIRecordQuery::GetReferenceInfo((sGetRecRefInfo*)inData);
                break;

            case kCloseRecord:
            macError = LWIRecordQuery::Close((sCloseRecord*)inData);
                break;

            case kGetRecordAttributeInfo:
            macError = LWIRecordQuery::GetAttributeInfo((sGetRecAttribInfo*)inData);
                break;

            case kGetRecordAttributeValueByID:
            macError = LWIRecordQuery::GetAttributeValueByID((sGetRecordAttributeValueByID*)inData);
                break;

            case kGetRecordAttributeValueByIndex:
            macError = LWIRecordQuery::GetAttributeValueByIndex((sGetRecordAttributeValueByIndex*)inData);
                break;

                /* Supported update operations */
            case kAddAttribute:
            macError = LWIRecordQuery::AddAttribute((sAddAttribute*)inData);
                break;

            case kAddAttributeValue:
            macError = LWIRecordQuery::AddAttributeValue((sAddAttributeValue*)inData);
                break;

            case kRemoveAttribute:
            macError = LWIRecordQuery::RemoveAttribute((sRemoveAttribute*)inData);
                break;

            case kFlushRecord:
            macError = LWIRecordQuery::FlushRecord((sFlushRecord*)inData);
                break;

            case kSetAttributeValues:
            macError = LWIRecordQuery::SetAttributeValues((sSetAttributeValues*)inData);
                break;

            case kSetAttributeValue:
            macError = LWIRecordQuery::SetAttributeValue((sSetAttributeValue*)inData);
                break;

            case kSetRecordName:
            case kSetRecordType:
            case kDeleteRecord:
            case kCreateRecord:
            case kCreateRecordAndOpen: /* sCreateRecord */
            case kRemoveAttributeValue:
            case kDoPlugInCustomCall:
            default:
            if ((msgType < kDSPlugInCallsBegin) || (msgType > kDSPlugInCallsEnd))
            {
                    LOG("Unsupported request type: %lu (%s)", msgType, TypeToString(msgType));
            }
            else
            {
                    LOG("Unknown request type: %lu", msgType);
                }
                macError = eNotHandledByThisNode;
                break;
        }
    }
    catch (LWIException& lwi)
    {
        macError = lwi.getErrorCode();
    }

cleanup:

    if (isAcquired)
    {
        GS_RELEASE();
    }

    if (pMsgHdr)
    {
        pMsgHdr->fResult = macError;
    }

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

    return macError;
}
Пример #3
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;
}
Пример #4
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;
}