Преглед на файлове

HPCC-22030 Add whitelist mechanism to Dali

NB: also adjust a few regression suite queries, that tried
to access Dali from thor slaves, by from within the query,
enabling 'slaveDaliClient'.
Which now, even when enabled would give 'Access denied' by
default via whitelist mechanism.

Signed-off-by: Jake Smith <jake.smith@lexisnexisrisk.com>
Jake Smith преди 6 години
родител
ревизия
f594983c4d

+ 1 - 1
dali/base/daclient.cpp

@@ -290,7 +290,7 @@ bool updateDaliEnv(IPropertyTree *env, bool forceGroupUpdate, const char *daliIp
     Owned<IGroup> group = createIGroup(epa);
 
     bool ret = true;
-    initClientProcess(group, DCR_Util);
+    initClientProcess(group, DCR_UpdateEnv);
     StringBuffer response;
     if (querySDS().updateEnvironment(env, forceGroupUpdate, response))
     {

+ 2 - 2
dali/base/dacoven.cpp

@@ -37,12 +37,12 @@ extern void closedownDFS();
 // base is saved in store whenever block exhausted, so replacement coven servers can restart 
 
 // server side versioning.
-#define ServerVersion    "3.15"
+#define ServerVersion    "3.2"
 #define MinClientVersion "1.5"
 
 
 // client side default versioning.
-static StringAttr ClientVersion("3.6");
+static StringAttr ClientVersion("3.7");
 static StringAttr MinServerVersion("3.1");      // when this upped check initClientProcess instances
 static CDaliVersion _ServerVersion;
 

+ 3 - 0
dali/base/dadiags.cpp

@@ -256,6 +256,9 @@ public:
                     bool success = querySDSServer().setSDSDebug(arr, reply);
                     mb.append(success).append(reply);
                 }
+                else if (0 == stricmp(id, "whitelist")) {
+                    mb.append(querySessionManager().getWhiteList(buf).str());
+                }
                 else
                     mb.append(StringBuffer("UNKNOWN OPTION: ").append(id).str());
             }

+ 4 - 7
dali/base/dasds.cpp

@@ -6477,14 +6477,11 @@ void CCovenSDSManager::saveDelta(const char *path, IPropertyTree &changeTree)
     if (externalEnvironment)
     {
         // don't save any changed to /Environment if external
-        if (0 == strncmp("/Environment", path, strlen("/Environment")))
-        {
-            OWARNLOG("Attempt to change read-only Dali environment, path = %s", path);
-            return;
-        }
-        if (0 == strcmp("/", path) && changeTree.hasProp("*[@name=\"Environment\"]"))
+
+        if (startsWith(path, "/Environment") || (streq(path, "/") && changeTree.hasProp("*[@name=\"Environment\"]")))
         {
-            OWARNLOG("Attempt to change read-only Dali environment, path = %s", path);
+            querySessionManager().refreshWhiteList();
+            PROGLOG("Dali Environment updated, path = %s", path);
             return;
         }
     }

+ 308 - 17
dali/base/dasess.cpp

@@ -16,6 +16,10 @@
 ############################################################################## */
 
 #define da_decl DECL_EXPORT
+
+#include <unordered_map>
+#include <unordered_set>
+
 #include "platform.h"
 #include "jlib.hpp"
 #include "jfile.hpp"
@@ -41,32 +45,62 @@ using namespace cryptohelper;
 #pragma warning (disable : 4355)
 #endif
 
+static std::unordered_map<std::string, DaliClientRole> daliClientRoleMap = {
+    { "Private", DCR_Private },
+    { "ThorSlave", DCR_ThorSlave },
+    { "ThorMaster", DCR_ThorMaster },
+    { "EclCCServer", DCR_EclCCServer },
+    { "EclCC", DCR_EclCC },
+    { "EclServer", DCR_EclServer },
+    { "EclScheduler", DCR_EclScheduler },
+    { "EclAgent", DCR_EclAgent },
+    { "AgentExec", DCR_AgentExec },
+    { "DaliServer", DCR_DaliServer },
+    { "SashaServer", DCR_SashaServer },
+    { "DfuServer", DCR_DfuServer },
+    { "EspServer", DCR_EspServer },
+    { "Config", DCR_Config },
+    { "SchedulerAdmin", DCR_ScheduleAdmin },
+    { "RoxieMaster", DCR_RoxyMaster },
+    { "BackupGen", DCR_BackupGen },
+    { "DaFsControl", DCR_DaFsControl },
+    { "SwapNode", DCR_SwapNode },
+    { "DaliAdmin", DCR_DaliAdmin },
+    { "UpdateEnv", DCR_UpdateEnv },
+    { "TreeView", DCR_TreeView },
+    { "DaliDiag", DCR_DaliDiag },
+    { "Testing", DCR_Testing },
+    { "XRef", DCR_XRef }
+};
+
 const char *queryRoleName(DaliClientRole role)
 {
     switch (role) {
     case DCR_Private: return "Private";
-    case DCR_Diagnostic: return "Diagnostic";
     case DCR_ThorSlave: return "ThorSlave";
     case DCR_ThorMaster: return "ThorMaster";
     case DCR_EclCCServer: return "EclCCServer";
-    case DCR_EclCC: return "eclcc";
+    case DCR_EclCC: return "EclCC";
     case DCR_EclServer: return "EclServer";
     case DCR_EclScheduler: return "EclScheduler";
     case DCR_EclAgent: return "EclAgent";
     case DCR_AgentExec: return "AgentExec";
     case DCR_DaliServer:return "DaliServer";
     case DCR_SashaServer: return "SashaServer";
-    case DCR_Util: return "Util";
-    case DCR_Dfu: return "Dfu";
     case DCR_DfuServer: return "DfuServer";
     case DCR_EspServer: return "EspServer";
-    case DCR_WuClient: return "WuClient";
     case DCR_Config: return "Config";
-    case DCR_Scheduler: return "Scheduler";
+    case DCR_ScheduleAdmin: return "SchedulerAdmin";
     case DCR_RoxyMaster: return "RoxieMaster";
-    case DCR_RoxySlave: return "RoxieSlave";
     case DCR_BackupGen: return "BackupGen";
-    case DCR_Other: return "Other";
+    case DCR_DaFsControl: return "DaFsControl";
+    case DCR_SwapNode: return "SwapNode";
+    case DCR_DaliAdmin: return "DaliAdmin";
+    case DCR_UpdateEnv: return "UpdateEnv";
+    case DCR_TreeView: return "TreeView";
+    case DCR_DaliDiag: return "DaliDiag";
+    case DCR_Testing: return "Testing";
+    case DCR_XRef: return "XRef";
     }
     return "Unknown";
 }
@@ -1081,19 +1115,17 @@ public:
 
     bool checkScopeScansLDAP()
     {
-        assertex(!"checkScopeScansLDAP called on client");
-        return true; // actually only used server size
+        throwUnexpectedX("checkScopeScansLDAP called on client");
     }
 
     unsigned getLDAPflags()
     {
-        assertex(!"getLdapFlags called on client");
-        return 0;
+        throwUnexpectedX("getLdapFlags called on client");
     }
 
     void setLDAPflags(unsigned)
     {
-        assertex(!"setLdapFlags called on client");
+        throwUnexpectedX("setLdapFlags called on client");
     }
 
     SessionId startSession(SecurityToken tok, SessionId parentid)
@@ -1118,6 +1150,16 @@ public:
         queryCoven().sendRecv(mb,RANK_RANDOM,MPTAG_DALI_SESSION_REQUEST,SESSIONREPLYTIMEOUT);
     }
 
+    virtual void refreshWhiteList() override
+    {
+        throwUnexpectedX("refreshWhiteList called on client");
+    }
+
+    virtual StringBuffer &getWhiteList(StringBuffer &out) const override
+    {
+        throwUnexpectedX("getWhiteList called on client");
+    }
+
     void onClose(SocketEndpoint &ep)
     {
         CHECKEDCRITICALBLOCK(sessmanagersect,60000);
@@ -1267,9 +1309,246 @@ public:
 };
 
 
-class CCovenSessionManager: public CSessionManagerBase, implements ISessionManagerServer, implements ISubscriptionManager
+// std::hash specialization for DaliClientRole, used in std::pair for whiteList
+namespace std {
+    template <>
+    struct hash<DaliClientRole> {
+        size_t operator ()(DaliClientRole value) const {
+            return static_cast<size_t>(value);
+        }
+    };
+}
+
+/* NB: Ideally this belongs within common/environment,
+ * however, that would introduce a circular dependency.
+ */
+class CWhiteListHandler
 {
+    struct PairHasher
+    {
+        template <class T1, class T2>
+        std::size_t operator () (std::pair<T1, T2> const &pair) const
+        {
+            std::size_t h1 = std::hash<T1>()(pair.first);
+            std::size_t h2 = std::hash<T2>()(pair.second);
+            return h1 ^ h2;
+        }
+    };
+    std::unordered_set<std::pair<std::string, DaliClientRole>, PairHasher> whiteList;
+    std::unordered_map<std::string, std::string> machineMap;
+    mutable CriticalSection populatedCrit;
+    bool populated = false;
+    bool enabled = true;
 
+    void populateMachineMap(IPropertyTree &environment)
+    {
+        Owned<IPropertyTreeIterator> machineIter = environment.getElements("Hardware/Computer");
+        ForEach(*machineIter)
+        {
+            const IPropertyTree &machine = machineIter->query();
+            const char *name = machine.queryProp("@name");
+            const char *host = machine.queryProp("@netAddress");
+            machineMap.insert({name, host});
+        }
+    }
+    const char *resolveComputer(const char *compName, StringBuffer &result) const
+    {
+        const auto &it = machineMap.find(compName);
+        if (it == machineMap.end())
+            return nullptr;
+        IpAddress ip(it->second.c_str());
+        if (ip.isNull())
+            return nullptr;
+        return ip.getIpText(result);
+    }
+    void addRoles(const IPropertyTree &component, const std::vector<DaliClientRole> &roles)
+    {
+        Owned<IPropertyTreeIterator> instanceIter = component.getElements("Instance");
+        ForEach(*instanceIter)
+        {
+            const char *compName = instanceIter->query().queryProp("@computer");
+            StringBuffer ipSB;
+            const char *ip = resolveComputer(compName, ipSB);
+            if (ip)
+            {
+                for (auto &role: roles)
+                    whiteList.insert({ ip, role });
+            }
+        }
+    }
+    void populate()
+    {
+        Owned<IRemoteConnection> conn = querySDS().connect("/Environment", 0, 0, INFINITE);
+        assertex(conn);
+        populateMachineMap(*conn->queryRoot());
+        enum SoftwareComponentType
+        {
+            RoxieCluster,
+            ThorCluster,
+            EclAgentProcess,
+            DfuServerProcess,
+            EclCCServerProcess,
+            EspProcess,
+            SashaServerProcess,
+            EclSchedulerProcess,
+            DaliServerProcess,
+            BackupNodeProcess,
+            EclServerProcess,
+        };
+        std::unordered_map<std::string, SoftwareComponentType> softwareTypeRoleMap = {
+                { "RoxieCluster", RoxieCluster },
+                { "ThorCluster", ThorCluster },
+                { "EclAgentProcess", EclAgentProcess },
+                { "DfuServerProcess", DfuServerProcess },
+                { "EclCCServerProcess", EclCCServerProcess },
+                { "EspProcess", EspProcess },
+                { "SashaServerProcess", SashaServerProcess },
+                { "EclSchedulerProcess", EclSchedulerProcess },
+                { "DaliServerProcess", DaliServerProcess },
+                { "BackupNodeProcess", BackupNodeProcess },
+                { "EclServerProcess", EclServerProcess },
+        };
+
+        Owned<IPropertyTreeIterator> softwareIter = conn->queryRoot()->getElements("Software/*");
+        ForEach(*softwareIter)
+        {
+            const IPropertyTree &component = softwareIter->query();
+            const char *compProcess = component.queryName();
+            const auto &it = softwareTypeRoleMap.find(compProcess);
+            if (it != softwareTypeRoleMap.end())
+            {
+                switch (it->second)
+                {
+                    case RoxieCluster:
+                    {
+                        Owned<IPropertyTreeIterator> serverIter = component.getElements("RoxieServerProcess");
+                        ForEach(*serverIter)
+                        {
+                            const char *serverCompName = serverIter->query().queryProp("@name");
+                            StringBuffer ipSB;
+                            const char *ip = resolveComputer(serverCompName, ipSB);
+                            if (ip)
+                                whiteList.insert({ ip, DCR_RoxyMaster });
+                        }
+                        break;
+                    }
+                    case ThorCluster:
+                    {
+                        const char *masterCompName = component.queryProp("ThorMasterProcess/@computer");
+                        StringBuffer ipSB;
+                        const char *ip = resolveComputer(masterCompName, ipSB);
+                        if (ip)
+                            whiteList.insert({ ip, DCR_ThorMaster });
+                        break;
+                    }
+                    case EclAgentProcess:
+                        addRoles(component, { DCR_EclAgent, DCR_AgentExec });
+                        break;
+                    case DfuServerProcess:
+                        addRoles(component, { DCR_DfuServer });
+                        break;
+                    case EclCCServerProcess:
+                        addRoles(component, { DCR_EclCCServer, DCR_EclCC });
+                        break;
+                    case EclServerProcess:
+                        addRoles(component, { DCR_EclServer, DCR_EclCC });
+                        break;
+                    case EspProcess:
+                        addRoles(component, { DCR_EspServer });
+                        break;
+                    case SashaServerProcess:
+                        addRoles(component, { DCR_SashaServer, DCR_XRef });
+                        break;
+                    case EclSchedulerProcess:
+                        addRoles(component, { DCR_EclScheduler });
+                        break;
+                    case BackupNodeProcess:
+                        addRoles(component, { DCR_BackupGen });
+                        break;
+                    case DaliServerProcess:
+                        addRoles(component, { DCR_DaliServer, DCR_DaliDiag, DCR_SwapNode, DCR_UpdateEnv, DCR_DaliAdmin, DCR_TreeView, DCR_Testing, DCR_DaFsControl, DCR_XRef, DCR_Config, DCR_ScheduleAdmin });
+                        break;
+                }
+            }
+        }
+        IPropertyTree *whiteListTree = conn->queryRoot()->queryPropTree("WhiteList");
+        if (whiteListTree)
+        {
+            enabled = whiteListTree->getPropBool("@enabled", true); // on by default
+            Owned<IPropertyTreeIterator> whiteListIter = whiteListTree->getElements("Entry");
+            ForEach(*whiteListIter)
+            {
+                const IPropertyTree &entry = whiteListIter->query();
+                StringArray hosts, roles;
+                hosts.appendListUniq(entry.queryProp("@hosts"), ",");
+                roles.appendListUniq(entry.queryProp("@roles"), ",");
+                ForEachItemIn(h, hosts)
+                {
+                    ForEachItemIn(r, roles)
+                    {
+                        const char *roleStr = roles.item(r);
+                        const auto &it = daliClientRoleMap.find(roleStr);
+                        if (it != daliClientRoleMap.end())
+                        {
+                            IpAddress ip(hosts.item(h));
+                            if (!ip.isNull())
+                            {
+                                StringBuffer ipStr;
+                                whiteList.insert({ ip.getIpText(ipStr).str(), it->second });
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        populated = true;
+    }
+    void ensurePopulated() const
+    {
+        // should be called within CS
+        if (populated)
+            return;
+        (const_cast <CWhiteListHandler *> (this))->populate();
+    }
+public:
+    bool isWhiteListed(const char *ip, DaliClientRole role) const
+    {
+        CriticalBlock block(populatedCrit);
+        ensurePopulated();
+        const auto &it = whiteList.find({ip, role});
+        if (it != whiteList.end())
+            return true;
+        else if (enabled)
+            return false;
+        else
+        {
+            WARNLOG("Whitelist mechanism is currently disabled");
+            return true;
+        }
+    }
+    StringBuffer &getWhiteList(StringBuffer &out) const
+    {
+        CriticalBlock block(populatedCrit);
+        ensurePopulated();
+        for (auto &it: whiteList)
+            out.append(it.first.c_str()).append(", ").append(queryRoleName(it.second)).append("\n");
+        return out;
+    }
+    void refresh()
+    {
+        /* NB: clear only, so that next usage will re-populated
+         * Do not want to repopulate now, because refresh() is likely called within a update write transaction
+         */
+        CriticalBlock block(populatedCrit);
+        enabled = true;
+        whiteList.clear();
+        machineMap.clear();
+        populated = false;
+    }
+};
+
+class CCovenSessionManager: public CSessionManagerBase, implements ISessionManagerServer, implements ISubscriptionManager
+{
     CSessionRequestServer   sessionrequestserver;
     CSessionStateTable      sessionstates;
     CMapProcessToSession    processlookup;
@@ -1279,6 +1558,7 @@ class CCovenSessionManager: public CSessionManagerBase, implements ISessionManag
     atomic_t ldapwaiting;
     Semaphore workthreadsem;
     bool stopping;
+    CWhiteListHandler whiteListHandler;
 
     void remoteAddProcessSession(rank_t dst,SessionId id,INode *node, DaliClientRole role)
     {
@@ -1317,7 +1597,6 @@ public:
         stubTable.kill();
     }
 
-
     void start()
     {
         sessionrequestserver.start();
@@ -1624,7 +1903,9 @@ public:
 
     bool authorizeConnection(const INode *client, DaliClientRole role)
     {
-        return true;
+        StringBuffer ipStr;
+        client->endpoint().getIpText(ipStr);
+        return whiteListHandler.isWhiteListed(ipStr, role);
     }
 
 
@@ -1790,6 +2071,16 @@ protected:
         }
     }
 
+    virtual void refreshWhiteList() override
+    {
+        whiteListHandler.refresh();
+    }
+
+    virtual StringBuffer &getWhiteList(StringBuffer &out) const override
+    {
+        return whiteListHandler.getWhiteList(out);
+    }
+
     void onClose(SocketEndpoint &ep)
     {
         StringBuffer clientStr;
@@ -1909,7 +2200,7 @@ public:
 
     void nodeDown(rank_t rank)
     {
-        assertex(!"TBD");
+        throwUnexpectedX("TBD");
     }
 
 };

+ 19 - 8
dali/base/dasess.hpp

@@ -44,31 +44,40 @@ enum DaliClientRole // if changed must update queryRoleName()
 {
     DCR_Unknown,
     DCR_Private,
-    DCR_Diagnostic,
+    DCR_Deprecated1,
     DCR_ThorSlave,
     DCR_ThorMaster,
-    DCR_Deprecated1, // legacy role
     DCR_Deprecated2, // legacy role
     DCR_Deprecated3, // legacy role
+    DCR_Deprecated4, // legacy role
     DCR_EclServer,
     DCR_EclAgent,
     DCR_DaliServer, // special (self)
     DCR_SashaServer,
-    DCR_Util,
-    DCR_Dfu,
+    DCR_Deprecated5,
+    DCR_Deprecated6,
     DCR_DfuServer,
     DCR_EspServer,
-    DCR_WuClient, // GAB etc
+    DCR_Deprecated7,
     DCR_Config,
-    DCR_Scheduler,
+    DCR_Deprecated8,
     DCR_RoxyMaster,
-    DCR_RoxySlave,
-    DCR_Other,
+    DCR_Deprecated9,
+    DCR_Deprecated10,
     DCR_BackupGen,
     DCR_AgentExec,
     DCR_EclScheduler,
     DCR_EclCCServer,
     DCR_EclCC,
+    DCR_DaFsControl,
+    DCR_SwapNode,
+    DCR_DaliAdmin,
+    DCR_UpdateEnv,
+    DCR_TreeView,
+    DCR_DaliDiag,
+    DCR_ScheduleAdmin,
+    DCR_Testing,
+    DCR_XRef,
     DCR_Max
 };
 
@@ -122,6 +131,8 @@ interface ISessionManager: extends IInterface
     virtual bool clearPermissionsCache(IUserDescriptor *udesc)=0;
     virtual bool queryScopeScansEnabled(IUserDescriptor *udesc, int * err, StringBuffer &retMsg)=0;
     virtual bool enableScopeScans(IUserDescriptor *udesc, bool enable, int * err, StringBuffer &retMsg)=0;
+    virtual void refreshWhiteList() = 0;
+    virtual StringBuffer &getWhiteList(StringBuffer &out) const = 0;
 };
 
 // the following are getPermissionsLDAP input flags for audit reporting

+ 1 - 1
dali/daliadmin/daliadmin.cpp

@@ -3330,7 +3330,7 @@ int main(int argc, char* argv[])
                 epa.append(ep);
                 Owned<IGroup> group = createIGroup(epa);
                 unsigned start = msTick();
-                initClientProcess(group, DCR_Util);
+                initClientProcess(group, DCR_DaliAdmin);
                 daliconnectelapsed = msTick()-start;
             }
             catch (IException *e) {

+ 3 - 2
dali/dalidiag/dalidiag.cpp

@@ -40,6 +40,7 @@ void usage(const char *exe)
     printf("-sdsstats           -- SDS statistics\n");
     printf("-sdssubscribers     -- list active SDS subscribers\n");
     printf("-connections        -- list SDS connections\n");
+    printf("-whitelist          -- list white list\n");
     printf("-threads            -- running threads\n");
     printf("-mpqueue            -- list waiting MP queue items\n");
     printf("-clients            -- list connected Dali clients\n");
@@ -520,10 +521,10 @@ int main(int _argc, char* argv[])
     }
     Owned<IGroup> group = createIGroup(epa); 
     assertex(group);
-    //CSystemCapability capability(DCR_Diagnostic, "DALIDIAG");
+    //CSystemCapability capability(DCR_DaliDiag, "DALIDIAG");
     //capability.secure((byte *)CLIENT_ENCRYPT_KEY, strlen(CLIENT_ENCRYPT_KEY));
     assertex(group);
-    initClientProcess(group, DCR_Diagnostic, 0, NULL, NULL, MP_WAIT_FOREVER);
+    initClientProcess(group, DCR_DaliDiag, 0, NULL, NULL, MP_WAIT_FOREVER);
 
     if (argc<2)
     {

+ 4 - 4
dali/datest/datest.cpp

@@ -2592,7 +2592,7 @@ public:
             Sleep(1000);
             WriteLockBlock b(*reinitLock);
             PROGLOG("shutdown / reinit test");
-            reinitClientProcess(group, DCR_Other);
+            reinitClientProcess(group, DCR_Testing);
         }
         else
         {
@@ -3089,7 +3089,7 @@ void TestServerShutdown(IGroup *group)
         catch (IException *e) {
             pexception("Exception",e);
         }
-        reinitClientProcess(group, DCR_Other);
+        reinitClientProcess(group, DCR_Testing);
     }
 }
 
@@ -3447,9 +3447,9 @@ int main(int argc, char* argv[])
         IGroup *group = createIGroup(epa); 
 
         if (TEST("SESSION"))
-            initClientProcess(group,DCR_Other, testParams.ordinality() ? 0 : 7777);
+            initClientProcess(group,DCR_Testing, testParams.ordinality() ? 0 : 7777);
         else
-            initClientProcess(group, DCR_Other);
+            initClientProcess(group, DCR_Testing);
 
         
         //testlockprop("test::propagated_matchrecs");

+ 1 - 1
dali/datest/dfuwutest.cpp

@@ -955,7 +955,7 @@ int main(int argc, char* argv[])
         ep.set(argv[1],DALI_SERVER_PORT);
         epa.append(ep);
         Owned<IGroup> group = createIGroup(epa); 
-        initClientProcess(group,DCR_Other);
+        initClientProcess(group,DCR_Testing);
         if (0) { 
             //test2();
             //testMultiFilename();

+ 1 - 1
dali/daunittest/daunittest.cpp

@@ -118,7 +118,7 @@ int main( int argc, char **argv )
         SocketEndpointArray epa;
         epa.append(ep);
         Owned<IGroup> group = createIGroup(epa); 
-        initClientProcess(group, DCR_Other);
+        initClientProcess(group, DCR_Testing);
 
 
         // Create the event manager and test controller

+ 1 - 1
dali/dfuxref/dfuxrefmain.cpp

@@ -76,7 +76,7 @@ int main(int argc, char* argv[])
     Owned<IGroup> group = createIGroup(epa); 
     try
     {
-        initClientProcess(group,DCR_Dfu);
+        initClientProcess(group, DCR_XRef);
         setPasswordsFromSDS();
         StringArray args, clusters;
         bool backupcheck = false;

+ 1 - 1
dali/hellodali/hellodali.cpp

@@ -96,7 +96,7 @@ int main(int argc, char* argv[])
     Owned<IGroup> group = createIGroup(1,&dalieps); 
 
     try {
-        initClientProcess(group, DCR_Other);            // I will add a DCR_Orbit at some point
+        initClientProcess(group, DCR_Testing);            // I will add a DCR_Orbit at some point
         try {
             doStuff();
         }

+ 2 - 2
dali/treeview/connect.cpp

@@ -163,9 +163,9 @@ public:
         try
         {
             IGroup * group = createIGroup(epa);
-//          CSystemCapability capability(DCR_Diagnostic, "DALITREE");
+//          CSystemCapability capability(DCR_TreeView, "DALITREE");
 //          capability.secure((byte *)CLIENT_ENCRYPT_KEY, strlen(CLIENT_ENCRYPT_KEY));
-            if(initClientProcess(group, DCR_Util, 0, NULL, NULL, CONNECTION_TIMEOUT))//, &capability)) 
+            if(initClientProcess(group, DCR_TreeView, 0, NULL, NULL, CONNECTION_TIMEOUT))//, &capability))
                 type = CT_remote;
             group->Release();
         }

+ 1 - 1
ecl/scheduleadmin/scheduleadmin.cpp

@@ -330,7 +330,7 @@ int main(int argc, char * const * argv)
         else
             usage();
         Owned<IGroup> serverGroup = createIGroup(argv[1], DALI_SERVER_PORT);
-        initClientProcess(serverGroup, DCR_Other); //PG MORE: right value
+        initClientProcess(serverGroup, DCR_ScheduleAdmin);
         task->doit();
         closedownClientProcess();
     }

+ 1 - 1
fs/dafscontrol/dafscontrol.cpp

@@ -461,7 +461,7 @@ int main(int argc, char* argv[])
                 break;
             }
             Owned<IGroup> daligroup = createIGroup(epa);
-            initClientProcess(daligroup, DCR_Util );
+            initClientProcess(daligroup, DCR_DaFsControl);
             isdali = true;
             ai++;
         }

+ 1 - 3
testing/regress/ecl/apply.ecl

@@ -18,8 +18,6 @@
 import lib_logging;
 import lib_workunitservices;
 
-#option('slaveDaliClient', true);
-
 Display :=
     SERVICE
         unsigned4 echo(const string src) : eclrtl,library='eclrtl',entrypoint='rtlDisplay';
@@ -56,5 +54,5 @@ SEQUENTIAL(
     before(doDisplay('Begin Apply....')),
     after(doDisplay('...End Apply'))
     ),
- OUTPUT(workunitservices.WorkunitMessages(WORKUNIT), { message })
+ NOTHOR(OUTPUT(workunitservices.WorkunitMessages(WORKUNIT), { message }))
 );

+ 0 - 1
testing/regress/ecl/multilfn.ecl

@@ -21,7 +21,6 @@ import std.system.thorlib;
 import Std.File AS FileServices;
 import std.str;
 
-#option('slaveDaliClient', true);
 #option('allFilenamesDynamic', true);
 
 rec := RECORD, MAXLENGTH(256)

+ 14 - 16
testing/regress/ecl/superfile5.ecl

@@ -24,8 +24,6 @@ import Std.System.Thorlib;
 import Std.File AS FileServices;
 import Std.Str;
 
-#option('slaveDaliClient', true);
-
 rec :=
 RECORD
         integer i;
@@ -65,10 +63,10 @@ SEQUENTIAL(
   FileServices.PromoteSuperFileList([prefix + 't5_superfile1',prefix + 't5_superfile2',prefix + 't5_superfile3',prefix + 't5_superfile4'],prefix + 't5_subfile3'),
   FileServices.PromoteSuperFileList([prefix + 't5_superfile1',prefix + 't5_superfile2',prefix + 't5_superfile3',prefix + 't5_superfile4'],prefix + 't5_subfile4'),
   FileServices.PromoteSuperFileList([prefix + 't5_superfile1',prefix + 't5_superfile2',prefix + 't5_superfile3',prefix + 't5_superfile4'],prefix + 't5_subfile5,' + prefix + 't5_subfile1'),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile1')), NAMED('SF5_RES1')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile2')), NAMED('SF5_RES2')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile3')), NAMED('SF5_RES3')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile4')), NAMED('SF5_RES4')),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile1')), NAMED('SF5_RES1'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile2')), NAMED('SF5_RES2'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile3')), NAMED('SF5_RES3'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile4')), NAMED('SF5_RES4'))),
   FileServices.CreateSuperFile(prefix + 't5_superfile5');
   FileServices.AddSuperFile (prefix + 't5_superfile5', prefix + 't5_subfile1'),
   FileServices.CreateSuperFile(prefix + 't5_superfile5',,true);
@@ -83,22 +81,22 @@ SEQUENTIAL(
   FileServices.PromoteSuperFileList([prefix + 't5_superfile1',prefix + 't5_superfile2',prefix + 't5_superfile3',prefix + 't5_superfile4'],prefix + 't5_subfile4',true),
   OUTPUT(ds1,,prefix + 't5_subfile1'),
   OUTPUT(ds5,,prefix + 't5_subfile5'),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile1')), NAMED('SF5_RES5')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile2')), NAMED('SF5_RES6')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile3')), NAMED('SF5_RES7')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile4')), NAMED('SF5_RES8')),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile1')), NAMED('SF5_RES5'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile2')), NAMED('SF5_RES6'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile3')), NAMED('SF5_RES7'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile4')), NAMED('SF5_RES8'))),
   FileServices.PromoteSuperFileList([prefix + 't5_superfile1',prefix + 't5_superfile2',prefix + 't5_superfile3',prefix + 't5_superfile4'],,false,reverse:=true),
   FileServices.PromoteSuperFileList([prefix + 't5_superfile1',prefix + 't5_superfile2',prefix + 't5_superfile3',prefix + 't5_superfile4'],,true,reverse:=true),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile1')), NAMED('SF5_RES9')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile2')), NAMED('SF5_RES10')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile3')), NAMED('SF5_RES11')),
-  OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile4')), NAMED('SF5_RES12')),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile1')), NAMED('SF5_RES9'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile2')), NAMED('SF5_RES10'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile3')), NAMED('SF5_RES11'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.SuperFileContents(prefix + 't5_superfile4')), NAMED('SF5_RES12'))),
   OUTPUT(FileServices.GetSuperFileSubCount(prefix + 't5_superfile1'), NAMED('SF5_RES13')),
   OUTPUT(FileServices.GetSuperFileSubCount(prefix + 't5_superfile2'), NAMED('SF5_RES14')),
   OUTPUT(stripPrefix(FileServices.GetSuperFileSubName(prefix + 't5_superfile1',1)), NAMED('SF5_RES15')),
   OUTPUT(stripPrefix(FileServices.GetSuperFileSubName(prefix + 't5_superfile2',1)), NAMED('SF5_RES16')),
-  OUTPUT(stripPrefixList(FileServices.LogicalFileSuperOwners(prefix + 't5_subfile1')), NAMED('SF5_RES17')),
-  OUTPUT(stripPrefixList(FileServices.LogicalFileSuperOwners(prefix + 't5_subfile2')), NAMED('SF5_RES18')),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.LogicalFileSuperOwners(prefix + 't5_subfile1')), NAMED('SF5_RES17'))),
+  NOTHOR(OUTPUT(stripPrefixList(FileServices.LogicalFileSuperOwners(prefix + 't5_subfile2')), NAMED('SF5_RES18'))),
   OUTPUT('Done')
 );
 

+ 0 - 2
testing/regress/ecl/superfile6.ecl

@@ -23,8 +23,6 @@ prefix := setup.Files(false, false).QueryFilePrefix;
 
 // Super File added to itself test
 
-#option('slaveDaliClient', true);
-
 string fsuper := prefix+'t6_superfile';
 string fsub := prefix + 't6_subfile';
 

+ 1 - 1
testing/unittests/dalitests.cpp

@@ -62,7 +62,7 @@ void daliClientInit()
     SocketEndpointArray epa;
     epa.append(ep);
     Owned<IGroup> group = createIGroup(epa);
-    initClientProcess(group, DCR_Other);
+    initClientProcess(group, DCR_Testing);
 
     initCounter++;
 }

+ 1 - 1
tools/swapnode/swapnode.cpp

@@ -47,7 +47,7 @@ struct DaliClient
         if (!serverGroup)
             throw MakeStringException(0, "Could not instantiate IGroup");
 
-        if (!initClientProcess(serverGroup,DCR_Util))
+        if (!initClientProcess(serverGroup,DCR_SwapNode))
             throw MakeStringException(0, "Could not initializing client process");
         setPasswordsFromSDS();
     }

+ 1 - 1
tools/wutool/wutool.cpp

@@ -363,7 +363,7 @@ int main(int argc, const char *argv[])
         if (globals->getProp("DALISERVER", daliServers))
         {
             Owned<IGroup> serverGroup = createIGroup(daliServers.str(), DALI_SERVER_PORT);
-            initClientProcess(serverGroup,DCR_Other);
+            initClientProcess(serverGroup, DCR_Testing);
             setPasswordsFromSDS();
         }
         else if (!serverSpecified)