LCOV - code coverage report
Current view: top level - source4/wrepl_server - wrepl_server.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 202 258 78.3 %
Date: 2024-05-31 13:13:24 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    
       4             :    WINS Replication server
       5             :    
       6             :    Copyright (C) Stefan Metzmacher      2005
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "../lib/util/dlinklist.h"
      24             : #include "samba/service_task.h"
      25             : #include "samba/service.h"
      26             : #include "lib/messaging/irpc.h"
      27             : #include "librpc/gen_ndr/winsrepl.h"
      28             : #include "wrepl_server/wrepl_server.h"
      29             : #include "nbt_server/wins/winsdb.h"
      30             : #include <ldb.h>
      31             : #include <ldb_errors.h>
      32             : #include "auth/auth.h"
      33             : #include "ldb_wrap.h"
      34             : #include "param/param.h"
      35             : #include "lib/socket/netif.h"
      36             : 
      37          65 : static struct ldb_context *wins_config_db_connect(TALLOC_CTX *mem_ctx, 
      38             :                                                   struct tevent_context *ev_ctx,
      39             :                                                   struct loadparm_context *lp_ctx)
      40             : {
      41          65 :         return ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, lpcfg_private_path(mem_ctx,
      42             :                                 lp_ctx, "wins_config.ldb"),
      43             :                                 system_session(lp_ctx), NULL, 0);
      44             : }
      45             : 
      46        4097 : static uint64_t wins_config_db_get_seqnumber(struct ldb_context *ldb)
      47             : {
      48          36 :         int ret;
      49          36 :         struct ldb_dn *dn;
      50        4097 :         struct ldb_result *res = NULL;
      51        4097 :         TALLOC_CTX *tmp_ctx = talloc_new(ldb);
      52        4097 :         uint64_t seqnumber = 0;
      53             : 
      54        4097 :         dn = ldb_dn_new(tmp_ctx, ldb, "@BASEINFO");
      55        4097 :         if (!dn) goto failed;
      56             : 
      57             :         /* find the record in the WINS database */
      58        4097 :         ret = ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
      59        4097 :         if (ret != LDB_SUCCESS) goto failed;
      60        4097 :         if (res->count > 1) goto failed;
      61             : 
      62        4097 :         if (res->count == 1) {
      63        4097 :                 seqnumber = ldb_msg_find_attr_as_uint64(res->msgs[0], "sequenceNumber", 0);
      64             :         }
      65             : 
      66           0 : failed:
      67        4097 :         talloc_free(tmp_ctx);
      68        4097 :         return seqnumber;
      69             : }
      70             : 
      71             : /*
      72             :   open winsdb
      73             : */
      74          65 : static NTSTATUS wreplsrv_open_winsdb(struct wreplsrv_service *service, 
      75             :                                      struct loadparm_context *lp_ctx)
      76             : {
      77          65 :         const char *owner = lpcfg_parm_string(lp_ctx, NULL, "winsdb", "local_owner");
      78             : 
      79          65 :         if (owner == NULL) {
      80           2 :                 struct interface *ifaces;
      81          65 :                 load_interface_list(service, lp_ctx, &ifaces);
      82          65 :                 owner = iface_list_first_v4(ifaces);
      83             :         }
      84             : 
      85          65 :         service->wins_db     = winsdb_connect(service, service->task->event_ctx, lp_ctx, owner, WINSDB_HANDLE_CALLER_WREPL);
      86          65 :         if (!service->wins_db) {
      87           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
      88             :         }
      89             : 
      90          65 :         service->config.ldb = wins_config_db_connect(service, service->task->event_ctx, lp_ctx);
      91          65 :         if (!service->config.ldb) {
      92           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
      93             :         }
      94             : 
      95             :         /* the default renew interval is 6 days */
      96          65 :         service->config.renew_interval         = lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","renew_interval", 6*24*60*60);
      97             : 
      98             :         /* the default tombstone (extinction) interval is 6 days */
      99          65 :         service->config.tombstone_interval= lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","tombstone_interval", 6*24*60*60);
     100             : 
     101             :         /* the default tombstone (extinction) timeout is 1 day */
     102          65 :         service->config.tombstone_timeout = lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","tombstone_timeout", 1*24*60*60);
     103             : 
     104             :         /* the default tombstone extra timeout is 3 days */
     105          65 :         service->config.tombstone_extra_timeout = lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","tombstone_extra_timeout", 3*24*60*60);
     106             : 
     107             :         /* the default verify interval is 24 days */
     108          65 :         service->config.verify_interval   = lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","verify_interval", 24*24*60*60);
     109             : 
     110             :         /* the default scavenging interval is 'renew_interval/2' */
     111         130 :         service->config.scavenging_interval=lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","scavenging_interval",
     112          65 :                                                         service->config.renew_interval/2);
     113             : 
     114             :         /* the maximum interval to the next periodic processing event */
     115          65 :         service->config.periodic_interval = lpcfg_parm_int(lp_ctx, NULL,"wreplsrv","periodic_interval", 15);
     116             : 
     117          65 :         return NT_STATUS_OK;
     118             : }
     119             : 
     120         799 : struct wreplsrv_partner *wreplsrv_find_partner(struct wreplsrv_service *service, const char *peer_addr)
     121             : {
     122           4 :         struct wreplsrv_partner *cur;
     123             : 
     124         854 :         for (cur = service->partners; cur; cur = cur->next) {
     125         734 :                 if (strcmp(cur->address, peer_addr) == 0) {
     126         679 :                         return cur;
     127             :                 }
     128             :         }
     129             : 
     130         116 :         return NULL;
     131             : }
     132             : 
     133          49 : static uint32_t wreplsrv_find_attr_as_uint32(const struct ldb_message *msg,
     134             :                                              const char *attr_name,
     135             :                                              uint32_t default_value)
     136             : {
     137          49 :         const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
     138          49 :         char buf[sizeof("-2147483648")] = {};
     139          49 :         char *end = NULL;
     140           2 :         uint32_t ret;
     141          49 :         int base = 10;
     142             : 
     143          49 :         if (!v || !v->data) {
     144           0 :                 return default_value;
     145             :         }
     146             : 
     147          49 :         if (v->length >= sizeof(buf)) {
     148           0 :                 return default_value;
     149             :         }
     150             : 
     151          49 :         memcpy(buf, v->data, v->length);
     152          49 :         if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
     153          49 :                 base = 16;
     154             :         }
     155             : 
     156          49 :         errno = 0;
     157          49 :         ret = strtoll(buf, &end, base);
     158          49 :         if (errno == ERANGE || errno == EINVAL) {
     159           0 :                 errno = 0;
     160           0 :                 ret = strtoull(buf, &end, base);
     161           0 :                 if (errno == ERANGE || errno == EINVAL) {
     162           0 :                         return default_value;
     163             :                 }
     164             :         }
     165          49 :         if (end && end[0] != '\0') {
     166           0 :                 return default_value;
     167             :         }
     168          47 :         return ret;
     169             : }
     170             : 
     171             : /*
     172             :   load our replication partners
     173             : */
     174        4097 : NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service)
     175             : {
     176          36 :         struct wreplsrv_partner *partner;
     177        4097 :         struct ldb_result *res = NULL;
     178          36 :         int ret;
     179          36 :         TALLOC_CTX *tmp_ctx;
     180          36 :         unsigned int i;
     181          36 :         uint64_t new_seqnumber;
     182             : 
     183        4097 :         new_seqnumber = wins_config_db_get_seqnumber(service->config.ldb);
     184             : 
     185             :         /* if it's not the first run and nothing changed we're done */
     186        4097 :         if (service->config.seqnumber != 0 && service->config.seqnumber == new_seqnumber) {
     187        4032 :                 return NT_STATUS_OK;
     188             :         }
     189             : 
     190          65 :         tmp_ctx = talloc_new(service);
     191          65 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     192             : 
     193          65 :         service->config.seqnumber = new_seqnumber;
     194             : 
     195             :         /* find the record in the WINS database */
     196          65 :         ret = ldb_search(service->config.ldb, tmp_ctx, &res,
     197             :                          ldb_dn_new(tmp_ctx, service->config.ldb, "CN=PARTNERS"),
     198             :                          LDB_SCOPE_SUBTREE, NULL, "(objectClass=wreplPartner)");
     199          65 :         if (ret != LDB_SUCCESS) goto failed;
     200             : 
     201             :         /* first disable all existing partners */
     202          65 :         for (partner=service->partners; partner; partner = partner->next) {
     203           0 :                 partner->type = WINSREPL_PARTNER_NONE;
     204             :         }
     205             : 
     206         114 :         for (i=0; i < res->count; i++) {
     207           2 :                 const char *address;
     208             : 
     209          49 :                 address = ldb_msg_find_attr_as_string(res->msgs[i], "address", NULL);
     210          49 :                 if (!address) {
     211           0 :                         goto failed;
     212             :                 }
     213             : 
     214          49 :                 partner = wreplsrv_find_partner(service, address);
     215          49 :                 if (partner) {
     216           0 :                         if (partner->name != partner->address) {
     217           0 :                                 talloc_free(discard_const(partner->name));
     218             :                         }
     219           0 :                         partner->name = NULL;
     220           0 :                         talloc_free(discard_const(partner->our_address));
     221           0 :                         partner->our_address = NULL;
     222             : 
     223             :                         /* force rescheduling of pulling */
     224           0 :                         partner->pull.next_run = timeval_zero();
     225             :                 } else {
     226          49 :                         partner = talloc_zero(service, struct wreplsrv_partner);
     227          49 :                         if (partner == NULL) goto failed;
     228             : 
     229          49 :                         partner->service = service;
     230          49 :                         partner->address = address;
     231          49 :                         talloc_steal(partner, partner->address);
     232             : 
     233          49 :                         DLIST_ADD_END(service->partners, partner);
     234             :                 }
     235             : 
     236          49 :                 partner->name                        = ldb_msg_find_attr_as_string(res->msgs[i], "name", partner->address);
     237          49 :                 talloc_steal(partner, partner->name);
     238          49 :                 partner->our_address         = ldb_msg_find_attr_as_string(res->msgs[i], "ourAddress", NULL);
     239          49 :                 talloc_steal(partner, partner->our_address);
     240             : 
     241          49 :                 partner->type                        = wreplsrv_find_attr_as_uint32(res->msgs[i], "type", WINSREPL_PARTNER_BOTH);
     242          49 :                 partner->pull.interval               = ldb_msg_find_attr_as_uint(res->msgs[i], "pullInterval",
     243             :                                                                     WINSREPL_DEFAULT_PULL_INTERVAL);
     244          49 :                 partner->pull.retry_interval = ldb_msg_find_attr_as_uint(res->msgs[i], "pullRetryInterval",
     245             :                                                                     WINSREPL_DEFAULT_PULL_RETRY_INTERVAL);
     246          49 :                 partner->push.change_count   = ldb_msg_find_attr_as_uint(res->msgs[i], "pushChangeCount",
     247             :                                                                     WINSREPL_DEFAULT_PUSH_CHANGE_COUNT);
     248          49 :                 partner->push.use_inform     = ldb_msg_find_attr_as_uint(res->msgs[i], "pushUseInform", true);
     249             : 
     250          49 :                 DEBUG(3,("wreplsrv_load_partners: found partner: %s type: 0x%X\n",
     251             :                         partner->address, partner->type));
     252             :         }
     253             : 
     254          65 :         DEBUG(2,("wreplsrv_load_partners: %u partners found: wins_config_db seqnumber %llu\n",
     255             :                 res->count, (unsigned long long)service->config.seqnumber));
     256             : 
     257          65 :         talloc_free(tmp_ctx);
     258          65 :         return NT_STATUS_OK;
     259           0 : failed:
     260           0 :         talloc_free(tmp_ctx);
     261           0 :         return NT_STATUS_FOOBAR;
     262             : }
     263             : 
     264           3 : NTSTATUS wreplsrv_fill_wrepl_table(struct wreplsrv_service *service,
     265             :                                    TALLOC_CTX *mem_ctx,
     266             :                                    struct wrepl_table *table_out,
     267             :                                    const char *initiator,
     268             :                                    bool full_table)
     269             : {
     270           0 :         struct wreplsrv_owner *cur;
     271           3 :         uint32_t i = 0;
     272             : 
     273           3 :         table_out->partner_count     = 0;
     274           3 :         table_out->partners          = NULL;
     275           3 :         table_out->initiator         = initiator;
     276             : 
     277           9 :         for (cur = service->table; cur; cur = cur->next) {
     278           6 :                 if (full_table) {
     279           6 :                         table_out->partner_count++;
     280           6 :                         continue;
     281             :                 }
     282             : 
     283           0 :                 if (strcmp(initiator, cur->owner.address) != 0) continue;
     284             : 
     285           0 :                 table_out->partner_count++;
     286           0 :                 break;
     287             :         }
     288             : 
     289           3 :         table_out->partners = talloc_array(mem_ctx, struct wrepl_wins_owner, table_out->partner_count);
     290           3 :         NT_STATUS_HAVE_NO_MEMORY(table_out->partners);
     291             : 
     292           9 :         for (cur = service->table; cur && i < table_out->partner_count; cur = cur->next) {
     293             :                 /*
     294             :                  * if it's our local entry
     295             :                  * update the max version
     296             :                  */
     297           6 :                 if (cur == service->owner) {
     298           3 :                         cur->owner.max_version = winsdb_get_maxVersion(service->wins_db);
     299             :                 }
     300             : 
     301           6 :                 if (full_table) {
     302           6 :                         table_out->partners[i] = cur->owner;
     303           6 :                         i++;
     304           6 :                         continue;
     305             :                 }
     306             : 
     307           0 :                 if (strcmp(initiator, cur->owner.address) != 0) continue;
     308             : 
     309           0 :                 table_out->partners[i] = cur->owner;
     310           0 :                 i++;
     311           0 :                 break;
     312             :         }
     313             : 
     314           3 :         return NT_STATUS_OK;
     315             : }
     316             : 
     317        5025 : struct wreplsrv_owner *wreplsrv_find_owner(struct wreplsrv_service *service,
     318             :                                            struct wreplsrv_owner *table,
     319             :                                            const char *wins_owner)
     320             : {
     321           6 :         struct wreplsrv_owner *cur;
     322             : 
     323       10634 :         for (cur = table; cur; cur = cur->next) {
     324       10560 :                 if (strcmp(cur->owner.address, wins_owner) == 0) {
     325             :                         /*
     326             :                          * if it's our local entry
     327             :                          * update the max version
     328             :                          */
     329        4951 :                         if (cur == service->owner) {
     330          74 :                                 cur->owner.max_version = winsdb_get_maxVersion(service->wins_db);
     331             :                         }
     332        4951 :                         return cur;
     333             :                 }
     334             :         }
     335             : 
     336          72 :         return NULL;
     337             : }
     338             : 
     339             : /*
     340             :  update the wins_owner_table max_version, if the given version is the highest version
     341             :  if no entry for the wins_owner exists yet, create one
     342             : */
     343        1480 : NTSTATUS wreplsrv_add_table(struct wreplsrv_service *service,
     344             :                             TALLOC_CTX *mem_ctx, struct wreplsrv_owner **_table,
     345             :                             const char *wins_owner, uint64_t version)
     346             : {
     347        1480 :         struct wreplsrv_owner *table = *_table;
     348           4 :         struct wreplsrv_owner *cur;
     349             : 
     350        1480 :         if (!wins_owner || strcmp(wins_owner, "0.0.0.0") == 0) {
     351           0 :                 wins_owner = service->wins_db->local_owner;
     352             :         }
     353             : 
     354        1480 :         cur = wreplsrv_find_owner(service, table, wins_owner);
     355             : 
     356             :         /* if it doesn't exists yet, create one */
     357        1480 :         if (!cur) {
     358          71 :                 cur = talloc_zero(mem_ctx, struct wreplsrv_owner);
     359          71 :                 NT_STATUS_HAVE_NO_MEMORY(cur);
     360             : 
     361          71 :                 cur->owner.address   = talloc_strdup(cur, wins_owner);
     362          71 :                 NT_STATUS_HAVE_NO_MEMORY(cur->owner.address);
     363          71 :                 cur->owner.min_version       = 0;
     364          71 :                 cur->owner.max_version       = 0;
     365          71 :                 cur->owner.type              = 1; /* don't know why this is always 1 */
     366             : 
     367          71 :                 cur->partner         = wreplsrv_find_partner(service, wins_owner);
     368             : 
     369          71 :                 DLIST_ADD_END(table, cur);
     370          71 :                 *_table = table;
     371             :         }
     372             : 
     373             :         /* the min_version is always 0 here, and won't be updated */
     374             : 
     375             :         /* if the given version is higher than the current max_version, update */
     376        1480 :         if (cur->owner.max_version < version) {
     377        1350 :                 cur->owner.max_version = version;
     378             :                 /* if it's for our local db, we need to update the wins.ldb too */
     379        1350 :                 if (cur == service->owner) {
     380           0 :                         uint64_t ret;
     381           0 :                         ret = winsdb_set_maxVersion(service->wins_db, cur->owner.max_version);
     382           0 :                         if (ret != cur->owner.max_version) {
     383           0 :                                 DEBUG(0,("winsdb_set_maxVersion(%llu) failed: %llu\n",
     384             :                                          (unsigned long long)cur->owner.max_version, 
     385             :                                          (unsigned long long)ret));
     386           0 :                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     387             :                         }
     388             :                 }
     389             :         }
     390             : 
     391        1480 :         return NT_STATUS_OK;
     392             : }
     393             : 
     394             : /*
     395             :   load the partner table
     396             : */
     397          65 : static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service)
     398             : {
     399          65 :         struct ldb_result *res = NULL;
     400           2 :         int ret;
     401           2 :         NTSTATUS status;
     402          65 :         TALLOC_CTX *tmp_ctx = talloc_new(service);
     403          65 :         struct ldb_context *ldb = service->wins_db->ldb;
     404           2 :         unsigned int i;
     405           2 :         struct wreplsrv_owner *local_owner;
     406           2 :         const char *wins_owner;
     407           2 :         uint64_t version;
     408          65 :         const char * const attrs[] = {
     409             :                 "winsOwner",
     410             :                 "versionID",
     411             :                 NULL
     412             :         };
     413             : 
     414             :         /*
     415             :          * make sure we have our local entry in the list,
     416             :          * but we set service->owner when we're done
     417             :          * to avoid to many calls to wreplsrv_local_max_version()
     418             :          */
     419          65 :         status = wreplsrv_add_table(service,
     420             :                                     service, &service->table,
     421          63 :                                     service->wins_db->local_owner, 0);
     422          65 :         if (!NT_STATUS_IS_OK(status)) goto failed;
     423          65 :         local_owner = wreplsrv_find_owner(service, service->table, service->wins_db->local_owner);
     424          65 :         if (!local_owner) {
     425           0 :                 status = NT_STATUS_INTERNAL_ERROR;
     426           0 :                 goto failed;
     427             :         }
     428             : 
     429             :         /* find the record in the WINS database */
     430          65 :         ret = ldb_search(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
     431             :                          attrs, "(objectClass=winsRecord)");
     432          65 :         status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     433          65 :         if (ret != LDB_SUCCESS) goto failed;
     434             : 
     435          65 :         for (i=0; i < res->count; i++) {
     436           0 :                 wins_owner     = ldb_msg_find_attr_as_string(res->msgs[i], "winsOwner", NULL);
     437           0 :                 version        = ldb_msg_find_attr_as_uint64(res->msgs[i], "versionID", 0);
     438             : 
     439           0 :                 status = wreplsrv_add_table(service,
     440             :                                             service, &service->table,
     441             :                                             wins_owner, version);
     442           0 :                 if (!NT_STATUS_IS_OK(status)) goto failed;
     443           0 :                 talloc_free(res->msgs[i]);
     444             :         }
     445             : 
     446             :         /*
     447             :          * this makes sure we call wreplsrv_local_max_version() before returning in
     448             :          * wreplsrv_find_owner()
     449             :          */
     450          65 :         service->owner = local_owner;
     451             : 
     452             :         /*
     453             :          * this makes sure the maxVersion in the database is updated,
     454             :          * with the highest version we found, if this is higher than the current stored one
     455             :          */
     456          67 :         status = wreplsrv_add_table(service,
     457             :                                     service, &service->table,
     458          65 :                                     service->wins_db->local_owner, local_owner->owner.max_version);
     459          65 :         if (!NT_STATUS_IS_OK(status)) goto failed;
     460             : 
     461          65 :         talloc_free(tmp_ctx);
     462          65 :         return NT_STATUS_OK;
     463           0 : failed:
     464           0 :         talloc_free(tmp_ctx);
     465           0 :         return status;
     466             : }
     467             : 
     468             : /*
     469             :   setup our replication partners
     470             : */
     471          65 : static NTSTATUS wreplsrv_setup_partners(struct wreplsrv_service *service)
     472             : {
     473           2 :         NTSTATUS status;
     474             : 
     475          65 :         status = wreplsrv_load_partners(service);
     476          65 :         NT_STATUS_NOT_OK_RETURN(status);
     477             : 
     478          65 :         status = wreplsrv_load_table(service);
     479          65 :         NT_STATUS_NOT_OK_RETURN(status);
     480             : 
     481          65 :         return NT_STATUS_OK;
     482             : }
     483             : 
     484             : /*
     485             :   startup the wrepl task
     486             : */
     487          65 : static NTSTATUS wreplsrv_task_init(struct task_server *task)
     488             : {
     489           2 :         NTSTATUS status;
     490           2 :         struct wreplsrv_service *service;
     491             : 
     492          65 :         if (!lpcfg_we_are_a_wins_server(task->lp_ctx)) {
     493           0 :                 return NT_STATUS_INVALID_DOMAIN_ROLE;
     494             :         }
     495             : 
     496          65 :         task_server_set_title(task, "task[wreplsrv]");
     497             : 
     498          65 :         service = talloc_zero(task, struct wreplsrv_service);
     499          65 :         if (!service) {
     500           0 :                 task_server_terminate(task, "wreplsrv_task_init: out of memory", true);
     501           0 :                 return NT_STATUS_NO_MEMORY;
     502             :         }
     503          65 :         service->task                = task;
     504          65 :         service->startup_time        = timeval_current();
     505          65 :         task->private_data   = service;
     506             : 
     507             :         /*
     508             :          * setup up all partners, and open the winsdb
     509             :          */
     510          65 :         status = wreplsrv_open_winsdb(service, task->lp_ctx);
     511          65 :         if (!NT_STATUS_IS_OK(status)) {
     512           0 :                 task_server_terminate(task, "wreplsrv_task_init: wreplsrv_open_winsdb() failed", true);
     513           0 :                 return status;
     514             :         }
     515             : 
     516             :         /*
     517             :          * setup timed events for each partner we want to pull from
     518             :          */
     519          65 :         status = wreplsrv_setup_partners(service);
     520          65 :         if (!NT_STATUS_IS_OK(status)) {
     521           0 :                 task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_partners() failed", true);
     522           0 :                 return status;
     523             :         }
     524             : 
     525             :         /* 
     526             :          * setup listen sockets, so we can answer requests from our partners,
     527             :          * which pull from us
     528             :          */
     529          65 :         status = wreplsrv_setup_sockets(service, task->lp_ctx);
     530          65 :         if (!NT_STATUS_IS_OK(status)) {
     531           0 :                 task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_sockets() failed", true);
     532           0 :                 return status;
     533             :         }
     534             : 
     535          65 :         status = wreplsrv_setup_periodic(service);
     536          65 :         if (!NT_STATUS_IS_OK(status)) {
     537           0 :                 task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed", true);
     538           0 :                 return status;
     539             :         }
     540             : 
     541          65 :         irpc_add_name(task->msg_ctx, "wrepl_server");
     542             : 
     543          65 :         return NT_STATUS_OK;
     544             : }
     545             : 
     546             : /*
     547             :   register ourselves as a available server
     548             : */
     549          66 : NTSTATUS server_service_wrepl_init(TALLOC_CTX *ctx)
     550             : {
     551           3 :         static const struct service_details details = {
     552             :                 .inhibit_fork_on_accept = true,
     553             :                 .inhibit_pre_fork = true,
     554             :                 .task_init = wreplsrv_task_init,
     555             :                 .post_fork = NULL
     556             :         };
     557          66 :         return register_server_service(ctx, "wrepl", &details);
     558             : }

Generated by: LCOV version 1.14