Bläddra i källkod

HPCC-12059 Need tool to create initial LDAP OUs and admin HPCC user

Currently admins are required to enter the LDAP Admin credentials in the Config
Manager which then gets flushed to the environment and config files. This is
insecure and they are only needed to create the initial OUs and an HPCC Admin
user. This pull request introduces a new "initldap" tool that should be run
once after installing HPCC and running config manager. The tools asks the user
to enter an LDAP Admin user/pw and uses them to create all the OUs and the initial
HPCC Admin that is specified in the config "systemUser" fields

Signed-off-by: William Whitehead <william.whitehead@lexisnexis.com>
William Whitehead 11 år sedan
förälder
incheckning
28a199b0d4
5 ändrade filer med 328 tillägg och 0 borttagningar
  1. 1 0
      tools/CMakeLists.txt
  2. 54 0
      tools/initldap/CMakeLists.txt
  3. 246 0
      tools/initldap/initldap.cpp
  4. 26 0
      tools/initldap/sourcedoc.xml
  5. 1 0
      tools/sourcedoc.xml

+ 1 - 0
tools/CMakeLists.txt

@@ -17,6 +17,7 @@ HPCC_ADD_SUBDIRECTORY (esdlcmd-xml)
 HPCC_ADD_SUBDIRECTORY (hidl)
 HPCC_ADD_SUBDIRECTORY (backupnode "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (addScopes "PLATFORM")
+HPCC_ADD_SUBDIRECTORY (initldap "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (combine "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (dumpkey "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (keydiff "PLATFORM")

+ 54 - 0
tools/initldap/CMakeLists.txt

@@ -0,0 +1,54 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2014 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+
+# Component: initldap
+
+#####################################################
+# Description:
+# ------------
+#    Cmake Input File for initldap
+#####################################################
+
+
+project( initldap )
+
+set (    SRCS
+         initldap.cpp
+    )
+
+include_directories (
+         ./../../system/security/LdapSecurity
+         ./../../system/security/shared
+         ./../../system/jlib
+         ./../../system/include
+         ${CMAKE_BINARY_DIR}
+         ${CMAKE_BINARY_DIR}/oss
+    )
+
+ADD_DEFINITIONS( -D_CONSOLE )
+
+
+HPCC_ADD_EXECUTABLE ( initldap ${SRCS} )
+install ( TARGETS initldap RUNTIME DESTINATION ${EXEC_DIR} )
+
+
+
+target_link_libraries ( initldap
+         jlib
+         LdapSecurity
+    )
+
+

+ 246 - 0
tools/initldap/initldap.cpp

@@ -0,0 +1,246 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2014 HPCC Systems.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+#include "ldapsecurity.ipp"
+#include "ldapsecurity.hpp"
+#include "build-config.h"
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+
+//-----------------------------------------------------
+//
+//-----------------------------------------------------
+void usage()
+{
+    fprintf(stdout, "\nUsage: initldap");
+    fprintf(stdout, "\n\n\tinitldap creates an initial HPCC Admin user account\n\tand all HPCC organization units, using the setting entered into configmanager 'LDAPServer' component\n");
+    fprintf(stdout, "\n");
+}
+
+//-----------------------------------------------------
+//
+//-----------------------------------------------------
+bool initLDAP(IPropertyTree * ldapProps)
+{
+    StringAttr serverType( ldapProps->queryProp("@serverType") );
+    if (!serverType.length())
+    {
+        fprintf(stderr, "\nERROR: serverType not set in LDAPServer component");
+        return false;
+    }
+
+    StringBuffer hpccUser;
+    StringBuffer hpccPwd;
+    ldapProps->getProp("@systemUser", hpccUser);
+    ldapProps->getProp("@systemPassword", hpccPwd);
+    if (0==hpccUser.length() || 0==hpccPwd.length())
+    {
+        fprintf(stderr, "\nERROR: HPCC systemUser credentials not found in configuration");
+        return false;
+    }
+
+    StringBuffer ldapAddress;
+    ldapProps->getProp("@ldapAddress", ldapAddress);
+
+    //Get LDAP admin creds from user
+    char buff[100];
+    fprintf(stdout, "\nEnter the '%s' LDAP Admin User name on '%s'...",serverType.get(),ldapAddress.str());
+    do
+    {
+        fgets(buff, sizeof(buff), stdin);
+    }
+    while (buff[0] == (char)'\n');
+
+    if (buff[strlen(buff)-1] == '\n')
+        buff[strlen(buff)-1] = (char)NULL;
+    StringAttr ldapUser(buff);
+
+    fprintf(stdout, "Enter the LDAP Admin user '%s' password...",ldapUser.get());
+    fgets(buff, sizeof(buff), stdin);
+    if (buff[strlen(buff)-1] == '\n')
+        buff[strlen(buff)-1] = (char)NULL;
+    StringAttr ldapPwd(buff);
+    if (0==ldapUser.length() || 0==ldapPwd.length())
+    {
+        fprintf(stderr, "\nERROR: Invalid LDAP Admin account credentials entered");
+        return false;
+    }
+
+    fprintf(stdout, "\nReady to initialize HPCC LDAP Environment, using the following settings");
+    fprintf(stdout, "\n\tLDAP Server     : %s", ldapAddress.str());
+    fprintf(stdout, "\n\tLDAP Type       : %s", serverType.get());
+    fprintf(stdout, "\n\tHPCC Admin User : %s", hpccUser.str());
+    fprintf(stdout, "\nProceed?  y/n ");
+    for (;;)
+    {
+        int c = getchar();
+        if (c == 'y' || c == 'Y')
+            break;
+        else if (c == 'n' || c == 'N')
+            return true;
+    }
+
+    if (stricmp(serverType.get(),"ActiveDirectory"))
+        ldapProps->setProp("@systemBasedn", "");
+
+    //Replace system user with LDAP Admin credentials
+    ldapProps->setProp("@systemUser", ldapUser);
+    ldapProps->setProp("@systemCommonName", ldapUser);
+    StringBuffer sb;
+    encrypt(sb,ldapPwd);
+    ldapProps->setProp("@systemPassword", sb.str());
+
+    //Create security manager. This creates the required OUs
+    Owned<ISecManager> secMgr;
+    try
+    {
+        secMgr.setown(newLdapSecManager("initldap", *LINK(ldapProps)));
+    }
+    catch(IException *e)
+    {
+        StringBuffer buff;
+        e->errorMessage(buff);
+        e->Release();
+        fprintf(stderr, "\nERROR: Unable to create security manager : %s", buff.str());
+        return false;
+    }
+
+    //Create HPCC Admin user
+    Owned<ISecUser> user = secMgr->createUser(hpccUser.str());
+    StringBuffer pwd;
+    decrypt(pwd, hpccPwd.str());
+    user->credentials().setPassword(pwd.str());
+    try { secMgr->addUser(*user.get()); }
+    catch(...) {}//user may already exist, so just move on
+
+    //Add HPCC admin user to Administrators group
+    CLdapSecManager* ldapSecMgr = dynamic_cast<CLdapSecManager*>(secMgr.get());
+    if (!ldapSecMgr)
+    {
+        fprintf(stderr, "\nERROR: Unable to access CLdapSecManager object");
+        return false;
+    }
+    StringAttr adminGroup;
+    bool isActiveDir = true;
+    if (0 == stricmp(serverType.get(),"ActiveDirectory"))
+        adminGroup.set("Administrators");
+    else
+        adminGroup.set("Directory Administrators");
+    try { ldapSecMgr->changeUserGroup("add", hpccUser.str(), adminGroup); }
+    catch(...) {}//user may already be in group so just move on
+
+    fprintf(stdout, "\n\nLDAP Initialization successful\n");
+    return true;
+}
+
+//-----------------------------------------------------
+//
+//-----------------------------------------------------
+int main(int argc, char* argv[])
+{
+#ifdef _NO_LDAP
+    fprintf(stderr, "System was built with _NO_LDAP\n");
+    return -1;
+#endif
+
+    for (int x = 1; x < argc; x++)
+    {
+        if (0==strncmp("-h", argv[x], 2))
+        {
+            usage();
+            exit(0);
+        }
+        else
+        {
+            fprintf(stderr, "\nERROR: Unrecognized parameter : '%s', enter 'initldap -h' for help\n", argv[x]);
+            exit(1);
+        }
+    }
+
+    InitModuleObjects();
+
+    //execute configgen to query the LDAP Server configuration(s)
+    StringBuffer cmd;
+    cmd.appendf("%s%cconfiggen -env %s%c%s -listldapservers", ADMIN_DIR,PATHSEPCHAR,CONFIG_DIR, PATHSEPCHAR, ENV_XML_FILE);
+
+    char * configBuffer = NULL;
+
+    //acquire LDAP configuration by executing configgen and capturing output
+    {
+        StringBuffer configBuff;
+        Owned<IPipeProcess> pipe = createPipeProcess();
+        if (pipe->run("configgen", cmd.str(), ".", false, true, true, 0))
+        {
+            Owned<ISimpleReadStream> pipeReader = pipe->getOutputStream();
+            const size32_t chunkSize = 8192;
+            for (;;)
+            {
+                size32_t sizeRead = pipeReader->read(chunkSize, configBuff.reserve(chunkSize));
+                if (sizeRead < chunkSize)
+                {
+                    configBuff.setLength(configBuff.length() - (chunkSize - sizeRead));
+                    break;
+                }
+            }
+            pipe->closeOutput();
+        }
+        int retcode = pipe->wait();
+        if (retcode)
+        {
+            fprintf(stderr, "\nERROR %d: unable to execute %s", retcode, cmd.str());
+            exit(1);
+        }
+        configBuffer = strdup(configBuff.str());
+    }
+
+    //Using the LDAP Server parms queried from configgen, build an
+    //LDAPSecurity property tree for each LDAP Server and call the LDAP
+    //Security Manager to create the needed entries
+    Owned<IPropertyTree> ldapProps;
+    char *saveptr;
+    char * pLine = strtok_r(configBuffer, "\n", &saveptr);
+    while (pLine)
+    {
+        if (pLine && 0==strcmp(pLine, "LDAPServerProcess"))
+        {
+            if (ldapProps)
+                initLDAP(ldapProps);
+            ldapProps.clear();
+            ldapProps.setown(createPTree("ldapSecurity"));
+        }
+        else
+        {
+            char * sep = strchr(pLine, ',');
+            if (sep)
+            {
+                *sep = (char)NULL;
+                ldapProps->addProp(pLine, sep+1);
+            }
+        }
+        pLine = strtok_r(NULL, "\n", &saveptr);
+    }
+    if (ldapProps)
+        initLDAP(ldapProps);
+    if (configBuffer)
+        free(configBuffer);
+    ldapProps.clear();
+
+    releaseAtoms();
+    return 0;
+}

+ 26 - 0
tools/initldap/sourcedoc.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2014 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+-->
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<section>
+    <title>tools/initldap</title>
+
+    <para>
+        The tools/initldap directory contains the sources for the tools/initldap tool.
+    </para>
+</section>

+ 1 - 0
tools/sourcedoc.xml

@@ -38,4 +38,5 @@
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="testsocket/sourcedoc.xml"/>
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="vkey/sourcedoc.xml"/>
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="wuget/sourcedoc.xml"/>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="initldap/sourcedoc.xml"/>
 </section>