From 7a4f3d9e3c62eb73f07df117813811a886d2b169 Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Thu, 30 Aug 2007 08:34:45 +0000
Subject: [PATCH] Fix for issue #2041

---
 opends/src/ads/org/opends/admin/ads/ADSContext.java                                 |   94 +++++++++++++++++++++++++++++--
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java |   76 +++++++++++++++++++++++--
 2 files changed, 158 insertions(+), 12 deletions(-)

diff --git a/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opends/src/ads/org/opends/admin/ads/ADSContext.java
index 74989dc..fbbbcae 100644
--- a/opends/src/ads/org/opends/admin/ads/ADSContext.java
+++ b/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -27,6 +27,8 @@
 
 package org.opends.admin.ads;
 
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Map;
@@ -318,7 +320,11 @@
     /**
      * The DN of the administrator.
      */
-    ADMINISTRATOR_DN("administrator dn",ADSPropertySyntax.STRING);
+    ADMINISTRATOR_DN("administrator dn",ADSPropertySyntax.STRING),
+    /**
+     * The administrator privilege.
+     */
+    PRIVILEGE("privilege",ADSPropertySyntax.STRING);
 
     private String attrName;
     private ADSPropertySyntax attrSyntax;
@@ -911,6 +917,9 @@
       SearchControls sc = new SearchControls();
 
       sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+      String[] attList = { "cn", "userpassword", "ds-privilege-name",
+          "description" };
+      sc.setReturningAttributes(attList);
       ne = dirContext.search(getAdministratorContainerDN(), "(objectclass=*)",
           sc);
       while (ne.hasMore())
@@ -1017,7 +1026,7 @@
     LdapName dnCentralAdmin =
       makeDNFromAdministratorProperties(adminProperties);
     BasicAttributes attrs = makeAttrsFromAdministratorProperties(
-        adminProperties, true);
+        adminProperties, true, null);
 
     try
     {
@@ -1107,11 +1116,29 @@
         adminProperties.put(AdministratorProperty.UID,newAdminUserId);
       }
 
+      // if modification includes 'privilege', we have to get first the
+      // current privileges list.
+      NamingEnumeration currentPrivileges = null;
+      if (adminProperties.containsKey(AdministratorProperty.PRIVILEGE))
+      {
+        SearchControls sc = new SearchControls();
+        sc.setSearchScope(SearchControls.OBJECT_SCOPE);
+        String[] attList = {"ds-privilege-name"};
+        sc.setReturningAttributes(attList);
+        NamingEnumeration ne = dirContext.search(
+            dnCentralAdmin, "(objectclass=*)", sc);
+        SearchResult sr = (SearchResult)ne.next();
+
+        currentPrivileges = sr.getAttributes().get("ds-privilege-name")
+            .getAll();
+      }
+
       // Replace properties, if needed.
       if (adminProperties.size() > 1)
       {
         BasicAttributes attrs =
-          makeAttrsFromAdministratorProperties(adminProperties, false);
+          makeAttrsFromAdministratorProperties(
+              adminProperties, false, currentPrivileges);
         dirContext.modifyAttributes(dnCentralAdmin,
             DirContext.REPLACE_ATTRIBUTE, attrs);
       }
@@ -1267,12 +1294,13 @@
    * @param adminProperties the administrator properties.
    * @param passwordRequired Indicates if the properties should include
    * the password.
+   * @param currentPrivileges The current privilege list or null.
    * @return the attributes for the given administrator properties.
    * @throws ADSContextException if something goes wrong.
    */
   private static BasicAttributes makeAttrsFromAdministratorProperties(
       Map<AdministratorProperty, Object> adminProperties,
-      boolean passwordRequired)
+      boolean passwordRequired, NamingEnumeration currentPrivileges)
   throws ADSContextException
   {
     BasicAttributes attrs = new BasicAttributes();
@@ -1290,6 +1318,51 @@
       attrs.put("description", adminProperties
           .get(AdministratorProperty.DESCRIPTION));
     }
+    Attribute privilegeAtt;
+    if (adminProperties.containsKey(AdministratorProperty.PRIVILEGE))
+    {
+      // We assume that privilege strings provided in
+      // AdministratorProperty.PRIVILEGE
+      // are valid privileges represented as a LinkedList of string.
+      privilegeAtt = new BasicAttribute("ds-privilege-name");
+      if (currentPrivileges != null)
+      {
+        while (currentPrivileges.hasMoreElements())
+        {
+          privilegeAtt.add(currentPrivileges.nextElement().toString());
+        }
+      }
+
+      LinkedList privileges = (LinkedList)
+        adminProperties.get(AdministratorProperty.PRIVILEGE);
+      for( Object o : privileges)
+      {
+        String p = o.toString() ;
+        if (p.startsWith("-"))
+        {
+          privilegeAtt.remove(p.substring(1));
+        }
+        else
+        {
+          privilegeAtt.add(p.toString());
+        }
+      }
+    }
+    else
+    {
+      privilegeAtt = addRootPrivileges();
+    }
+    attrs.put(privilegeAtt);
+    return attrs;
+  }
+
+
+  /**
+   * Builds an attribute which contains 'root' privileges.
+   * @return The attribute which contains 'root' privileges.
+   */
+  private static Attribute addRootPrivileges()
+  {
     Attribute privilege = new BasicAttribute("ds-privilege-name");
     privilege.add("bypass-acl");
     privilege.add("modify-acl");
@@ -1307,8 +1380,7 @@
     privilege.add("update-schema");
     privilege.add("privilege-change");
     privilege.add("unindexed-search");
-    attrs.put(privilege);
-    return attrs;
+    return privilege;
   }
 
   /**
@@ -1604,6 +1676,16 @@
           value = attr.get(0);
           result.put(AdministratorProperty.DESCRIPTION, value);
         }
+        else if (attrID.equalsIgnoreCase("ds-privilege-name"))
+        {
+          LinkedHashSet<String> privileges = new LinkedHashSet<String>();
+          NamingEnumeration attValueList = attr.getAll();
+          while (attValueList.hasMoreElements())
+          {
+            privileges.add(attValueList.next().toString());
+          }
+          result.put(AdministratorProperty.PRIVILEGE, privileges);
+        }
       }
     }
     catch(NamingException x)
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
index adcef30..cbd2fe8 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliGlobalAdmin.java
@@ -51,6 +51,7 @@
 import org.opends.admin.ads.ADSContext.AdministratorProperty;
 import org.opends.admin.ads.ADSContextException.ErrorType;
 import org.opends.server.tools.dsconfig.ArgumentExceptionFactory;
+import org.opends.server.types.Privilege;
 import org.opends.server.util.args.Argument;
 import org.opends.server.util.args.ArgumentException;
 import org.opends.server.util.args.BooleanArgument;
@@ -365,7 +366,7 @@
       AdministratorProperty prop = AdministratorProperty.UID;
       String attName = prop.getAttributeName();
       StringArgument arg = new StringArgument(attName, null,
-          prop.getAttributeName(), false, false, true, "", null, null, null);
+          attName, false, false, true, "", null, null, null);
       userAdminProperties.put(prop, arg);
     }
 
@@ -377,7 +378,7 @@
       AdministratorProperty prop = AdministratorProperty.PASSWORD;
       String attName = prop.getAttributeName();
       StringArgument arg = new StringArgument(attName, null,
-          prop.getAttributeName(), false, false, true, "", null, null, null);
+          attName, false, false, true, "", null, null, null);
       userAdminProperties.put(prop, arg);
     }
 
@@ -388,7 +389,7 @@
       AdministratorProperty prop = AdministratorProperty.DESCRIPTION;
       String attName = prop.getAttributeName();
       StringArgument arg = new StringArgument(attName, null,
-          prop.getAttributeName(), false, false, true, "", null, null, null);
+          attName, false, false, true, "", null, null, null);
       userAdminProperties.put(prop, arg);
     }
 
@@ -399,10 +400,21 @@
       AdministratorProperty prop = AdministratorProperty.ADMINISTRATOR_DN;
       String attName = prop.getAttributeName();
       StringArgument arg = new StringArgument(attName, null,
-          prop.getAttributeName(), false, false, true, "", null, null, null);
+          attName, false, false, true, "", null, null, null);
       userAdminProperties.put(prop, arg);
       readonlyadminUserProperties.add(prop);
     }
+
+    /**
+     * The PRIVILEGE associated to the user.
+     */
+    {
+      AdministratorProperty prop = AdministratorProperty.PRIVILEGE;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null,
+          attName, true, true, true, "", "root", null, null);
+      userAdminProperties.put(prop, arg);
+    }
   }
 
   /**
@@ -667,6 +679,7 @@
   {
     HashMap<AdministratorProperty, Object> map =
       new HashMap<AdministratorProperty, Object>();
+    boolean rootPrivileges = false ;
     for (String m : propertySetArgument.getValues())
     {
       // Parse the property "property:value".
@@ -714,10 +727,61 @@
             ERR_CLI_ERROR_INVALID_PROPERTY_VALUE.get(propertyName, value);
         throw new ArgumentException(message);
       }
-      userAdminProperties.get(adminUserProperty).addValue(value);
+      if (adminUserProperty.equals(AdministratorProperty.PRIVILEGE))
+      {
+        // Check if 'root' privilege is requested, or
+        // if it's a valid privilege
+        if (value.equals(arg.getDefaultValue()))
+        {
+          rootPrivileges = true ;
+        }
+        else
+        {
+          String valueToCheck = value ;
+          if (value.startsWith("-"))
+          {
+            valueToCheck = value.substring(1);
+          }
+          if (Privilege.privilegeForName(valueToCheck) == null)
+          {
+            Message message = ERR_CLI_ERROR_INVALID_PROPERTY_VALUE.get(
+                AdministratorProperty.PRIVILEGE.getAttributeName(),
+                valueToCheck);
+            throw new ArgumentException(message);
+          }
+        }
+      }
+
+      // Add the value to the argument.
+      arg.addValue(value);
 
       // add to the map.
-      map.put(adminUserProperty, value);
+      if (arg.isMultiValued())
+      {
+        map.put(adminUserProperty, arg.getValues());
+      }
+      else
+      {
+        map.put(adminUserProperty, value);
+      }
+    }
+
+    // If privileges was not provided by the user, set the default value
+    if (! map.containsKey(AdministratorProperty.PRIVILEGE))
+    {
+      rootPrivileges = true ;
+    }
+
+    // If we have root privilege, translate it to the corresponding
+    // list of privileges associated to 'root' user.
+    if (rootPrivileges)
+    {
+      LinkedList<String> privilegesList = new LinkedList<String>();
+      for (Privilege p : Privilege.getDefaultRootPrivileges())
+      {
+        privilegesList.add(p.getName());
+      }
+      map.put(AdministratorProperty.PRIVILEGE,privilegesList);
     }
 
     // Check that all mandatory props are set.

--
Gitblit v1.10.0