The branch, master has been updated
       via  0bf6ec8 s3:selftest: run smbtorture3 CLEANUP3 in the s3dc:local 
environment
       via  68d03f2 s3: Test whether get_share_mode_lock cleans up stale 
processes
       via  58dff07 s3: Do not check the PIDs is parse_share_modes
       via  50fdb32 Ensure we only return NT_STATUS_DELETE_PENDING if the share 
modes are valid.
       via  89cf7ea s3: Check for serverid_exists in close_directory
       via  bdc4404 s3: Check for serverid_exists in close_remove_share_mode
       via  bc3b7d7 s3: Be less picky on stale share mode entries
       via  1b15d8b s3: Check for serverid_exists in find_oplock_types
       via  6666de1 s3: Check for serverid_exists in rename_share_filename
       via  e2818d4 s3: Check for serverid_exists in smb_posix_unlink
       via  fdcca54 s3: Check for serverid_exists in open_mode_check
       via  19b6671 s3: Check for serverid_exists in notify_deferred_opens
       via  65264326 Fix an invalid state only reachable on server crash/abort.
       via  5842d4e s3: Add "share_mode_stale_pid"
       via  035342c Fix bug #8373 - Can't join XP Pro workstations to 3.6.1 DC.
      from  e17fa58 s3:smbd: move global smbd_msg_state to smbXsrv_connection

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0bf6ec88eddc8e3267deeaa8f48b79f76a184834
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed May 16 09:11:40 2012 +0200

    s3:selftest: run smbtorture3 CLEANUP3 in the s3dc:local environment
    
    metze
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User: Jeremy Allison <j...@samba.org>
    Autobuild-Date: Fri May 25 20:09:15 CEST 2012 on sn-devel-104

commit 68d03f2ef587d32e1c80e51716b032c8c307ad1e
Author: Volker Lendecke <v...@samba.org>
Date:   Fri May 11 14:39:42 2012 +0200

    s3: Test whether get_share_mode_lock cleans up stale processes
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 58dff077d994b66591f5c208112027959336b178
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 16:34:11 2012 +0200

    s3: Do not check the PIDs is parse_share_modes
    
    We do that when conflicts arise
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 50fdb32a4d30128d3e23d98833b31b84fc3f8215
Author: Jeremy Allison <j...@samba.org>
Date:   Tue May 22 12:28:04 2012 -0700

    Ensure we only return NT_STATUS_DELETE_PENDING if the share modes are valid.
    
    Ensure we only return *file_existed = true if there were valid share modes.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 89cf7ea944b8947d5b64b5e2819936ea8af1e661
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 15:23:29 2012 +0200

    s3: Check for serverid_exists in close_directory
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit bdc4404ef950e3cb4d026dd49a247b5ab8ecdbd4
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 15:23:29 2012 +0200

    s3: Check for serverid_exists in close_remove_share_mode
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit bc3b7d76a8ea1b96668163af9379ba4be3771466
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 14 14:57:34 2012 +0200

    s3: Be less picky on stale share mode entries
    
    If a process died, the share mode entry might be bogus. Ignore those 
entries.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 1b15d8b3da19c2f43f41632cd3e1fe20f5088bbb
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 15:23:29 2012 +0200

    s3: Check for serverid_exists in find_oplock_types
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 6666de1975e596990cc7b031a89ce67000093987
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 15:23:10 2012 +0200

    s3: Check for serverid_exists in rename_share_filename
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit e2818d4a0b87bf9ff8b2dc14698fa14c7e695c23
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 15:23:29 2012 +0200

    s3: Check for serverid_exists in smb_posix_unlink
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit fdcca54ca302e9b92bdf72823f6a7c9b63886728
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 15:23:10 2012 +0200

    s3: Check for serverid_exists in open_mode_check
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 19b6671c07be2419398a07f202e22abefe562176
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 12:22:50 2012 +0200

    s3: Check for serverid_exists in notify_deferred_opens
    
    We will remove the check in parse_share_modes soon
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 6526432682760f182fdd9152b923fa3468c042ff
Author: Jeremy Allison <j...@samba.org>
Date:   Tue May 22 12:27:06 2012 -0700

    Fix an invalid state only reachable on server crash/abort.
    
    Remove any delete-on-close tokens and clear the count if there are no
    valid share modes.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 5842d4e025e4c042829a585fe6c58b71b219386f
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 7 12:57:07 2012 +0200

    s3: Add "share_mode_stale_pid"
    
    This is a helper routine that prunes a dead share mode entry on demand. This
    prepares for removing the serverids_exist call in parse_share_modes.
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 035342c11719d1daa647c0b2ae7cec27a969f83a
Author: Jeremy Allison <j...@samba.org>
Date:   Fri May 25 09:16:50 2012 -0700

    Fix bug #8373 - Can't join XP Pro workstations to 3.6.1 DC.
    
    Treat LIBNDR_FLAG_NOALIGN and LIBNDR_FLAG_REMAINING the same as the
    other align flags - make them mutually exclusive.
    
    Combined work from Metze, Günther and Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 librpc/ndr/libndr.h               |    8 ++-
 librpc/ndr/ndr.c                  |    8 +-
 source3/Makefile.in               |    3 +-
 source3/locking/locking.c         |   51 +++++++++++-
 source3/locking/proto.h           |    1 +
 source3/locking/share_mode_lock.c |   42 ---------
 source3/selftest/tests.py         |    4 +
 source3/smbd/close.c              |   16 +++-
 source3/smbd/open.c               |   46 +++++++++-
 source3/smbd/trans2.c             |    3 +
 source3/torture/proto.h           |    1 +
 source3/torture/test_cleanup.c    |  175 +++++++++++++++++++++++++++++++++++++
 source3/torture/torture.c         |    1 +
 source3/wscript_build             |    3 +-
 14 files changed, 307 insertions(+), 55 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index 37a3145..1bd284f 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -135,7 +135,13 @@ struct ndr_print {
 #define LIBNDR_FLAG_ALIGN4       (1<<23)
 #define LIBNDR_FLAG_ALIGN8       (1<<24)
 
-#define LIBNDR_ALIGN_FLAGS 
(LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8)
+#define LIBNDR_ALIGN_FLAGS ( 0        | \
+               LIBNDR_FLAG_NOALIGN   | \
+               LIBNDR_FLAG_REMAINING | \
+               LIBNDR_FLAG_ALIGN2    | \
+               LIBNDR_FLAG_ALIGN4    | \
+               LIBNDR_FLAG_ALIGN8    | \
+               0)
 
 #define LIBNDR_PRINT_ARRAY_HEX   (1<<25)
 #define LIBNDR_PRINT_SET_VALUES  (1<<26)
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index 2279d1c..b77bfae 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -378,11 +378,11 @@ _PUBLIC_ void ndr_set_flags(uint32_t *pflags, uint32_t 
new_flags)
                (*pflags) &= ~LIBNDR_FLAG_LITTLE_ENDIAN;
                (*pflags) &= ~LIBNDR_FLAG_NDR64;
        }
-       if (new_flags & LIBNDR_FLAG_REMAINING) {
-               (*pflags) &= ~LIBNDR_ALIGN_FLAGS;
-       }
        if (new_flags & LIBNDR_ALIGN_FLAGS) {
-               (*pflags) &= ~LIBNDR_FLAG_REMAINING;
+               /* Ensure we only have the passed-in
+                  align flag set in the new_flags,
+                  remove any old align flag. */
+               (*pflags) &= ~LIBNDR_ALIGN_FLAGS;
        }
        if (new_flags & LIBNDR_FLAG_NO_RELATIVE_REVERSE) {
                (*pflags) &= ~LIBNDR_FLAG_RELATIVE_REVERSE;
diff --git a/source3/Makefile.in b/source3/Makefile.in
index e289252..9bd4f90 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1283,11 +1283,12 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o 
torture/scanner.o torture/uta
                torture/t_strappend.o
 
 SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \
-       $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+       $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LOCKING_OBJ) \
        @LIBWBCLIENT_STATIC@ \
         torture/wbc_async.o \
         ../nsswitch/wb_reqtrans.o \
        ../libcli/lsarpc/util_lsarpc.o \
+       lib/filename_util.o \
        $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBCLI_ECHO_OBJ)
 
 MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index b9afd23..00a46fa 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -556,6 +556,10 @@ bool rename_share_filename(struct messaging_context 
*msg_ctx,
                        continue;
                }
 
+               if (share_mode_stale_pid(d, i)) {
+                       continue;
+               }
+
                DEBUG(10,("rename_share_filename: sending rename message to "
                          "pid %s file_id %s sharepath %s base_name %s "
                          "stream_name %s\n",
@@ -616,7 +620,9 @@ bool is_valid_share_mode_entry(const struct 
share_mode_entry *e)
        num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
        num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
 
-       SMB_ASSERT(num_props <= 1);
+       if (serverid_exists(&e->pid) && (num_props > 1)) {
+               smb_panic("Invalid share mode entry");
+       }
        return (num_props != 0);
 }
 
@@ -625,6 +631,49 @@ bool is_deferred_open_entry(const struct share_mode_entry 
*e)
        return (e->op_type == DEFERRED_OPEN_ENTRY);
 }
 
+/*
+ * In case d->share_modes[i] conflicts with something or otherwise is
+ * being used, we need to make sure the corresponding process still
+ * exists. This routine checks it and potentially removes the entry
+ * from d->share_modes. Modifies d->num_share_modes, watch out in
+ * routines iterating over that array.
+ */
+bool share_mode_stale_pid(struct share_mode_data *d, unsigned i)
+{
+       struct share_mode_entry *e;
+
+       if (i > d->num_share_modes) {
+               DEBUG(1, ("Asking for index %u, only %u around\n",
+                         i, (unsigned)d->num_share_modes));
+               return false;
+       }
+       e = &d->share_modes[i];
+       if (serverid_exists(&e->pid)) {
+               DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
+                          procid_str_static(&e->pid), i,
+                          (unsigned)d->num_share_modes));
+               return false;
+       }
+       DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
+                  procid_str_static(&e->pid), i,
+                  (unsigned)d->num_share_modes));
+       *e = d->share_modes[d->num_share_modes-1];
+       d->num_share_modes -= 1;
+
+       if (d->num_share_modes == 0 &&
+           d->num_delete_tokens) {
+               /*
+                * We cannot have any delete tokens
+                * if there are no valid share modes.
+                */
+               TALLOC_FREE(d->delete_tokens);
+               d->num_delete_tokens = 0;
+       }
+
+       d->modified = true;
+       return true;
+}
+
 /*******************************************************************
  Fill a share mode entry.
 ********************************************************************/
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 54badd9..f6a6f2e 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -168,6 +168,7 @@ void get_file_infos(struct file_id id,
                    struct timespec *write_time);
 bool is_valid_share_mode_entry(const struct share_mode_entry *e);
 bool is_deferred_open_entry(const struct share_mode_entry *e);
+bool share_mode_stale_pid(struct share_mode_data *d, unsigned i);
 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
                    uid_t uid, uint64_t mid, uint16 op_type);
 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
diff --git a/source3/locking/share_mode_lock.c 
b/source3/locking/share_mode_lock.c
index 493bc15..171c72f 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -118,9 +118,6 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX 
*mem_ctx,
                                                 const TDB_DATA dbuf)
 {
        struct share_mode_data *d;
-       int i;
-       struct server_id *pids;
-       bool *pid_exists;
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
 
@@ -148,45 +145,6 @@ static struct share_mode_data 
*parse_share_modes(TALLOC_CTX *mem_ctx,
                NDR_PRINT_DEBUG(share_mode_data, d);
        }
 
-       /*
-        * Ensure that each entry has a real process attached.
-        */
-
-       pids = talloc_array(talloc_tos(), struct server_id,
-                           d->num_share_modes);
-       if (pids == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               goto fail;
-       }
-       pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes);
-       if (pid_exists == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               goto fail;
-       }
-
-       for (i=0; i<d->num_share_modes; i++) {
-               pids[i] = d->share_modes[i].pid;
-       }
-       if (!serverids_exist(pids, d->num_share_modes, pid_exists)) {
-               DEBUG(0, ("serverid_exists failed\n"));
-               goto fail;
-       }
-
-       i = 0;
-       while (i < d->num_share_modes) {
-               struct share_mode_entry *e = &d->share_modes[i];
-               if (!pid_exists[i]) {
-                       DEBUG(10, ("wipe non-existent pid %s\n",
-                                  procid_str_static(&e->pid)));
-                       *e = d->share_modes[d->num_share_modes-1];
-                       d->num_share_modes -= 1;
-                       d->modified = True;
-                       continue;
-               }
-               i += 1;
-       }
-       TALLOC_FREE(pid_exists);
-       TALLOC_FREE(pids);
        return d;
 fail:
        TALLOC_FREE(d);
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index fa1f5e5..ce80274 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -90,6 +90,10 @@ for t in tests:
     plantestsuite("samba3.smbtorture_s3.crypt(s3dc).%s" % t, "s3dc", 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', binpath('smbtorture3'), "-e", "-l 
$LOCAL_PATH"])
     plantestsuite("samba3.smbtorture_s3.plain(dc).%s" % t, "dc", 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', binpath('smbtorture3'), "", "-l 
$LOCAL_PATH"])
 
+env = "s3dc:local"
+t = "CLEANUP3"
+plantestsuite("samba3.smbtorture_s3.plain(%s).%s" % (env, t), env, 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', binpath('smbtorture3'), "", "-l 
$LOCAL_PATH"])
+
 local_tests=[
        "LOCAL-SUBSTITUTE",
        "LOCAL-GENCACHE",
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 22d756c..4b7f694 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -179,9 +179,15 @@ static void notify_deferred_opens(struct 
smbd_server_connection *sconn,
 
        num_deferred = 0;
        for (i=0; i<lck->data->num_share_modes; i++) {
-               if (is_deferred_open_entry(&lck->data->share_modes[i])) {
-                       num_deferred += 1;
+               struct share_mode_entry *e = &lck->data->share_modes[i];
+
+               if (!is_deferred_open_entry(e)) {
+                       continue;
+               }
+               if (share_mode_stale_pid(lck->data, i)) {
+                       continue;
                }
+               num_deferred += 1;
        }
        if (num_deferred == 0) {
                return;
@@ -419,6 +425,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                                if (fsp->posix_open && (e->flags & 
SHARE_MODE_FLAG_POSIX_OPEN)) {
                                        continue;
                                }
+                               if (share_mode_stale_pid(lck->data, i)) {
+                                       continue;
+                               }
                                delete_file = False;
                                break;
                        }
@@ -1081,6 +1090,9 @@ static NTSTATUS close_directory(struct smb_request *req, 
files_struct *fsp,
                                if (fsp->posix_open && (e->flags & 
SHARE_MODE_FLAG_POSIX_OPEN)) {
                                        continue;
                                }
+                               if (share_mode_stale_pid(lck->data, i)) {
+                                       continue;
+                               }
                                delete_dir = False;
                                break;
                        }
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 543a661..9042e90 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -984,12 +984,23 @@ static NTSTATUS open_mode_check(connection_struct *conn,
                return NT_STATUS_OK;
        }
 
-       *file_existed = True;
-
        /* A delete on close prohibits everything */
 
        if (is_delete_on_close_set(lck, name_hash)) {
-               return NT_STATUS_DELETE_PENDING;
+               /*
+                * Check the delete on close token
+                * is valid. It could have been left
+                * after a server crash.
+                */
+               for(i = 0; i < lck->data->num_share_modes; i++) {
+                       if (!share_mode_stale_pid(lck->data, i)) {
+
+                               *file_existed = true;
+
+                               return NT_STATUS_DELETE_PENDING;
+                       }
+               }
+               return NT_STATUS_OK;
        }
 
        if (is_stat_open(access_mask)) {
@@ -1024,10 +1035,21 @@ static NTSTATUS open_mode_check(connection_struct *conn,
                 * too */
                if (share_conflict(&lck->data->share_modes[i],
                                   access_mask, share_access)) {
+
+                       if (share_mode_stale_pid(lck->data, i)) {
+                               continue;
+                       }
+
+                       *file_existed = true;
+
                        return NT_STATUS_SHARING_VIOLATION;
                }
        }
 
+       if (lck->data->num_share_modes != 0) {
+               *file_existed = true;
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -1123,6 +1145,10 @@ static void find_oplock_types(files_struct *fsp,
 
                if (BATCH_OPLOCK_TYPE(lck->data->share_modes[i].op_type)) {
                        /* batch - can only be one. */
+                       if (share_mode_stale_pid(lck->data, i)) {
+                               DEBUG(10, ("Found stale batch oplock\n"));
+                               continue;
+                       }
                        if (*pp_ex_or_batch || *pp_batch || *got_level2 || 
*got_no_oplock) {
                                smb_panic("Bad batch oplock entry.");
                        }
@@ -1130,6 +1156,10 @@ static void find_oplock_types(files_struct *fsp,
                }
 
                if (EXCLUSIVE_OPLOCK_TYPE(lck->data->share_modes[i].op_type)) {
+                       if (share_mode_stale_pid(lck->data, i)) {
+                               DEBUG(10, ("Found stale duplicate oplock\n"));
+                               continue;
+                       }
                        /* Exclusive or batch - can only be one. */
                        if (*pp_ex_or_batch || *got_level2 || *got_no_oplock) {
                                smb_panic("Bad exclusive or batch oplock 
entry.");
@@ -1139,6 +1169,11 @@ static void find_oplock_types(files_struct *fsp,
 
                if (LEVEL_II_OPLOCK_TYPE(lck->data->share_modes[i].op_type)) {
                        if (*pp_batch || *pp_ex_or_batch) {
+                               if (share_mode_stale_pid(lck->data, i)) {
+                                       DEBUG(10, ("Found stale LevelII "
+                                                  "oplock\n"));
+                                       continue;
+                               }
                                smb_panic("Bad levelII oplock entry.");
                        }
                        *got_level2 = true;
@@ -1146,6 +1181,11 @@ static void find_oplock_types(files_struct *fsp,
 
                if (lck->data->share_modes[i].op_type == NO_OPLOCK) {
                        if (*pp_batch || *pp_ex_or_batch) {
+                               if (share_mode_stale_pid(lck->data, i)) {
+                                       DEBUG(10, ("Found stale NO_OPLOCK "
+                                                  "entry\n"));
+                                       continue;
+                               }
                                smb_panic("Bad no oplock entry.");
                        }
                        *got_no_oplock = true;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index d4b32ce..af2a21f 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7596,6 +7596,9 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                        if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
                                continue;
                        }
+                       if (share_mode_stale_pid(lck->data, i)) {
+                               continue;
+                       }
                        /* Fail with sharing violation. */
                        close_file(req, fsp, NORMAL_CLOSE);
                        TALLOC_FREE(lck);
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index 80618ce..4104fbc 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -104,6 +104,7 @@ bool run_local_conv_auth_info(int dummy);
 bool run_local_sprintf_append(int dummy);
 bool run_cleanup1(int dummy);
 bool run_cleanup2(int dummy);
+bool run_cleanup3(int dummy);
 bool run_ctdb_conn(int dummy);
 bool run_msg_test(int dummy);
 bool run_notify_bench2(int dummy);
diff --git a/source3/torture/test_cleanup.c b/source3/torture/test_cleanup.c
index 39f579a..d9dce40 100644
--- a/source3/torture/test_cleanup.c
+++ b/source3/torture/test_cleanup.c
@@ -18,11 +18,14 @@
 */
 
 #include "includes.h"
+#include "locking/proto.h"
 #include "torture/proto.h"
 #include "system/filesys.h"
+#include "system/select.h"
 #include "libsmb/libsmb.h"
 #include "libcli/smb/smbXcli_base.h"
 #include "libcli/security/security.h"
+#include "librpc/gen_ndr/open_files.h"
 
 bool run_cleanup1(int dummy)
 {
@@ -154,3 +157,175 @@ bool run_cleanup2(int dummy)
        }
        return true;
 }
+
+static bool create_stale_share_mode_entry(const char *fname,
+                                         struct file_id *p_id)
+{
+       struct cli_state *cli;
+       uint16_t fnum;
+       NTSTATUS status;
+       SMB_STRUCT_STAT sbuf;
+       struct file_id id;
+
+       if (!torture_open_connection(&cli, 0)) {
+               return false;
+       }
+
+       status = torture_setup_unix_extensions(cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("torture_setup_unix_extensions failed: %s\n",
+                      nt_errstr(status));
+               return false;
+       }
+       status = cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_ALL, &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("open of %s failed (%s)\n", fname, nt_errstr(status));
+               return false;
+       }
+       status = cli_posix_stat(cli, fname, &sbuf);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_stat failed: %s\n", nt_errstr(status));
+               return false;
+       }
+       status = smbXcli_conn_samba_suicide(cli->conn, 1);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("smbXcli_conn_samba_suicide failed: %s\n",
+                      nt_errstr(status));
+               return false;
+       }
+
+       id.devid = sbuf.st_ex_rdev;
+       id.inode = sbuf.st_ex_ino;
+       id.extid = 0;
+
+       poll(NULL, 0, 1000);
+
+       *p_id = id;
+       return true;
+}
+
+static bool corrupt_dummy(struct share_mode_data *d)
+{
+       return true;
+}
+
+static bool invalidate_sharemode(struct share_mode_data *d)
+{
+       d->share_modes[0].op_type =
+               OPLOCK_EXCLUSIVE|OPLOCK_BATCH|OPLOCK_LEVEL_II;
+       d->modified = true;
+       return true;
+}
+
+static bool duplicate_entry(struct share_mode_data *d, int i)
+{
+       struct share_mode_entry *tmp;
+
+       if (i >= d->num_share_modes) {
+               return false;
+       }
+
+       tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
+                            d->num_share_modes + 1);
+       if (tmp == NULL) {
+               return false;
+       }
+       d->share_modes = tmp;
+       d->num_share_modes += 1;
+       d->share_modes[d->num_share_modes-1] = d->share_modes[i];
+       d->modified = true;
+       return true;
+}
+
+static bool create_duplicate_batch(struct share_mode_data *d)
+{
+       if (d->num_share_modes != 1) {
+               return false;
+       }
+       d->share_modes[0].op_type = OPLOCK_BATCH;
+       if (!duplicate_entry(d, 0)) {
+               return false;
+       }
+       return true;


-- 
Samba Shared Repository

Reply via email to