[PATCH 6/6] s3-spoolss: Add support for IPAddress and GetConfigInfo XcvData commands

Justin Chevrier jchevrier at gmail.com
Wed Aug 31 13:03:14 MDT 2011


Signed-off-by: Justin Chevrier <jchevrier at gmail.com>
---
 librpc/idl/spoolss.idl                      |    4 +
 source3/rpc_server/spoolss/srv_spoolss_nt.c |  154 ++++++++++++++++++++++++---
 2 files changed, 144 insertions(+), 14 deletions(-)

diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl
index 46efe69..7cec577 100644
--- a/librpc/idl/spoolss.idl
+++ b/librpc/idl/spoolss.idl
@@ -3053,6 +3053,10 @@ cpp_quote("#define spoolss_security_descriptor security_descriptor")
 		nstring dll_name;
 	} spoolss_MonitorUi;
 
+	typedef [public] struct {
+		nstring ip_address;
+	} spoolss_IPAddress;
+
 	WERROR spoolss_XcvData(
 		[in,ref] policy_handle *handle,
 		[in] [string,charset(UTF16)] uint16 function_name[],
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index db1d96a..6e2b57b 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -166,7 +166,9 @@ const struct standard_mapping printserver_std_mapping = {
 
 struct xcv_api_table {
 	const char *name;
-	WERROR(*fn) (TALLOC_CTX *mem_ctx, struct security_token *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
+	WERROR(*fn) (TALLOC_CTX *mem_ctx, const struct auth_session_info *session_info,
+	struct messaging_context *msg_ctx, struct security_token *token, const char *printername,
+	DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
 };
 
 static void prune_printername_cache(void);
@@ -10078,7 +10080,10 @@ static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
 *******************************************************************/
 
 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
-			       struct security_token *token, DATA_BLOB *in,
+			       const struct auth_session_info *session_info,
+			       struct messaging_context *msg_ctx,
+			       struct security_token *token,
+			       const char *printername, DATA_BLOB *in,
 			       DATA_BLOB *out, uint32_t *needed)
 {
 	const char *dllname = "tcpmonui.dll";
@@ -10099,6 +10104,21 @@ static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
 /*******************************************************************
  ********************************************************************/
 
+static bool push_port_data_1(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
+			     struct spoolss_PortData1 *port1)
+{
+	enum ndr_err_code ndr_err;
+	ndr_err = ndr_push_struct_blob(buf, mem_ctx, port1,
+		       (ndr_push_flags_fn_t)ndr_push_spoolss_PortData1);
+	if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
+		NDR_PRINT_DEBUG(spoolss_PortData1, port1);
+	}
+	return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
+}
+
+/*******************************************************************
+ ********************************************************************/
+
 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
 			     struct spoolss_PortData1 *port1,
 			     const DATA_BLOB *buf)
@@ -10133,8 +10153,11 @@ static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
 *******************************************************************/
 
 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
-			     struct security_token *token, DATA_BLOB *in,
-			     DATA_BLOB *out, uint32_t *needed)
+			     const struct auth_session_info *session_info,
+			     struct messaging_context *msg_ctx,
+			     struct security_token *token,
+			     const char *printername,
+			     DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed)
 {
 	struct spoolss_PortData1 port1;
 	struct spoolss_PortData2 port2;
@@ -10216,16 +10239,110 @@ static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
 }
 
 /*******************************************************************
+ Streams the PortData1 structure of the port
+*******************************************************************/
+
+static WERROR xcvtcp_getconfiginfo(TALLOC_CTX *mem_ctx,
+				   const struct auth_session_info *session_info,
+				   struct messaging_context *msg_ctx,
+				   struct security_token *token,
+				   const char *printername, DATA_BLOB *in,
+				   DATA_BLOB *out, uint32_t *needed)
+{
+	WERROR result;
+	struct spoolss_PortData1 *port1 = NULL;
+	/* Windows appears to set needed to 0 */
+	*needed = 0;
+
+	result = winreg_get_port_internal(mem_ctx,
+					  session_info,
+					  msg_ctx,
+					  printername,
+					  &port1);
+
+	if (!W_ERROR_IS_OK(result)) {
+		return WERR_UNKNOWN_PORT;
+	}
+
+	if (!push_port_data_1(mem_ctx, out, port1)) {
+		return WERR_NOMEM;
+	}
+
+	TALLOC_FREE(port1);
+
+	return WERR_OK;
+}
+
+/*******************************************************************
+ ********************************************************************/
+ 
+static bool push_ipaddress_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
+			       const char *ipaddress)
+{
+	enum ndr_err_code ndr_err;
+	struct spoolss_IPAddress ip;
+
+	ip.ip_address = ipaddress;
+
+	ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ip,
+		       (ndr_push_flags_fn_t)ndr_push_spoolss_IPAddress);
+	if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
+		NDR_PRINT_DEBUG(spoolss_IPAddress, &ip);
+	}
+	return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
+}
+
+/*******************************************************************
+ Streams the IP Address of the port
+*******************************************************************/
+
+static WERROR xcvtcp_ipaddress(TALLOC_CTX *mem_ctx,
+			       const struct auth_session_info *session_info,
+			       struct messaging_context *msg_ctx,
+			       struct security_token *token,
+			       const char *printername, DATA_BLOB *in,
+			       DATA_BLOB *out, uint32_t *needed)
+{
+	WERROR result;
+	struct spoolss_PortData1 *port1 = NULL;
+	/* Windows appears to set needed to 0 */
+	*needed = 0;
+
+	result = winreg_get_port_internal(mem_ctx,
+					  session_info,
+					  msg_ctx,
+					  printername,
+					  &port1);
+
+	if (!W_ERROR_IS_OK(result)) {
+		return WERR_UNKNOWN_PORT;
+	}
+
+	if (!push_ipaddress_buf(mem_ctx, out, port1->ip_address)) {
+		return WERR_NOMEM;
+	}
+
+	TALLOC_FREE(port1);
+
+	return WERR_OK;
+}
+
+/*******************************************************************
 *******************************************************************/
 
 struct xcv_api_table xcvtcp_cmds[] = {
-	{ "MonitorUI",	xcvtcp_monitorui },
-	{ "AddPort",	xcvtcp_addport},
-	{ NULL,		NULL }
+	{ "MonitorUI",		xcvtcp_monitorui },
+	{ "AddPort",		xcvtcp_addport },
+	{ "GetConfigInfo",	xcvtcp_getconfiginfo },
+	{ "IPAddress",		xcvtcp_ipaddress },
+	{ NULL,			NULL }
 };
 
 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
+				     const struct auth_session_info *session_info,
+				     struct messaging_context *msg_ctx,
 				     struct security_token *token, const char *command,
+				     const char *printername,
 				     DATA_BLOB *inbuf,
 				     DATA_BLOB *outbuf,
 				     uint32_t *needed )
@@ -10236,7 +10353,7 @@ static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
 
 	for ( i=0; xcvtcp_cmds[i].name; i++ ) {
 		if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
-			return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
+			return xcvtcp_cmds[i].fn(mem_ctx, session_info, msg_ctx, token, printername, inbuf, outbuf, needed);
 	}
 
 	return WERR_BADFUNC;
@@ -10247,7 +10364,7 @@ static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
 #if 0 	/* don't support management using the "Local Port" monitor */
 
 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
-				 struct security_token *token, DATA_BLOB *in,
+				 struct security_token *token, const char *printername, DATA_BLOB *in,
 				 DATA_BLOB *out, uint32_t *needed)
 {
 	const char *dllname = "localui.dll";
@@ -10284,8 +10401,10 @@ struct xcv_api_table xcvlocal_cmds[] = {
 *******************************************************************/
 
 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
+				       const struct auth_session_info *session_info,
+				       struct messaging_context *msg_ctx,
 				       struct security_token *token, const char *command,
-				       DATA_BLOB *inbuf, DATA_BLOB *outbuf,
+				       const char *printername, DATA_BLOB *inbuf, DATA_BLOB *outbuf,
 				       uint32_t *needed)
 {
 	int i;
@@ -10294,7 +10413,7 @@ static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
 
 	for ( i=0; xcvlocal_cmds[i].name; i++ ) {
 		if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
-			return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
+			return xcvlocal_cmds[i].fn(mem_ctx, session_info, msg_ctx, token, printername, inbuf, outbuf, needed);
 	}
 	return WERR_BADFUNC;
 }
@@ -10323,9 +10442,10 @@ WERROR _spoolss_XcvData(struct pipes_struct *p,
 		return WERR_BADFID;
 	}
 
-	/* requires administrative access to the server */
-
-	if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
+	/* AddPort, ConfigPort, DeletePort and MonitorUI require administrative access to the server */
+	if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) && 
+	      (strequal(r->in.function_name, "AddPort") || strequal(r->in.function_name, "ConfigPort") ||
+	       strequal(r->in.function_name, "DeletePort") || strequal(r->in.function_name, "MonitorUI")) ) {
 		DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
 		return WERR_ACCESS_DENIED;
 	}
@@ -10342,15 +10462,21 @@ WERROR _spoolss_XcvData(struct pipes_struct *p,
 	switch ( Printer->printer_type ) {
 	case SPLHND_PORTMON_TCP:
 		werror = process_xcvtcp_command(p->mem_ctx,
+						p->session_info,
+					        p->msg_ctx,
 						p->session_info->security_token,
 						r->in.function_name,
+						Printer->sharename,
 						&r->in.in_data, &out_data,
 						r->out.needed);
 		break;
 	case SPLHND_PORTMON_LOCAL:
 		werror = process_xcvlocal_command(p->mem_ctx,
+						  p->session_info,
+						  p->msg_ctx,
 						  p->session_info->security_token,
 						  r->in.function_name,
+						  Printer->sharename,
 						  &r->in.in_data, &out_data,
 						  r->out.needed);
 		break;
-- 
1.7.3.4



More information about the samba-technical mailing list