sq
authorStefan Metzmacher <metze@samba.org>
Fri, 19 Jul 2013 08:46:52 +0000 (10:46 +0200)
committerStefan Metzmacher <metze@samba.org>
Sun, 29 Jun 2014 21:45:24 +0000 (23:45 +0200)
source4/rpc_server/drsuapi/getncchanges.c

index b1cafbbe667b47f428990a4ddc278275326c7be2..84994d3f1f73615a4633a426c3715f1b377f216d 100644 (file)
@@ -226,7 +226,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
        if (rdn_sa == NULL) {
                DEBUG(0,(__location__ ": Can't find dsds_attribute for rDN %s in %s\n", 
                         rdn, ldb_dn_get_linearized(msg->dn)));
-               return WERR_DS_DRA_INTERNAL_ERROR;
+               return WERR_DS_DRA_SCHEMA_MISMATCH;
        }
 
        obj->meta_data_ctr = talloc(obj, struct drsuapi_DsReplicaMetaDataCtr);
@@ -257,7 +257,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
                        DEBUG(0,(__location__ ": Failed to find attribute in schema for attrid %u mentioned in replPropertyMetaData of %s\n", 
                                 (unsigned int)md.ctr.ctr1.array[i].attid, 
                                 ldb_dn_get_linearized(msg->dn)));
-                       return WERR_DS_DRA_SCHEMA_MISMATCH;             
+                       return WERR_DS_DRA_SCHEMA_MISMATCH;
                }
 
                if (sa->linkID) {
@@ -337,8 +337,9 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
        
                sa = dsdb_attribute_by_attributeID_id(schema, attids[i]);
                if (!sa) {
-                       DEBUG(0,("Unable to find attributeID %u in schema\n", attids[i]));
-                       return WERR_DS_DRA_INTERNAL_ERROR;
+                       DEBUG(0,(__location__ "Unable to find attributeID %u in schema\n",
+                               attids[i]));
+                       return WERR_DS_DRA_SCHEMA_MISMATCH;
                }
 
                el = ldb_msg_find_element(msg, sa->lDAPDisplayName);
@@ -531,8 +532,13 @@ static WERROR get_nc_changes_add_links(struct ldb_context *sam_ctx,
                unsigned int j;
 
                sa = dsdb_attribute_by_lDAPDisplayName(schema, el->name);
+               if (sa == NULL) {
+                       DEBUG(0,(__location__ ": Can't find dsds_attribute by name %s\n",
+                                el->name));
+                       return WERR_DS_DRA_SCHEMA_MISMATCH;
+               }
 
-               if (!sa || sa->linkID == 0 || (sa->linkID & 1)) {
+               if (sa->linkID == 0 || (sa->linkID & 1)) {
                        /* we only want forward links */
                        continue;
                }
@@ -1243,9 +1249,12 @@ static WERROR dcesrv_drsuapi_is_reveal_secrets_request(struct drsuapi_bind_state
        /* check the attributes they asked for */
        for (i=0; i<req10->partial_attribute_set->num_attids; i++) {
                const struct dsdb_attribute *sa;
-               sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set->attids[i]);
+               sa = dsdb_attribute_by_attributeID_id(schema,
+                                       req10->partial_attribute_set->attids[i]);
                if (sa == NULL) {
-                       return WERR_DS_DRA_SCHEMA_MISMATCH;
+                       DEBUG(0,(__location__ ": Can't find dsds_attribute by attid 0x%08X\n",
+                                req10->partial_attribute_set->attids[i]));
+                       return WERR_DS_DRA_INCOMPATIBLE_PARTIAL_SET;
                }
                if (!dsdb_attr_in_rodc_fas(sa)) {
                        *is_secret_request = true;
@@ -1257,9 +1266,12 @@ static WERROR dcesrv_drsuapi_is_reveal_secrets_request(struct drsuapi_bind_state
                /* check the extended attributes they asked for */
                for (i=0; i<req10->partial_attribute_set_ex->num_attids; i++) {
                        const struct dsdb_attribute *sa;
-                       sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set_ex->attids[i]);
+                       sa = dsdb_attribute_by_attributeID_id(schema,
+                                       req10->partial_attribute_set_ex->attids[i]);
                        if (sa == NULL) {
-                               return WERR_DS_DRA_SCHEMA_MISMATCH;
+                               DEBUG(0,(__location__ ": Can't find dsds_attribute by attid 0x%08X\n",
+                                       req10->partial_attribute_set_ex->attids[i]));
+                               return WERR_DS_DRA_INCOMPATIBLE_PARTIAL_SET;
                        }
                        if (!dsdb_attr_in_rodc_fas(sa)) {
                                *is_secret_request = true;
@@ -1311,9 +1323,12 @@ static WERROR dcesrv_drsuapi_is_gc_pas_request(struct drsuapi_bind_state *b_stat
        /* check the attributes they asked for */
        for (i=0; i<req10->partial_attribute_set->num_attids; i++) {
                const struct dsdb_attribute *sa;
-               sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set->attids[i]);
+               sa = dsdb_attribute_by_attributeID_id(schema,
+                               req10->partial_attribute_set->attids[i]);
                if (sa == NULL) {
-                       return WERR_DS_DRA_SCHEMA_MISMATCH;
+                       DEBUG(0,(__location__ ": Can't find dsds_attribute by attid 0x%08X\n",
+                                req10->partial_attribute_set->attids[i]));
+                       return WERR_DS_DRA_INCOMPATIBLE_PARTIAL_SET;
                }
                if (!sa->isMemberOfPartialAttributeSet) {
                        *is_gc_pas_request = false;
@@ -1325,9 +1340,12 @@ static WERROR dcesrv_drsuapi_is_gc_pas_request(struct drsuapi_bind_state *b_stat
                /* check the extended attributes they asked for */
                for (i=0; i<req10->partial_attribute_set_ex->num_attids; i++) {
                        const struct dsdb_attribute *sa;
-                       sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set_ex->attids[i]);
+                       sa = dsdb_attribute_by_attributeID_id(schema,
+                                       req10->partial_attribute_set_ex->attids[i]);
                        if (sa == NULL) {
-                               return WERR_DS_DRA_SCHEMA_MISMATCH;
+                               DEBUG(0,(__location__ ": Can't find dsds_attribute by attid 0x%08X\n",
+                                       req10->partial_attribute_set_ex->attids[i]));
+                               return WERR_DS_DRA_INCOMPATIBLE_PARTIAL_SET;
                        }
                        if (!sa->isMemberOfPartialAttributeSet) {
                                *is_gc_pas_request = false;
@@ -1575,6 +1593,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
           GUID_DRS_GET_FILTERED_ATTRIBUTES */
        werr = dcesrv_drsuapi_is_gc_pas_request(b_state, req10, &is_gc_pas_request);
        if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(1,(__location__ ": dcesrv_drsuapi_is_gc_pas_request failed %s\n",
+                        win_errstr(werr)));
                return werr;
        }
        if (is_gc_pas_request) {
@@ -1590,6 +1610,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
 
        werr = dcesrv_drsuapi_is_reveal_secrets_request(b_state, req10, &is_secret_request);
        if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(1,(__location__ ": dcesrv_drsuapi_is_reveal_secrets_request failed %s\n",
+                        win_errstr(werr)));
                return werr;
        }
        if (is_secret_request && req10->extended_op != DRSUAPI_EXOP_REPL_SECRET) {
@@ -1913,6 +1935,7 @@ allowed:
                                            NULL };
                struct ldb_result *msg_res;
                struct ldb_dn *msg_dn;
+               uint32_t save_la_count;
 
                obj = talloc_zero(mem_ctx, struct drsuapi_DsReplicaObjectListItemEx);
                W_ERROR_HAVE_NO_MEMORY(obj);
@@ -1949,19 +1972,21 @@ allowed:
                                                   req10->uptodateness_vector,
                                                   req10->extended_op,
                                                   max_wait_reached);
-
                /* Retry if the schema changed under our feet */
                if (W_ERROR_EQUAL(werr, WERR_DS_DRA_SCHEMA_MISMATCH)) {
                        /* Force a reload */
                        schema->last_refresh = 0;
                        schema->metadata_usn = 0;
                        talloc_unlink(mem_ctx, schema);
-                       
+
                        schema = dsdb_get_schema(sam_ctx, mem_ctx);
                        if (!schema) {
                                DEBUG(0,("No schema in sam_ctx\n"));
                                return WERR_DS_DRA_INTERNAL_ERROR;
                        }
+
+                       DEBUG(0,(__location__ ": retry get_nc_changes_build_object(%s) after %s\n",
+                                ldb_dn_get_linearized(msg->dn), win_errstr(werr)));
                        werr = get_nc_changes_build_object(obj, msg,
                                                           sam_ctx, getnc_state->ncRoot_dn,
                                                           getnc_state->is_schema_nc,
@@ -1973,9 +1998,12 @@ allowed:
                                                           max_wait_reached);
                }
                if (!W_ERROR_IS_OK(werr)) {
+                       DEBUG(0,(__location__ ": get_nc_changes_build_object(%s) failed %s\n",
+                                ldb_dn_get_linearized(msg->dn), win_errstr(werr)));
                        return werr;
                }
 
+               save_la_count = getnc_state->la_count;
                werr = get_nc_changes_add_links(sam_ctx, getnc_state,
                                                getnc_state->ncRoot_dn,
                                                schema, getnc_state->min_usn,
@@ -1984,7 +2012,34 @@ allowed:
                                                &getnc_state->la_list,
                                                &getnc_state->la_count,
                                                req10->uptodateness_vector);
+               /* Retry if the schema changed under our feet */
+               if (W_ERROR_EQUAL(werr, WERR_DS_DRA_SCHEMA_MISMATCH)) {
+                       /* Force a reload */
+                       schema->last_refresh = 0;
+                       schema->metadata_usn = 0;
+                       talloc_unlink(mem_ctx, schema);
+
+                       schema = dsdb_get_schema(sam_ctx, mem_ctx);
+                       if (!schema) {
+                               DEBUG(0,("No schema in sam_ctx\n"));
+                               return WERR_DS_DRA_INTERNAL_ERROR;
+                       }
+
+                       DEBUG(0,(__location__ ": retry get_nc_changes_add_links(%s) after %s\n",
+                                ldb_dn_get_linearized(msg->dn), win_errstr(werr)));
+                       getnc_state->la_count = save_la_count;
+                       werr = get_nc_changes_add_links(sam_ctx, getnc_state,
+                                                       getnc_state->ncRoot_dn,
+                                                       schema, getnc_state->min_usn,
+                                                       req10->replica_flags,
+                                                       msg,
+                                                       &getnc_state->la_list,
+                                                       &getnc_state->la_count,
+                                                       req10->uptodateness_vector);
+               }
                if (!W_ERROR_IS_OK(werr)) {
+                       DEBUG(0,(__location__ ": get_nc_changes_add_links(%s) failed %s\n",
+                                ldb_dn_get_linearized(msg->dn), win_errstr(werr)));
                        return werr;
                }