Explorar o código

HPCC-15005 Support creating service accounts for HPCC

Need the ability for the security manager to manage employee IDs in the
HPCC user's accounts. This PR updates ws_access and the LDAP security manager
to create/modify/report an optional employee ID.

Signed-off-by: Russ Whitehead <william.whitehead@lexisnexis.com>
Russ Whitehead %!s(int64=8) %!d(string=hai) anos
pai
achega
ee135ddbd5

+ 5 - 1
esp/scm/ws_access.ecm

@@ -38,6 +38,7 @@ ESPstruct UserInfo
     string username;
     string fullname;
     [min_ver("1.07")] string passwordexpiration;
+    [min_ver("1.10")] string employeeID;
 };
 
 ESPstruct GroupInfo
@@ -217,6 +218,7 @@ ESPresponse UserInfoEditInputResponse
     string username;
     string firstname;
     string lastname;
+    [min_ver("1.10")] string employeeID;
 };
 
 ESPrequest UserInfoEditRequest
@@ -224,6 +226,7 @@ ESPrequest UserInfoEditRequest
     string username;
     string firstname;
     string lastname;
+    [min_ver("1.10")] string employeeID;
 };
 
 ESPresponse UserInfoEditResponse
@@ -240,6 +243,7 @@ ESPrequest AddUserRequest
     [label("Last Name"), cols(20)] string lastname;
     [label("Password"), password, cols(20)] password1;
     [label("Retype password"), password, cols(20)] password2;
+    [min_ver("1.10"), label("Employee ID"), cols(20)] string employeeID;
 };
 
 ESPresponse AddUserResponse
@@ -788,7 +792,7 @@ ESPresponse [nil_remove] UserAccountExportResponse
 };
 
 
-ESPservice [version("1.09"), exceptions_inline("./smc_xslt/exceptions.xslt")] ws_access
+ESPservice [version("1.10"), exceptions_inline("./smc_xslt/exceptions.xslt")] ws_access
 {
     ESPmethod [client_xslt("/esp/xslt/access_users.xslt")] Users(UserRequest, UserResponse);
     ESPmethod [client_xslt("/esp/xslt/access_useredit.xslt")] UserEdit(UserEditRequest, UserEditResponse);

+ 23 - 2
esp/services/ws_access/ws_accessService.cpp

@@ -435,6 +435,12 @@ bool Cws_accessEx::onUsers(IEspContext &context, IEspUserRequest &req, IEspUserR
                 oneusr->setFullname(usr->getFullName());
 
                 double version = context.getClientVersion();
+
+                if (version >= 1.10)
+                {
+                    oneusr->setEmployeeID(usr->getEmployeeID());
+                }
+
                 if (version >= 1.07)
                 {
                     StringBuffer sb;
@@ -525,7 +531,6 @@ bool Cws_accessEx::onUserQuery(IEspContext &context, IEspUserQueryRequest &req,
             const char* passwordExpiration = usr.queryProp(getUserFieldNames(UFPasswordExpiration));
             if (passwordExpiration && *passwordExpiration)
                 userInfo->setPasswordexpiration(passwordExpiration);
-
             espUsers.append(*userInfo.getClear());
         }
 
@@ -863,6 +868,12 @@ bool Cws_accessEx::onAddUser(IEspContext &context, IEspAddUserRequest &req, IEsp
             return false;
         }
 
+        const char * employeeID = NULL;
+        if (context.getClientVersion() >= 1.10)
+        {
+            employeeID = req.getEmployeeID();
+        }
+
         Owned<ISecUser> user = secmgr->createUser(username);
         ISecCredentials& cred = user->credentials();
         const char* firstname = req.getFirstname();
@@ -871,6 +882,8 @@ bool Cws_accessEx::onAddUser(IEspContext &context, IEspAddUserRequest &req, IEsp
             user->setFirstName(firstname);
         if(lastname != NULL)
             user->setLastName(lastname);
+        if(employeeID != NULL)
+            user->setEmployeeID(employeeID);
         if(pass1 != NULL)
             cred.setPassword(pass1);
         try
@@ -2568,7 +2581,7 @@ bool Cws_accessEx::onPermissionsReset(IEspContext &context, IEspPermissionsReset
 }
 
 //For every resources inside a baseDN, if there is no permission for this account, add the baseDN name to the basednNames list
-void Cws_accessEx::getBaseDNsForAddingPermssionToAccount(CLdapSecManager* secmgr, const char* prefix, const char* accountName, 
+void Cws_accessEx::getBaseDNsForAddingPermssionToAccount(CLdapSecManager* secmgr, const char* prefix, const char* accountName,
                                            int accountType, StringArray& basednNames)
 {
     if(secmgr == NULL)
@@ -3193,6 +3206,10 @@ bool Cws_accessEx::onUserInfoEdit(IEspContext &context, IEspUserInfoEditRequest
 
         user->setFirstName(firstname);
         user->setLastName(lastname);
+        if (context.getClientVersion() >= 1.10)
+        {
+            user->setEmployeeID(req.getEmployeeID());
+        }
 
         try
         {
@@ -3242,6 +3259,10 @@ bool Cws_accessEx::onUserInfoEditInput(IEspContext &context, IEspUserInfoEditInp
 
         resp.setFirstname(user->getFirstName());
         resp.setLastname(user->getLastName());
+        if (context.getClientVersion() >= 1.10)
+        {
+            resp.setEmployeeID(user->getEmployeeID());
+        }
     }
     catch(IException* e)
     {

+ 37 - 4
system/security/LdapSecurity/ldapconnection.cpp

@@ -1974,7 +1974,7 @@ public:
             Owned<ILdapConnection> lconn = m_connections->getConnection();
             LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
 
-            char        *attrs[] = {"cn", "givenName", "sn", "gidnumber", "uidnumber", "homedirectory", "loginshell", "objectClass", NULL};
+            char        *attrs[] = {"cn", "givenName", "sn", "gidnumber", "uidnumber", "homedirectory", "loginshell", "objectClass", "employeeNumber", NULL};
             CLDAPMessage searchResult;
             int rc = ldap_search_ext_s(ld, (char*)basedn, LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs, 0, NULL, NULL, &timeOut, LDAP_NO_LIMIT,   &searchResult.msg );
 
@@ -2023,6 +2023,8 @@ public:
                                 valind++;
                             }
                         }
+                        else if(stricmp(attribute, "employeeNumber") == 0)
+                            user.setEmployeeID(vals.queryCharValue(0));
                     }
                 }
             }
@@ -2390,7 +2392,7 @@ public:
             filter.appendf(")(|(%s=*%s*)(%s=*%s*)(%s=*%s*)))", act_fieldname, searchstr, "givenName", searchstr, "sn", searchstr);
         }
 
-        char *attrs[] = {act_fieldname, sid_fieldname, "cn", "userAccountControl", "pwdLastSet", NULL};
+        char *attrs[] = {act_fieldname, sid_fieldname, "cn", "userAccountControl", "pwdLastSet", "employeeNumber", NULL};
 
         CPagedLDAPSearch pagedSrch(ld, (char*)m_ldapconfig->getUserBasedn(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
         for (message = pagedSrch.getFirstEntry(); message; message = pagedSrch.getNextEntry())
@@ -2469,6 +2471,12 @@ public:
                             ((CLdapSecUser*)user.get())->setUserID(atoi(vals.queryCharValue(0)));
                     }
                 }
+                else if(stricmp(attribute, "employeeNumber") == 0)
+                {
+                    CLDAPGetValuesLenWrapper vals(ld, message, attribute);
+                    if (vals.hasValues())
+                        user->setEmployeeID(vals.queryCharValue(0));
+                }
             }
             if (user->getName() && *user->getName())
                 users.append(*LINK(user.get()));
@@ -2642,7 +2650,17 @@ public:
                 dispname_values
             };
 
-            LDAPMod *attrs[4];
+
+            StringBuffer emplID(user.getEmployeeID());
+            char *employeeID_values[] = {(char*)emplID.str(), NULL };
+            LDAPMod employeeID_attr =
+            {
+                LDAP_MOD_REPLACE,
+                "employeeNumber",
+                employeeID_values
+            };
+
+            LDAPMod *attrs[5];
             int ind = 0;
         
             attrs[ind++] = &gn_attr;
@@ -2656,6 +2674,9 @@ public:
             {
                 attrs[ind++] = &cn_attr;
             }
+
+            if (!emplID.isEmpty())
+                attrs[ind++] = &employeeID_attr;
             
             attrs[ind] = NULL;
             
@@ -5656,6 +5677,8 @@ private:
             fullname = fullname_buf.str();
         }
 
+        const char* employeeID = user.getEmployeeID();
+
         StringBuffer dn;
         if(m_ldapconfig->getServerType() == ACTIVE_DIRECTORY)
         {
@@ -5745,7 +5768,15 @@ private:
             username_values
         };
 
-        LDAPMod *attrs[8];
+        char* employeeID_values[] = {(char*)employeeID, NULL};
+        LDAPMod employeeID_attr =
+        {
+            LDAP_MOD_ADD,
+            "EmployeeNumber",
+            employeeID_values
+        };
+
+        LDAPMod *attrs[9];
         int ind = 0;
         
         attrs[ind++] = &cn_attr;
@@ -5760,6 +5791,8 @@ private:
         {
             attrs[ind++] = &username_attr;
             attrs[ind++] = &dispname_attr;
+            if (user.getEmployeeID())
+                attrs[ind++] = &employeeID_attr;
         }
         else
         {

+ 12 - 0
system/security/LdapSecurity/ldapsecurity.cpp

@@ -116,6 +116,17 @@ bool CLdapSecUser::setLastName(const char * lname)
     return true;
 }
 
+const char * CLdapSecUser::getEmployeeID()
+{
+    return m_employeeID.get();
+}
+
+bool CLdapSecUser::setEmployeeID(const char * emplID)
+{
+    m_employeeID.set(emplID);
+    return true;
+}
+
 const char * CLdapSecUser::getRealm()
 {
     return m_realm.get();
@@ -194,6 +205,7 @@ void CLdapSecUser::copyTo(ISecUser& destination)
     dest->setFullName(getFullName());
     dest->setFirstName(getFirstName());
     dest->setLastName(getLastName());
+    dest->setEmployeeID(getEmployeeID());
     dest->setRealm(getRealm());
     dest->credentials().setPassword(credentials().getPassword());
     dest->setUserSid(m_usersid.length(), m_usersid.toByteArray());

+ 3 - 0
system/security/LdapSecurity/ldapsecurity.ipp

@@ -40,6 +40,7 @@ private:
     StringAttr   m_firstname;
     StringAttr   m_lastname;
     StringAttr   m_pw;
+    StringAttr   m_employeeID;
     StringAttr   m_Fqdn;
     StringAttr   m_Peer;
     authStatus   m_authenticateStatus;
@@ -79,6 +80,8 @@ public:
     virtual bool setFirstName(const char * fname);
     virtual const char * getLastName();
     virtual bool setLastName(const char * lname);
+    virtual const char * getEmployeeID();
+    virtual bool setEmployeeID(const char * emplID);
     const char * getRealm();
     bool setRealm(const char * name);
     ISecCredentials & credentials();

+ 14 - 0
system/security/shared/SecureUser.hpp

@@ -33,6 +33,7 @@ private:
     StringBuffer    m_fullname;
     StringBuffer    m_firstname;
     StringBuffer    m_lastname;
+    StringBuffer    m_employeeID;
     unsigned        m_userID;
     StringBuffer    m_Fqdn;
     StringBuffer    m_Peer;
@@ -101,6 +102,18 @@ public:
         }
         return true;
     }
+
+    const char * getEmployeeID()
+    {
+        return m_employeeID.str();
+    }
+
+    bool setEmployeeID(const char * emplID)
+    {
+        m_employeeID.set(emplID);
+        return true;
+    }
+
     const char * getRealm()
     {
         return m_realm.str();
@@ -209,6 +222,7 @@ public:
         destination.setFullName(getFullName());
         destination.setFirstName(getFirstName());
         destination.setLastName(getLastName());
+        destination.setEmployeeID(getEmployeeID());
         destination.setRealm(getRealm());
         destination.setFqdn(getFqdn());
         destination.setPeer(getPeer());

+ 2 - 0
system/security/shared/seclib.hpp

@@ -152,6 +152,8 @@ interface ISecUser : extends IInterface
     virtual bool setFirstName(const char * fname) = 0;
     virtual const char * getLastName() = 0;
     virtual bool setLastName(const char * lname) = 0;
+    virtual const char * getEmployeeID() = 0;
+    virtual bool setEmployeeID(const char * emplID) = 0;
     virtual const char * getRealm() = 0;
     virtual bool setRealm(const char * realm) = 0;
     virtual const char * getFqdn() = 0;