s3:dbwrap_ctdb fix record parsing of empty records winbindd
authorChristian Ambach <ambi@samba.org>
Mon, 22 Apr 2013 20:55:54 +0000 (22:55 +0200)
committerChristian Ambach <ambi@samba.org>
Fri, 17 May 2013 12:42:41 +0000 (14:42 +0200)
If the record has the exact size of ctdb_ltdb_header, it is deleted.
Handle it as such, otherwise calls like dbwrap_exists will
report it as still being around

Signed-off-by: Christian Ambach <ambi@samba.org>
source3/lib/ctdbd_conn.c
source3/lib/dbwrap/dbwrap_ctdb.c
source3/locking/share_mode_lock.c

index 1481a9c1852c92f33ac585f0b4f5e91bbd54d6e5..1e5d09fad8a58a81365d874630552809510dccca 100644 (file)
@@ -1475,9 +1475,14 @@ NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
                goto fail;
        }
 
-       parser(key, make_tdb_data(&reply->data[0], reply->datalen),
-              private_data);
+       /* empty record == deleted record */
+       if (reply->datalen == 0) {
+               parser(key, tdb_null, private_data);
+       } else {
+               parser(key, make_tdb_data(&reply->data[0], reply->datalen),
+                      private_data);
 
+       }
        status = NT_STATUS_OK;
  fail:
        TALLOC_FREE(reply);
index f90e7b80f1ef01b972378e8cb7dec2ae1bac6400..2c2c8dbacda7d5eeac6c1499807d8f043f50dbfb 100644 (file)
@@ -101,8 +101,10 @@ static int db_ctdb_ltdb_parser(TDB_DATA key, TDB_DATA data,
                (struct db_ctdb_ltdb_parse_state *)private_data;
 
        if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
+               /* invalid record  */
                return -1;
        }
+
        state->parser(
                key, (struct ctdb_ltdb_header *)data.dptr,
                make_tdb_data(data.dptr + sizeof(struct ctdb_ltdb_header),
@@ -1189,7 +1191,11 @@ static void db_ctdb_parse_record_parser_nonpersistent(
                (struct db_ctdb_parse_record_state *)private_data;
 
        if (db_ctdb_can_use_local_hdr(header, true)) {
-               state->parser(key, data, state->private_data);
+               if (data.dsize == 0) {
+                       state->parser(key, tdb_null, state->private_data);
+               } else {
+                       state->parser(key, data, state->private_data);
+               }
                state->done = true;
        } else {
                /*
index 0693cf54085129b446af0d4e0e4fa2659f9e54dc..4c2376a7774a7438507e5df39ffa0f6549db8242 100644 (file)
@@ -123,6 +123,12 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
 
+
+       /* empty record */
+       if (dbuf.dptr == NULL || dbuf.dsize == 0) {
+               return NULL;
+       }
+
        d = talloc(mem_ctx, struct share_mode_data);
        if (d == NULL) {
                DEBUG(0, ("talloc failed\n"));
@@ -307,7 +313,7 @@ static struct share_mode_lock *get_share_mode_lock_internal(
 
        value = dbwrap_record_get_value(rec);
 
-       if (value.dptr == NULL) {
+       if (value.dptr == NULL || value.dsize == 0) {
                d = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
                                          old_write_time);
        } else {