[SCM] Samba Shared Repository - branch v4-2-test updated

Karolin Seeger kseeger at samba.org
Wed Nov 5 04:25:40 MST 2014


The branch, v4-2-test has been updated
       via  e7a90aa s3:locking: remove dead code from brl_get_locks_readonly()
       via  38b8e09 s3:locking: Change from ndr_pull_struct_blob() to ndr_pull_struct_blob_all() so we fail if not all bytes are consumed.
       via  1fd4868 s4:torture/smb2: test rename dir deny with open files
       via  b5cc961 s3:smbd: Don't rename a dir with files open underneath
       via  beb05a1b selftest:Samba3: use "strict rename = yes"
       via  4ff4c58 s3:param: Add new option "strict rename".
       via  b527525 s3:locking: allow early return for share_entry_forall()
       via  cfa74dc s3:locking: Introduce share_mode_forall
       via  ac37fae s3:locking: Rename share_mode_forall->share_entry_forall
       via  e430584 s3: smbd: Preparation for leases code merge. Ensure VFS is ready for 4.2.0.
       via  fd4cc75 samba-tool group add: Add option --nis-domain and --gid
      from  703957e s3: libsmbclient - smb2. MacOSX 10 SMB2 server doesn't set STATUS_NO_MORE_FILES when handed a non-wildcard path.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-2-test


- Log -----------------------------------------------------------------
commit e7a90aaa200d95afe0d6e90a1149d0c9f09aed8f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Oct 29 17:29:06 2014 +0100

    s3:locking: remove dead code from brl_get_locks_readonly()
    
    struct byte_range_lock *rw = NULL; will never change...
    
    commit 105724073300af03eb0835b3c93d9b2e2bfacb07 removed the
    possible assigment of 'rw'.
    
    So we can remove all code under if (rw != NULL) { ...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Oct 31 06:07:43 CET 2014 on sn-devel-104
    
    (cherry picked from commit a3b333a1a2ab23ba0c59be1fc65c730e2b53e8c5)
    
    The last 10 patches address bug #10911 - SMB2 leases are not yet supported.
    
    Autobuild-User(v4-2-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-2-test): Tue Nov  4 23:38:34 CET 2014 on sn-devel-104

commit 38b8e0975c0ad51af722556e27d7c5f7402daf94
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Oct 28 15:20:26 2014 -0700

    s3:locking: Change from ndr_pull_struct_blob() to ndr_pull_struct_blob_all() so we fail if not all bytes are consumed.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 151b9caeef7dc4fa4816035a406acb9f1c5812c3)

commit 1fd48687fe5bf5fd3dcd918422a4fe4fc34d38b9
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Sep 25 01:32:00 2014 +0200

    s4:torture/smb2: test rename dir deny with open files
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 8334428666b8282d2cfbcfd411acab0c338ae390)

commit b5cc9614fc6d5296fb5b3482a56888a3aa03461b
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Sep 25 01:30:33 2014 +0200

    s3:smbd: Don't rename a dir with files open underneath
    
    This is an EXPENSIVE check. We'll have to guard this with an option
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 035fd7200d8a025cdb8bfae30c264757aa3cb193)

commit beb05a1b891fd51463def0b6f3b43394e4451414
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 24 13:57:04 2014 -0700

    selftest:Samba3: use "strict rename = yes"
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 5f60dcc38ca275aedeb1d67611b5acf9b26361d5)

commit 4ff4c58ee75887b8e5e4ea3752eb0d82e13e903a
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 24 13:57:04 2014 -0700

    s3:param: Add new option "strict rename".
    
    Control whether smbd can rename directories containing
    open files. Defaults to "no" (meaning we *can* do
    such renames).
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit b0a434386dc2f77df89811bc3f56c4cc7fb7b16c)

commit b5275259290ae468c9047ef5a1e27b7f113c9718
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Sep 24 20:46:15 2014 +0200

    s3:locking: allow early return for share_entry_forall()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 9010bbeb00264f4476c3be7d2e8c8420c695cfbb)

commit cfa74dcf2617b2c03de1458e35cbb0533d2bfffb
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Sep 23 05:45:49 2014 +0200

    s3:locking: Introduce share_mode_forall
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 48926b761975a7d9cb6daf30d64d6a4f0a34f38a)

commit ac37fae12b5023a2680df73fe230825be069b515
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Sep 23 05:18:54 2014 +0200

    s3:locking: Rename share_mode_forall->share_entry_forall
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 0d4f7bfdb995a239508457cd433bc8001c0e8279)

commit e4305846e7fb3963336189f30839811424151c84
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Oct 8 09:06:06 2014 -0700

    s3: smbd: Preparation for leases code merge. Ensure VFS is ready for 4.2.0.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Oct 10 02:55:53 CEST 2014 on sn-devel-104
    
    (cherry picked from commit aa2a6c7b18e2e2bd3979ffb53208564764b8b9cf)

commit fd4cc75b3b19e6dce1f5fdb9e09fe539bb8d026b
Author: Marc Muehlfeld <mmuehlfeld at samba.org>
Date:   Sat Oct 18 00:34:35 2014 +0200

    samba-tool group add: Add option --nis-domain and --gid
    
    This allows creating RFC2307 enabled groups via samba-tool
    
    Signed-off-by: Marc Muehlfeld <mmuehlfeld at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Thu Oct 23 18:19:35 CEST 2014 on sn-devel-104
    
    (cherry picked from commit 4bec1867987845fc40e9a17a283d2affc36e0dc5)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10895
    samba-tool can't treat RCF2307 enabled groups

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

Summary of changes:
 docs-xml/smbdotconf/tuning/strictrename.xml |  25 ++++++
 lib/param/param_table.c                     |   9 +++
 python/samba/netcmd/group.py                |  15 +++-
 python/samba/samdb.py                       |  13 ++-
 selftest/knownfail                          |   1 +
 selftest/target/Samba3.pm                   |   1 +
 source3/include/vfs.h                       |   7 ++
 source3/locking/brlock.c                    |  78 +++++++-----------
 source3/locking/proto.h                     |   6 +-
 source3/locking/share_mode_lock.c           | 105 ++++++++++++++++--------
 source3/param/loadparm.c                    |   1 +
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c   |  54 +++++++------
 source3/smbd/dir.c                          | 121 +++++++++++++++++++++++++++-
 source3/utils/status.c                      |  14 ++--
 source4/torture/smb2/rename.c               |  97 ++++++++++++++++++++++
 15 files changed, 430 insertions(+), 117 deletions(-)
 create mode 100644 docs-xml/smbdotconf/tuning/strictrename.xml


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/tuning/strictrename.xml b/docs-xml/smbdotconf/tuning/strictrename.xml
new file mode 100644
index 0000000..5478863
--- /dev/null
+++ b/docs-xml/smbdotconf/tuning/strictrename.xml
@@ -0,0 +1,25 @@
+<samba:parameter name="strict rename"
+                 context="S"
+				 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+    <para>By default a Windows SMB server prevents directory
+    renames when there are open file or directory handles below
+    it in the filesystem hierarchy. Historically Samba has always
+    allowed this as POSIX filesystem semantics require it.</para>
+
+    <para>This boolean parameter allows Samba to match the Windows
+    behavior. Setting this to "yes" is a very expensive change,
+    as it forces Samba to travers the entire open file handle
+    database on every directory rename request. In a clustered
+    Samba system the cost is even greater than the non-clustered
+    case.</para>
+
+    <para>For this reason the default is "no", and it is recommended
+    to be left that way unless a specific Windows application requires
+    it to be changed.</para>
+
+</description>
+
+<value type="default">no</value>
+</samba:parameter>
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index d3f60c3..4d0e6a9 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -1882,6 +1882,15 @@ struct parm_struct parm_table[] = {
 		.flags		= FLAG_ADVANCED | FLAG_SHARE,
 	},
 	{
+		.label		= "strict rename",
+		.type		= P_BOOL,
+		.p_class	= P_LOCAL,
+		.offset		= LOCAL_VAR(strict_rename),
+		.special	= NULL,
+		.enum_list	= NULL,
+		.flags		= FLAG_ADVANCED | FLAG_SHARE,
+	},
+	{
 		.label		= "strict sync",
 		.type		= P_BOOL,
 		.p_class	= P_LOCAL,
diff --git a/python/samba/netcmd/group.py b/python/samba/netcmd/group.py
index 1a24e5f..4b5fd27 100644
--- a/python/samba/netcmd/group.py
+++ b/python/samba/netcmd/group.py
@@ -70,6 +70,11 @@ Example2:
 sudo samba-tool group add Group2 --group-type=Distribution
 
 Example2 adds a new distribution group to the local server.  The command is run under root using the sudo command.
+
+Example3:
+samba-tool group add Group3 --nis-domain=samdom --gid=12345
+
+Example3 adds a new RFC2307 enabled group for NIS domain samdom and GID 12345 (both options are required to enable this feature).
 """
 
     synopsis = "%prog <groupname> [options]"
@@ -93,19 +98,24 @@ Example2 adds a new distribution group to the local server.  The command is run
         Option("--description", help="Group's description", type=str),
         Option("--mail-address", help="Group's email address", type=str),
         Option("--notes", help="Groups's notes", type=str),
+        Option("--gid-number", help="Group's Unix/RFC2307 GID number", type=int),
+        Option("--nis-domain", help="SFU30 NIS Domain", type=str),
     ]
 
     takes_args = ["groupname"]
 
     def run(self, groupname, credopts=None, sambaopts=None,
             versionopts=None, H=None, groupou=None, group_scope=None,
-            group_type=None, description=None, mail_address=None, notes=None):
+            group_type=None, description=None, mail_address=None, notes=None, gid_number=None, nis_domain=None):
 
         if (group_type or "Security") == "Security":
             gtype = security_group.get(group_scope, GTYPE_SECURITY_GLOBAL_GROUP)
         else:
             gtype = distribution_group.get(group_scope, GTYPE_DISTRIBUTION_GLOBAL_GROUP)
 
+        if (gid_number is None and nis_domain is not None) or (gid_number is not None and nis_domain is None):
+            raise CommandError('Both --gid-number and --nis-domain have to be set for a RFC2307-enabled group. Operation cancelled.')
+
         lp = sambaopts.get_loadparm()
         creds = credopts.get_credentials(lp, fallback_machine=True)
 
@@ -113,7 +123,8 @@ Example2 adds a new distribution group to the local server.  The command is run
             samdb = SamDB(url=H, session_info=system_session(),
                           credentials=creds, lp=lp)
             samdb.newgroup(groupname, groupou=groupou, grouptype = gtype,
-                          description=description, mailaddress=mail_address, notes=notes)
+                          description=description, mailaddress=mail_address, notes=notes,
+                          gidnumber=gid_number, nisdomain=nis_domain)
         except Exception, e:
             # FIXME: catch more specific exception
             raise CommandError('Failed to create group "%s"' % groupname, e)
diff --git a/python/samba/samdb.py b/python/samba/samdb.py
index 2dfc839..e68519f 100644
--- a/python/samba/samdb.py
+++ b/python/samba/samdb.py
@@ -169,7 +169,8 @@ pwdLastSet: 0
         self.modify_ldif(mod)
 
     def newgroup(self, groupname, groupou=None, grouptype=None,
-                 description=None, mailaddress=None, notes=None, sd=None):
+                 description=None, mailaddress=None, notes=None, sd=None,
+                 gidnumber=None, nisdomain=None):
         """Adds a new group with additional parameters
 
         :param groupname: Name of the new group
@@ -177,6 +178,8 @@ pwdLastSet: 0
         :param description: Description of the new group
         :param mailaddress: Email address of the new group
         :param notes: Notes of the new group
+        :param gidnumber: GID Number of the new group
+        :param nisdomain: NIS Domain Name of the new group
         :param sd: security descriptor of the object
         """
 
@@ -188,6 +191,8 @@ pwdLastSet: 0
             "sAMAccountName": groupname,
             "objectClass": "group"}
 
+        ldbmessage["msSFU30Name"] = groupname
+
         if grouptype is not None:
             ldbmessage["groupType"] = normalise_int32(grouptype)
 
@@ -200,6 +205,12 @@ pwdLastSet: 0
         if notes is not None:
             ldbmessage["info"] = notes
 
+        if gidnumber is not None:
+            ldbmessage["gidNumber"] = normalise_int32(gidnumber)
+
+        if nisdomain is not None:
+            ldbmessage["msSFU30NisDomain"] = nisdomain
+
         if sd is not None:
             ldbmessage["nTSecurityDescriptor"] = ndr_pack(sd)
 
diff --git a/selftest/knownfail b/selftest/knownfail
index 3d73495..6cca3dd 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -112,6 +112,7 @@
 ^samba4.smb2.rename.no_share_delete_no_delete_access\(.*\)$
 ^samba4.smb2.rename.msword
 ^samba4.smb2.rename.rename_dir_bench\(dc\)
+^samba4.smb2.rename.rename_dir_openfile\(.*\)$
 ^samba4.smb2.oplock.doc
 ^samba4.smb2.compound.related3
 ^samba4.smb2.compound.compound-break
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index de40ced..ebe2c09 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1073,6 +1073,7 @@ sub provision($$$$$$)
 	store dos attributes = yes
 	create mask = 755
 	dos filemode = yes
+	strict rename = yes
 	vfs objects = acl_xattr fake_acls xattr_tdb streams_depot
 
 	printing = vlp
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 3702b75..b0f00e8 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -158,6 +158,7 @@
 
 /* Bump to version 32 - Samba 4.2 will ship with that. */
 /* Version 32 - Add "lease" to CREATE_FILE operation */
+/* Version 32 - Add "lease" to struct files_struct */
 
 #define SMB_VFS_INTERFACE_VERSION 32
 
@@ -202,6 +203,11 @@ struct fd_handle {
 	unsigned long gen_id;
 };
 
+struct fsp_lease {
+	size_t ref_count;
+	struct smb2_lease lease;
+};
+
 typedef struct files_struct {
 	struct files_struct *next, *prev;
 	uint64_t fnum;
@@ -225,6 +231,7 @@ typedef struct files_struct {
 	bool write_time_forced;
 
 	int oplock_type;
+	struct fsp_lease *lease; /* Not yet used. Placeholder for leases. */
 	int sent_oplock_break;
 	struct tevent_timer *oplock_timeout;
 	struct lock_struct last_lock_failure;
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 295e147..1c4c4d0 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -2026,7 +2026,8 @@ static void brl_get_locks_readonly_parser(TDB_DATA key, TDB_DATA data,
 struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
 {
 	struct byte_range_lock *br_lock = NULL;
-	struct byte_range_lock *rw = NULL;
+	struct brl_get_locks_readonly_state state;
+	NTSTATUS status;
 
 	DEBUG(10, ("seqnum=%d, fsp->brlock_seqnum=%d\n",
 		   dbwrap_get_seqnum(brlock_db), fsp->brlock_seqnum));
@@ -2040,60 +2041,39 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
 		return fsp->brlock_rec;
 	}
 
-	if (rw != NULL) {
-		size_t lock_data_size;
+	/*
+	 * Parse the record fresh from the database
+	 */
+
+	state.mem_ctx = fsp;
+	state.br_lock = &br_lock;
 
+	status = dbwrap_parse_record(
+		brlock_db,
+		make_tdb_data((uint8_t *)&fsp->file_id,
+			      sizeof(fsp->file_id)),
+		brl_get_locks_readonly_parser, &state);
+
+	if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_FOUND)) {
 		/*
-		 * Make a copy of the already retrieved and sanitized rw record
+		 * No locks on this file. Return an empty br_lock.
 		 */
-		lock_data_size = rw->num_locks * sizeof(struct lock_struct);
-		br_lock = talloc_pooled_object(
-			fsp, struct byte_range_lock, 1, lock_data_size);
+		br_lock = talloc(fsp, struct byte_range_lock);
 		if (br_lock == NULL) {
-			goto fail;
+			return NULL;
 		}
-		br_lock->have_read_oplocks = rw->have_read_oplocks;
-		br_lock->num_locks = rw->num_locks;
-		br_lock->lock_data = (struct lock_struct *)talloc_memdup(
-			br_lock, rw->lock_data, lock_data_size);
-	} else {
-		struct brl_get_locks_readonly_state state;
-		NTSTATUS status;
-
-		/*
-		 * Parse the record fresh from the database
-		 */
 
-		state.mem_ctx = fsp;
-		state.br_lock = &br_lock;
-
-		status = dbwrap_parse_record(
-			brlock_db,
-			make_tdb_data((uint8_t *)&fsp->file_id,
-				      sizeof(fsp->file_id)),
-			brl_get_locks_readonly_parser, &state);
-
-		if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_FOUND)) {
-			/*
-			 * No locks on this file. Return an empty br_lock.
-			 */
-			br_lock = talloc(fsp, struct byte_range_lock);
-			if (br_lock == NULL) {
-				goto fail;
-			}
-
-			br_lock->have_read_oplocks = false;
-			br_lock->num_locks = 0;
-			br_lock->lock_data = NULL;
+		br_lock->have_read_oplocks = false;
+		br_lock->num_locks = 0;
+		br_lock->lock_data = NULL;
 
-		} else if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(3, ("Could not parse byte range lock record: "
-				  "%s\n", nt_errstr(status)));
-			goto fail;
-		}
-		if (br_lock == NULL) {
-			goto fail;
-		}
+	} else if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("Could not parse byte range lock record: "
+			  "%s\n", nt_errstr(status)));
+		return NULL;
+	}
+	if (br_lock == NULL) {
+		return NULL;
 	}
 
 	br_lock->fsp = fsp;
@@ -2117,8 +2097,6 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
 		fsp->brlock_seqnum = dbwrap_get_seqnum(brlock_db);
 	}
 
-fail:
-	TALLOC_FREE(rw);
 	return br_lock;
 }
 
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 46eec2a..44f3ba1 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -190,7 +190,11 @@ bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash);
 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time);
 bool set_write_time(struct file_id fileid, struct timespec write_time);
 struct timespec get_share_mode_write_time(struct share_mode_lock *lck);
-int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
+int share_mode_forall(int (*fn)(struct file_id fid,
+				const struct share_mode_data *data,
+				void *private_data),
+		      void *private_data);
+int share_entry_forall(int (*fn)(const struct share_mode_entry *, const char *,
 				 const char *, void *),
 		      void *private_data);
 bool share_mode_cleanup_disconnected(struct file_id id,
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 12f499b..65409ac 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -133,7 +133,7 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
 	blob.data = dbuf.dptr;
 	blob.length = dbuf.dsize;
 
-	ndr_err = ndr_pull_struct_blob(
+	ndr_err = ndr_pull_struct_blob_all(
 		&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n",
@@ -440,30 +440,33 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
 	return lck;
 }
 
-struct forall_state {
-	void (*fn)(const struct share_mode_entry *entry,
-		   const char *sharepath,
-		   const char *fname,
-		   void *private_data);
+struct share_mode_forall_state {
+	int (*fn)(struct file_id fid, const struct share_mode_data *data,
+		  void *private_data);
 	void *private_data;
 };
 
-static int traverse_fn(struct db_record *rec, void *_state)
+static int share_mode_traverse_fn(struct db_record *rec, void *_state)
 {
-	struct forall_state *state = (struct forall_state *)_state;
+	struct share_mode_forall_state *state =
+		(struct share_mode_forall_state *)_state;
 	uint32_t i;
 	TDB_DATA key;
 	TDB_DATA value;
 	DATA_BLOB blob;
 	enum ndr_err_code ndr_err;
 	struct share_mode_data *d;
+	struct file_id fid;
+	int ret;
 
 	key = dbwrap_record_get_key(rec);
 	value = dbwrap_record_get_value(rec);
 
 	/* Ensure this is a locking_key record. */
-	if (key.dsize != sizeof(struct file_id))
+	if (key.dsize != sizeof(fid)) {
 		return 0;
+	}
+	memcpy(&fid, key.dptr, sizeof(fid));
 
 	d = talloc(talloc_tos(), struct share_mode_data);
 	if (d == NULL) {
@@ -473,7 +476,7 @@ static int traverse_fn(struct db_record *rec, void *_state)
 	blob.data = value.dptr;
 	blob.length = value.dsize;
 
-	ndr_err = ndr_pull_struct_blob(
+	ndr_err = ndr_pull_struct_blob_all(
 		&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
@@ -485,42 +488,80 @@ static int traverse_fn(struct db_record *rec, void *_state)
 	}
 	for (i=0; i<d->num_share_modes; i++) {
 		d->share_modes[i].stale = false; /* [skip] in idl */
-		state->fn(&d->share_modes[i],
-			  d->servicepath, d->base_name,
-			  state->private_data);
 	}
-	TALLOC_FREE(d);
 
-	return 0;
-}
+	ret = state->fn(fid, d, state->private_data);
 
-/*******************************************************************
- Call the specified function on each entry under management by the
- share mode system.
-********************************************************************/
+	TALLOC_FREE(d);
+	return ret;
+}
 
-int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
-				 const char *, void *),
+int share_mode_forall(int (*fn)(struct file_id fid,
+				const struct share_mode_data *data,
+				void *private_data),
 		      void *private_data)
 {
-	struct forall_state state;
+	struct share_mode_forall_state state = {
+		.fn = fn,
+		.private_data = private_data
+	};
 	NTSTATUS status;
 	int count;
 
-	if (lock_db == NULL)
+	if (lock_db == NULL) {
 		return 0;
+	}
 
-	state.fn = fn;
-	state.private_data = private_data;
-
-	status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
-				      &count);
-
+	status = dbwrap_traverse_read(lock_db, share_mode_traverse_fn,
+				      &state, &count);
 	if (!NT_STATUS_IS_OK(status)) {
 		return -1;
-	} else {
-		return count;
 	}
+
+	return count;
+}
+
+struct share_entry_forall_state {
+	int (*fn)(const struct share_mode_entry *e,
+		  const char *service_path, const char *base_name,
+		  void *private_data);
+	void *private_data;
+};
+
+static int share_entry_traverse_fn(struct file_id fid,
+				   const struct share_mode_data *data,
+				   void *private_data)
+{
+	struct share_entry_forall_state *state = private_data;
+	uint32_t i;
+
+	for (i=0; i<data->num_share_modes; i++) {
+		int ret;
+
+		ret = state->fn(&data->share_modes[i],
+				data->servicepath, data->base_name,
+				state->private_data);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************
+ Call the specified function on each entry under management by the
+ share mode system.
+********************************************************************/
+
+int share_entry_forall(int (*fn)(const struct share_mode_entry *,
+				 const char *, const char *, void *),
+		       void *private_data)
+{
+	struct share_entry_forall_state state = {
+		.fn = fn, .private_data = private_data };
+
+	return share_mode_forall(share_entry_traverse_fn, &state);
 }
 
 bool share_mode_cleanup_disconnected(struct file_id fid,
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 5ab0de7..884cc45 100644


-- 
Samba Shared Repository


More information about the samba-cvs mailing list