LCOV - code coverage report
Current view: top level - source4/wrepl_server - wrepl_scavenging.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 17 334 5.1 %
Date: 2024-04-21 15:09:00 Functions: 2 6 33.3 %

          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 "librpc/gen_ndr/ndr_winsrepl.h"
      24             : #include "wrepl_server/wrepl_server.h"
      25             : #include "nbt_server/wins/winsdb.h"
      26             : #include <ldb.h>
      27             : #include <ldb_errors.h>
      28             : #include "system/time.h"
      29             : #include "samba/service_task.h"
      30             : #include "lib/messaging/irpc.h"
      31             : #include "librpc/gen_ndr/ndr_irpc_c.h"
      32             : #include "librpc/gen_ndr/ndr_nbt.h"
      33             : #include "param/param.h"
      34             : 
      35         780 : const char *wreplsrv_owner_filter(struct wreplsrv_service *service,
      36             :                                   TALLOC_CTX *mem_ctx,
      37             :                                   const char *wins_owner)
      38             : {
      39         780 :         if (strcmp(wins_owner, service->wins_db->local_owner) == 0) {
      40           9 :                 return talloc_asprintf(mem_ctx, "(|(winsOwner=%s)(winsOwner=0.0.0.0))",
      41             :                                        wins_owner);
      42             :         }
      43             : 
      44         771 :         return talloc_asprintf(mem_ctx, "(&(winsOwner=%s)(!(winsOwner=0.0.0.0)))",
      45             :                                wins_owner);
      46             : }
      47             : 
      48           0 : static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *service, TALLOC_CTX *tmp_mem)
      49             : {
      50           0 :         NTSTATUS status;
      51           0 :         struct winsdb_record *rec = NULL;
      52           0 :         struct ldb_result *res = NULL;
      53           0 :         const char *owner_filter;
      54           0 :         const char *filter;
      55           0 :         unsigned int i;
      56           0 :         int ret;
      57           0 :         time_t now = time(NULL);
      58           0 :         const char *now_timestr;
      59           0 :         const char *action;
      60           0 :         const char *old_state=NULL;
      61           0 :         const char *new_state=NULL;
      62           0 :         uint32_t modify_flags;
      63           0 :         bool modify_record;
      64           0 :         bool delete_record;
      65           0 :         bool delete_tombstones;
      66           0 :         struct timeval tombstone_extra_time;
      67           0 :         const char *local_owner = service->wins_db->local_owner;
      68           0 :         bool propagate = lpcfg_parm_bool(service->task->lp_ctx, NULL, "wreplsrv", "propagate name releases", false);
      69             : 
      70           0 :         now_timestr = ldb_timestring(tmp_mem, now);
      71           0 :         NT_STATUS_HAVE_NO_MEMORY(now_timestr);
      72           0 :         owner_filter = wreplsrv_owner_filter(service, tmp_mem, local_owner);
      73           0 :         NT_STATUS_HAVE_NO_MEMORY(owner_filter);
      74           0 :         filter = talloc_asprintf(tmp_mem,
      75             :                                  "(&%s(objectClass=winsRecord)"
      76             :                                  "(expireTime<=%s))",
      77             :                                  owner_filter, now_timestr);
      78           0 :         NT_STATUS_HAVE_NO_MEMORY(filter);
      79           0 :         ret = ldb_search(service->wins_db->ldb, tmp_mem, &res, NULL, LDB_SCOPE_SUBTREE, NULL, "%s", filter);
      80           0 :         if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION;
      81           0 :         DEBUG(10,("WINS scavenging: filter '%s' count %d\n", filter, res->count));
      82             : 
      83           0 :         tombstone_extra_time = timeval_add(&service->startup_time,
      84             :                                            service->config.tombstone_extra_timeout,
      85             :                                            0);
      86           0 :         delete_tombstones = timeval_expired(&tombstone_extra_time);
      87             : 
      88           0 :         for (i=0; i < res->count; i++) {
      89           0 :                 bool has_replicas = false;
      90             : 
      91             :                 /*
      92             :                  * we pass '0' as 'now' here,
      93             :                  * because we want to get the raw timestamps which are in the DB
      94             :                  */
      95           0 :                 status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
      96           0 :                 NT_STATUS_NOT_OK_RETURN(status);
      97           0 :                 talloc_free(res->msgs[i]);
      98             : 
      99           0 :                 modify_flags    = 0;
     100           0 :                 modify_record   = false;
     101           0 :                 delete_record   = false;
     102             : 
     103           0 :                 switch (rec->state) {
     104           0 :                 case WREPL_STATE_ACTIVE:
     105           0 :                         old_state       = "active";
     106           0 :                         if (rec->is_static) {
     107             :                                 /*
     108             :                                  *we store it again, so that it won't appear
     109             :                                  * in the scavenging the next time
     110             :                                  */
     111           0 :                                 old_state       = "active(static)";
     112           0 :                                 new_state       = "active(static)";
     113           0 :                                 modify_flags    = 0;
     114           0 :                                 modify_record   = true;
     115           0 :                                 break;
     116             :                         }
     117           0 :                         if (rec->type != WREPL_TYPE_SGROUP || !propagate) {
     118           0 :                                 new_state       = "released";
     119           0 :                                 rec->state   = WREPL_STATE_RELEASED;
     120           0 :                                 rec->expire_time= service->config.tombstone_interval + now;
     121           0 :                                 modify_flags    = 0;
     122           0 :                                 modify_record   = true;
     123           0 :                                 break;
     124             :                         }
     125             :                         /* check if there's any replica address */
     126           0 :                         for (i=0;rec->addresses[i];i++) {
     127           0 :                                 if (strcmp(rec->addresses[i]->wins_owner, local_owner) != 0) {
     128           0 :                                         has_replicas = true;
     129           0 :                                         rec->addresses[i]->expire_time= service->config.renew_interval + now;
     130             :                                 }
     131             :                         }
     132           0 :                         if (has_replicas) {
     133             :                                 /* if it has replica addresses propagate them */
     134           0 :                                 new_state       = "active(propagated)";
     135           0 :                                 rec->state   = WREPL_STATE_ACTIVE;
     136           0 :                                 rec->expire_time= service->config.renew_interval + now;
     137           0 :                                 modify_flags    = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
     138           0 :                                 modify_record   = true;
     139           0 :                                 break;
     140             :                         }
     141             :                         /*
     142             :                          * if it doesn't have replica addresses, make it a tombstone,
     143             :                          * so that the released owned addresses are propagated
     144             :                          */
     145           0 :                         new_state       = "tombstone";
     146           0 :                         rec->state   = WREPL_STATE_TOMBSTONE;
     147           0 :                         rec->expire_time= time(NULL) +
     148           0 :                                           service->config.tombstone_interval +
     149           0 :                                           service->config.tombstone_timeout;
     150           0 :                         modify_flags    = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
     151           0 :                         modify_record   = true;
     152           0 :                         break;
     153             : 
     154           0 :                 case WREPL_STATE_RELEASED:
     155           0 :                         old_state       = "released";
     156           0 :                         new_state       = "tombstone";
     157           0 :                         rec->state   = WREPL_STATE_TOMBSTONE;
     158           0 :                         rec->expire_time= service->config.tombstone_timeout + now;
     159           0 :                         modify_flags    = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
     160           0 :                         modify_record   = true;
     161           0 :                         break;
     162             : 
     163           0 :                 case WREPL_STATE_TOMBSTONE:
     164           0 :                         old_state       = "tombstone";
     165           0 :                         new_state       = "tombstone";
     166           0 :                         if (!delete_tombstones) break;
     167           0 :                         new_state       = "deleted";
     168           0 :                         delete_record = true;
     169           0 :                         break;
     170             : 
     171           0 :                 case WREPL_STATE_RESERVED:
     172           0 :                         DEBUG(0,("%s: corrupted record: %s\n",
     173             :                                 __location__, nbt_name_string(rec, rec->name)));
     174           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     175             :                 }
     176             : 
     177           0 :                 if (modify_record) {
     178           0 :                         action = "modify";
     179           0 :                         ret = winsdb_modify(service->wins_db, rec, modify_flags);
     180           0 :                 } else if (delete_record) {
     181           0 :                         action = "delete";
     182           0 :                         ret = winsdb_delete(service->wins_db, rec);
     183             :                 } else {
     184           0 :                         action = "skip";
     185           0 :                         ret = NBT_RCODE_OK;
     186             :                 }
     187             : 
     188           0 :                 if (ret != NBT_RCODE_OK) {
     189           0 :                         DEBUG(2,("WINS scavenging: failed to %s name %s (owned:%s -> owned:%s): error:%u\n",
     190             :                                 action, nbt_name_string(rec, rec->name), old_state, new_state, ret));
     191             :                 } else {
     192           0 :                         DEBUG(4,("WINS scavenging: %s name: %s (owned:%s -> owned:%s)\n",
     193             :                                 action, nbt_name_string(rec, rec->name), old_state, new_state));
     194             :                 }
     195             : 
     196           0 :                 talloc_free(rec);
     197             :         }
     198             : 
     199           0 :         return NT_STATUS_OK;
     200             : }
     201             : 
     202           0 : static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_service *service, TALLOC_CTX *tmp_mem)
     203             : {
     204           0 :         NTSTATUS status;
     205           0 :         struct winsdb_record *rec = NULL;
     206           0 :         struct ldb_result *res = NULL;
     207           0 :         const char *owner_filter;
     208           0 :         const char *filter;
     209           0 :         unsigned int i;
     210           0 :         int ret;
     211           0 :         time_t now = time(NULL);
     212           0 :         const char *now_timestr;
     213           0 :         const char *action;
     214           0 :         const char *old_state=NULL;
     215           0 :         const char *new_state=NULL;
     216           0 :         uint32_t modify_flags;
     217           0 :         bool modify_record;
     218           0 :         bool delete_record;
     219           0 :         bool delete_tombstones;
     220           0 :         struct timeval tombstone_extra_time;
     221             : 
     222           0 :         now_timestr = ldb_timestring(tmp_mem, now);
     223           0 :         NT_STATUS_HAVE_NO_MEMORY(now_timestr);
     224           0 :         owner_filter = wreplsrv_owner_filter(service, tmp_mem,
     225           0 :                                              service->wins_db->local_owner);
     226           0 :         NT_STATUS_HAVE_NO_MEMORY(owner_filter);
     227           0 :         filter = talloc_asprintf(tmp_mem,
     228             :                                  "(&(!%s)(objectClass=winsRecord)"
     229             :                                  "(!(recordState=%u))(expireTime<=%s))",
     230             :                                  owner_filter, WREPL_STATE_ACTIVE, now_timestr);
     231           0 :         NT_STATUS_HAVE_NO_MEMORY(filter);
     232           0 :         ret = ldb_search(service->wins_db->ldb, tmp_mem, &res, NULL, LDB_SCOPE_SUBTREE, NULL, "%s", filter);
     233           0 :         if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION;
     234           0 :         DEBUG(10,("WINS scavenging: filter '%s' count %d\n", filter, res->count));
     235             : 
     236           0 :         tombstone_extra_time = timeval_add(&service->startup_time,
     237             :                                            service->config.tombstone_extra_timeout,
     238             :                                            0);
     239           0 :         delete_tombstones = timeval_expired(&tombstone_extra_time);
     240             : 
     241           0 :         for (i=0; i < res->count; i++) {
     242             :                 /*
     243             :                  * we pass '0' as 'now' here,
     244             :                  * because we want to get the raw timestamps which are in the DB
     245             :                  */
     246           0 :                 status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
     247           0 :                 NT_STATUS_NOT_OK_RETURN(status);
     248           0 :                 talloc_free(res->msgs[i]);
     249             : 
     250           0 :                 modify_flags    = 0;
     251           0 :                 modify_record   = false;
     252           0 :                 delete_record   = false;
     253             : 
     254           0 :                 switch (rec->state) {
     255           0 :                 case WREPL_STATE_ACTIVE:
     256           0 :                         DEBUG(0,("%s: corrupted record: %s\n",
     257             :                                 __location__, nbt_name_string(rec, rec->name)));
     258           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     259             : 
     260           0 :                 case WREPL_STATE_RELEASED:
     261           0 :                         old_state       = "released";
     262           0 :                         new_state       = "tombstone";
     263           0 :                         rec->state   = WREPL_STATE_TOMBSTONE;
     264           0 :                         rec->expire_time= service->config.tombstone_timeout + now;
     265           0 :                         modify_flags    = 0;
     266           0 :                         modify_record   = true;
     267           0 :                         break;
     268             : 
     269           0 :                 case WREPL_STATE_TOMBSTONE:
     270           0 :                         old_state       = "tombstone";
     271           0 :                         new_state       = "tombstone";
     272           0 :                         if (!delete_tombstones) break;
     273           0 :                         new_state       = "deleted";
     274           0 :                         delete_record = true;
     275           0 :                         break;
     276             : 
     277           0 :                 case WREPL_STATE_RESERVED:
     278           0 :                         DEBUG(0,("%s: corrupted record: %s\n",
     279             :                                 __location__, nbt_name_string(rec, rec->name)));
     280           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     281             :                 }
     282             : 
     283           0 :                 if (modify_record) {
     284           0 :                         action = "modify";
     285           0 :                         ret = winsdb_modify(service->wins_db, rec, modify_flags);
     286           0 :                 } else if (delete_record) {
     287           0 :                         action = "delete";
     288           0 :                         ret = winsdb_delete(service->wins_db, rec);
     289             :                 } else {
     290           0 :                         action = "skip";
     291           0 :                         ret = NBT_RCODE_OK;
     292             :                 }
     293             : 
     294           0 :                 if (ret != NBT_RCODE_OK) {
     295           0 :                         DEBUG(2,("WINS scavenging: failed to %s name %s (replica:%s -> replica:%s): error:%u\n",
     296             :                                 action, nbt_name_string(rec, rec->name), old_state, new_state, ret));
     297             :                 } else {
     298           0 :                         DEBUG(4,("WINS scavenging: %s name: %s (replica:%s -> replica:%s)\n",
     299             :                                 action, nbt_name_string(rec, rec->name), old_state, new_state));
     300             :                 }
     301             : 
     302           0 :                 talloc_free(rec);
     303             :         }
     304             : 
     305           0 :         return NT_STATUS_OK;
     306             : }
     307             : 
     308             : struct verify_state {
     309             :         struct imessaging_context *msg_ctx;
     310             :         struct wreplsrv_service *service;
     311             :         struct winsdb_record *rec;
     312             :         struct nbtd_proxy_wins_challenge r;
     313             : };
     314             : 
     315           0 : static void verify_handler(struct tevent_req *subreq)
     316             : {
     317           0 :         struct verify_state *s =
     318           0 :                 tevent_req_callback_data(subreq,
     319             :                 struct verify_state);
     320           0 :         struct winsdb_record *rec = s->rec;
     321           0 :         const char *action;
     322           0 :         const char *old_state = "active";
     323           0 :         const char *new_state = "active";
     324           0 :         const char *new_owner = "replica";
     325           0 :         uint32_t modify_flags = 0;
     326           0 :         bool modify_record = false;
     327           0 :         bool delete_record = false;
     328           0 :         bool different = false;
     329           0 :         int ret;
     330           0 :         NTSTATUS status;
     331           0 :         uint32_t i, j;
     332             : 
     333             :         /*
     334             :          * - if the name isn't present anymore remove our record
     335             :          * - if the name is found and not a normal group check if the addresses match,
     336             :          *   - if they don't match remove the record
     337             :          *   - if they match do nothing
     338             :          * - if an error happens do nothing
     339             :          */
     340           0 :         status = dcerpc_nbtd_proxy_wins_challenge_r_recv(subreq, s);
     341           0 :         TALLOC_FREE(subreq);
     342           0 :         if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
     343           0 :                 delete_record = true;
     344           0 :                 new_state = "deleted";
     345           0 :         } else if (NT_STATUS_IS_OK(status) && rec->type != WREPL_TYPE_GROUP) {
     346           0 :                 for (i=0; i < s->r.out.num_addrs; i++) {
     347           0 :                         bool found = false;
     348           0 :                         for (j=0; rec->addresses[j]; j++) {
     349           0 :                                 if (strcmp(s->r.out.addrs[i].addr, rec->addresses[j]->address) == 0) {
     350           0 :                                         found = true;
     351           0 :                                         break;
     352             :                                 }
     353             :                         }
     354           0 :                         if (!found) {
     355           0 :                                 different = true;
     356           0 :                                 break;
     357             :                         }
     358             :                 }
     359           0 :         } else if (NT_STATUS_IS_OK(status) && rec->type == WREPL_TYPE_GROUP) {
     360           0 :                 if (s->r.out.num_addrs != 1 || strcmp(s->r.out.addrs[0].addr, "255.255.255.255") != 0) {
     361           0 :                         different = true;
     362             :                 }
     363             :         }
     364             : 
     365           0 :         if (different) {
     366             :                 /*
     367             :                  * if the reply from the owning wins server has different addresses
     368             :                  * then take the ownership of the record and make it a tombstone
     369             :                  * this will then hopefully replicated to the original owner of the record
     370             :                  * which will then propagate it's own record, so that the current record will
     371             :                  * be replicated to to us
     372             :                  */
     373           0 :                 DEBUG(2,("WINS scavenging: replica %s verify got different addresses from winsserver: %s: tombstoning record\n",
     374             :                         nbt_name_string(rec, rec->name), rec->wins_owner));
     375             : 
     376           0 :                 rec->state   = WREPL_STATE_TOMBSTONE;
     377           0 :                 rec->expire_time= time(NULL) + s->service->config.tombstone_timeout;
     378           0 :                 for (i=0; rec->addresses[i]; i++) {
     379           0 :                         rec->addresses[i]->expire_time = rec->expire_time;
     380             :                 }
     381           0 :                 modify_record   = true;
     382           0 :                 modify_flags    = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
     383           0 :                 new_state       = "tombstone";
     384           0 :                 new_owner       = "owned";
     385           0 :         } else if (NT_STATUS_IS_OK(status)) {
     386             :                 /* if the addresses are the same, just update the timestamps */
     387           0 :                 rec->expire_time = time(NULL) + s->service->config.verify_interval;
     388           0 :                 for (i=0; rec->addresses[i]; i++) {
     389           0 :                         rec->addresses[i]->expire_time = rec->expire_time;
     390             :                 }
     391           0 :                 modify_record   = true;
     392           0 :                 modify_flags    = 0;
     393           0 :                 new_state       = "active";
     394             :         }
     395             : 
     396           0 :         if (modify_record) {
     397           0 :                 action = "modify";
     398           0 :                 ret = winsdb_modify(s->service->wins_db, rec, modify_flags);
     399           0 :         } else if (delete_record) {
     400           0 :                 action = "delete";
     401           0 :                 ret = winsdb_delete(s->service->wins_db, rec);
     402             :         } else {
     403           0 :                 action = "skip";
     404           0 :                 ret = NBT_RCODE_OK;
     405             :         }
     406             : 
     407           0 :         if (ret != NBT_RCODE_OK) {
     408           0 :                 DEBUG(2,("WINS scavenging: failed to %s name %s (replica:%s -> %s:%s): error:%u\n",
     409             :                         action, nbt_name_string(rec, rec->name), old_state, new_owner, new_state, ret));
     410             :         } else {
     411           0 :                 DEBUG(4,("WINS scavenging: %s name: %s (replica:%s -> %s:%s): %s: %s\n",
     412             :                         action, nbt_name_string(rec, rec->name), old_state, new_owner, new_state,
     413             :                         rec->wins_owner, nt_errstr(status)));
     414             :         }
     415             : 
     416           0 :         talloc_free(s);
     417           0 : }
     418             : 
     419           0 : static NTSTATUS wreplsrv_scavenging_replica_active_records(struct wreplsrv_service *service, TALLOC_CTX *tmp_mem)
     420             : {
     421           0 :         NTSTATUS status;
     422           0 :         struct winsdb_record *rec = NULL;
     423           0 :         struct ldb_result *res = NULL;
     424           0 :         const char *owner_filter;
     425           0 :         const char *filter;
     426           0 :         unsigned int i;
     427           0 :         int ret;
     428           0 :         time_t now = time(NULL);
     429           0 :         const char *now_timestr;
     430           0 :         struct tevent_req *subreq;
     431           0 :         struct verify_state *s;
     432           0 :         struct dcerpc_binding_handle *irpc_handle;
     433             : 
     434           0 :         now_timestr = ldb_timestring(tmp_mem, now);
     435           0 :         NT_STATUS_HAVE_NO_MEMORY(now_timestr);
     436           0 :         owner_filter = wreplsrv_owner_filter(service, tmp_mem,
     437           0 :                                              service->wins_db->local_owner);
     438           0 :         NT_STATUS_HAVE_NO_MEMORY(owner_filter);
     439           0 :         filter = talloc_asprintf(tmp_mem,
     440             :                                  "(&(!%s)(objectClass=winsRecord)"
     441             :                                  "(recordState=%u)(expireTime<=%s))",
     442             :                                  owner_filter, WREPL_STATE_ACTIVE, now_timestr);
     443           0 :         NT_STATUS_HAVE_NO_MEMORY(filter);
     444           0 :         ret = ldb_search(service->wins_db->ldb, tmp_mem, &res, NULL, LDB_SCOPE_SUBTREE, NULL, "%s", filter);
     445           0 :         if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION;
     446           0 :         DEBUG(10,("WINS scavenging: filter '%s' count %d\n", filter, res->count));
     447             : 
     448           0 :         for (i=0; i < res->count; i++) {
     449             :                 /*
     450             :                  * we pass '0' as 'now' here,
     451             :                  * because we want to get the raw timestamps which are in the DB
     452             :                  */
     453           0 :                 status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
     454           0 :                 NT_STATUS_NOT_OK_RETURN(status);
     455           0 :                 talloc_free(res->msgs[i]);
     456             : 
     457           0 :                 if (rec->state != WREPL_STATE_ACTIVE) {
     458           0 :                         DEBUG(0,("%s: corrupted record: %s\n",
     459             :                                 __location__, nbt_name_string(rec, rec->name)));
     460           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     461             :                 }
     462             : 
     463             :                 /* 
     464             :                  * ask the owning wins server if the record still exists,
     465             :                  * if not delete the record
     466             :                  *
     467             :                  * TODO: NOTE: this is a simpliefied version, to verify that
     468             :                  *             a record still exist, I assume that w2k3 uses
     469             :                  *             DCERPC calls or some WINSREPL packets for this,
     470             :                  *             but we use a wins name query
     471             :                  */
     472           0 :                 DEBUG(2,("ask wins server '%s' if '%s' with version_id:%llu still exists\n",
     473             :                          rec->wins_owner, nbt_name_string(rec, rec->name), 
     474             :                          (unsigned long long)rec->version));
     475             : 
     476           0 :                 s = talloc_zero(tmp_mem, struct verify_state);
     477           0 :                 NT_STATUS_HAVE_NO_MEMORY(s);
     478           0 :                 s->msg_ctx   = service->task->msg_ctx;
     479           0 :                 s->service   = service;
     480           0 :                 s->rec               = talloc_steal(s, rec);
     481             : 
     482           0 :                 s->r.in.name         = *rec->name;
     483           0 :                 s->r.in.num_addrs    = 1;
     484           0 :                 s->r.in.addrs                = talloc_array(s, struct nbtd_proxy_wins_addr, s->r.in.num_addrs);
     485           0 :                 NT_STATUS_HAVE_NO_MEMORY(s->r.in.addrs);
     486             :                 /* TODO: fix pidl to handle inline ipv4address arrays */
     487           0 :                 s->r.in.addrs[0].addr        = rec->wins_owner;
     488             : 
     489           0 :                 irpc_handle = irpc_binding_handle_by_name(s,
     490           0 :                                                           service->task->msg_ctx,
     491             :                                                           "nbt_server",
     492             :                                                           &ndr_table_irpc);
     493           0 :                 if (irpc_handle == NULL) {
     494           0 :                         return NT_STATUS_INTERNAL_ERROR;
     495             :                 }
     496             : 
     497           0 :                 subreq = dcerpc_nbtd_proxy_wins_challenge_r_send(s,
     498           0 :                                                                  service->task->event_ctx,
     499             :                                                                  irpc_handle,
     500             :                                                                  &s->r);
     501           0 :                 NT_STATUS_HAVE_NO_MEMORY(subreq);
     502             : 
     503           0 :                 tevent_req_set_callback(subreq, verify_handler, s);
     504             : 
     505           0 :                 talloc_steal(service, s);
     506             :         }
     507             : 
     508           0 :         return NT_STATUS_OK;
     509             : }
     510             : 
     511        3626 : NTSTATUS wreplsrv_scavenging_run(struct wreplsrv_service *service)
     512             : {
     513          31 :         NTSTATUS status;
     514          31 :         TALLOC_CTX *tmp_mem;
     515        3626 :         bool skip_first_run = false;
     516             : 
     517        3626 :         if (!timeval_expired(&service->scavenging.next_run)) {
     518        3561 :                 return NT_STATUS_OK;
     519             :         }
     520             : 
     521          65 :         if (timeval_is_zero(&service->scavenging.next_run)) {
     522          65 :                 skip_first_run = true;
     523             :         }
     524             : 
     525          65 :         service->scavenging.next_run = timeval_current_ofs(service->config.scavenging_interval, 0);
     526          65 :         status = wreplsrv_periodic_schedule(service, service->config.scavenging_interval);
     527          65 :         NT_STATUS_NOT_OK_RETURN(status);
     528             : 
     529             :         /*
     530             :          * if it's the first time this functions is called (startup)
     531             :          * the next_run is zero, in this case we should not do scavenging
     532             :          */
     533          65 :         if (skip_first_run) {
     534          65 :                 return NT_STATUS_OK;
     535             :         }
     536             : 
     537           0 :         if (service->scavenging.processing) {
     538           0 :                 return NT_STATUS_OK;
     539             :         }
     540             : 
     541           0 :         DEBUG(2,("wreplsrv_scavenging_run(): start\n"));
     542             : 
     543           0 :         tmp_mem = talloc_new(service);
     544           0 :         NT_STATUS_HAVE_NO_MEMORY(tmp_mem);
     545           0 :         service->scavenging.processing = true;
     546           0 :         status = wreplsrv_scavenging_owned_records(service,tmp_mem);
     547           0 :         service->scavenging.processing = false;
     548           0 :         talloc_free(tmp_mem);
     549           0 :         NT_STATUS_NOT_OK_RETURN(status);
     550             : 
     551           0 :         tmp_mem = talloc_new(service);  
     552           0 :         NT_STATUS_HAVE_NO_MEMORY(tmp_mem);
     553           0 :         service->scavenging.processing = true;
     554           0 :         status = wreplsrv_scavenging_replica_non_active_records(service, tmp_mem);
     555           0 :         service->scavenging.processing = false;
     556           0 :         talloc_free(tmp_mem);
     557           0 :         NT_STATUS_NOT_OK_RETURN(status);
     558             : 
     559           0 :         tmp_mem = talloc_new(service);
     560           0 :         NT_STATUS_HAVE_NO_MEMORY(tmp_mem);
     561           0 :         service->scavenging.processing = true;
     562           0 :         status = wreplsrv_scavenging_replica_active_records(service, tmp_mem);
     563           0 :         service->scavenging.processing = false;
     564           0 :         talloc_free(tmp_mem);
     565           0 :         NT_STATUS_NOT_OK_RETURN(status);
     566             : 
     567           0 :         DEBUG(2,("wreplsrv_scavenging_run(): end\n"));
     568             : 
     569           0 :         return NT_STATUS_OK;
     570             : }

Generated by: LCOV version 1.14