diff options
author | Gerald Carter <jerry@samba.org> | 2006-03-03 16:44:30 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:10:55 -0500 |
commit | e33b728c7b2076917e2149191222b259e5c1d942 (patch) | |
tree | 1144d7f4e0da8594598a77e015924e029356bdb0 | |
parent | a7552e677ed1c2df795c844987a7b7036c93bb35 (diff) | |
download | samba-e33b728c7b2076917e2149191222b259e5c1d942.tar.gz samba-e33b728c7b2076917e2149191222b259e5c1d942.tar.bz2 samba-e33b728c7b2076917e2149191222b259e5c1d942.zip |
r13815: "Into the blind world let us now descend,"
Began the poet, his face as pale as death.
"I will go first, and you will follow me."
---
Adding XcvDataPort() to the spoolss code for remotely
add ports. The design is to allow an intuitive means
of creating a new CUPS print queue from the Windows 2000/XP
APW without hacks like specifying the deviceURI in the
location field of the printer properties dialog.
Also set 'default devmode = yes' as the new default
since it causes no harm and only is executed when you
have a NULL devmode anyways.
(This used to be commit 123e478ce5b5f63a61d00197332b847e83722468)
-rw-r--r-- | source3/include/nt_printing.h | 1 | ||||
-rwxr-xr-x | source3/include/rpc_spoolss.h | 28 | ||||
-rw-r--r-- | source3/param/loadparm.c | 2 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 64 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 55 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 149 |
6 files changed, 161 insertions, 138 deletions
diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index f0d50878ce..7e3bd32003 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -423,6 +423,7 @@ typedef struct { #define PRINTER_HANDLE_IS_PRINTER 0 #define PRINTER_HANDLE_IS_PRINTSERVER 1 +#define PRINTER_HANDLE_IS_TCPMON 2 /* structure to store the printer handles */ /* and a reference to what it's pointing to */ diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 3b88f76588..347aca0e08 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -4,7 +4,7 @@ Copyright (C) Andrew Tridgell 1992-2000, Copyright (C) Luke Kenneth Casson Leighton 1996-2000, Copyright (C) Jean Francois Micouleau 1998-2000. - Copyright (C) Gerald Carter 2001-2005. + Copyright (C) Gerald Carter 2001-2006. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -107,8 +107,16 @@ #define SPOOLSS_DELETEPRINTERDATAEX 0x51 #define SPOOLSS_DELETEPRINTERKEY 0x52 #define SPOOLSS_DELETEPRINTERDRIVEREX 0x54 +#define SPOOLSS_XCVDATAPORT 0x58 #define SPOOLSS_ADDPRINTERDRIVEREX 0x59 +/* + * Special strings for the OpenPrinter() call. See the MSDN DDK + * docs on the XcvDataPort() for more details. + */ + +#define SPL_XCV_MONITOR_TCPMON ",XcvMonitor Standard TCP/IP Port" + #define PRINTER_CONTROL_UNPAUSE 0x00000000 #define PRINTER_CONTROL_PAUSE 0x00000001 @@ -2161,6 +2169,24 @@ typedef struct spool_r_getprintprocessordirectory } SPOOL_R_GETPRINTPROCESSORDIRECTORY; +/**************************************/ + +typedef struct spool_q_xcvdataport { + POLICY_HND handle; + UNISTR2 dataname; + RPC_BUFFER indata; + uint32 indata_len; + uint32 offered; + uint32 unknown; +} SPOOL_Q_XCVDATAPORT; + +typedef struct spool_r_xcvdataport { + RPC_BUFFER outdata; + uint32 *unknown1; + uint32 *unknown2; + WERROR status; +} SPOOL_R_XCVDATAPORT; + #define PRINTER_DRIVER_VERSION 2 #define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86" diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6d0eb46f23..ce4bef8d27 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -574,7 +574,7 @@ static service sDefault = { False, /* bInheritOwner */ True, /* bMSDfsRoot */ False, /* bUseClientDriver */ - False, /* bDefaultDevmode */ + True, /* bDefaultDevmode */ False, /* bForcePrintername */ True, /* bNTAclSupport */ False, /* bForceUnknownAclUser */ diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 45b683e9c6..6f3245243d 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -7406,3 +7406,67 @@ BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle, return True; } + + +/******************************************************************* + ********************************************************************/ + +BOOL spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + + if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if(!prs_rpcbuffer("", ps, depth, &q_u->indata)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len)) + return False; + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; + if (!prs_uint32("unknown", ps, depth, &q_u->unknown)) + return False; + + return True; +} + +/******************************************************************* + ********************************************************************/ + +BOOL spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport"); + depth++; + + if(!prs_align(ps)) + return False; + if(!prs_rpcbuffer("", ps, depth, &r_u->outdata)) + return False; + + if (!prs_align(ps)) + return False; + + if(!prs_pointer("unknown1", ps, depth, (void**)&r_u->unknown1, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_uint32)) + return False; + if(!prs_pointer("unknown2", ps, depth, (void**)&r_u->unknown2, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_uint32)) + return False; + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index b3a67dd6cf..0a43e8ae8a 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -1519,66 +1519,34 @@ static BOOL api_spoolss_deleteprinterdriverex(pipes_struct *p) return True; } -#if 0 - -/**************************************************************************** -****************************************************************************/ - -static BOOL api_spoolss_replyopenprinter(pipes_struct *p) -{ - SPOOL_Q_REPLYOPENPRINTER q_u; - SPOOL_R_REPLYOPENPRINTER r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!spoolss_io_q_replyopenprinter("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_replyopenprinter: unable to unmarshall SPOOL_Q_REPLYOPENPRINTER.\n")); - return False; - } - - r_u.status = _spoolss_replyopenprinter(p, &q_u, &r_u); - - if(!spoolss_io_r_replyopenprinter("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_replyopenprinter: unable to marshall SPOOL_R_REPLYOPENPRINTER.\n")); - return False; - } - - return True; -} - /**************************************************************************** ****************************************************************************/ -static BOOL api_spoolss_replycloseprinter(pipes_struct *p) +static BOOL api_spoolss_xcvdataport(pipes_struct *p) { - SPOOL_Q_REPLYCLOSEPRINTER q_u; - SPOOL_R_REPLYCLOSEPRINTER r_u; + SPOOL_Q_XCVDATAPORT q_u; + SPOOL_R_XCVDATAPORT r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - if(!spoolss_io_q_replycloseprinter("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_replycloseprinter: unable to unmarshall SPOOL_Q_REPLYCLOSEPRINTER.\n")); + if(!spoolss_io_q_xcvdataport("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_replyopenprinter: unable to unmarshall SPOOL_Q_XCVDATAPORT.\n")); return False; } - r_u.status = _spoolss_replycloseprinter(p, &q_u, &r_u); + r_u.status = _spoolss_xcvdataport(p, &q_u, &r_u); - if(!spoolss_io_r_replycloseprinter("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_replycloseprinter: unable to marshall SPOOL_R_REPLYCLOSEPRINTER.\n")); + if(!spoolss_io_r_xcvdataport("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_replyopenprinter: unable to marshall SPOOL_R_XCVDATAPORT.\n")); return False; } return True; } -#endif - /******************************************************************* \pipe\spoolss commands ********************************************************************/ @@ -1636,11 +1604,8 @@ static BOOL api_spoolss_replycloseprinter(pipes_struct *p) {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory}, {"SPOOLSS_ADDPRINTERDRIVEREX", SPOOLSS_ADDPRINTERDRIVEREX, api_spoolss_addprinterdriverex }, {"SPOOLSS_DELETEPRINTERDRIVEREX", SPOOLSS_DELETEPRINTERDRIVEREX, api_spoolss_deleteprinterdriverex }, -#if 0 - {"SPOOLSS_REPLYOPENPRINTER", SPOOLSS_REPLYOPENPRINTER, api_spoolss_replyopenprinter }, - {"SPOOLSS_REPLYCLOSEPRINTER", SPOOLSS_REPLYCLOSEPRINTER, api_spoolss_replycloseprinter } -#endif - }; + {"SPOOLSS_XCVDATAPORT", SPOOLSS_XCVDATAPORT, api_spoolss_xcvdataport }, +}; void spoolss_get_pipe_fns( struct api_struct **fns, int *n_fns ) { diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index c767daf88c..cfa0cc7cba 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -435,7 +435,10 @@ static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename } /**************************************************************************** - Set printer handle name. + Set printer handle name.. Accept names like \\server, \\server\printer, + \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See + the MSDN docs regarding OpenPrinter() for details on the XcvData() and + XcvDataPort() interface. ****************************************************************************/ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) @@ -477,6 +480,14 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) return False; DEBUGADD(5, ("searching for [%s]\n", aprinter )); + + /* check for the TCPMON interface */ + + if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) { + Printer->printer_type = PRINTER_HANDLE_IS_TCPMON; + fstrcpy(sname, SPL_XCV_MONITOR_TCPMON); + found = True; + } /* Search all sharenames first as this is easier than pulling the printer_info_2 off of disk. Don't use find_service() since @@ -1473,60 +1484,6 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R } /******************************************************************** - * spoolss_open_printer - * - * If the openprinterex rpc call contains a devmode, - * it's a per-user one. This per-user devmode is derivated - * from the global devmode. Openprinterex() contains a per-user - * devmode for when you do EMF printing and spooling. - * In the EMF case, the NT workstation is only doing half the job - * of rendering the page. The other half is done by running the printer - * driver on the server. - * The EMF file doesn't contain the page description (paper size, orientation, ...). - * The EMF file only contains what is to be printed on the page. - * So in order for the server to know how to print, the NT client sends - * a devicemode attached to the openprinterex call. - * But this devicemode is short lived, it's only valid for the current print job. - * - * If Samba would have supported EMF spooling, this devicemode would - * have been attached to the handle, to sent it to the driver to correctly - * rasterize the EMF file. - * - * As Samba only supports RAW spooling, we only receive a ready-to-print file, - * we just act as a pass-thru between windows and the printer. - * - * In order to know that Samba supports only RAW spooling, NT has to call - * getprinter() at level 2 (attribute field) or NT has to call startdoc() - * and until NT sends a RAW job, we refuse it. - * - * But to call getprinter() or startdoc(), you first need a valid handle, - * and to get an handle you have to call openprintex(). Hence why you have - * a devicemode in the openprinterex() call. - * - * - * Differences between NT4 and NT 2000. - * NT4: - * --- - * On NT4, you only have a global devicemode. This global devicemode can be changed - * by the administrator (or by a user with enough privs). Everytime a user - * wants to print, the devicemode is resetted to the default. In Word, everytime - * you print, the printer's characteristics are always reset to the global devicemode. - * - * NT 2000: - * ------- - * In W2K, there is the notion of per-user devicemode. The first time you use - * a printer, a per-user devicemode is build from the global devicemode. - * If you change your per-user devicemode, it is saved in the registry, under the - * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default - * printer preferences available. - * - * To change the per-user devicemode: it's the "Printing Preferences ..." button - * on the General Tab of the printer properties windows. - * - * To change the global devicemode: it's the "Printing Defaults..." button - * on the Advanced Tab of the printer properties window. - * - * JFM. ********************************************************************/ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u) @@ -1581,10 +1538,15 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, * Second case: the user is opening a printer: * NT doesn't let us connect to a printer if the connecting user * doesn't have print permission. + * + * Third case: user is opening the TCP/IP port monitor + * access checks same as opening a handle to the print server. */ - if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) + switch (Printer->printer_type ) { + case PRINTER_HANDLE_IS_PRINTSERVER: + case PRINTER_HANDLE_IS_TCPMON: /* Printserver handles use global struct... */ snum = -1; @@ -1642,10 +1604,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" )); /* We fall through to return WERR_OK */ - - } - else - { + break; + + case PRINTER_HANDLE_IS_PRINTER: /* NT doesn't let us connect to a printer if the connecting user doesn't have print permission. */ @@ -1702,6 +1663,11 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" )); + break; + + default: + /* sanity check to prevent programmer error */ + return WERR_BADFID; } Printer->access_granted = printer_default->access_required; @@ -8496,18 +8462,22 @@ WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - PRINTMONITOR_1 *info_1=NULL; + PRINTMONITOR_1 *info_1; WERROR result = WERR_OK; + int i; - if((info_1 = SMB_MALLOC_P(PRINTMONITOR_1)) == NULL) + if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL) return WERR_NOMEM; - (*returned) = 0x1; + *returned = 2; - init_unistr(&info_1->name, "Local Port"); - - *needed += spoolss_size_printmonitor_info_1(info_1); + init_unistr(&(info_1[0].name), "Local Port"); + init_unistr(&(info_1[1].name), "Standard TCP/IP Port"); + for ( i=0; i<*returned; i++ ) { + *needed += spoolss_size_printmonitor_info_1(&info_1[i]); + } + if (*needed > offered) { result = WERR_INSUFFICIENT_BUFFER; goto out; @@ -8518,7 +8488,9 @@ static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint goto out; } - smb_io_printmonitor_info_1("", buffer, info_1, 0); + for ( i=0; i<*returned; i++ ) { + smb_io_printmonitor_info_1("", buffer, &info_1[i], 0); + } out: SAFE_FREE(info_1); @@ -8535,20 +8507,27 @@ out: static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - PRINTMONITOR_2 *info_2=NULL; + PRINTMONITOR_2 *info_2; WERROR result = WERR_OK; + int i; - if((info_2 = SMB_MALLOC_P(PRINTMONITOR_2)) == NULL) + if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL) return WERR_NOMEM; - (*returned) = 0x1; + *returned = 2; - init_unistr(&info_2->name, "Local Port"); - init_unistr(&info_2->environment, "Windows NT X86"); - init_unistr(&info_2->dll_name, "localmon.dll"); - - *needed += spoolss_size_printmonitor_info_2(info_2); + init_unistr(&(info_2[0].name), "Local Port"); + init_unistr(&(info_2[0].environment), "Windows NT X86"); + init_unistr(&(info_2[0].dll_name), "localmon.dll"); + + init_unistr(&(info_2[1].name), "Standard TCP/IP Port"); + init_unistr(&(info_2[1].environment), "Windows NT X86"); + init_unistr(&(info_2[1].dll_name), "tcpmon.dll"); + for ( i=0; i<*returned; i++ ) { + *needed += spoolss_size_printmonitor_info_2(&info_2[i]); + } + if (*needed > offered) { result = WERR_INSUFFICIENT_BUFFER; goto out; @@ -8559,7 +8538,9 @@ static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint goto out; } - smb_io_printmonitor_info_2("", buffer, info_2, 0); + for ( i=0; i<*returned; i++ ) { + smb_io_printmonitor_info_2("", buffer, &info_2[i], 0); + } out: SAFE_FREE(info_2); @@ -9398,23 +9379,9 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC return result; } -#if 0 - -WERROR _spoolss_replyopenprinter(pipes_struct *p, SPOOL_Q_REPLYOPENPRINTER *q_u, - SPOOL_R_REPLYOPENPRINTER *r_u) +WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u) { - DEBUG(5,("_spoolss_replyopenprinter\n")); - - DEBUG(10, ("replyopenprinter for localprinter %d\n", q_u->printer)); - return WERR_OK; } -WERROR _spoolss_replycloseprinter(pipes_struct *p, SPOOL_Q_REPLYCLOSEPRINTER *q_u, - SPOOL_R_REPLYCLOSEPRINTER *r_u) -{ - DEBUG(5,("_spoolss_replycloseprinter\n")); - return WERR_OK; -} -#endif |