diff options
| -rw-r--r-- | source3/include/proto.h | 14 | ||||
| -rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 87 | ||||
| -rw-r--r-- | source3/smbd/ipc.c | 13 | ||||
| -rw-r--r-- | source3/smbd/nttrans.c | 2 | ||||
| -rw-r--r-- | source3/smbd/pipes.c | 54 | 
5 files changed, 99 insertions, 71 deletions
| diff --git a/source3/include/proto.h b/source3/include/proto.h index 71ad259085..e3d93494ff 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6226,11 +6226,13 @@ pipes_struct *get_next_internal_pipe(pipes_struct *p);  void init_rpc_pipe_hnd(void);  bool fsp_is_np(struct files_struct *fsp); -NTSTATUS np_open(struct smb_request *smb_req, const char *name, -		 struct files_struct **pfsp); -NTSTATUS np_write(struct files_struct *fsp, const uint8_t *data, size_t len, -		  ssize_t *nwritten); -NTSTATUS np_read(struct files_struct *fsp, uint8_t *data, size_t len, +NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, +		 const char *client_address, +		 struct auth_serversupplied_info *server_info, +		 struct fake_file_handle **phandle); +NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data, +		  size_t len, ssize_t *nwritten); +NTSTATUS np_read(struct fake_file_handle *handle, uint8_t *data, size_t len,  		 ssize_t *nread, bool *is_data_outstanding);  /* The following definitions come from rpc_server/srv_samr_util.c  */ @@ -7068,6 +7070,8 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password,  /* The following definitions come from smbd/pipes.c  */ +NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, +		      struct files_struct **pfsp);  void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req);  void reply_pipe_write(struct smb_request *req);  void reply_pipe_write_and_X(struct smb_request *req); diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index e574f0387d..cbb6a8f4bf 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1075,92 +1075,69 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,  	return NULL;  } -NTSTATUS np_open(struct smb_request *smb_req, const char *name, -		 struct files_struct **pfsp) +NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, +		 const char *client_address, +		 struct auth_serversupplied_info *server_info, +		 struct fake_file_handle **phandle)  { -	struct connection_struct *conn = smb_req->conn; -	NTSTATUS status; -	struct files_struct *fsp;  	const char **proxy_list; +	struct fake_file_handle *handle; -	proxy_list = lp_parm_string_list(SNUM(conn), "np", "proxy", NULL); - -	status = file_new(smb_req, conn, &fsp); -	if (!NT_STATUS_IS_OK(status)) { -		DEBUG(0, ("file_new failed: %s\n", nt_errstr(status))); -		return status; -	} - -	fsp->conn = conn; -	fsp->fh->fd = -1; -	fsp->vuid = smb_req->vuid; -	fsp->can_lock = false; -	fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA; -	string_set(&fsp->fsp_name, name); +	proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL); -	fsp->fake_file_handle = talloc(NULL, struct fake_file_handle); -	if (fsp->fake_file_handle == NULL) { -		file_free(smb_req, fsp); +	handle = talloc(mem_ctx, struct fake_file_handle); +	if (handle == NULL) {  		return NT_STATUS_NO_MEMORY;  	}  	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); +		p = make_external_rpc_pipe_p(handle, name, server_info); -		fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY; -		fsp->fake_file_handle->private_data = p; +		handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY; +		handle->private_data = p;  	} else {  		struct pipes_struct *p;  		if (!is_known_pipename(name)) { -			file_free(smb_req, fsp); +			TALLOC_FREE(handle);  			return NT_STATUS_OBJECT_NAME_NOT_FOUND;  		} -		p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name, -					     conn->client_address, -					     conn->server_info); +		p = make_internal_rpc_pipe_p(handle, name, client_address, +					     server_info); -		fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE; -		fsp->fake_file_handle->private_data = p; +		handle->type = FAKE_FILE_TYPE_NAMED_PIPE; +		handle->private_data = p;  	} -	if (fsp->fake_file_handle->private_data == NULL) { -		file_free(smb_req, fsp); +	if (handle->private_data == NULL) { +		TALLOC_FREE(handle);  		return NT_STATUS_PIPE_NOT_AVAILABLE;  	} -	*pfsp = fsp; +	*phandle = handle;  	return NT_STATUS_OK;  } -NTSTATUS np_write(struct files_struct *fsp, const uint8_t *data, size_t len, -		  ssize_t *nwritten) +NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data, +		  size_t len, ssize_t *nwritten)  { -	if (!fsp_is_np(fsp)) { -		return NT_STATUS_INVALID_HANDLE; -	} - -	DEBUG(6, ("np_write: %x name: %s len: %d\n", (int)fsp->fnum, -		  fsp->fsp_name, (int)len)); +	DEBUG(6, ("np_write: len: %d\n", (int)len));  	dump_data(50, data, len); -	switch (fsp->fake_file_handle->type) { +	switch (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); +			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); +			handle->private_data, struct np_proxy_state);  		*nwritten = write_data(p->fd, (char *)data, len);  		break;  	} @@ -1173,26 +1150,20 @@ NTSTATUS np_write(struct files_struct *fsp, const uint8_t *data, size_t len,  		? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;  } -NTSTATUS np_read(struct files_struct *fsp, uint8_t *data, size_t len, +NTSTATUS np_read(struct fake_file_handle *handle, uint8_t *data, size_t len,  		 ssize_t *nread, bool *is_data_outstanding)  { -	if (!fsp_is_np(fsp)) { -		return NT_STATUS_INVALID_HANDLE; -	} - -	switch (fsp->fake_file_handle->type) { +	switch (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); +			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); +			handle->private_data, struct np_proxy_state);  		int available = 0;  		*nread = sys_read(p->fd, (char *)data, len); diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index fabc8393ce..7c150561b1 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -220,8 +220,14 @@ static void api_rpc_trans_reply(connection_struct *conn,  		return;  	} -	status = np_read(fsp, rdata, max_trans_reply, &data_len, -			 &is_data_outstanding); +	if (!fsp_is_np(fsp)) { +		SAFE_FREE(rdata); +		api_no_reply(conn,req); +		return; +	} + +	status = np_read(fsp->fake_file_handle, rdata, max_trans_reply, +			 &data_len, &is_data_outstanding);  	if (!NT_STATUS_IS_OK(status)) {  		SAFE_FREE(rdata);  		api_no_reply(conn,req); @@ -355,7 +361,8 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,  	case TRANSACT_DCERPCCMD: {  		/* dce/rpc command */  		ssize_t nwritten; -		status = np_write(fsp, data, tdscnt, &nwritten); +		status = np_write(fsp->fake_file_handle, data, tdscnt, +				  &nwritten);  		if (!NT_STATUS_IS_OK(status)) {  			api_no_reply(conn, req);  			return; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 63b4776fbc..1ee3edbdbe 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -316,7 +316,7 @@ static void nt_open_pipe(char *fname, connection_struct *conn,  	/* Strip \\ off the name. */  	fname++; -	status = np_open(req, fname, &fsp); +	status = open_np_file(req, fname, &fsp);  	if (!NT_STATUS_IS_OK(status)) {  		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {  			reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4841882cc3..b148cff045 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -32,6 +32,40 @@  #define MAX_PIPE_NAME_LEN	24 +NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, +		      struct files_struct **pfsp) +{ +	struct connection_struct *conn = smb_req->conn; +	struct files_struct *fsp; +	NTSTATUS status; + +	status = file_new(smb_req, conn, &fsp); +	if (!NT_STATUS_IS_OK(status)) { +		DEBUG(0, ("file_new failed: %s\n", nt_errstr(status))); +		return status; +	} + +	fsp->conn = conn; +	fsp->fh->fd = -1; +	fsp->vuid = smb_req->vuid; +	fsp->can_lock = false; +	fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA; +	string_set(&fsp->fsp_name, name); + +	status = np_open(NULL, name, conn->client_address, +			 conn->server_info, &fsp->fake_file_handle); +	if (!NT_STATUS_IS_OK(status)) { +		DEBUG(10, ("np_open(%s) returned %s\n", name, +			   nt_errstr(status))); +		file_free(smb_req, fsp); +		return status; +	} + +	*pfsp = fsp; + +	return NT_STATUS_OK; +} +  /****************************************************************************   Reply to an open and X on a named pipe.   This code is basically stolen from reply_open_and_X with some @@ -77,7 +111,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)  	}  #endif -	status = np_open(req, fname, &fsp); +	status = open_np_file(req, fname, &fsp);  	if (!NT_STATUS_IS_OK(status)) {  		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {  			reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, @@ -133,7 +167,14 @@ void reply_pipe_write(struct smb_request *req)  		nwritten = 0;  	} else {  		NTSTATUS status; -		status = np_write(fsp, data, numtowrite, &nwritten); +		if (!fsp_is_np(fsp)) { +			reply_nterror(req, NT_STATUS_INVALID_HANDLE); +			return; +		} +		DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", +			  (int)fsp->fnum, fsp->fsp_name, (int)numtowrite)); +		status = np_write(fsp->fake_file_handle, data, numtowrite, +				  &nwritten);  		if (!NT_STATUS_IS_OK(status)) {  			reply_nterror(req, status);  			return; @@ -183,6 +224,9 @@ void reply_pipe_write_and_X(struct smb_request *req)  		return;  	} +	DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n", +		  (int)fsp->fnum, fsp->fsp_name, (int)numtowrite)); +  	data = (uint8_t *)smb_base(req->inbuf) + smb_doff;  	if (numtowrite == 0) { @@ -208,7 +252,8 @@ void reply_pipe_write_and_X(struct smb_request *req)  			data += 2;  			numtowrite -= 2;  		}                         -		status = np_write(fsp, data, numtowrite, &nwritten); +		status = np_write(fsp->fake_file_handle, data, numtowrite, +				  &nwritten);  		if (!NT_STATUS_IS_OK(status)) {  			reply_nterror(req, status);  			return; @@ -268,7 +313,8 @@ void reply_pipe_read_and_X(struct smb_request *req)  	data = (uint8_t *)smb_buf(req->outbuf); -	status = np_read(fsp, data, smb_maxcnt, &nread, &unused); +	status = np_read(fsp->fake_file_handle, data, smb_maxcnt, &nread, +			 &unused);  	if (!NT_STATUS_IS_OK(status)) {  		reply_doserror(req, ERRDOS, ERRnoaccess); | 
