Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source4/dsdb/kcc
Files:
5 added
3 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/dsdb/kcc/kcc_periodic.c

    r414 r740  
    2727#include "smbd/service.h"
    2828#include "lib/messaging/irpc.h"
     29#include "dsdb/kcc/kcc_connection.h"
    2930#include "dsdb/kcc/kcc_service.h"
    30 #include "lib/ldb/include/ldb_errors.h"
     31#include <ldb_errors.h>
    3132#include "../lib/util/dlinklist.h"
    3233#include "librpc/gen_ndr/ndr_misc.h"
    3334#include "librpc/gen_ndr/ndr_drsuapi.h"
    3435#include "librpc/gen_ndr/ndr_drsblobs.h"
     36#include "librpc/gen_ndr/ndr_irpc_c.h"
    3537#include "param/param.h"
     38
     39/*
     40 * see if two repsFromToBlob blobs are for the same source DSA
     41 */
     42static bool kccsrv_same_source_dsa(struct repsFromToBlob *r1, struct repsFromToBlob *r2)
     43{
     44        return GUID_compare(&r1->ctr.ctr1.source_dsa_obj_guid,
     45                            &r2->ctr.ctr1.source_dsa_obj_guid) == 0;
     46}
    3647
    3748/*
     
    4051static bool reps_in_list(struct repsFromToBlob *r, struct repsFromToBlob *reps, uint32_t count)
    4152{
    42         int i;
     53        uint32_t i;
    4354        for (i=0; i<count; i++) {
    44                 if (strcmp(r->ctr.ctr1.other_info->dns_name,
    45                            reps[i].ctr.ctr1.other_info->dns_name) == 0 &&
    46                     GUID_compare(&r->ctr.ctr1.source_dsa_obj_guid,
    47                                  &reps[i].ctr.ctr1.source_dsa_obj_guid) == 0) {
     55                if (kccsrv_same_source_dsa(r, &reps[i])) {
    4856                        return true;
    4957                }
     
    5260}
    5361
     62/*
     63  make sure we only add repsFrom entries for DCs who are masters for
     64  the partition
     65 */
     66static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r,
     67                           struct ldb_result *res)
     68{
     69        struct repsFromTo1 *r1 = &r->ctr.ctr1;
     70        struct GUID invocation_id = r1->source_dsa_invocation_id;
     71        unsigned int i, j;
     72
     73        /* we are expecting only version 1 */
     74        SMB_ASSERT(r->version == 1);
     75
     76        for (i=0; i<res->count; i++) {
     77                struct ldb_message *msg = res->msgs[i];
     78                struct ldb_message_element *el;
     79                struct ldb_dn *dn;
     80
     81                struct GUID id2 = samdb_result_guid(msg, "invocationID");
     82                if (GUID_all_zero(&id2) ||
     83                    !GUID_equal(&invocation_id, &id2)) {
     84                        continue;
     85                }
     86
     87                el = ldb_msg_find_element(msg, "msDS-hasMasterNCs");
     88                if (!el || el->num_values == 0) {
     89                        el = ldb_msg_find_element(msg, "hasMasterNCs");
     90                        if (!el || el->num_values == 0) {
     91                                continue;
     92                        }
     93                }
     94                for (j=0; j<el->num_values; j++) {
     95                        dn = ldb_dn_from_ldb_val(p, p->service->samdb, &el->values[j]);
     96                        if (!ldb_dn_validate(dn)) {
     97                                talloc_free(dn);
     98                                continue;
     99                        }
     100                        if (ldb_dn_compare(dn, p->dn) == 0) {
     101                                talloc_free(dn);
     102                                DEBUG(5,("%s %s match on %s in %s\n",
     103                                         r1->other_info->dns_name,
     104                                         el->name,
     105                                         ldb_dn_get_linearized(dn),
     106                                         ldb_dn_get_linearized(msg->dn)));
     107                                return true;
     108                        }
     109                        talloc_free(dn);
     110                }
     111        }
     112        return false;
     113}
     114
     115struct kccsrv_notify_drepl_server_state {
     116        struct dreplsrv_refresh r;
     117};
     118
     119static void kccsrv_notify_drepl_server_done(struct tevent_req *subreq);
     120
     121/**
     122 * Force dreplsrv to update its state as topology is changed
     123 */
     124static void kccsrv_notify_drepl_server(struct kccsrv_service *s,
     125                                       TALLOC_CTX *mem_ctx)
     126{
     127        struct kccsrv_notify_drepl_server_state *state;
     128        struct dcerpc_binding_handle *irpc_handle;
     129        struct tevent_req *subreq;
     130
     131        state = talloc_zero(s, struct kccsrv_notify_drepl_server_state);
     132        if (state == NULL) {
     133                return;
     134        }
     135
     136        irpc_handle = irpc_binding_handle_by_name(state, s->task->msg_ctx,
     137                                                  "dreplsrv", &ndr_table_irpc);
     138        if (irpc_handle == NULL) {
     139                /* dreplsrv is not running yet */
     140                TALLOC_FREE(state);
     141                return;
     142        }
     143
     144        subreq = dcerpc_dreplsrv_refresh_r_send(state, s->task->event_ctx,
     145                                                irpc_handle, &state->r);
     146        if (subreq == NULL) {
     147                TALLOC_FREE(state);
     148                return;
     149        }
     150        tevent_req_set_callback(subreq, kccsrv_notify_drepl_server_done, state);
     151}
     152
     153static void kccsrv_notify_drepl_server_done(struct tevent_req *subreq)
     154{
     155        struct kccsrv_notify_drepl_server_state *state =
     156                tevent_req_callback_data(subreq,
     157                struct kccsrv_notify_drepl_server_state);
     158        NTSTATUS status;
     159
     160        status = dcerpc_dreplsrv_refresh_r_recv(subreq, state);
     161        TALLOC_FREE(subreq);
     162
     163        /* we don't care about errors */
     164        TALLOC_FREE(state);
     165}
     166
     167static uint32_t kccsrv_replica_flags(struct kccsrv_service *s)
     168{
     169        if (s->am_rodc) {
     170                return DRSUAPI_DRS_INIT_SYNC |
     171                        DRSUAPI_DRS_PER_SYNC |
     172                        DRSUAPI_DRS_ADD_REF |
     173                        DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING |
     174                        DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP |
     175                        DRSUAPI_DRS_NONGC_RO_REP;
     176        }
     177        return DRSUAPI_DRS_INIT_SYNC |
     178                DRSUAPI_DRS_PER_SYNC |
     179                DRSUAPI_DRS_ADD_REF |
     180                DRSUAPI_DRS_WRIT_REP;
     181}
    54182
    55183/*
     
    57185 */
    58186static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx,
    59                                     struct repsFromToBlob *reps, uint32_t count)
     187                                    struct repsFromToBlob *reps, uint32_t count,
     188                                    struct ldb_result *res)
    60189{
    61190        struct kccsrv_partition *p;
     191        bool notify_dreplsrv = false;
     192        uint32_t replica_flags = kccsrv_replica_flags(s);
    62193
    63194        /* update the repsFrom on all partitions */
    64195        for (p=s->partitions; p; p=p->next) {
    65                 struct repsFromToBlob *old_reps;
    66                 uint32_t old_count;
     196                struct repsFromToBlob *our_reps;
     197                uint32_t our_count;
    67198                WERROR werr;
    68                 int i;
     199                uint32_t i, j;
    69200                bool modified = false;
    70201
    71                 werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsFrom", &old_reps, &old_count);
     202                werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsFrom", &our_reps, &our_count);
    72203                if (!W_ERROR_IS_OK(werr)) {
    73204                        DEBUG(0,(__location__ ": Failed to load repsFrom from %s - %s\n",
     
    76207                }
    77208
    78                 /* add any new ones */
     209                /* see if the entry already exists */
    79210                for (i=0; i<count; i++) {
    80                         if (!reps_in_list(&reps[i], old_reps, old_count)) {
    81                                 old_reps = talloc_realloc(mem_ctx, old_reps, struct repsFromToBlob, old_count+1);
    82                                 NT_STATUS_HAVE_NO_MEMORY(old_reps);
    83                                 old_reps[old_count] = reps[i];
    84                                 old_count++;
     211                        for (j=0; j<our_count; j++) {
     212                                if (kccsrv_same_source_dsa(&reps[i], &our_reps[j])) {
     213                                        /* we already have this one -
     214                                           check the replica_flags are right */
     215                                        if (replica_flags != our_reps[j].ctr.ctr1.replica_flags) {
     216                                                /* we need to update the old one with
     217                                                 * the new flags
     218                                                 */
     219                                                our_reps[j].ctr.ctr1.replica_flags = replica_flags;
     220                                                modified = true;
     221                                        }
     222                                        break;
     223                                }
     224                        }
     225                        if (j == our_count) {
     226                                /* we don't have the new one - add it
     227                                 * if it is a master
     228                                 */
     229                                if (!check_MasterNC(p, &reps[i], res)) {
     230                                        /* its not a master, we don't
     231                                           want to pull from it */
     232                                        continue;
     233                                }
     234                                /* we need to add it to our repsFrom */
     235                                our_reps = talloc_realloc(mem_ctx, our_reps, struct repsFromToBlob, our_count+1);
     236                                NT_STATUS_HAVE_NO_MEMORY(our_reps);
     237                                our_reps[our_count] = reps[i];
     238                                our_reps[our_count].ctr.ctr1.replica_flags = replica_flags;
     239                                our_count++;
    85240                                modified = true;
     241                                DEBUG(4,(__location__ ": Added repsFrom for %s\n",
     242                                         reps[i].ctr.ctr1.other_info->dns_name));
    86243                        }
    87244                }
    88245
    89246                /* remove any stale ones */
    90                 for (i=0; i<old_count; i++) {
    91                         if (!reps_in_list(&old_reps[i], reps, count)) {
    92                                 memmove(&old_reps[i], &old_reps[i+1], (old_count-(i+1))*sizeof(old_reps[0]));
    93                                 old_count--;
     247                for (i=0; i<our_count; i++) {
     248                        if (!reps_in_list(&our_reps[i], reps, count) ||
     249                            !check_MasterNC(p, &our_reps[i], res)) {
     250                                DEBUG(4,(__location__ ": Removed repsFrom for %s\n",
     251                                         our_reps[i].ctr.ctr1.other_info->dns_name));
     252                                memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0]));
     253                                our_count--;
    94254                                i--;
    95255                                modified = true;
    96256                        }
    97257                }
    98                
     258
    99259                if (modified) {
    100                         werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsFrom", old_reps, old_count);
     260                        werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsFrom", our_reps, our_count);
    101261                        if (!W_ERROR_IS_OK(werr)) {
    102262                                DEBUG(0,(__location__ ": Failed to save repsFrom to %s - %s\n",
     
    104264                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    105265                        }
    106                 }
     266                        /* dreplsrv should refresh its state */
     267                        notify_dreplsrv = true;
     268                }
     269
     270                /* remove stale repsTo entries */
     271                modified = false;
     272                werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsTo", &our_reps, &our_count);
     273                if (!W_ERROR_IS_OK(werr)) {
     274                        DEBUG(0,(__location__ ": Failed to load repsTo from %s - %s\n",
     275                                 ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb)));
     276                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     277                }
     278
     279                /* remove any stale ones */
     280                for (i=0; i<our_count; i++) {
     281                        if (!reps_in_list(&our_reps[i], reps, count)) {
     282                                DEBUG(4,(__location__ ": Removed repsTo for %s\n",
     283                                         our_reps[i].ctr.ctr1.other_info->dns_name));
     284                                memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0]));
     285                                our_count--;
     286                                i--;
     287                                modified = true;
     288                        }
     289                }
     290
     291                if (modified) {
     292                        werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsTo", our_reps, our_count);
     293                        if (!W_ERROR_IS_OK(werr)) {
     294                                DEBUG(0,(__location__ ": Failed to save repsTo to %s - %s\n",
     295                                         ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb)));
     296                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     297                        }
     298                        /* dreplsrv should refresh its state */
     299                        notify_dreplsrv = true;
     300                }
     301        }
     302
     303        /* notify dreplsrv toplogy has changed */
     304        if (notify_dreplsrv) {
     305                kccsrv_notify_drepl_server(s, mem_ctx);
    107306        }
    108307
     
    116315  objects, except for ourselves
    117316 */
    118 static NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
     317NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
    119318{
    120319        struct ldb_result *res;
    121         int ret, i;
    122         const char *attrs[] = { "objectGUID", "invocationID", NULL };
     320        unsigned int i;
     321        int ret;
     322        const char *attrs[] = { "objectGUID", "invocationID", "msDS-hasMasterNCs", "hasMasterNCs", NULL };
    123323        struct repsFromToBlob *reps = NULL;
    124324        uint32_t count = 0;
     325        struct kcc_connection_list *ntds_conn, *dsa_conn;
    125326
    126327        ret = ldb_search(s->samdb, mem_ctx, &res, s->config_dn, LDB_SCOPE_SUBTREE,
     
    131332        }
    132333
     334        /* get the current list of connections */
     335        ntds_conn = kccsrv_find_connections(s, mem_ctx);
     336
     337        dsa_conn = talloc_zero(mem_ctx, struct kcc_connection_list);
     338
    133339        for (i=0; i<res->count; i++) {
    134340                struct repsFromTo1 *r1;
     
    153359                r1->other_info->dns_name     = talloc_asprintf(r1->other_info, "%s._msdcs.%s",
    154360                                                               GUID_string(mem_ctx, &ntds_guid),
    155                                                                lp_realm(s->task->lp_ctx));
     361                                                               lpcfg_dnsdomain(s->task->lp_ctx));
    156362                r1->source_dsa_obj_guid      = ntds_guid;
    157363                r1->source_dsa_invocation_id = invocation_id;
    158                 r1->replica_flags            =
    159                         DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE |
    160                         DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP |
    161                         DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS;
     364                r1->replica_flags = kccsrv_replica_flags(s);
    162365                memset(r1->schedule, 0x11, sizeof(r1->schedule));
     366
     367                dsa_conn->servers = talloc_realloc(dsa_conn, dsa_conn->servers,
     368                                                  struct kcc_connection,
     369                                                  dsa_conn->count + 1);
     370                NT_STATUS_HAVE_NO_MEMORY(dsa_conn->servers);
     371                dsa_conn->servers[dsa_conn->count].dsa_guid = r1->source_dsa_obj_guid;
     372                dsa_conn->count++;
     373
    163374                count++;
    164375        }
    165376
    166         return kccsrv_add_repsFrom(s, mem_ctx, reps, count);
     377        kccsrv_apply_connections(s, ntds_conn, dsa_conn);
     378
     379        return kccsrv_add_repsFrom(s, mem_ctx, reps, count, res);
    167380}
    168381
     
    217430
    218431        tmp_mem = talloc_new(service);
    219         DEBUG(2,("kccsrv_periodic_schedule(%u) %sscheduled for: %s\n",
     432        DEBUG(4,("kccsrv_periodic_schedule(%u) %sscheduled for: %s\n",
    220433                next_interval,
    221434                (service->periodic.te?"re":""),
     
    234447        NTSTATUS status;
    235448
    236         DEBUG(2,("kccsrv_periodic_run(): simple update\n"));
     449        DEBUG(4,("kccsrv_periodic_run(): simple update\n"));
    237450
    238451        mem_ctx = talloc_new(service);
     
    241454                DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status)));
    242455        }
     456
     457        status = kccsrv_check_deleted(service, mem_ctx);
     458        if (!NT_STATUS_IS_OK(status)) {
     459                DEBUG(0,("kccsrv_check_deleted failed - %s\n", nt_errstr(status)));
     460        }
    243461        talloc_free(mem_ctx);
    244462}
  • vendor/current/source4/dsdb/kcc/kcc_service.c

    r414 r740  
    2929#include "lib/messaging/irpc.h"
    3030#include "dsdb/kcc/kcc_service.h"
    31 #include "lib/ldb/include/ldb_errors.h"
     31#include <ldb_errors.h>
    3232#include "../lib/util/dlinklist.h"
    3333#include "librpc/gen_ndr/ndr_misc.h"
     
    4141static WERROR kccsrv_init_creds(struct kccsrv_service *service)
    4242{
    43         NTSTATUS status;
    44 
    45         status = auth_system_session_info(service, service->task->lp_ctx,
    46                                           &service->system_session_info);
    47         if (!NT_STATUS_IS_OK(status)) {
    48                 return ntstatus_to_werror(status);
     43        service->system_session_info = system_session(service->task->lp_ctx);
     44        if (!service->system_session_info) {
     45                return WERR_NOMEM;
    4946        }
    5047
     
    5956        const struct GUID *ntds_guid;
    6057
    61         service->samdb = samdb_connect(service, service->task->event_ctx, lp_ctx, service->system_session_info);
     58        service->samdb = samdb_connect(service, service->task->event_ctx, lp_ctx, service->system_session_info, 0);
    6259        if (!service->samdb) {
    6360                return WERR_DS_UNAVAILABLE;
     
    7067
    7168        service->ntds_guid = *ntds_guid;
     69
     70        if (samdb_rodc(service->samdb, &service->am_rodc) != LDB_SUCCESS) {
     71                DEBUG(0,(__location__ ": Failed to determine RODC status\n"));
     72                return WERR_DS_UNAVAILABLE;
     73        }
    7274
    7375        return WERR_OK;
     
    8486        struct ldb_message_element *el;
    8587        static const char *attrs[] = { "namingContexts", "configurationNamingContext", NULL };
    86         uint32_t i;
     88        unsigned int i;
    8789        int ret;
    8890
     
    105107        }
    106108
    107         for (i=0; el && i < el->num_values; i++) {
     109        for (i=0; i < el->num_values; i++) {
    108110                const char *v = (const char *)el->values[i].data;
    109111                struct ldb_dn *pdn;
     
    140142}
    141143
     144static NTSTATUS kccsrv_execute_kcc(struct irpc_message *msg, struct drsuapi_DsExecuteKCC *r)
     145{
     146        TALLOC_CTX *mem_ctx;
     147        NTSTATUS status;
     148        struct kccsrv_service *service = talloc_get_type(msg->private_data, struct kccsrv_service);
     149
     150        mem_ctx = talloc_new(service);
     151        status = kccsrv_simple_update(service, mem_ctx);
     152
     153        if (!NT_STATUS_IS_OK(status)) {
     154                DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status)));
     155                talloc_free(mem_ctx);
     156                return status;
     157        }
     158
     159        talloc_free(mem_ctx);
     160        return NT_STATUS_OK;
     161}
     162
     163static NTSTATUS kccsrv_replica_get_info(struct irpc_message *msg, struct drsuapi_DsReplicaGetInfo *r)
     164{
     165        return kccdrs_replica_get_info(msg, r);
     166}
    142167
    143168/*
     
    150175        uint32_t periodic_startup_interval;
    151176
    152         switch (lp_server_role(task->lp_ctx)) {
     177        switch (lpcfg_server_role(task->lp_ctx)) {
    153178        case ROLE_STANDALONE:
    154179                task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false);
     
    198223        }
    199224
    200         periodic_startup_interval       = lp_parm_int(task->lp_ctx, NULL, "kccsrv",
     225        periodic_startup_interval       = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv",
    201226                                                      "periodic_startup_interval", 15); /* in seconds */
    202         service->periodic.interval      = lp_parm_int(task->lp_ctx, NULL, "kccsrv",
     227        service->periodic.interval      = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv",
    203228                                                      "periodic_interval", 300); /* in seconds */
    204229
     
    212237
    213238        irpc_add_name(task->msg_ctx, "kccsrv");
     239
     240        IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service);
     241        IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAGETINFO, kccsrv_replica_get_info, service);
    214242}
    215243
  • vendor/current/source4/dsdb/kcc/kcc_service.h

    r414 r740  
    7979                struct tevent_timer *te;
    8080        } periodic;
     81
     82        time_t last_deleted_check;
     83
     84        bool am_rodc;
    8185};
     86
     87struct kcc_connection_list;
    8288
    8389#include "dsdb/kcc/kcc_service_proto.h"
Note: See TracChangeset for help on using the changeset viewer.