[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Apr 9 19:32:02 UTC 2019


The branch, master has been updated
       via  bfbe24d8274 leases_db: Make leases_db_del use leases_db_do_locked
       via  885d433b468 leases_db: Make leases_db_add use leases_db_do_locked
       via  ee53763a3e7 leases_db: Make leases_db_rename atomic
       via  cc4513dd4d3 smbd: Factor out map_lease_type_to_oplock
       via  bcb27521259 lib: Initialize variables in parse_resolvconf_fp
       via  c0b2272a7d1 lib: Initialize getline() arguments
      from  b1582a4d09f CVE-2019-3880 s3: rpc: winreg: Remove implementations of SaveKey/RestoreKey.

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


- Log -----------------------------------------------------------------
commit bfbe24d827425683c094a479e0f0158c5580bda7
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 8 15:38:01 2019 +0200

    leases_db: Make leases_db_del use leases_db_do_locked
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Apr  9 19:31:09 UTC 2019 on sn-devel-144

commit 885d433b468216a86b2963c6b4af896b254caa65
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 8 15:33:30 2019 +0200

    leases_db: Make leases_db_add use leases_db_do_locked
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ee53763a3e7ce13f534dd4071a0ce60a29671e67
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 8 15:18:31 2019 +0200

    leases_db: Make leases_db_rename atomic
    
    Do the rename under one lock to protect against potential races while
    we don't hold it.
    
    Factor out the NDR marshalling into leases_db_do_locked(), leaving the
    rename function pretty simple.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cc4513dd4d35f2d9ff4649f595bd85b0bb3a2fa3
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Sep 18 10:53:23 2018 +0200

    smbd: Factor out map_lease_type_to_oplock
    
    grant_fsp_oplock_type has enough complex logic, make this a bit shorter
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit bcb2752125986cbbf33a9388bd6420bb2af48ef6
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Apr 9 12:49:00 2019 +0200

    lib: Initialize variables in parse_resolvconf_fp
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit c0b2272a7d15d266ce64c86cf6a313b5b0fb67fd
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Apr 9 12:47:13 2019 +0200

    lib: Initialize getline() arguments
    
    Keep "len" valid across the loop iterations for getline to consume
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13892
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 libcli/dns/resolvconf.c     |   8 +-
 source3/locking/leases_db.c | 372 ++++++++++++++++++++++++--------------------
 source3/smbd/open.c         |  36 +++--
 3 files changed, 230 insertions(+), 186 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/dns/resolvconf.c b/libcli/dns/resolvconf.c
index 90d4e6a74b6..5cf8b4e7882 100644
--- a/libcli/dns/resolvconf.c
+++ b/libcli/dns/resolvconf.c
@@ -30,15 +30,15 @@ int parse_resolvconf_fp(
 	size_t *pnum_nameservers)
 {
 	char *line = NULL;
+	size_t len = 0;
 	char **nameservers = NULL;
 	size_t num_nameservers = 0;
 	int ret = 0;
 
 	while (true) {
-		char *saveptr, *option, *ns;
-		char **tmp;
-		ssize_t n;
-		size_t len;
+		char *saveptr = NULL, *option = NULL, *ns = NULL;
+		char **tmp = NULL;
+		ssize_t n = 0;
 
 		n = getline(&line, &len, fp);
 		if (n < 0) {
diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c
index 31576280fb6..3893841b172 100644
--- a/source3/locking/leases_db.c
+++ b/source3/locking/leases_db.c
@@ -86,223 +86,226 @@ static TDB_DATA leases_db_key(struct leases_db_key_buf *buf,
 	return (TDB_DATA) { .dptr = buf->buf, .dsize = sizeof(buf->buf) };
 }
 
-NTSTATUS leases_db_add(const struct GUID *client_guid,
-		       const struct smb2_lease_key *lease_key,
-		       const struct file_id *id,
-		       const char *servicepath,
-		       const char *base_name,
-		       const char *stream_name)
-{
-	struct leases_db_key_buf keybuf;
-	TDB_DATA db_key = leases_db_key(&keybuf, client_guid, lease_key);
-	TDB_DATA db_value;
-	DATA_BLOB blob;
-	struct db_record *rec;
+struct leases_db_do_locked_state {
+	void (*fn)(struct leases_db_value *value,
+		   bool *modified,
+		   void *private_data);
+	void *private_data;
 	NTSTATUS status;
-	struct leases_db_value new_value;
-	struct leases_db_file new_file;
+};
+
+static void leases_db_do_locked_fn(struct db_record *rec, void *private_data)
+{
+	struct leases_db_do_locked_state *state = private_data;
+	TDB_DATA db_value = dbwrap_record_get_value(rec);
+	DATA_BLOB blob = { .data = db_value.dptr, .length = db_value.dsize };
 	struct leases_db_value *value = NULL;
 	enum ndr_err_code ndr_err;
+	bool modified = false;
 
-	if (!leases_db_init(false)) {
-		return NT_STATUS_INTERNAL_ERROR;
-	}
-
-	rec = dbwrap_fetch_locked(leases_db, talloc_tos(), db_key);
-	if (rec == NULL) {
-		return NT_STATUS_INTERNAL_ERROR;
+	value = talloc_zero(talloc_tos(), struct leases_db_value);
+	if (value == NULL) {
+		state->status = NT_STATUS_NO_MEMORY;
+		goto done;
 	}
 
-	db_value = dbwrap_record_get_value(rec);
-	if (db_value.dsize != 0) {
-		uint32_t i;
-
-		DEBUG(10, ("%s: record exists\n", __func__));
-
-		value = talloc(talloc_tos(), struct leases_db_value);
-		if (value == NULL) {
-			status = NT_STATUS_NO_MEMORY;
-			goto out;
-		}
-
-		blob.data = db_value.dptr;
-		blob.length = db_value.dsize;
-
+	if (blob.length != 0) {
 		ndr_err = ndr_pull_struct_blob_all(
-			&blob, value, value,
+			&blob,
+			value,
+			value,
 			(ndr_pull_flags_fn_t)ndr_pull_leases_db_value);
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-			DEBUG(10, ("%s: ndr_pull_struct_blob_failed: %s\n",
-				   __func__, ndr_errstr(ndr_err)));
-			status = ndr_map_error2ntstatus(ndr_err);
-			goto out;
+			DBG_DEBUG("ndr_pull_struct_blob_failed: %s\n",
+				  ndr_errstr(ndr_err));
+			state->status = ndr_map_error2ntstatus(ndr_err);
+			goto done;
 		}
+	}
 
-		/* id must be unique. */
-		for (i = 0; i < value->num_files; i++) {
-			if (file_id_equal(id, &value->files[i].id)) {
-				status = NT_STATUS_OBJECT_NAME_COLLISION;
-				goto out;
-			}
-		}
+	state->fn(value, &modified, state->private_data);
+
+	if (!modified) {
+		goto done;
+	}
 
-		value->files = talloc_realloc(value, value->files,
-					struct leases_db_file,
-					value->num_files + 1);
-		if (value->files == NULL) {
-			status = NT_STATUS_NO_MEMORY;
-			goto out;
+	if (value->num_files == 0) {
+		state->status = dbwrap_record_delete(rec);
+		if (!NT_STATUS_IS_OK(state->status)) {
+			DBG_DEBUG("dbwrap_record_delete returned %s\n",
+				  nt_errstr(state->status));
 		}
-		value->files[value->num_files].id = *id;
-		value->files[value->num_files].servicepath = servicepath;
-		value->files[value->num_files].base_name = base_name;
-		value->files[value->num_files].stream_name = stream_name;
-		value->num_files += 1;
-
-	} else {
-		DEBUG(10, ("%s: new record\n", __func__));
-
-		new_file = (struct leases_db_file) {
-			.id = *id,
-			.servicepath = servicepath,
-			.base_name = base_name,
-			.stream_name = stream_name,
-		};
-
-		new_value = (struct leases_db_value) {
-			.num_files = 1,
-			.files = &new_file,
-		};
-		value = &new_value;
+		goto done;
 	}
 
 	ndr_err = ndr_push_struct_blob(
-		&blob, talloc_tos(), value,
+		&blob,
+		value,
+		value,
 		(ndr_push_flags_fn_t)ndr_push_leases_db_value);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		DEBUG(10, ("%s: ndr_push_struct_blob_failed: %s\n",
-			   __func__, ndr_errstr(ndr_err)));
-		status = ndr_map_error2ntstatus(ndr_err);
-		goto out;
+		DBG_DEBUG("ndr_push_struct_blob_failed: %s\n",
+			  ndr_errstr(ndr_err));
+		state->status = ndr_map_error2ntstatus(ndr_err);
+		goto done;
 	}
 
 	if (DEBUGLEVEL >= 10) {
-		DEBUG(10, ("%s:\n", __func__));
+		DBG_DEBUG("\n");
 		NDR_PRINT_DEBUG(leases_db_value, value);
 	}
 
 	db_value = make_tdb_data(blob.data, blob.length);
 
-	status = dbwrap_record_store(rec, db_value, 0);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("%s: dbwrap_record_store returned %s\n",
-			   __func__, nt_errstr(status)));
+	state->status = dbwrap_record_store(rec, db_value, 0);
+	if (!NT_STATUS_IS_OK(state->status)) {
+		DBG_DEBUG("dbwrap_record_store returned %s\n",
+			  nt_errstr(state->status));
 	}
 
-  out:
-
-	if (value != &new_value) {
-		TALLOC_FREE(value);
-	}
-	TALLOC_FREE(rec);
-	return status;
+done:
+	TALLOC_FREE(value);
 }
 
-NTSTATUS leases_db_del(const struct GUID *client_guid,
-		       const struct smb2_lease_key *lease_key,
-		       const struct file_id *id)
+static NTSTATUS leases_db_do_locked(
+	const struct GUID *client_guid,
+	const struct smb2_lease_key *lease_key,
+	void (*fn)(struct leases_db_value *value,
+		   bool *modified,
+		   void *private_data),
+	void *private_data)
 {
 	struct leases_db_key_buf keybuf;
 	TDB_DATA db_key = leases_db_key(&keybuf, client_guid, lease_key);
-	TDB_DATA db_value;
-	struct db_record *rec;
+	struct leases_db_do_locked_state state = {
+		.fn = fn, .private_data = private_data,
+	};
 	NTSTATUS status;
-	struct leases_db_value *value;
-	enum ndr_err_code ndr_err;
-	DATA_BLOB blob;
-	uint32_t i;
 
 	if (!leases_db_init(false)) {
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	rec = dbwrap_fetch_locked(leases_db, talloc_tos(), db_key);
-	if (rec == NULL) {
-		return NT_STATUS_NOT_FOUND;
+	status = dbwrap_do_locked(
+		leases_db, db_key, leases_db_do_locked_fn, &state);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
 	}
-	db_value = dbwrap_record_get_value(rec);
-	if (db_value.dsize == 0) {
-		status = NT_STATUS_INTERNAL_ERROR;
-		goto out;
+	return state.status;
+}
+
+struct leases_db_add_state {
+	const struct file_id *id;
+	const char *servicepath;
+	const char *base_name;
+	const char *stream_name;
+	NTSTATUS status;
+};
+
+static void leases_db_add_fn(
+	struct leases_db_value *value, bool *modified, void *private_data)
+{
+	struct leases_db_add_state *state = private_data;
+	struct leases_db_file *tmp = NULL;
+	uint32_t i;
+
+	/* id must be unique. */
+	for (i = 0; i < value->num_files; i++) {
+		if (file_id_equal(state->id, &value->files[i].id)) {
+			state->status = NT_STATUS_OBJECT_NAME_COLLISION;
+			return;
+		}
 	}
 
-	value = talloc(rec, struct leases_db_value);
-	if (value == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto out;
+	tmp = talloc_realloc(
+		value,
+		value->files,
+		struct leases_db_file,
+		value->num_files + 1);
+	if (tmp == NULL) {
+		state->status = NT_STATUS_NO_MEMORY;
+		return;
 	}
+	value->files = tmp;
 
-	blob.data = db_value.dptr;
-	blob.length = db_value.dsize;
+	value->files[value->num_files] = (struct leases_db_file) {
+		.id = *state->id,
+		.servicepath = state->servicepath,
+		.base_name = state->base_name,
+		.stream_name = state->stream_name,
+	};
+	value->num_files += 1;
 
-	ndr_err = ndr_pull_struct_blob_all(
-		&blob, value, value,
-		(ndr_pull_flags_fn_t)ndr_pull_leases_db_value);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		DEBUG(10, ("%s: ndr_pull_struct_blob_failed: %s\n",
-			   __func__, ndr_errstr(ndr_err)));
-		status = ndr_map_error2ntstatus(ndr_err);
-		goto out;
+	*modified = true;
+}
+
+NTSTATUS leases_db_add(const struct GUID *client_guid,
+		       const struct smb2_lease_key *lease_key,
+		       const struct file_id *id,
+		       const char *servicepath,
+		       const char *base_name,
+		       const char *stream_name)
+{
+	struct leases_db_add_state state = {
+		.id = id,
+		.servicepath = servicepath,
+		.base_name = base_name,
+		.stream_name = stream_name,
+	};
+	NTSTATUS status;
+
+	status = leases_db_do_locked(
+		client_guid, lease_key, leases_db_add_fn, &state);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_DEBUG("leases_db_do_locked failed: %s\n",
+			  nt_errstr(status));
+		return status;
 	}
+	return state.status;
+}
+
+struct leases_db_del_state {
+	const struct file_id *id;
+	NTSTATUS status;
+};
+
+static void leases_db_del_fn(
+	struct leases_db_value *value, bool *modified, void *private_data)
+{
+	struct leases_db_del_state *state = private_data;
+	uint32_t i;
 
-	/* id must exist. */
 	for (i = 0; i < value->num_files; i++) {
-		if (file_id_equal(id, &value->files[i].id)) {
+		if (file_id_equal(state->id, &value->files[i].id)) {
 			break;
 		}
 	}
-
 	if (i == value->num_files) {
-		status = NT_STATUS_NOT_FOUND;
-		goto out;
+		state->status = NT_STATUS_NOT_FOUND;
+		return;
 	}
 
 	value->files[i] = value->files[value->num_files-1];
 	value->num_files -= 1;
 
-	if (value->num_files == 0) {
-		DEBUG(10, ("%s: deleting record\n", __func__));
-		status = dbwrap_record_delete(rec);
-	} else {
-		DEBUG(10, ("%s: updating record\n", __func__));
-		ndr_err = ndr_push_struct_blob(
-			&blob, rec, value,
-			(ndr_push_flags_fn_t)ndr_push_leases_db_value);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-			DEBUG(10, ("%s: ndr_push_struct_blob_failed: %s\n",
-				   __func__, ndr_errstr(ndr_err)));
-			status = ndr_map_error2ntstatus(ndr_err);
-			goto out;
-		}
-
-		if (DEBUGLEVEL >= 10) {
-			DEBUG(10, ("%s:\n", __func__));
-			NDR_PRINT_DEBUG(leases_db_value, value);
-		}
+	*modified = true;
+}
 
-		db_value = make_tdb_data(blob.data, blob.length);
+NTSTATUS leases_db_del(const struct GUID *client_guid,
+		       const struct smb2_lease_key *lease_key,
+		       const struct file_id *id)
+{
+	struct leases_db_del_state state = { .id = id };
+	NTSTATUS status;
 
-		status = dbwrap_record_store(rec, db_value, 0);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(10, ("%s: dbwrap_record_store returned %s\n",
-				   __func__, nt_errstr(status)));
-		}
+	status = leases_db_do_locked(
+		client_guid, lease_key, leases_db_del_fn, &state);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_DEBUG("leases_db_do_locked failed: %s\n",
+			  nt_errstr(status));
+		return status;
 	}
-
-  out:
-
-	TALLOC_FREE(rec);
-	return status;
+	return state.status;
 }
 
 struct leases_db_fetch_state {
@@ -381,6 +384,40 @@ NTSTATUS leases_db_parse(const struct GUID *client_guid,
 	return state.status;
 }
 
+struct leases_db_rename_state {
+	const struct file_id *id;
+	const char *servicename_new;
+	const char *filename_new;
+	const char *stream_name_new;
+	NTSTATUS status;
+};
+
+static void leases_db_rename_fn(
+	struct leases_db_value *value, bool *modified, void *private_data)
+{
+	struct leases_db_rename_state *state = private_data;
+	struct leases_db_file *file = NULL;
+	uint32_t i;
+
+	/* id must exist. */
+	for (i = 0; i < value->num_files; i++) {
+		if (file_id_equal(state->id, &value->files[i].id)) {
+			break;
+		}
+	}
+	if (i == value->num_files) {
+		state->status = NT_STATUS_NOT_FOUND;
+		return;
+	}
+
+	file = &value->files[i];
+	file->servicepath = state->servicename_new;
+	file->base_name = state->filename_new;
+	file->stream_name = state->stream_name_new;
+
+	*modified = true;
+}
+
 NTSTATUS leases_db_rename(const struct GUID *client_guid,
 		       const struct smb2_lease_key *lease_key,
 		       const struct file_id *id,
@@ -388,21 +425,22 @@ NTSTATUS leases_db_rename(const struct GUID *client_guid,
 		       const char *filename_new,
 		       const char *stream_name_new)
 {
+	struct leases_db_rename_state state = {
+		.id = id,
+		.servicename_new = servicename_new,
+		.filename_new = filename_new,
+		.stream_name_new = stream_name_new,
+	};
 	NTSTATUS status;
 
-	status = leases_db_del(client_guid,
-				lease_key,
-				id);
+	status = leases_db_do_locked(
+		client_guid, lease_key, leases_db_rename_fn, &state);
 	if (!NT_STATUS_IS_OK(status)) {
+		DBG_DEBUG("leases_db_do_locked failed: %s\n",
+			  nt_errstr(status));
 		return status;
 	}
-
-	return leases_db_add(client_guid,
-				lease_key,
-				id,
-				servicename_new,
-				filename_new,
-				stream_name_new);
+	return state.status;
 }
 
 NTSTATUS leases_db_copy_file_ids(TALLOC_CTX *mem_ctx,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 22f6715c6c0..167d82f0b13 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2166,6 +2166,26 @@ static bool is_same_lease(const files_struct *fsp,
 				&d->leases[e->lease_idx].lease_key);
 }
 
+static int map_lease_type_to_oplock(uint32_t lease_type)
+{
+	int result = NO_OPLOCK;
+
+	switch (lease_type) {
+	case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:


-- 
Samba Shared Repository



More information about the samba-cvs mailing list