The branch, master has been updated
       via  595982a... s4-rootdse: we don't need DSDB_FLAG_OWN_MODULE here
       via  9c46f42... s4-drs: enable the recyclebin optional feature
      from  aba7376... s4-kcc: remove C++ comment

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 595982a47517bcae156820b34e7f21e56d2c25e3
Author: Andrew Tridgell <tri...@samba.org>
Date:   Mon Feb 15 23:49:26 2010 +1100

    s4-rootdse: we don't need DSDB_FLAG_OWN_MODULE here

commit 9c46f425a231543c20ce9953621e1f077bb7bdec
Author: Eduardo Lima <eduard...@gmail.com>
Date:   Fri Feb 12 14:18:27 2010 -0200

    s4-drs: enable the recyclebin optional feature
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/rootdse.c   |  269 ++++++++++++++++++++++++++--
 source4/setup/provision_configuration.ldif |   12 ++
 2 files changed, 262 insertions(+), 19 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c 
b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 9d2b8cd..d5a3499 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -26,6 +26,9 @@
 #include "system/time.h"
 #include "dsdb/samdb/samdb.h"
 #include "version.h"
+#include "dsdb/samdb/ldb_modules/util.h"
+#include "libcli/security/security.h"
+#include "librpc/ndr/libndr.h"
 
 struct private_data {
        int num_controls;
@@ -689,32 +692,232 @@ static int rootdse_init(struct ldb_module *module)
        return LDB_SUCCESS;
 }
 
-static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
+/*
+ * This function gets the string SCOPE_DN:OPTIONAL_FEATURE_GUID and parse it
+ * to a DN and a GUID object
+ */
+static int get_optional_feature_dn_guid(struct ldb_request *req, struct 
ldb_context *ldb,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct ldb_dn 
**op_feature_scope_dn,
+                                               struct GUID *op_feature_guid)
 {
-       struct ldb_context *ldb;
-       struct ldb_result *ext_res;
+       const struct ldb_message *msg = req->op.mod.message;
+       const char *ldb_val_str;
+       char *dn, *guid;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       NTSTATUS status;
+
+       ldb_val_str = ldb_msg_find_attr_as_string(msg, "enableOptionalFeature", 
NULL);
+       if (!ldb_val_str) {
+               ldb_asprintf_errstring(ldb,
+                                      "rootdse: unable to find 
enableOptionalFeature\n");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       guid = strchr(ldb_val_str, ':');
+       if (!guid) {
+               ldb_asprintf_errstring(ldb,
+                                      "rootdse: unable to find GUID in 
enableOptionalFeature\n");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+       status = GUID_from_string(guid+1, op_feature_guid);
+       if (!NT_STATUS_IS_OK(status)) {
+               ldb_asprintf_errstring(ldb,
+                                      "rootdse: bad GUID in 
enableOptionalFeature\n");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       dn = talloc_strndup(tmp_ctx, ldb_val_str, guid-ldb_val_str);
+       if (!dn) {
+               ldb_asprintf_errstring(ldb,
+                                      "rootdse: bad DN in 
enableOptionalFeature\n");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       *op_feature_scope_dn = ldb_dn_new(mem_ctx, ldb, dn);
+
+       talloc_free(tmp_ctx);
+       return LDB_SUCCESS;
+}
+
+/*
+ * This function gets the OPTIONAL_FEATURE_GUID and looks for the optional 
feature
+ * ldb_message object.
+ */
+static int dsdb_find_optional_feature(struct ldb_module *module, struct 
ldb_context *ldb,
+                               TALLOC_CTX *mem_ctx, struct GUID 
op_feature_guid, struct ldb_message **msg)
+{
+       struct ldb_result *res;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        int ret;
-       struct ldb_dn *schema_dn;
-       struct ldb_message_element *schemaUpdateNowAttr;
-       
-       /*
-               If dn is not "" we should let it pass through
-       */
-       if (!ldb_dn_is_null(req->op.mod.message->dn)) {
-               return ldb_next_request(module, req);
+
+       ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
+                               NULL,
+                               DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
+                                "(&(objectClass=msDS-OptionalFeature)"
+                                
"(msDS-OptionalFeatureGUID=%s))",GUID_string(tmp_ctx, &op_feature_guid));
+
+       if (ret != LDB_SUCCESS) {
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+       if (res->count == 0) {
+               talloc_free(tmp_ctx);
+               return LDB_ERR_NO_SUCH_OBJECT;
+       }
+       if (res->count != 1) {
+               ldb_asprintf_errstring(ldb,
+                               "More than one object found matching optional 
feature GUID %s\n",
+                               GUID_string(tmp_ctx, &op_feature_guid));
+               talloc_free(tmp_ctx);
+               return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       ldb = ldb_module_get_ctx(module);
+       *msg = talloc_steal(mem_ctx, res->msgs[0]);
+
+       talloc_free(tmp_ctx);
+       return LDB_SUCCESS;
+}
+
+static int rootdse_enable_recycle_bin(struct ldb_module *module,struct 
ldb_context *ldb,
+                       TALLOC_CTX *mem_ctx, struct ldb_dn *op_feature_scope_dn,
+                       struct ldb_message *op_feature_msg)
+{
+       int ret;
+       const int domain_func_level = dsdb_functional_level(ldb);
+       struct ldb_dn *ntds_settings_dn;
+       TALLOC_CTX *tmp_ctx;
+       uint32_t el_count = 0;
+       struct ldb_message *msg;
+
+       ret = ldb_msg_find_attr_as_int(op_feature_msg, 
"msDS-RequiredForestBehaviorVersion", 0);
+       if (domain_func_level < ret){
+               ldb_asprintf_errstring(ldb,
+                                                      "rootdse: Domain 
functional level must be at least %d\n",
+                                                      ret);
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       tmp_ctx = talloc_new(mem_ctx);
+       ntds_settings_dn = samdb_ntds_settings_dn(ldb);
+       if (!ntds_settings_dn) {
+               ldb_asprintf_errstring(ldb,
+                               __location__ ": Failed to find NTDS settings 
DN\n");
+               ret = LDB_ERR_OPERATIONS_ERROR;
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+       ntds_settings_dn = ldb_dn_copy(tmp_ctx, ntds_settings_dn);
+       if (!ntds_settings_dn) {
+               DEBUG(0, (__location__ ": Failed to copy NTDS settings DN\n"));
+               ret = LDB_ERR_OPERATIONS_ERROR;
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+       msg = ldb_msg_new(tmp_ctx);
+       msg->dn = ntds_settings_dn;
+
+       ldb_msg_add_linearized_dn(msg, "msDS-EnabledFeature", 
op_feature_msg->dn);
+       msg->elements[el_count++].flags = LDB_FLAG_MOD_ADD;
+
+       ret = dsdb_module_modify(module, msg, 0);
+       if (ret != LDB_SUCCESS) {
+               ldb_asprintf_errstring(ldb,
+                               "rootdse_enable_recycle_bin: Failed to modify 
object %s - %s",
+                               ldb_dn_get_linearized(ntds_settings_dn), 
ldb_errstring(ldb));
+               talloc_free(tmp_ctx);
+               return ret;
+       }
 
+       msg->dn = op_feature_scope_dn;
+       ret = dsdb_module_modify(module, msg, 0);
+       if (ret != LDB_SUCCESS) {
+               ldb_asprintf_errstring(ldb, "rootdse_enable_recycle_bin: Failed 
to modify object %s - %s",
+                                      
ldb_dn_get_linearized(op_feature_scope_dn), ldb_errstring(ldb));
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+       return LDB_SUCCESS;
+}
+
+static int rootdse_enableoptionalfeature(struct ldb_module *module, struct 
ldb_request *req)
+{
        /*
-               dn is empty so check for schemaUpdateNow attribute
-               "The type of modification and values specified in the LDAP 
modify operation do not matter." MSDN
-       */
-       schemaUpdateNowAttr = ldb_msg_find_element(req->op.mod.message, 
"schemaUpdateNow");
-       if (!schemaUpdateNowAttr) {
-               return LDB_ERR_OPERATIONS_ERROR;
+         steps:
+              - check for system (only system can enable features)
+              - extract GUID from the request
+              - find the feature object
+              - check functional level, must be at least 
msDS-RequiredForestBehaviorVersion
+              - check if it is already enabled (if enabled return 
LDAP_ATTRIBUTE_OR_VALUE_EXISTS) - probably not needed, just return error from 
the add/modify
+              - add/modify objects (see ntdsconnection code for an example)
+        */
+
+       struct ldb_context *ldb = ldb_module_get_ctx(module);
+       struct GUID op_feature_guid;
+       struct ldb_dn *op_feature_scope_dn;
+       struct ldb_message *op_feature_msg;
+       struct auth_session_info *session_info =
+                               (struct auth_session_info *)ldb_get_opaque(ldb, 
"sessionInfo");
+       TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+       int ret;
+       const char *guid_string;
+
+       if (security_session_user_level(session_info) != SECURITY_SYSTEM) {
+               ldb_asprintf_errstring(ldb, "rootdse: Insufficient rights for 
enableoptionalfeature");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       ret = get_optional_feature_dn_guid(req, ldb, tmp_ctx, 
&op_feature_scope_dn, &op_feature_guid);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(tmp_ctx);
+               return ret;
        }
 
+       guid_string = GUID_string(tmp_ctx, &op_feature_guid);
+       if (!guid_string) {
+               ldb_asprintf_errstring(ldb, "rootdse: bad optional feature 
GUID");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       ret = dsdb_find_optional_feature(module, ldb, tmp_ctx, op_feature_guid, 
&op_feature_msg);
+       if (ret != LDB_SUCCESS) {
+               ldb_asprintf_errstring(ldb, "rootdse: unable to find optional 
feature for %s - %s",
+                                                      guid_string, 
ldb_errstring(ldb));
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+       if (strcasecmp(DS_GUID_FEATURE_RECYCLE_BIN, guid_string) == 0) {
+                       ret = rootdse_enable_recycle_bin(module, ldb,
+                                                        tmp_ctx, 
op_feature_scope_dn,
+                                                        op_feature_msg);
+       } else {
+               ldb_asprintf_errstring(ldb, "rootdse: unknown optional feature 
%s",
+                                      guid_string);
+               talloc_free(tmp_ctx);
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+       if (ret != LDB_SUCCESS) {
+               ldb_asprintf_errstring(ldb, "rootdse: failed to set optional 
feature for %s - %s",
+                                      guid_string, ldb_errstring(ldb));
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+       talloc_free(tmp_ctx);
+       return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);;
+}
+
+static int rootdse_schemaupdatenow(struct ldb_module *module, struct 
ldb_request *req)
+{
+       struct ldb_context *ldb = ldb_module_get_ctx(module);
+       struct ldb_result *ext_res;
+       int ret;
+       struct ldb_dn *schema_dn;
+
        schema_dn = samdb_schema_dn(ldb);
        if (!schema_dn) {
                ldb_reset_err_string(ldb);
@@ -727,11 +930,39 @@ static int rootdse_modify(struct ldb_module *module, 
struct ldb_request *req)
        if (ret != LDB_SUCCESS) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       
+
        talloc_free(ext_res);
        return ldb_module_done(req, NULL, NULL, ret);
 }
 
+static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_context *ldb;
+
+       /*
+               If dn is not "" we should let it pass through
+       */
+       if (!ldb_dn_is_null(req->op.mod.message->dn)) {
+               return ldb_next_request(module, req);
+       }
+
+       ldb = ldb_module_get_ctx(module);
+
+       /*
+               dn is empty so check for schemaUpdateNow attribute
+               "The type of modification and values specified in the LDAP 
modify operation do not matter." MSDN
+       */
+       if (ldb_msg_find_element(req->op.mod.message, "schemaUpdateNow")) {
+               return rootdse_schemaupdatenow(module, req);
+       }
+
+       if (ldb_msg_find_element(req->op.mod.message, "enableOptionalFeature")) 
{
+               return rootdse_enableoptionalfeature(module, req);
+       }
+
+       return LDB_ERR_OPERATIONS_ERROR;
+}
+
 _PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = {
        .name           = "rootdse",
        .init_context   = rootdse_init,
diff --git a/source4/setup/provision_configuration.ldif 
b/source4/setup/provision_configuration.ldif
index 0716345..13d162e 100644
--- a/source4/setup/provision_configuration.ldif
+++ b/source4/setup/provision_configuration.ldif
@@ -970,6 +970,18 @@ msDS-Other-Settings: DynamicObjectDefaultTTL=86400
 sPNMappings: 
host=alerter,appmgmt,cisvc,clipsrv,browser,dhcp,dnscache,replicator,eventlog,eventsystem,policyagent,oakley,dmserver,dns,mcsvc,fax,msiserver,ias,messenger,netlogon,netman,netdde,netddedsm,nmagent,plugplay,protectedstorage,rasman,rpclocator,rpc,rpcss,remoteaccess,rsvp,samss,scardsvr,scesrv,seclogon,scm,dcom,cifs,spooler,snmp,schedule,tapisrv,trksvr,trkwks,ups,time,wins,www,http,w3svc,iisadmin,msdtc
 tombstoneLifetime: 180
 
+dn: CN=Optional Features,CN=Directory Service,CN=Windows 
NT,CN=Services,${CONFIGDN}
+objectClass: top
+objectClass: container
+
+dn: CN=Recycle Bin Feature,CN=Optional Features,CN=Directory 
Service,CN=Windows NT,CN=Services,${CONFIGDN}
+objectClass: top
+objectClass: msDS-OptionalFeature
+msDS-OptionalFeatureGUID: 766ddcd8-acd0-445e-f3b9-a7f9b6744f2a
+msDS-OptionalFeatureFlags: 1
+msDS-RequiredForestBehaviorVersion: 4
+systemFlags: -1946157056
+
 dn: CN=Query-Policies,CN=Directory Service,CN=Windows 
NT,CN=Services,${CONFIGDN}
 objectClass: top
 objectClass: container


-- 
Samba Shared Repository

Reply via email to