1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-05 12:23:50 +03:00

r13829: 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
This commit is contained in:
Gerald Carter
2006-03-04 00:05:40 +00:00
committed by Gerald (Jerry) Carter
parent a444aa7f00
commit 6d74de7a67
5 changed files with 244 additions and 13 deletions

View File

@@ -348,6 +348,28 @@ typedef struct
#define SAMBA_PRINTER_PORT_NAME "Samba Printer Port" #define SAMBA_PRINTER_PORT_NAME "Samba Printer Port"
#endif #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 */ /* DOS header format */
#define DOS_HEADER_SIZE 64 #define DOS_HEADER_SIZE 64
#define DOS_HEADER_MAGIC_OFFSET 0 #define DOS_HEADER_MAGIC_OFFSET 0

View File

@@ -2174,7 +2174,23 @@ SPOOL_R_GETPRINTPROCESSORDIRECTORY;
/**************************************/ /**************************************/
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; POLICY_HND handle;
UNISTR2 dataname; UNISTR2 dataname;
RPC_BUFFER indata; RPC_BUFFER indata;
@@ -2183,7 +2199,7 @@ typedef struct spool_q_xcvdataport {
uint32 unknown; uint32 unknown;
} SPOOL_Q_XCVDATAPORT; } SPOOL_Q_XCVDATAPORT;
typedef struct spool_r_xcvdataport { typedef struct {
RPC_BUFFER outdata; RPC_BUFFER outdata;
uint32 needed; uint32 needed;
uint32 unknown; uint32 unknown;

View File

@@ -104,6 +104,7 @@ typedef struct {
char *unix_charset; char *unix_charset;
char *display_charset; char *display_charset;
char *szPrintcapname; char *szPrintcapname;
char *szAddPortCommand;
char *szEnumPortsCommand; char *szEnumPortsCommand;
char *szAddPrinterCommand; char *szAddPrinterCommand;
char *szDeletePrinterCommand; char *szDeletePrinterCommand;
@@ -1050,6 +1051,7 @@ static struct parm_struct parm_table[] = {
{"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, {"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}, {"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}, {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, 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}, {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
@@ -1763,6 +1765,7 @@ FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir) FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString) FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime) 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_enumports_cmd, &Globals.szEnumPortsCommand)
FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand) FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand) FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)

View File

@@ -7488,3 +7488,103 @@ BOOL make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
return True; 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;
}

View File

@@ -91,7 +91,7 @@ extern STANDARD_MAPPING printer_std_mapping, printserver_std_mapping;
struct xcv_api_table { struct xcv_api_table {
const char *name; 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 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
/**************************************************************************** /****************************************************************************
****************************************************************************/ ****************************************************************************/
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) BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
{ {
char *cmd = lp_addprinter_cmd(); char *cmd = lp_addprinter_cmd();
@@ -6025,6 +6071,7 @@ BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
return True; return True;
} }
/******************************************************************** /********************************************************************
* Called by spoolss_api_setprinter * Called by spoolss_api_setprinter
* when updating a printer description. * when updating a printer description.
@@ -9400,7 +9447,8 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
Streams the monitor UI DLL name in UNICODE 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"; const char *dllname = "tcpmonui.dll";
@@ -9417,16 +9465,54 @@ static WERROR xcvtcp_monitorui( RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed
return WERR_OK; return WERR_OK;
} }
/*******************************************************************
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[] = { struct xcv_api_table xcvtcp_cmds[] = {
{ "MonitorUI", xcvtcp_monitorui }, { "MonitorUI", xcvtcp_monitorui },
{ "AddPort", xcvtcp_addport},
{ NULL, NULL } { NULL, NULL }
}; };
static WERROR process_xcvtcp_command( const char *command, RPC_BUFFER *inbuf, static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command,
RPC_BUFFER *outbuf, uint32 *needed ) RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
uint32 *needed )
{ {
int i; int i;
@@ -9434,7 +9520,7 @@ static WERROR process_xcvtcp_command( const char *command, RPC_BUFFER *inbuf,
for ( i=0; xcvtcp_cmds[i].name; i++ ) { for ( i=0; xcvtcp_cmds[i].name; i++ ) {
if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 ) 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; return WERR_BADFUNC;
@@ -9443,7 +9529,8 @@ static WERROR process_xcvtcp_command( const char *command, RPC_BUFFER *inbuf,
/******************************************************************* /*******************************************************************
*******************************************************************/ *******************************************************************/
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"; const char *dllname = "localui.dll";
@@ -9472,8 +9559,9 @@ struct xcv_api_table xcvlocal_cmds[] = {
/******************************************************************* /*******************************************************************
*******************************************************************/ *******************************************************************/
static WERROR process_xcvlocal_command( const char *command, RPC_BUFFER *inbuf, static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command,
RPC_BUFFER *outbuf, uint32 *needed ) RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
uint32 *needed )
{ {
int i; int i;
@@ -9482,7 +9570,7 @@ static WERROR process_xcvlocal_command( const char *command, RPC_BUFFER *inbuf,
for ( i=0; xcvlocal_cmds[i].name; i++ ) { for ( i=0; xcvlocal_cmds[i].name; i++ ) {
if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 ) 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; return WERR_BADFUNC;
} }
@@ -9526,9 +9614,11 @@ WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_X
switch ( Printer->printer_type ) { switch ( Printer->printer_type ) {
case SPLHND_PORTMON_TCP: 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: 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; return WERR_INVALID_PRINT_MONITOR;