[SCM] Samba Shared Repository - branch master updated - 7bea6684c23f34319feb393023e634b1f069f20f

Volker Lendecke vlendec at samba.org
Sat Oct 25 15:40:34 GMT 2008


The branch, master has been updated
       via  7bea6684c23f34319feb393023e634b1f069f20f (commit)
      from  f87219d6e6e049a6d233696d126ea231cbbc1672 (commit)

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


- Log -----------------------------------------------------------------
commit 7bea6684c23f34319feb393023e634b1f069f20f
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Oct 25 15:37:13 2008 +0200

    Add proxied named pipe support
    
    This is a central piece of the "merged build" thing: Forward named pipes from
    samba3 to samba4. This patch is not finished yet, as we will have to forward
    the smb-level authentication information to samba4, but I'm pushing this patch
    already to demonstrate the implementation without clutter.
    
    It adds an intermediate parameter
    
    np:proxy = srvsvc samr winreg wkssvc ... and so on
    
    that states which of the pipes should be forwarded to the s4 unix domain socket
    DEFAULT. The parameter is intermediate because once we have a proper endpoint
    mapper implementation, this information will be retrieved out of a database.
    
    If anybody wants to try this, do the merged build and configure s4 with
    
    server services = samba3_smb, rpc, nbt, wrepl, ldap, cldap, kdc, drepl
    samba3:smbd = /data/inst/sbin/smbd
    
    and s3 with
    
    auth methods = guest netlogond
    np:proxy = srvsvc samr winreg wkssvc netlogon ntlsa ntsvcs lsass lsarpc netdfs \
    rpcecho initshutdown epmapper svcctl eventlog drsuapi
    
    Then run rpcclient against samba4. It will fork s3, which authenticates against
    s4, and then forwards the rpc requests to s4.
    
    Volker

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

Summary of changes:
 source3/include/fake_file.h       |    3 +-
 source3/rpc_server/srv_pipe_hnd.c |  172 +++++++++++++++++++++++++++++++------
 2 files changed, 146 insertions(+), 29 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/fake_file.h b/source3/include/fake_file.h
index c4b271f..6b34005 100644
--- a/source3/include/fake_file.h
+++ b/source3/include/fake_file.h
@@ -23,7 +23,8 @@
 enum FAKE_FILE_TYPE {
 	FAKE_FILE_TYPE_NONE = 0,
 	FAKE_FILE_TYPE_QUOTA,
-	FAKE_FILE_TYPE_NAMED_PIPE
+	FAKE_FILE_TYPE_NAMED_PIPE,
+	FAKE_FILE_TYPE_NAMED_PIPE_PROXY
 };
 
 /*
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 822d50a..b892755 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -913,9 +913,74 @@ static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
 
 bool fsp_is_np(struct files_struct *fsp)
 {
-	return ((fsp != NULL)
-		&& (fsp->fake_file_handle != NULL)
-		&& (fsp->fake_file_handle->type == FAKE_FILE_TYPE_NAMED_PIPE));
+	enum FAKE_FILE_TYPE type;
+
+	if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
+		return false;
+	}
+
+	type = fsp->fake_file_handle->type;
+
+	return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
+		|| (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
+}
+
+struct np_proxy_state {
+	int fd;
+};
+
+static int np_proxy_state_destructor(struct np_proxy_state *state)
+{
+	if (state->fd != -1) {
+		close(state->fd);
+	}
+	return 0;
+}
+
+static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
+						       const char *pipe_name,
+						       struct auth_serversupplied_info *server_info)
+{
+	struct np_proxy_state *result;
+	struct sockaddr_un addr;
+	char *socket_path;
+
+	result = talloc(mem_ctx, struct np_proxy_state);
+	if (result == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		return NULL;
+	}
+
+	result->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (result->fd == -1) {
+		DEBUG(10, ("socket(2) failed: %s\n", strerror(errno)));
+		goto fail;
+	}
+	talloc_set_destructor(result, np_proxy_state_destructor);
+
+	ZERO_STRUCT(addr);
+	addr.sun_family = AF_UNIX;
+
+	socket_path = talloc_asprintf(talloc_tos(), "%s/%s",
+				      get_dyn_NCALRPCDIR(), "DEFAULT");
+	if (socket_path == NULL) {
+		DEBUG(0, ("talloc_asprintf failed\n"));
+		goto fail;
+	}
+	strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
+	TALLOC_FREE(socket_path);
+
+	if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
+		DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
+			  strerror(errno)));
+		goto fail;
+	}
+
+	return result;
+
+ fail:
+	TALLOC_FREE(result);
+	return NULL;
 }
 
 NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
@@ -923,13 +988,9 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
 {
 	NTSTATUS status;
 	struct files_struct *fsp;
-	struct pipes_struct *p;
-
-	/* See if it is one we want to handle. */
+	const char **proxy_list;
 
-	if (!is_known_pipename(name)) {
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-	}
+	proxy_list = lp_parm_string_list(SNUM(conn), "np", "proxy", NULL);
 
 	status = file_new(smb_req, conn, &fsp);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -949,16 +1010,36 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
 		file_free(smb_req, fsp);
 		return NT_STATUS_NO_MEMORY;
 	}
-	fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
 
-	p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name,
-				     conn->client_address, conn->server_info,
-				     smb_req->vuid);
-	if (p == NULL) {
+	if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
+		struct np_proxy_state *p;
+
+		p = make_external_rpc_pipe_p(fsp->fake_file_handle, name,
+					     conn->server_info);
+
+		fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
+		fsp->fake_file_handle->private_data = p;
+	} else {
+		struct pipes_struct *p;
+
+		if (!is_known_pipename(name)) {
+			file_free(smb_req, fsp);
+			return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		}
+
+		p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name,
+					     conn->client_address,
+					     conn->server_info,
+					     smb_req->vuid);
+
+		fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
+		fsp->fake_file_handle->private_data = p;
+	}
+
+	if (fsp->fake_file_handle->private_data == NULL) {
 		file_free(smb_req, fsp);
 		return NT_STATUS_PIPE_NOT_AVAILABLE;
 	}
-	fsp->fake_file_handle->private_data = p;
 
 	*pfsp = fsp;
 
@@ -968,20 +1049,33 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
 NTSTATUS np_write(struct files_struct *fsp, uint8_t *data, size_t len,
 		  ssize_t *nwritten)
 {
-	struct pipes_struct *p;
-
 	if (!fsp_is_np(fsp)) {
 		return NT_STATUS_INVALID_HANDLE;
 	}
 
-	p = talloc_get_type_abort(
-		fsp->fake_file_handle->private_data, struct pipes_struct);
-
 	DEBUG(6, ("np_write: %x name: %s len: %d\n", (int)fsp->fnum,
 		  fsp->fsp_name, (int)len));
 	dump_data(50, data, len);
 
-	*nwritten = write_to_internal_pipe(p, (char *)data, len);
+	switch (fsp->fake_file_handle->type) {
+	case FAKE_FILE_TYPE_NAMED_PIPE: {
+		struct pipes_struct *p = talloc_get_type_abort(
+			fsp->fake_file_handle->private_data,
+			struct pipes_struct);
+		*nwritten = write_to_internal_pipe(p, (char *)data, len);
+		break;
+	}
+	case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+		struct np_proxy_state *p = talloc_get_type_abort(
+			fsp->fake_file_handle->private_data,
+			struct np_proxy_state);
+		*nwritten = write_data(p->fd, (char *)data, len);
+		break;
+	}
+	default:
+		return NT_STATUS_INVALID_HANDLE;
+		break;
+	}
 
 	return ((*nwritten) >= 0)
 		? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
@@ -990,19 +1084,41 @@ NTSTATUS np_write(struct files_struct *fsp, uint8_t *data, size_t len,
 NTSTATUS np_read(struct files_struct *fsp, uint8_t *data, size_t len,
 		 ssize_t *nread, bool *is_data_outstanding)
 {
-	struct pipes_struct *p;
-
 	if (!fsp_is_np(fsp)) {
 		return NT_STATUS_INVALID_HANDLE;
 	}
 
-	p = talloc_get_type_abort(
-		fsp->fake_file_handle->private_data, struct pipes_struct);
+	switch (fsp->fake_file_handle->type) {
+	case FAKE_FILE_TYPE_NAMED_PIPE: {
+		struct pipes_struct *p = talloc_get_type_abort(
+			fsp->fake_file_handle->private_data,
+			struct pipes_struct);
+		*nread = read_from_internal_pipe(p, (char *)data, len,
+						 is_data_outstanding);
+		break;
+	}
+	case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+		struct np_proxy_state *p = talloc_get_type_abort(
+			fsp->fake_file_handle->private_data,
+			struct np_proxy_state);
+		int available = 0;
+
+		*nread = sys_read(p->fd, (char *)data, len);
+
+		/*
+		 * We don't look at the ioctl result. We don't really care
+		 * if there is data available, because this is racy anyway.
+		 */
+		ioctl(p->fd, FIONREAD, &available);
+		*is_data_outstanding = (available > 0);
 
-	*nread = read_from_internal_pipe(p, (char *)data, len,
-					 is_data_outstanding);
+		break;
+	}
+	default:
+		return NT_STATUS_INVALID_HANDLE;
+		break;
+	}
 
 	return ((*nread) >= 0)
 		? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
-
 }


-- 
Samba Shared Repository


More information about the samba-cvs mailing list