From f4c48b7724e536d58310ec386bf1b4eddef69899 Mon Sep 17 00:00:00 2001
From: Jan Orel <jorel@opennebula.systems>
Date: Thu, 17 Dec 2020 19:49:06 +0100
Subject: [PATCH] B #5210: Make LDAP group_admin configurable (code)

(cherry picked from commit 960380acf82a42d7bb805c7550901ac743152422)
---
 include/OpenNebulaTemplate.h       |  1 +
 src/template/OpenNebulaTemplate.cc | 16 +++---
 src/um/UserPool.cc                 | 79 +++++++++++++++++++-----------
 3 files changed, 60 insertions(+), 36 deletions(-)

diff --git a/include/OpenNebulaTemplate.h b/include/OpenNebulaTemplate.h
index 7edd9f5669..46c0c3a157 100644
--- a/include/OpenNebulaTemplate.h
+++ b/include/OpenNebulaTemplate.h
@@ -130,6 +130,7 @@ private:
     void set_conf_auth(const std::string& name,
                        const std::string& change_password,
                        const std::string& driver_managed_groups,
+                       const std::string& driver_managed_group_admin,
                        const std::string& max_token_time);
 
     /**
diff --git a/src/template/OpenNebulaTemplate.cc b/src/template/OpenNebulaTemplate.cc
index c5a01ea59b..75108e5d9b 100644
--- a/src/template/OpenNebulaTemplate.cc
+++ b/src/template/OpenNebulaTemplate.cc
@@ -138,13 +138,13 @@ void OpenNebulaTemplate::set_multiple_conf_default()
 # server_x509
 #******
 */
-    set_conf_auth("core", "YES", "NO", "-1");
-    set_conf_auth("public", "NO", "NO", "-1");
-    set_conf_auth("ssh", "YES", "NO", "-1");
-    set_conf_auth("x509", "NO", "NO", "-1");
-    set_conf_auth("ldap", "YES", "YES", "86400");
-    set_conf_auth("server_cipher", "NO", "NO", "-1");
-    set_conf_auth("server_x509", "NO", "NO", "-1");
+    set_conf_auth("core", "YES", "NO", "NO", "-1");
+    set_conf_auth("public", "NO", "NO", "NO", "-1");
+    set_conf_auth("ssh", "YES", "NO", "NO", "-1");
+    set_conf_auth("x509", "NO", "NO", "NO", "-1");
+    set_conf_auth("ldap", "YES", "YES", "YES", "86400");
+    set_conf_auth("server_cipher", "NO", "NO", "NO", "-1");
+    set_conf_auth("server_x509", "NO", "NO", "NO", "-1");
 
     register_multiple_conf_default("AUTH_MAD_CONF");
 
@@ -304,6 +304,7 @@ void OpenNebulaTemplate::set_conf_market(const std::string& name,
 void OpenNebulaTemplate::set_conf_auth(const std::string& name,
                                        const std::string& password_change,
                                        const std::string& driver_managed_groups,
+                                       const std::string& driver_managed_group_admin,
                                        const std::string& max_token_time)
 {
     VectorAttribute *   vattribute;
@@ -312,6 +313,7 @@ void OpenNebulaTemplate::set_conf_auth(const std::string& name,
     vvalue.insert(make_pair("NAME", name));
     vvalue.insert(make_pair("PASSWORD_CHANGE", password_change));
     vvalue.insert(make_pair("DRIVER_MANAGED_GROUPS", driver_managed_groups));
+    vvalue.insert(make_pair("DRIVER_MANAGED_GROUP_ADMIN", driver_managed_group_admin));
     vvalue.insert(make_pair("MAX_TOKEN_TIME", max_token_time));
 
     vattribute = new VectorAttribute("AUTH_MAD_CONF", vvalue);
diff --git a/src/um/UserPool.cc b/src/um/UserPool.cc
index 42acfeb6ea..b1e2019e15 100644
--- a/src/um/UserPool.cc
+++ b/src/um/UserPool.cc
@@ -327,6 +327,7 @@ int UserPool::allocate(
     string upass       = password;
 
     string gname;
+    bool driver_managed_group_admin = false;
 
     ostringstream   oss;
 
@@ -427,21 +428,30 @@ int UserPool::allocate(
         group->unlock();
     }
 
-    // Set the user group admin
-    for(set<int>::const_iterator it = agids.begin(); it != agids.end(); it++)
+    if (nd.get_auth_conf_attribute(auth_driver, "DRIVER_MANAGED_GROUP_ADMIN",
+            driver_managed_group_admin) != 0)
     {
-        Group * group = gpool->get(*it);
+        driver_managed_group_admin = false;
+    }
 
-        if( group == 0 ) //Secondary group no longer exists
+    if ( driver_managed_group_admin )
+    {
+        // Set the user group admin
+        for(set<int>::const_iterator it = agids.begin(); it != agids.end(); it++)
         {
-            goto error_group;
+            Group * group = gpool->get(*it);
+
+            if( group == 0 ) //Secondary group no longer exists
+            {
+                goto error_group;
+            }
+
+            group->add_admin(*oid, error_str);
+
+            gpool->update(group);
+
+            group->unlock();
         }
-
-        group->add_admin(*oid, error_str);
-
-        gpool->update(group);
-
-        group->unlock();
     }
 
     return *oid;
@@ -652,6 +662,7 @@ bool UserPool::authenticate_internal(User *        user,
     string error_str;
 
     bool driver_managed_groups = false;
+    bool driver_managed_group_admin = false;
 
     int egid    = -1;
     int new_gid = -1;
@@ -696,6 +707,12 @@ bool UserPool::authenticate_internal(User *        user,
         driver_managed_groups = false;
     }
 
+    if (nd.get_auth_conf_attribute(auth_driver, "DRIVER_MANAGED_GROUP_ADMIN",
+            driver_managed_group_admin) != 0)
+    {
+        driver_managed_group_admin = false;
+    }
+
     AuthRequest ar(user_id, group_ids);
 
     // -------------------------------------------------------------------------
@@ -897,7 +914,8 @@ bool UserPool::authenticate_internal(User *        user,
             continue;
         }
 
-        if ( new_group_admin_ids.find(*it) != new_group_admin_ids.end() )
+        if ( driver_managed_group_admin &&
+             new_group_admin_ids.find(*it) != new_group_admin_ids.end() )
         {
             group->add_admin(user_id, error_str);
         }
@@ -929,32 +947,35 @@ bool UserPool::authenticate_internal(User *        user,
     // For groups which user remained member also check if the admin status
     // did not changed
     // -------------------------------------------------------------------------
-    for(it = groups_same.begin(); it != groups_same.end(); it++)
+    if ( driver_managed_group_admin )
     {
-        // user was admin before but is not now
-        if ( group_admin_ids.find(*it) != group_admin_ids.end()
-             && new_group_admin_ids.find(*it) == new_group_admin_ids.end() )
+        for(it = groups_same.begin(); it != groups_same.end(); it++)
         {
-            group = gpool->get(*it);
+            // user was admin before but is not now
+            if ( group_admin_ids.find(*it) != group_admin_ids.end()
+                 && new_group_admin_ids.find(*it) == new_group_admin_ids.end() )
+            {
+                group = gpool->get(*it);
 
-            group->del_admin(user_id, error_str);
+                group->del_admin(user_id, error_str);
 
-            gpool->update(group);
+                gpool->update(group);
 
-            group->unlock();
-        }
+                group->unlock();
+            }
 
-        // user was not admin before but is now
-        if ( group_admin_ids.find(*it) == group_admin_ids.end()
-             && new_group_admin_ids.find(*it) != new_group_admin_ids.end() )
-        {
-            group = gpool->get(*it);
+            // user was not admin before but is now
+            if ( group_admin_ids.find(*it) == group_admin_ids.end()
+                 && new_group_admin_ids.find(*it) != new_group_admin_ids.end() )
+            {
+                group = gpool->get(*it);
 
-            group->add_admin(user_id, error_str);
+                group->add_admin(user_id, error_str);
 
-            gpool->update(group);
+                gpool->update(group);
 
-            group->unlock();
+                group->unlock();
+            }
         }
     }