svn commit: samba r13829 - in branches/SAMBA_3_0/source: include param rpc_parse rpc_server

jerry at samba.org jerry at samba.org
Sat Mar 4 00:05:44 GMT 2006


Author: jerry
Date: 2006-03-04 00:05:40 +0000 (Sat, 04 Mar 2006)
New Revision: 13829

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=13829

Log:
>From the "It's not pretty but it works" category

* Finish prototype of the "add port command" implementation
  Format is "addportcommand portname deviceURI"

* DeviceURI is either 
  - socket://hostname:port/
  - lpr://hostname/queue
  depending on what the client sent in the request



Modified:
   branches/SAMBA_3_0/source/include/nt_printing.h
   branches/SAMBA_3_0/source/include/rpc_spoolss.h
   branches/SAMBA_3_0/source/param/loadparm.c
   branches/SAMBA_3_0/source/rpc_parse/parse_spoolss.c
   branches/SAMBA_3_0/source/rpc_server/srv_spoolss_nt.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/nt_printing.h
===================================================================
--- branches/SAMBA_3_0/source/include/nt_printing.h	2006-03-03 23:17:56 UTC (rev 13828)
+++ branches/SAMBA_3_0/source/include/nt_printing.h	2006-03-04 00:05:40 UTC (rev 13829)
@@ -348,6 +348,28 @@
 #define SAMBA_PRINTER_PORT_NAME "Samba Printer Port"
 #endif
 
+
+/*
+ * Structures for the XcvDataPort() calls
+ */
+
+#define PORT_PROTOCOL_DIRECT	1
+#define PORT_PROTOCOL_LPR	2
+
+typedef struct {
+	fstring name;
+	uint32 version;
+	uint32 protocol;
+	fstring hostaddr;
+	fstring snmpcommunity;
+	fstring queue;
+	uint32 dblspool;
+	fstring ipaddr;
+	uint32 port;
+	BOOL enable_snmp;
+	uint32 snmp_index;
+} NT_PORT_DATA_1;
+
 /* DOS header format */
 #define DOS_HEADER_SIZE                 64
 #define DOS_HEADER_MAGIC_OFFSET         0

Modified: branches/SAMBA_3_0/source/include/rpc_spoolss.h
===================================================================
--- branches/SAMBA_3_0/source/include/rpc_spoolss.h	2006-03-03 23:17:56 UTC (rev 13828)
+++ branches/SAMBA_3_0/source/include/rpc_spoolss.h	2006-03-04 00:05:40 UTC (rev 13829)
@@ -2174,7 +2174,23 @@
 
 /**************************************/
 
-typedef struct spool_q_xcvdataport {
+typedef struct {
+	UNISTR portname;	/* constant 64 wchars */
+	uint32 version;
+	uint32 protocol;
+	uint32 size;
+	uint32 reserved;
+	UNISTR hostaddress;	/* constant 49 wchars */
+	UNISTR snmpcommunity;	/* constant 33 wchars */
+	uint32 dblspool;
+	UNISTR queue;		/* constant 33 wchars */
+	UNISTR ipaddress;	/* constant 17 wchars */
+	uint32 port;
+	uint32 snmpenabled;
+	uint32 snmpdevindex;
+} SPOOL_PORT_DATA_1;
+
+typedef struct {
 	POLICY_HND handle;
 	UNISTR2 dataname;
 	RPC_BUFFER indata;
@@ -2183,7 +2199,7 @@
 	uint32 unknown;
 } SPOOL_Q_XCVDATAPORT;
 
-typedef struct spool_r_xcvdataport {
+typedef struct {
 	RPC_BUFFER outdata;
 	uint32 needed;
 	uint32 unknown;

Modified: branches/SAMBA_3_0/source/param/loadparm.c
===================================================================
--- branches/SAMBA_3_0/source/param/loadparm.c	2006-03-03 23:17:56 UTC (rev 13828)
+++ branches/SAMBA_3_0/source/param/loadparm.c	2006-03-04 00:05:40 UTC (rev 13829)
@@ -104,6 +104,7 @@
 	char *unix_charset;
 	char *display_charset;
 	char *szPrintcapname;
+	char *szAddPortCommand;
 	char *szEnumPortsCommand;
 	char *szAddPrinterCommand;
 	char *szDeletePrinterCommand;
@@ -1050,6 +1051,7 @@
 	{"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
 	{"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
 
+	{"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED}, 
 	{"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED}, 
 	{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
 	{"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
@@ -1763,6 +1765,7 @@
 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
+FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)

Modified: branches/SAMBA_3_0/source/rpc_parse/parse_spoolss.c
===================================================================
--- branches/SAMBA_3_0/source/rpc_parse/parse_spoolss.c	2006-03-03 23:17:56 UTC (rev 13828)
+++ branches/SAMBA_3_0/source/rpc_parse/parse_spoolss.c	2006-03-04 00:05:40 UTC (rev 13829)
@@ -7488,3 +7488,103 @@
 
 	return True;
 }
+
+/*******************************************************************
+ ********************************************************************/  
+
+static BOOL smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
+{
+	prs_struct *ps = &buf->prs;
+	uint8 *fodder;
+
+	prs_debug(ps, depth, desc, "smb_io_port_data_1");
+	depth++;
+
+	if(!prs_align(ps))
+		return False;	
+		
+	if ( UNMARSHALLING(ps) ) {
+		p1->portname.buffer = PRS_ALLOC_MEM( ps, uint16, 64 );
+		p1->hostaddress.buffer = PRS_ALLOC_MEM( ps, uint16, 49 );
+		p1->snmpcommunity.buffer = PRS_ALLOC_MEM( ps, uint16, 33 );
+		p1->queue.buffer = PRS_ALLOC_MEM( ps, uint16, 33 );
+		p1->ipaddress.buffer = PRS_ALLOC_MEM( ps, uint16, 17 );	
+		fodder = PRS_ALLOC_MEM( ps, uint8, 540 );	
+	}
+
+	if( !prs_uint16s(True, "portname", ps, depth, p1->portname.buffer, 64))
+		return False;
+
+	if (!prs_uint32("version", ps, depth, &p1->version))
+		return False;
+	if (!prs_uint32("protocol", ps, depth, &p1->protocol))
+		return False;
+	if (!prs_uint32("size", ps, depth, &p1->size))
+		return False;
+	if (!prs_uint32("reserved", ps, depth, &p1->reserved))
+		return False;
+
+	if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress.buffer, 49))
+		return False;
+	if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity.buffer, 33))
+		return False;
+
+	if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
+		return False;
+		
+	if( !prs_uint16s(True, "queue", ps, depth, p1->queue.buffer, 33))
+		return False;
+	if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress.buffer, 17))
+		return False;
+
+	/* fodder according to MSDN */
+	if( !prs_uint8s(False, "", ps, depth, fodder, 540))
+		return False;
+		
+	if (!prs_uint32("port", ps, depth, &p1->port))
+		return False;
+	if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
+		return False;
+	if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
+		return False;
+		
+	return True;
+}
+
+/*******************************************************************
+ ********************************************************************/  
+
+BOOL convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
+{
+	SPOOL_PORT_DATA_1 spdata_1;
+	
+	ZERO_STRUCT( spdata_1 );
+	
+	if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
+		return False;
+		
+	rpcstr_pull(port1->name, spdata_1.portname.buffer, sizeof(port1->name),
+		-1, 0);
+	rpcstr_pull(port1->queue, spdata_1.queue.buffer, sizeof(port1->queue), 
+		-1, 0);
+	rpcstr_pull(port1->hostaddr, spdata_1.hostaddress.buffer, 
+		sizeof(port1->hostaddr), -1, 0);
+	
+	port1->port = spdata_1.port;
+	
+	switch ( spdata_1.protocol ) {
+	case 1:
+		port1->protocol = PORT_PROTOCOL_DIRECT;
+		break;
+	case 2:
+		port1->protocol = PORT_PROTOCOL_LPR;
+		break;
+	default:
+		DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
+			spdata_1.protocol));
+		return False;
+	}
+
+	return True;
+}
+

Modified: branches/SAMBA_3_0/source/rpc_server/srv_spoolss_nt.c
===================================================================
--- branches/SAMBA_3_0/source/rpc_server/srv_spoolss_nt.c	2006-03-03 23:17:56 UTC (rev 13828)
+++ branches/SAMBA_3_0/source/rpc_server/srv_spoolss_nt.c	2006-03-04 00:05:40 UTC (rev 13829)
@@ -91,7 +91,7 @@
 
 struct xcv_api_table {
 	const char *name;
-	WERROR(*fn) (RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed);
+	WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed);
 };
 
 
@@ -5956,6 +5956,52 @@
 /****************************************************************************
 ****************************************************************************/
 
+WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri )
+{
+	char *cmd = lp_addport_cmd();
+	pstring command;
+	int ret;
+	int fd;
+	SE_PRIV se_printop = SE_PRINT_OPERATOR;
+	BOOL is_print_op = False;
+
+	if ( !*cmd ) {
+		return WERR_ACCESS_DENIED;
+	}
+		
+	slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", cmd, portname, uri );
+
+	if ( token )
+		is_print_op = user_has_privileges( token, &se_printop );
+
+	DEBUG(10,("Running [%s]\n", command));
+
+	/********* BEGIN SePrintOperatorPrivilege **********/
+
+	if ( is_print_op )
+		become_root();
+	
+	ret = smbrun(command, &fd);
+
+	if ( is_print_op )
+		unbecome_root();
+
+	/********* END SePrintOperatorPrivilege **********/
+
+	DEBUGADD(10,("returned [%d]\n", ret));
+
+	if ( ret != 0 ) {
+		if (fd != -1)
+			close(fd);
+		return WERR_ACCESS_DENIED;
+	}
+	
+	return WERR_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
 BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
 {
 	char *cmd = lp_addprinter_cmd();
@@ -6025,6 +6071,7 @@
 	return True;
 }
 
+
 /********************************************************************
  * Called by spoolss_api_setprinter
  * when updating a printer description.
@@ -9400,7 +9447,8 @@
  Streams the monitor UI DLL name in UNICODE
 *******************************************************************/
 
-static WERROR xcvtcp_monitorui( RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed )
+static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, 
+                                RPC_BUFFER *out, uint32 *needed )
 {
 	const char *dllname = "tcpmonui.dll";
 	
@@ -9418,15 +9466,53 @@
 }
 
 /*******************************************************************
+ Create a new TCP/IP port
 *******************************************************************/
 
+static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in, 
+                              RPC_BUFFER *out, uint32 *needed )
+{
+	NT_PORT_DATA_1 port1;
+	pstring device_uri;
+
+	ZERO_STRUCT( port1 );
+
+	/* convert to our internal port data structure */
+
+	if ( !convert_port_data_1( &port1, in ) ) {
+		return WERR_NOMEM;
+	}
+
+	/* create the device URI and call the add_port_hook() */
+
+	switch ( port1.protocol ) {
+	case PORT_PROTOCOL_DIRECT:
+		pstr_sprintf( device_uri, "socket://%s:%d/", port1.hostaddr, port1.port );
+		break;
+
+	case PORT_PROTOCOL_LPR:
+		pstr_sprintf( device_uri, "lpr://%s/%s", port1.hostaddr, port1.queue );
+		break;
+	
+	default:
+		return WERR_UNKNOWN_PORT;
+	}
+
+	return add_port_hook( token, port1.name, device_uri );
+}
+
+/*******************************************************************
+*******************************************************************/
+
 struct xcv_api_table xcvtcp_cmds[] = {
 	{ "MonitorUI",	xcvtcp_monitorui },
+	{ "AddPort",	xcvtcp_addport},
 	{ NULL,		NULL }
 };
 
-static WERROR process_xcvtcp_command( const char *command, RPC_BUFFER *inbuf,
-                                        RPC_BUFFER *outbuf, uint32 *needed )
+static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command, 
+                                      RPC_BUFFER *inbuf, RPC_BUFFER *outbuf, 
+                                      uint32 *needed )
 {
 	int i;
 	
@@ -9434,7 +9520,7 @@
 	
 	for ( i=0; xcvtcp_cmds[i].name; i++ ) {
 		if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
-			return xcvtcp_cmds[i].fn( inbuf, outbuf, needed );
+			return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed );
 	}
 	
 	return WERR_BADFUNC;
@@ -9443,7 +9529,8 @@
 /*******************************************************************
 *******************************************************************/
 
-static WERROR xcvlocal_monitorui( RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed )
+static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, 
+                                  RPC_BUFFER *out, uint32 *needed )
 {
 	const char *dllname = "localui.dll";
 	
@@ -9472,8 +9559,9 @@
 /*******************************************************************
 *******************************************************************/
 
-static WERROR process_xcvlocal_command( const char *command, RPC_BUFFER *inbuf, 
-                                        RPC_BUFFER *outbuf, uint32 *needed )
+static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command, 
+                                        RPC_BUFFER *inbuf, RPC_BUFFER *outbuf, 
+					uint32 *needed )
 {
 	int i;
 	
@@ -9482,7 +9570,7 @@
 
 	for ( i=0; xcvlocal_cmds[i].name; i++ ) {
 		if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
-			return xcvlocal_cmds[i].fn( inbuf, outbuf , needed );
+			return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed );
 	}
 	return WERR_BADFUNC;
 }
@@ -9526,9 +9614,11 @@
 	
 	switch ( Printer->printer_type ) {
 	case SPLHND_PORTMON_TCP:
-		return process_xcvtcp_command( command, &q_u->indata, &r_u->outdata, &r_u->needed );
+		return process_xcvtcp_command( p->pipe_user.nt_user_token, command, 
+			&q_u->indata, &r_u->outdata, &r_u->needed );
 	case SPLHND_PORTMON_LOCAL:
-		return process_xcvlocal_command( command, &q_u->indata, &r_u->outdata, &r_u->needed );
+		return process_xcvlocal_command( p->pipe_user.nt_user_token, command, 
+			&q_u->indata, &r_u->outdata, &r_u->needed );
 	}
 
 	return WERR_INVALID_PRINT_MONITOR;



More information about the samba-cvs mailing list