s3: Fix a long-standing problem with recycled PIDs
authorVolker Lendecke <vl@samba.org>
Tue, 2 Mar 2010 16:02:01 +0000 (17:02 +0100)
committerMichael Adam <obnox@samba.org>
Mon, 22 Mar 2010 16:51:26 +0000 (17:51 +0100)
When a samba server process dies hard, it has no chance to clean up its entries
in locking.tdb, brlock.tdb, connections.tdb and sessionid.tdb.

For locking.tdb and brlock.tdb Samba is robust by checking every time we read
an entry from the database if the corresponding process still exists. If it
does not exist anymore, the entry is deleted. This is not 100% failsafe though:
On systems with a limited PID space there is a non-zero chance that between the
smbd's death and the fresh access, the PID is recycled by another long-running
process. This renders all files that had been locked by the killed smbd
potentially unusable until the new process also dies.

This patch is supposed to fix the problem the following way: Every process ID
in every database is augmented by a random 64-bit number that is stored in a
serverid.tdb. Whenever we need to check if a process still exists we know its
PID and the 64-bit number. We look up the PID in serverid.tdb and compare the
64-bit number. If it's the same, the process still is a valid smbd holding the
lock. If it is different, a new smbd has taken over.

I believe this is safe against an smbd that has died hard and the PID has been
taken over by a non-samba process. This process would not have registered
itself with a fresh 64-bit number in serverid.tdb, so the old one still exists
in serverid.tdb. We protect against this case by the parent smbd taking care of
deregistering PIDs from serverid.tdb and the fact that serverid.tdb is
CLEAR_IF_FIRST.

While there, this also cleans up overloading connections.tdb with all the
process entries just for messaging_send_all().

Volker

17 files changed:
source3/Makefile.in
source3/include/includes.h
source3/include/messages.h
source3/include/proto.h
source3/include/serverid.h [new file with mode: 0644]
source3/lib/messages.c
source3/lib/serverid.c [new file with mode: 0644]
source3/lib/util.c
source3/locking/brlock.c
source3/locking/locking.c
source3/nmbd/nmbd.c
source3/printing/nt_printing.c
source3/printing/printing.c
source3/smbd/negprot.c
source3/smbd/server.c
source3/winbindd/winbindd.c
source3/winbindd/winbindd_proto.h

index 3666fe4b46951b69175298f58b0d47e52afb83b1..69b5b3810d3aa4c7cd40531664c989a1799bfa25 100644 (file)
@@ -367,6 +367,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
          lib/interfaces.o lib/memcache.o \
          lib/util_transfer_file.o ../lib/async_req/async_req.o \
          ../lib/async_req/async_sock.o ../lib/async_req/async_req_ntstatus.o \
+         lib/serverid.o \
          $(TDB_LIB_OBJ) \
          $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
          lib/interface.o lib/pidfile.o \
index 6207dce1ba87b10499c68e394017c0dcf915c91d..ab21233dbc81e73d9050dafb29b44943f8f839df 100644 (file)
@@ -672,6 +672,7 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
 #include "../lib/util/talloc_stack.h"
 #include "memcache.h"
 #include "../lib/async_req/async_req_ntstatus.h"
+#include "serverid.h"
 #include "async_smb.h"
 #include "../lib/async_req/async_sock.h"
 #include "services.h"
index 2e42fc6554662a22f454a356056dc870290ac884..6063d358ea7fe1469946b463342b01466116e182 100644 (file)
@@ -72,6 +72,7 @@ struct server_id {
 #ifdef CLUSTER_SUPPORT
        uint32 vnn;
 #endif
+       uint64_t unique_id;
 };
 
 #ifdef CLUSTER_SUPPORT
index 28f5223e59667e1e9551ff215d982f6fb4cdce75..d5dd38a647486740944a13c38f50f8cc631ffc7d 100644 (file)
@@ -1195,6 +1195,7 @@ uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options);
 pid_t procid_to_pid(const struct server_id *proc);
 void set_my_vnn(uint32 vnn);
 uint32 get_my_vnn(void);
+void set_my_unique_id(uint64_t unique_id);
 struct server_id pid_to_procid(pid_t pid);
 struct server_id procid_self(void);
 struct server_id server_id_self(void);
diff --git a/source3/include/serverid.h b/source3/include/serverid.h
new file mode 100644 (file)
index 0000000..8e87c27
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+   Unix SMB/CIFS implementation.
+   Implementation of a reliable server_exists()
+   Copyright (C) Volker Lendecke 2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SERVERID_H__
+#define __SERVERID_H__
+
+#include "includes.h"
+
+/*
+ * Register a server with its unique id
+ */
+bool serverid_register(const struct server_id id, uint32_t msg_flags);
+
+/*
+ * De-register a server with its unique id
+ */
+bool serverid_deregister(const struct server_id id);
+
+/*
+ * Check existence of a server id
+ */
+bool serverid_exists(const struct server_id *id);
+
+/*
+ * Walk the list of server_ids registered
+ */
+bool serverid_traverse(int (*fn)(struct db_record *rec,
+                                const struct server_id *id,
+                                uint32_t msg_flags,
+                                void *private_data),
+                      void *private_data);
+
+/*
+ * Walk the list of server_ids registered read-only
+ */
+bool serverid_traverse_read(int (*fn)(const struct server_id *id,
+                                     uint32_t msg_flags,
+                                     void *private_data),
+                           void *private_data);
+#endif
index 5e11dd4e25148b5bb29668f9aa627f0c1e3f4d7a..2fcdc24179191f2edd5e48329a95856deaff5630 100644 (file)
@@ -95,36 +95,29 @@ struct msg_all {
  Send one of the messages for the broadcast.
 ****************************************************************************/
 
-static int traverse_fn(struct db_record *rec,
-                      const struct connections_key *ckey,
-                      const struct connections_data *crec,
-                      void *state)
+static int traverse_fn(struct db_record *rec, const struct server_id *id,
+                      uint32_t msg_flags, void *state)
 {
        struct msg_all *msg_all = (struct msg_all *)state;
        NTSTATUS status;
 
-       if (crec->cnum != -1)
-               return 0;
-
        /* Don't send if the receiver hasn't registered an interest. */
 
-       if(!(crec->bcast_msg_flags & msg_all->msg_flag))
+       if((msg_flags & msg_all->msg_flag) == 0) {
                return 0;
+       }
 
        /* If the msg send fails because the pid was not found (i.e. smbd died), 
         * the msg has already been deleted from the messages.tdb.*/
 
-       status = messaging_send_buf(msg_all->msg_ctx,
-                                   crec->pid, msg_all->msg_type,
+       status = messaging_send_buf(msg_all->msg_ctx, *id, msg_all->msg_type,
                                    (uint8 *)msg_all->buf, msg_all->len);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
                
                /* If the pid was not found delete the entry from connections.tdb */
 
-               DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
-                        procid_str_static(&crec->pid), crec->cnum,
-                        crec->servicename));
+               DEBUG(2, ("pid %s doesn't exist\n", procid_str_static(id)));
 
                rec->delete_rec(rec);
        }
@@ -172,7 +165,7 @@ bool message_send_all(struct messaging_context *msg_ctx,
        msg_all.n_sent = 0;
        msg_all.msg_ctx = msg_ctx;
 
-       connections_forall(traverse_fn, &msg_all);
+       serverid_traverse(traverse_fn, &msg_all);
        if (n_sent)
                *n_sent = msg_all.n_sent;
        return True;
diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c
new file mode 100644 (file)
index 0000000..ff08c3a
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+   Unix SMB/CIFS implementation.
+   Implementation of a reliable server_exists()
+   Copyright (C) Volker Lendecke 2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "serverid.h"
+
+struct serverid_key {
+       pid_t pid;
+#ifdef CLUSTER_SUPPORT
+       uint32_t vnn;
+#endif
+};
+
+struct serverid_data {
+       uint64_t unique_id;
+       uint32_t msg_flags;
+};
+
+static struct db_context *serverid_db(void)
+{
+       static struct db_context *db;
+
+       if (db != NULL) {
+               return db;
+       }
+       db = db_open(talloc_autofree_context(), lock_path("serverid.tdb"),
+                    0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0644);
+       return db;
+}
+
+static void serverid_fill_key(const struct server_id *id,
+                             struct serverid_key *key)
+{
+       ZERO_STRUCTP(key);
+       key->pid = id->pid;
+#ifdef CLUSTER_SUPPORT
+       key->vnn = id->vnn;
+#endif
+}
+
+bool serverid_register(const struct server_id id, uint32_t msg_flags)
+{
+       struct db_context *db;
+       struct serverid_key key;
+       struct serverid_data data;
+       struct db_record *rec;
+       TDB_DATA tdbkey, tdbdata;
+       NTSTATUS status;
+       bool ret = false;
+
+       db = serverid_db();
+       if (db == NULL) {
+               return false;
+       }
+
+       serverid_fill_key(&id, &key);
+       tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));
+
+       rec = db->fetch_locked(db, talloc_tos(), tdbkey);
+       if (rec == NULL) {
+               DEBUG(1, ("Could not fetch_lock serverid.tdb record\n"));
+               return false;
+       }
+
+       ZERO_STRUCT(data);
+       data.unique_id = id.unique_id;
+       data.msg_flags = msg_flags;
+
+       tdbdata = make_tdb_data((uint8_t *)&data, sizeof(data));
+       status = rec->store(rec, tdbdata, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Storing serverid.tdb record failed: %s\n",
+                         nt_errstr(status)));
+               goto done;
+       }
+       ret = true;
+done:
+       TALLOC_FREE(rec);
+       return ret;
+}
+
+bool serverid_deregister(const struct server_id id)
+{
+       struct db_context *db;
+       struct serverid_key key;
+       struct db_record *rec;
+       TDB_DATA tdbkey;
+       NTSTATUS status;
+       bool ret = false;
+
+       db = serverid_db();
+       if (db == NULL) {
+               return false;
+       }
+
+       serverid_fill_key(&id, &key);
+       tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));
+
+       rec = db->fetch_locked(db, talloc_tos(), tdbkey);
+       if (rec == NULL) {
+               DEBUG(1, ("Could not fetch_lock serverid.tdb record\n"));
+               return false;
+       }
+
+       status = rec->delete_rec(rec);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Deleting serverid.tdb record failed: %s\n",
+                         nt_errstr(status)));
+               goto done;
+       }
+       ret = true;
+done:
+       TALLOC_FREE(rec);
+       return ret;
+}
+
+struct serverid_exists_state {
+       const struct server_id *id;
+       bool exists;
+};
+
+static int server_exists_parse(TDB_DATA key, TDB_DATA data, void *priv)
+{
+       struct serverid_exists_state *state =
+               (struct serverid_exists_state *)priv;
+       uint64_t unique_id;
+
+       if (data.dsize != sizeof(struct serverid_data)) {
+               return -1;
+       }
+
+       /* memcpy, data.dptr might not be aligned */
+       memcpy(&unique_id, data.dptr, sizeof(unique_id));
+
+       state->exists = (state->id->unique_id == unique_id);
+       return 0;
+}
+
+bool serverid_exists(const struct server_id *id)
+{
+       struct db_context *db;
+       struct serverid_exists_state state;
+       struct serverid_key key;
+       TDB_DATA tdbkey;
+
+       db = serverid_db();
+       if (db == NULL) {
+               return false;
+       }
+
+       serverid_fill_key(id, &key);
+       tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));
+
+       state.id = id;
+       state.exists = false;
+
+       if (db->parse_record(db, tdbkey, server_exists_parse, &state) == -1) {
+               return false;
+       }
+       return state.exists;
+}
+
+static bool serverid_rec_parse(const struct db_record *rec,
+                              struct server_id *id, uint32_t *msg_flags)
+{
+       struct serverid_key key;
+       struct serverid_data data;
+
+       if (rec->key.dsize != sizeof(key)) {
+               DEBUG(1, ("Found invalid key length %d in serverid.tdb\n",
+                         (int)rec->key.dsize));
+               return false;
+       }
+       if (rec->value.dsize != sizeof(data)) {
+               DEBUG(1, ("Found invalid value length %d in serverid.tdb\n",
+                         (int)rec->value.dsize));
+               return false;
+       }
+
+       memcpy(&key, rec->key.dptr, sizeof(key));
+       memcpy(&data, rec->value.dptr, sizeof(data));
+
+       id->pid = key.pid;
+#ifdef CLUSTER_SUPPORT
+       id->vnn = key.vnn;
+#endif
+       id->unique_id = data.unique_id;
+       *msg_flags = data.msg_flags;
+       return true;
+}
+
+struct serverid_traverse_read_state {
+       int (*fn)(const struct server_id *id, uint32_t msg_flags,
+                 void *private_data);
+       void *private_data;
+};
+
+static int serverid_traverse_read_fn(struct db_record *rec, void *private_data)
+{
+       struct serverid_traverse_read_state *state =
+               (struct serverid_traverse_read_state *)private_data;
+       struct server_id id;
+       uint32_t msg_flags;
+
+       if (!serverid_rec_parse(rec, &id, &msg_flags)) {
+               return 0;
+       }
+       return state->fn(&id, msg_flags,state->private_data);
+}
+
+bool serverid_traverse_read(int (*fn)(const struct server_id *id,
+                                     uint32_t msg_flags, void *private_data),
+                           void *private_data)
+{
+       struct db_context *db;
+       struct serverid_traverse_read_state state;
+
+       db = serverid_db();
+       if (db == NULL) {
+               return false;
+       }
+       state.fn = fn;
+       state.private_data = private_data;
+       return db->traverse_read(db, serverid_traverse_read_fn, &state);
+}
+
+struct serverid_traverse_state {
+       int (*fn)(struct db_record *rec, const struct server_id *id,
+                 uint32_t msg_flags, void *private_data);
+       void *private_data;
+};
+
+static int serverid_traverse_fn(struct db_record *rec, void *private_data)
+{
+       struct serverid_traverse_state *state =
+               (struct serverid_traverse_state *)private_data;
+       struct server_id id;
+       uint32_t msg_flags;
+
+       if (!serverid_rec_parse(rec, &id, &msg_flags)) {
+               return 0;
+       }
+       return state->fn(rec, &id, msg_flags, state->private_data);
+}
+
+bool serverid_traverse(int (*fn)(struct db_record *rec,
+                                const struct server_id *id,
+                                uint32_t msg_flags, void *private_data),
+                           void *private_data)
+{
+       struct db_context *db;
+       struct serverid_traverse_state state;
+
+       db = serverid_db();
+       if (db == NULL) {
+               return false;
+       }
+       state.fn = fn;
+       state.private_data = private_data;
+       return db->traverse(db, serverid_traverse_fn, &state);
+}
index 8ed288a129129a7c918980c75ac642f2e0539a07..8e3cec8084e43cc28b17e3e3326d92bbe54236e1 100644 (file)
@@ -2693,10 +2693,18 @@ uint32 get_my_vnn(void)
        return my_vnn;
 }
 
+static uint64_t my_unique_id = 0;
+
+void set_my_unique_id(uint64_t unique_id)
+{
+       my_unique_id = unique_id;
+}
+
 struct server_id pid_to_procid(pid_t pid)
 {
        struct server_id result;
        result.pid = pid;
+       result.unique_id = my_unique_id;
 #ifdef CLUSTER_SUPPORT
        result.vnn = my_vnn;
 #endif
@@ -2771,6 +2779,7 @@ struct server_id interpret_pid(const char *pid_string)
        if (result.pid < 0) {
                result.pid = -1;
        }
+       result.unique_id = 0;
        return result;
 }
 
index be2948c53113fd51218595c0d9e80b3ff02c6f7e..527d61ad1d768d75960834b380affbd34dc046d5 100644 (file)
@@ -1501,7 +1501,7 @@ static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct
 
        for (i = 0; i < *pnum_entries; i++) {
                struct lock_struct *lock_data = &locks[i];
-               if (!process_exists(lock_data->context.pid)) {
+               if (!serverid_exists(&lock_data->context.pid)) {
                        /* This process no longer exists - mark this
                           entry as invalid by zeroing it. */
                        ZERO_STRUCTP(lock_data);
index dd735be88a32835d722c260e7b02449d464b3ad1..33400fc5d0e3b5e4f0b84533d89777fde337055b 100644 (file)
@@ -647,7 +647,7 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
                }
                DEBUG(10,("parse_share_modes: %s\n",
                        str ? str : ""));
-               if (!process_exists(entry_p->pid)) {
+               if (!serverid_exists(&entry_p->pid)) {
                        DEBUG(10,("parse_share_modes: deleted %s\n",
                                str ? str : ""));
                        entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
index 3d5b2784387321ca298474bf16c1e750ad127170..ab938dc20c9e499d96e865c7083b10d47477fb77 100644 (file)
@@ -929,7 +929,12 @@ static bool open_sockets(bool isdaemon, int port)
                exit(1);
 
        /* get broadcast messages */
-       claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP);
+
+       if (!serverid_register(procid_self(),
+                              FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
+               DEBUG(1, ("Could not register myself in serverid.tdb\n"));
+               exit(1);
+       }
 
        messaging_register(nmbd_messaging_context(), NULL,
                           MSG_FORCE_ELECTION, nmbd_message_election);
index ebe4573a48cd638fb0227be5bad33dcc404ecd85..3415f98e94c343ce50b174bc55d03a0e9709a10c 100644 (file)
@@ -618,7 +618,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
 
        /* of course, none of the message callbacks matter if you don't
           tell messages.c that you interested in receiving PRINT_GENERAL
-          msgs.  This is done in claim_connection() */
+          msgs.  This is done in serverid_register() */
 
 
        if ( lp_security() == SEC_ADS ) {
index a741c707c2d78e994e0c93a401be996e62dce513..e28e2f45e5361c95fdaf03a1c0e1b93eaedfcdc5 100644 (file)
@@ -1446,8 +1446,11 @@ void start_background_queue(void)
                smbd_setup_sig_term_handler();
                smbd_setup_sig_hup_handler();
 
-               claim_connection( NULL, "smbd lpq backend",
-                       FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
+               if (!serverid_register(procid_self(),
+                                      FLAG_MSG_GENERAL|FLAG_MSG_SMBD
+                                      |FLAG_MSG_PRINT_GENERAL)) {
+                       exit(1);
+               }
 
                if (!locking_init()) {
                        exit(1);
index e548c587c15e7df326e9e22a4a4d678450dbaae2..ef3d235e7cb60fad70d2e2585bae1f520d1476d3 100644 (file)
@@ -648,8 +648,8 @@ void reply_negprot(struct smb_request *req)
           when the client connects to port 445.  Of course there is a small
           window where we are listening to messages   -- jerry */
 
-       claim_connection(
-               NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
+       serverid_register(procid_self(), FLAG_MSG_GENERAL|FLAG_MSG_SMBD
+                         |FLAG_MSG_PRINT_GENERAL);
     
        /* Check for protocols, most desirable first */
        for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
index 01a2840d222710bdc3be362739a680a1c353294c..b06bf9084dab4016a90b93f43be50919d84212cd 100644 (file)
@@ -233,6 +233,7 @@ static void remove_child_pid(pid_t pid, bool unclean_shutdown)
 {
        struct child_pid *child;
        static struct timed_event *cleanup_te;
+       struct server_id child_id;
 
        if (unclean_shutdown) {
                /* a child terminated uncleanly so tickle all
@@ -257,6 +258,14 @@ static void remove_child_pid(pid_t pid, bool unclean_shutdown)
                }
        }
 
+       child_id = procid_self(); /* Just initialize pid and potentially vnn */
+       child_id.pid = pid;
+
+       if (!serverid_deregister(child_id)) {
+               DEBUG(1, ("Could not remove pid %d from serverid.tdb\n",
+                         (int)pid));
+       }
+
        if (lp_max_smbd_processes() == 0) {
                /* Don't bother with the child list if we don't care anyway */
                return;
@@ -368,6 +377,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
        struct sockaddr_storage addr;
        socklen_t in_addrlen = sizeof(addr);
        pid_t pid = 0;
+       uint64_t unique_id;
 
        smbd_set_server_fd(accept(s->fd,(struct sockaddr *)&addr,&in_addrlen));
 
@@ -392,12 +402,21 @@ static void smbd_accept_connection(struct tevent_context *ev,
                return;
        }
 
+       /*
+        * Generate a unique id in the parent process so that we use
+        * the global random state in the parent.
+        */
+       generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id));
+
        pid = sys_fork();
        if (pid == 0) {
                NTSTATUS status = NT_STATUS_OK;
+
                /* Child code ... */
                am_parent = 0;
 
+               set_my_unique_id(unique_id);
+
                /* Stop zombies, the parent explicitly handles
                 * them, counting worker smbds. */
                CatchChild();
@@ -429,6 +448,14 @@ static void smbd_accept_connection(struct tevent_context *ev,
                smbd_setup_sig_term_handler();
                smbd_setup_sig_hup_handler();
 
+               if (!serverid_register(procid_self(),
+                                      FLAG_MSG_GENERAL|FLAG_MSG_SMBD
+                                      |FLAG_MSG_DBWRAP
+                                      |FLAG_MSG_PRINT_GENERAL)) {
+                       exit_server_cleanly("Could not register myself in "
+                                           "serverid.tdb");
+               }
+
                smbd_process();
         exit:
                exit_server_cleanly("end of child");
@@ -659,8 +686,14 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
           clustered mode, ctdb won't allow us to start doing database
           operations until it has gone thru a full startup, which
           includes checking to see that smbd is listening. */
-       claim_connection(NULL,"",
-                        FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_DBWRAP);
+
+       if (!serverid_register(procid_self(),
+                              FLAG_MSG_GENERAL|FLAG_MSG_SMBD
+                              |FLAG_MSG_DBWRAP)) {
+               DEBUG(0, ("open_sockets_smbd: Failed to register "
+                         "myself in serverid.tdb\n"));
+               return false;
+       }
 
         /* Listen to messages */
 
index dd6783d20d4467586f09345cd9fbc8def9a9919f..5ef2a8ea196652eb5092dd37c7bfae830638d9c5 100644 (file)
@@ -1351,7 +1351,12 @@ int main(int argc, char **argv, char **envp)
        }
 
        /* get broadcast messages */
-       claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP);
+
+       if (!serverid_register(procid_self(),
+                              FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
+               DEBUG(1, ("Could not register myself in serverid.tdb\n"));
+               exit(1);
+       }
 
        /* React on 'smbcontrol winbindd reload-config' in the same way
           as to SIGHUP signal */
index e4f06a4dfa1350583ce25bdddd4863a456b317d1..2fcadbeedeb4eda6f9e255a58a4b9bf59a83e7b4 100644 (file)
@@ -44,9 +44,6 @@ void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
 
 bool yield_connection(connection_struct *conn, const char *name);
 int count_current_connections( const char *sharename, bool clear  );
-int count_all_current_connections(void);
-bool claim_connection(connection_struct *conn, const char *name,
-                     uint32 msg_flags);
 bool register_message_flags(bool doreg, uint32 msg_flags);
 
 /* The following definitions come from winbindd/winbindd.c  */