lib: Fix server_id_db_set_exclusive
authorVolker Lendecke <vl@samba.org>
Tue, 29 Sep 2015 18:24:10 +0000 (20:24 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 1 Oct 2015 00:53:58 +0000 (02:53 +0200)
For server_id_db_set_exclusive we need to store the unique id along
with the vnn:pid combo. I had tested all this just with some
smbtorture and net command tests, all of which have a unique id of
zero. When trying to exclusively register "notify-daemon" when smbd
is running, this fails because serverid_exists only tests with zero
unique id. notifyd does have a non-zero unique id, so server_id_exists
will think the existing notifyd is another non-samba process that
happened to claim notifyd's pid.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Oct  1 02:53:58 CEST 2015 on sn-devel-104

lib/util/server_id_db.c

index 087412973ad1d5d332dc7679ec71edb49e34c22f..1e65ce25426789f71cd496876cff3fad153119bf 100644 (file)
@@ -93,8 +93,7 @@ static int server_id_db_destructor(struct server_id_db *db)
 int server_id_db_add(struct server_id_db *db, const char *name)
 {
        struct tdb_context *tdb = db->tdb->tdb;
-       struct server_id_buf buf;
-       TDB_DATA key, data;
+       TDB_DATA key;
        char *n;
        int ret;
 
@@ -110,10 +109,17 @@ int server_id_db_add(struct server_id_db *db, const char *name)
 
        key = string_term_tdb_data(name);
 
-       server_id_str_buf(db->pid, &buf);
-       data = string_term_tdb_data(buf.buf);
+       {
+               size_t idlen = server_id_str_buf_unique(db->pid, NULL, 0);
+               char idbuf[idlen];
+
+               server_id_str_buf_unique(db->pid, idbuf, idlen);
+
+               ret = tdb_append(
+                       tdb, key,
+                       (TDB_DATA) { .dptr = (uint8_t *)idbuf, .dsize = idlen });
+       }
 
-       ret = tdb_append(tdb, key, data);
        if (ret != 0) {
                enum TDB_ERROR err = tdb_error(tdb);
                strv_delete(&db->names, strv_find(db->names, name));
@@ -127,14 +133,15 @@ int server_id_db_prune_name(struct server_id_db *db, const char *name,
                            struct server_id server)
 {
        struct tdb_context *tdb = db->tdb->tdb;
-       struct server_id_buf buf;
+       size_t idbuf_len = server_id_str_buf_unique(server, NULL, 0);
+       char idbuf[idbuf_len];
        TDB_DATA key;
        uint8_t *data;
        char *ids, *id;
        int ret;
 
        key = string_term_tdb_data(name);
-       server_id_str_buf(server, &buf);
+       server_id_str_buf_unique(server, idbuf, idbuf_len);
 
        ret = tdb_chainlock(tdb, key);
        if (ret == -1) {
@@ -150,7 +157,7 @@ int server_id_db_prune_name(struct server_id_db *db, const char *name,
 
        ids = (char *)data;
 
-       id = strv_find(ids, buf.buf);
+       id = strv_find(ids, idbuf);
        if (id == NULL) {
                tdb_chainunlock(tdb, key);
                TALLOC_FREE(data);