2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009-2010.
11 * Copyright (C) Andreas Schneider 2010.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
39 #include "registry/reg_objects.h"
40 #include "include/printing.h"
42 #include "../librpc/gen_ndr/netlogon.h"
44 /* macros stolen from s4 spoolss server */
45 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
46 ((info)?ndr_size_##fn(info, level, 0):0)
48 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
49 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
51 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
52 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
54 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
57 #define DBGC_CLASS DBGC_RPC_SRV
59 static Printer_entry
*printers_list
;
61 typedef struct _counter_printer_0
{
62 struct _counter_printer_0
*next
;
63 struct _counter_printer_0
*prev
;
69 static counter_printer_0
*counter_list
;
71 static struct rpc_pipe_client
*notify_cli_pipe
; /* print notify back-channel pipe handle*/
72 static uint32_t smb_connections
= 0;
75 /* Map generic permissions to printer object specific permissions */
77 const struct standard_mapping printer_std_mapping
= {
84 /* Map generic permissions to print server object specific permissions */
86 const struct standard_mapping printserver_std_mapping
= {
93 /* API table for Xcv Monitor functions */
95 struct xcv_api_table
{
97 WERROR(*fn
) (TALLOC_CTX
*mem_ctx
, NT_USER_TOKEN
*token
, DATA_BLOB
*in
, DATA_BLOB
*out
, uint32_t *needed
);
100 static void prune_printername_cache(void);
102 /********************************************************************
103 * Canonicalize servername.
104 ********************************************************************/
106 static const char *canon_servername(const char *servername
)
108 const char *pservername
= servername
;
109 while (*pservername
== '\\') {
115 /* translate between internal status numbers and NT status numbers */
116 static int nt_printj_status(int v
)
122 return JOB_STATUS_PAUSED
;
124 return JOB_STATUS_SPOOLING
;
126 return JOB_STATUS_PRINTING
;
128 return JOB_STATUS_ERROR
;
130 return JOB_STATUS_DELETING
;
132 return JOB_STATUS_OFFLINE
;
134 return JOB_STATUS_PAPEROUT
;
136 return JOB_STATUS_PRINTED
;
138 return JOB_STATUS_DELETED
;
140 return JOB_STATUS_BLOCKED_DEVQ
;
141 case LPQ_USER_INTERVENTION
:
142 return JOB_STATUS_USER_INTERVENTION
;
147 static int nt_printq_status(int v
)
151 return PRINTER_STATUS_PAUSED
;
160 /***************************************************************************
161 Disconnect from the client
162 ****************************************************************************/
164 static void srv_spoolss_replycloseprinter(int snum
, struct policy_handle
*handle
)
170 * Tell the specific printing tdb we no longer want messages for this printer
171 * by deregistering our PID.
174 if (!print_notify_deregister_pid(snum
))
175 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum
) ));
177 /* weird if the test succeds !!! */
178 if (smb_connections
==0) {
179 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
183 status
= rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe
, talloc_tos(),
186 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
187 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
188 win_errstr(result
)));
190 /* if it's the last connection, deconnect the IPC$ share */
191 if (smb_connections
==1) {
193 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe
) );
194 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
196 messaging_deregister(smbd_messaging_context(),
197 MSG_PRINTER_NOTIFY2
, NULL
);
199 /* Tell the connections db we're no longer interested in
200 * printer notify messages. */
202 serverid_register_msg_flags(
203 messaging_server_id(smbd_messaging_context()),
204 false, FLAG_MSG_PRINT_NOTIFY
);
210 /****************************************************************************
211 Functions to free a printer entry datastruct.
212 ****************************************************************************/
214 static int printer_entry_destructor(Printer_entry
*Printer
)
216 if (Printer
->notify
.client_connected
== true) {
219 if ( Printer
->printer_type
== SPLHND_SERVER
) {
221 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
222 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
223 snum
= print_queue_snum(Printer
->sharename
);
225 srv_spoolss_replycloseprinter(snum
,
226 &Printer
->notify
.client_hnd
);
230 Printer
->notify
.flags
=0;
231 Printer
->notify
.options
=0;
232 Printer
->notify
.localmachine
[0]='\0';
233 Printer
->notify
.printerlocal
=0;
234 TALLOC_FREE(Printer
->notify
.option
);
235 Printer
->notify
.client_connected
= false;
237 TALLOC_FREE(Printer
->devmode
);
239 /* Remove from the internal list. */
240 DLIST_REMOVE(printers_list
, Printer
);
244 /****************************************************************************
245 find printer index by handle
246 ****************************************************************************/
248 static Printer_entry
*find_printer_index_by_hnd(struct pipes_struct
*p
,
249 struct policy_handle
*hnd
)
251 Printer_entry
*find_printer
= NULL
;
253 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
254 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
261 /****************************************************************************
262 Close printer index by handle.
263 ****************************************************************************/
265 static bool close_printer_handle(struct pipes_struct
*p
, struct policy_handle
*hnd
)
267 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
270 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
275 close_policy_hnd(p
, hnd
);
280 /****************************************************************************
281 Delete a printer given a handle.
282 ****************************************************************************/
284 static WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
286 char *cmd
= lp_deleteprinter_cmd();
287 char *command
= NULL
;
289 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
290 bool is_print_op
= false;
292 /* can't fail if we don't try */
297 command
= talloc_asprintf(ctx
,
304 is_print_op
= user_has_privileges( token
, &se_printop
);
306 DEBUG(10,("Running [%s]\n", command
));
308 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
313 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
314 /* Tell everyone we updated smb.conf. */
315 message_send_all(smbd_messaging_context(),
316 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
322 /********** END SePrintOperatorPrivlege BLOCK **********/
324 DEBUGADD(10,("returned [%d]\n", ret
));
326 TALLOC_FREE(command
);
329 return WERR_BADFID
; /* What to return here? */
331 /* go ahead and re-read the services immediately */
333 reload_services(false);
336 if ( lp_servicenumber( sharename
) >= 0 )
337 return WERR_ACCESS_DENIED
;
342 /****************************************************************************
343 Delete a printer given a handle.
344 ****************************************************************************/
346 static WERROR
delete_printer_handle(struct pipes_struct
*p
, struct policy_handle
*hnd
)
348 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
352 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
358 * It turns out that Windows allows delete printer on a handle
359 * opened by an admin user, then used on a pipe handle created
360 * by an anonymous user..... but they're working on security.... riiight !
364 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
365 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
366 return WERR_ACCESS_DENIED
;
369 /* this does not need a become root since the access check has been
370 done on the handle already */
372 result
= winreg_delete_printer_key(p
->mem_ctx
, p
->server_info
,
373 Printer
->sharename
, "");
374 if (!W_ERROR_IS_OK(result
)) {
375 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
379 result
= delete_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
380 Printer
->sharename
);
381 if (!W_ERROR_IS_OK(result
)) {
384 prune_printername_cache();
388 /****************************************************************************
389 Return the snum of a printer corresponding to an handle.
390 ****************************************************************************/
392 static bool get_printer_snum(struct pipes_struct
*p
, struct policy_handle
*hnd
,
393 int *number
, struct share_params
**params
)
395 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
398 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
403 switch (Printer
->printer_type
) {
405 DEBUG(4,("short name:%s\n", Printer
->sharename
));
406 *number
= print_queue_snum(Printer
->sharename
);
407 return (*number
!= -1);
415 /****************************************************************************
416 Set printer handle type.
417 Check if it's \\server or \\server\printer
418 ****************************************************************************/
420 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, const char *handlename
)
422 DEBUG(3,("Setting printer type=%s\n", handlename
));
424 /* it's a print server */
425 if (handlename
&& *handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
426 DEBUGADD(4,("Printer is a print server\n"));
427 Printer
->printer_type
= SPLHND_SERVER
;
429 /* it's a printer (set_printer_hnd_name() will handle port monitors */
431 DEBUGADD(4,("Printer is a printer\n"));
432 Printer
->printer_type
= SPLHND_PRINTER
;
438 static void prune_printername_cache_fn(const char *key
, const char *value
,
439 time_t timeout
, void *private_data
)
444 static void prune_printername_cache(void)
446 gencache_iterate(prune_printername_cache_fn
, NULL
, "PRINTERNAME/*");
449 /****************************************************************************
450 Set printer handle name.. Accept names like \\server, \\server\printer,
451 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
452 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
453 XcvDataPort() interface.
454 ****************************************************************************/
456 static bool set_printer_hnd_name(TALLOC_CTX
*mem_ctx
,
457 struct auth_serversupplied_info
*server_info
,
458 Printer_entry
*Printer
,
459 const char *handlename
)
462 int n_services
=lp_numservices();
464 const char *printername
;
465 const char *servername
= NULL
;
468 struct spoolss_PrinterInfo2
*info2
= NULL
;
472 * Hopefully nobody names his printers like this. Maybe \ or ,
473 * are illegal in printer names even?
475 const char printer_not_found
[] = "Printer \\, !@#$%^&*( not found";
479 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
,
480 (unsigned long)strlen(handlename
)));
482 aprinter
= CONST_DISCARD(char *, handlename
);
483 if ( *handlename
== '\\' ) {
484 servername
= canon_servername(handlename
);
485 if ( (aprinter
= strchr_m( servername
, '\\' )) != NULL
) {
489 if (!is_myname_or_ipaddr(servername
)) {
493 fstrcpy(Printer
->servername
, servername
);
496 if (Printer
->printer_type
== SPLHND_SERVER
) {
500 if (Printer
->printer_type
!= SPLHND_PRINTER
) {
504 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
506 /* check for the Port Monitor Interface */
507 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
508 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
509 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
512 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
513 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
514 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
519 * With hundreds of printers, the "for" loop iterating all
520 * shares can be quite expensive, as it is done on every
521 * OpenPrinter. The loop maps "aprinter" to "sname", the
522 * result of which we cache in gencache.
525 cache_key
= talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
527 if ((cache_key
!= NULL
) && gencache_get(cache_key
, &tmp
, NULL
)) {
529 found
= (strcmp(tmp
, printer_not_found
) != 0);
531 DEBUG(4, ("Printer %s not found\n", aprinter
));
539 /* Search all sharenames first as this is easier than pulling
540 the printer_info_2 off of disk. Don't use find_service() since
541 that calls out to map_username() */
543 /* do another loop to look for printernames */
544 for (snum
= 0; !found
&& snum
< n_services
; snum
++) {
545 const char *printer
= lp_const_servicename(snum
);
547 /* no point going on if this is not a printer */
548 if (!(lp_snum_ok(snum
) && lp_print_ok(snum
))) {
552 /* ignore [printers] share */
553 if (strequal(printer
, "printers")) {
557 fstrcpy(sname
, printer
);
558 if (strequal(aprinter
, printer
)) {
563 /* no point looking up the printer object if
564 we aren't allowing printername != sharename */
565 if (lp_force_printername(snum
)) {
569 result
= winreg_get_printer(mem_ctx
,
574 if ( !W_ERROR_IS_OK(result
) ) {
575 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
576 sname
, win_errstr(result
)));
580 printername
= strrchr(info2
->printername
, '\\');
581 if (printername
== NULL
) {
582 printername
= info2
->printername
;
587 if (strequal(printername
, aprinter
)) {
592 DEBUGADD(10, ("printername: %s\n", printername
));
598 if (cache_key
!= NULL
) {
599 gencache_set(cache_key
, printer_not_found
,
601 TALLOC_FREE(cache_key
);
603 DEBUGADD(4,("Printer not found\n"));
607 if (cache_key
!= NULL
) {
608 gencache_set(cache_key
, sname
, time(NULL
)+300);
609 TALLOC_FREE(cache_key
);
612 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
614 fstrcpy(Printer
->sharename
, sname
);
619 /****************************************************************************
620 Find first available printer slot. creates a printer handle for you.
621 ****************************************************************************/
623 static bool open_printer_hnd(struct pipes_struct
*p
, struct policy_handle
*hnd
,
624 const char *name
, uint32_t access_granted
)
626 Printer_entry
*new_printer
;
628 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
630 new_printer
= TALLOC_ZERO_P(NULL
, Printer_entry
);
631 if (new_printer
== NULL
) {
634 talloc_set_destructor(new_printer
, printer_entry_destructor
);
636 if (!create_policy_hnd(p
, hnd
, new_printer
)) {
637 TALLOC_FREE(new_printer
);
641 /* Add to the internal list. */
642 DLIST_ADD(printers_list
, new_printer
);
644 new_printer
->notify
.option
=NULL
;
646 if (!set_printer_hnd_printertype(new_printer
, name
)) {
647 close_printer_handle(p
, hnd
);
651 if (!set_printer_hnd_name(p
->mem_ctx
, p
->server_info
, new_printer
, name
)) {
652 close_printer_handle(p
, hnd
);
656 new_printer
->access_granted
= access_granted
;
658 DEBUG(5, ("%d printer handles active\n",
659 (int)num_pipe_handles(p
)));
664 /***************************************************************************
665 check to see if the client motify handle is monitoring the notification
666 given by (notify_type, notify_field).
667 **************************************************************************/
669 static bool is_monitoring_event_flags(uint32_t flags
, uint16_t notify_type
,
670 uint16_t notify_field
)
675 static bool is_monitoring_event(Printer_entry
*p
, uint16_t notify_type
,
676 uint16_t notify_field
)
678 struct spoolss_NotifyOption
*option
= p
->notify
.option
;
682 * Flags should always be zero when the change notify
683 * is registered by the client's spooler. A user Win32 app
684 * might use the flags though instead of the NOTIFY_OPTION_INFO
693 return is_monitoring_event_flags(
694 p
->notify
.flags
, notify_type
, notify_field
);
696 for (i
= 0; i
< option
->count
; i
++) {
698 /* Check match for notify_type */
700 if (option
->types
[i
].type
!= notify_type
)
703 /* Check match for field */
705 for (j
= 0; j
< option
->types
[i
].count
; j
++) {
706 if (option
->types
[i
].fields
[j
].field
== notify_field
) {
712 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
713 p
->servername
, p
->sharename
, notify_type
, notify_field
));
718 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
719 _data->data.integer[0] = _integer; \
720 _data->data.integer[1] = 0;
723 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
724 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
725 if (!_data->data.string.string) {\
726 _data->data.string.size = 0; \
728 _data->data.string.size = strlen_m_term(_p) * 2;
730 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
731 _data->data.devmode.devmode = _devmode;
733 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
734 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
735 if (!_data->data.sd.sd) { \
736 _data->data.sd.sd_size = 0; \
738 _data->data.sd.sd_size = \
739 ndr_size_security_descriptor(_data->data.sd.sd, 0);
741 static void init_systemtime_buffer(TALLOC_CTX
*mem_ctx
,
746 struct spoolss_Time st
;
750 if (!init_systemtime(&st
, t
)) {
754 p
= talloc_array(mem_ctx
, char, len
);
760 * Systemtime must be linearized as a set of UINT16's.
761 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
764 SSVAL(p
, 0, st
.year
);
765 SSVAL(p
, 2, st
.month
);
766 SSVAL(p
, 4, st
.day_of_week
);
768 SSVAL(p
, 8, st
.hour
);
769 SSVAL(p
, 10, st
.minute
);
770 SSVAL(p
, 12, st
.second
);
771 SSVAL(p
, 14, st
.millisecond
);
777 /* Convert a notification message to a struct spoolss_Notify */
779 static void notify_one_value(struct spoolss_notify_msg
*msg
,
780 struct spoolss_Notify
*data
,
783 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, msg
->notify
.value
[0]);
786 static void notify_string(struct spoolss_notify_msg
*msg
,
787 struct spoolss_Notify
*data
,
790 /* The length of the message includes the trailing \0 */
792 data
->data
.string
.size
= msg
->len
* 2;
793 data
->data
.string
.string
= talloc_strdup(mem_ctx
, msg
->notify
.data
);
794 if (!data
->data
.string
.string
) {
795 data
->data
.string
.size
= 0;
800 static void notify_system_time(struct spoolss_notify_msg
*msg
,
801 struct spoolss_Notify
*data
,
804 data
->data
.string
.string
= NULL
;
805 data
->data
.string
.size
= 0;
807 if (msg
->len
!= sizeof(time_t)) {
808 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
813 init_systemtime_buffer(mem_ctx
, gmtime((time_t *)msg
->notify
.data
),
814 &data
->data
.string
.string
,
815 &data
->data
.string
.size
);
818 struct notify2_message_table
{
820 void (*fn
)(struct spoolss_notify_msg
*msg
,
821 struct spoolss_Notify
*data
, TALLOC_CTX
*mem_ctx
);
824 static struct notify2_message_table printer_notify_table
[] = {
825 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string
},
826 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string
},
827 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string
},
828 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string
},
829 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string
},
830 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string
},
831 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string
},
832 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL
},
833 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string
},
834 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string
},
835 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL
},
836 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string
},
837 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL
},
838 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value
},
839 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value
},
840 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL
},
841 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL
},
842 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL
},
843 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value
},
846 static struct notify2_message_table job_notify_table
[] = {
847 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL
},
848 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL
},
849 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL
},
850 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string
},
851 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL
},
852 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL
},
853 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL
},
854 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL
},
855 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL
},
856 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL
},
857 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value
},
858 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL
},
859 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL
},
860 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string
},
861 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL
},
862 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL
},
863 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time
},
864 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL
},
865 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL
},
866 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL
},
867 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value
},
868 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL
},
869 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value
},
870 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL
},
874 /***********************************************************************
875 Allocate talloc context for container object
876 **********************************************************************/
878 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
883 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
888 /***********************************************************************
889 release all allocated memory and zero out structure
890 **********************************************************************/
892 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
898 talloc_destroy(ctr
->ctx
);
905 /***********************************************************************
906 **********************************************************************/
908 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
916 /***********************************************************************
917 **********************************************************************/
919 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32_t idx
)
921 if ( !ctr
|| !ctr
->msg_groups
)
924 if ( idx
>= ctr
->num_groups
)
927 return &ctr
->msg_groups
[idx
];
931 /***********************************************************************
932 How many groups of change messages do we have ?
933 **********************************************************************/
935 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
940 return ctr
->num_groups
;
943 /***********************************************************************
944 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
945 **********************************************************************/
947 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
949 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
950 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
951 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
957 /* loop over all groups looking for a matching printer name */
959 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
960 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
964 /* add a new group? */
966 if ( i
== ctr
->num_groups
) {
969 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
970 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
973 ctr
->msg_groups
= groups
;
975 /* clear the new entry and set the printer name */
977 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
978 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
981 /* add the change messages; 'i' is the correct index now regardless */
983 msg_grp
= &ctr
->msg_groups
[i
];
987 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
988 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
991 msg_grp
->msgs
= msg_list
;
993 new_slot
= msg_grp
->num_msgs
-1;
994 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
996 /* need to allocate own copy of data */
999 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
1000 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
1002 return ctr
->num_groups
;
1005 static void construct_info_data(struct spoolss_Notify
*info_data
,
1006 enum spoolss_NotifyType type
,
1007 uint16_t field
, int id
);
1009 /***********************************************************************
1010 Send a change notication message on all handles which have a call
1012 **********************************************************************/
1014 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32_t idx
)
1017 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
1018 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
1019 SPOOLSS_NOTIFY_MSG
*messages
;
1020 int sending_msg_count
;
1023 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1027 messages
= msg_group
->msgs
;
1030 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
1034 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
1036 /* loop over all printers */
1038 for (p
= printers_list
; p
; p
= p
->next
) {
1039 struct spoolss_Notify
*notifies
;
1044 /* Is there notification on this handle? */
1046 if ( !p
->notify
.client_connected
)
1049 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
1051 /* For this printer? Print servers always receive
1054 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
1055 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
1058 DEBUG(10,("Our printer\n"));
1060 /* allocate the max entries possible */
1062 notifies
= TALLOC_ZERO_ARRAY(mem_ctx
, struct spoolss_Notify
, msg_group
->num_msgs
);
1067 /* build the array of change notifications */
1069 sending_msg_count
= 0;
1071 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
1072 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
1074 /* Are we monitoring this event? */
1076 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1079 sending_msg_count
++;
1082 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1083 msg
->type
, msg
->field
, p
->sharename
));
1086 * if the is a printer notification handle and not a job notification
1087 * type, then set the id to 0. Other wise just use what was specified
1090 * When registering change notification on a print server handle
1091 * we always need to send back the id (snum) matching the printer
1092 * for which the change took place. For change notify registered
1093 * on a printer handle, this does not matter and the id should be 0.
1098 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1104 /* Convert unix jobid to smb jobid */
1106 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1107 id
= sysjob_to_jobid(msg
->id
);
1110 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1115 construct_info_data( ¬ifies
[count
], msg
->type
, msg
->field
, id
);
1118 case PRINTER_NOTIFY_TYPE
:
1119 if ( printer_notify_table
[msg
->field
].fn
)
1120 printer_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1123 case JOB_NOTIFY_TYPE
:
1124 if ( job_notify_table
[msg
->field
].fn
)
1125 job_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1129 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1136 if ( sending_msg_count
) {
1139 union spoolss_ReplyPrinterInfo info
;
1140 struct spoolss_NotifyInfo info0
;
1141 uint32_t reply_result
;
1143 info0
.version
= 0x2;
1144 info0
.flags
= count
? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED
;
1145 info0
.count
= count
;
1146 info0
.notifies
= notifies
;
1148 info
.info0
= &info0
;
1150 status
= rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe
, mem_ctx
,
1151 &p
->notify
.client_hnd
,
1152 p
->notify
.change
, /* color */
1155 0, /* reply_type, must be 0 */
1158 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(werr
)) {
1159 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1160 notify_cli_pipe
->srv_name_slash
,
1163 switch (reply_result
) {
1166 case PRINTER_NOTIFY_INFO_DISCARDED
:
1167 case PRINTER_NOTIFY_INFO_DISCARDNOTED
:
1168 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH
:
1177 DEBUG(8,("send_notify2_changes: Exit...\n"));
1181 /***********************************************************************
1182 **********************************************************************/
1184 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1187 uint32_t tv_sec
, tv_usec
;
1190 /* Unpack message */
1192 offset
+= tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "f",
1195 offset
+= tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "ddddddd",
1197 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1200 tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "dd",
1201 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1203 tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "B",
1204 &msg
->len
, &msg
->notify
.data
);
1206 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1207 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1209 tv
->tv_sec
= tv_sec
;
1210 tv
->tv_usec
= tv_usec
;
1213 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1214 msg
->notify
.value
[1]));
1216 dump_data(3, (uint8_t *)msg
->notify
.data
, msg
->len
);
1221 /********************************************************************
1222 Receive a notify2 message list
1223 ********************************************************************/
1225 static void receive_notify2_message_list(struct messaging_context
*msg
,
1228 struct server_id server_id
,
1231 size_t msg_count
, i
;
1232 char *buf
= (char *)data
->data
;
1235 SPOOLSS_NOTIFY_MSG notify
;
1236 SPOOLSS_NOTIFY_MSG_CTR messages
;
1239 if (data
->length
< 4) {
1240 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1244 msg_count
= IVAL(buf
, 0);
1247 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1249 if (msg_count
== 0) {
1250 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1254 /* initialize the container */
1256 ZERO_STRUCT( messages
);
1257 notify_msg_ctr_init( &messages
);
1260 * build message groups for each printer identified
1261 * in a change_notify msg. Remember that a PCN message
1262 * includes the handle returned for the srv_spoolss_replyopenprinter()
1263 * call. Therefore messages are grouped according to printer handle.
1266 for ( i
=0; i
<msg_count
; i
++ ) {
1267 struct timeval msg_tv
;
1269 if (msg_ptr
+ 4 - buf
> data
->length
) {
1270 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1274 msg_len
= IVAL(msg_ptr
,0);
1277 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1278 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1282 /* unpack messages */
1284 ZERO_STRUCT( notify
);
1285 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1288 /* add to correct list in container */
1290 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1292 /* free memory that might have been allocated by notify2_unpack_msg() */
1294 if ( notify
.len
!= 0 )
1295 SAFE_FREE( notify
.notify
.data
);
1298 /* process each group of messages */
1300 num_groups
= notify_msg_ctr_numgroups( &messages
);
1301 for ( i
=0; i
<num_groups
; i
++ )
1302 send_notify2_changes( &messages
, i
);
1307 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1308 (uint32_t)msg_count
));
1310 notify_msg_ctr_destroy( &messages
);
1315 /********************************************************************
1316 Send a message to ourself about new driver being installed
1317 so we can upgrade the information for each printer bound to this
1319 ********************************************************************/
1321 static bool srv_spoolss_drv_upgrade_printer(const char *drivername
)
1323 int len
= strlen(drivername
);
1328 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1331 messaging_send_buf(smbd_messaging_context(),
1332 messaging_server_id(smbd_messaging_context()),
1333 MSG_PRINTER_DRVUPGRADE
,
1334 (uint8_t *)drivername
, len
+1);
1339 /**********************************************************************
1340 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1341 over all printers, upgrading ones as necessary
1342 **********************************************************************/
1344 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1347 struct server_id server_id
,
1350 TALLOC_CTX
*tmp_ctx
;
1351 struct auth_serversupplied_info
*server_info
= NULL
;
1352 struct spoolss_PrinterInfo2
*pinfo2
;
1355 const char *drivername
;
1357 int n_services
= lp_numservices();
1360 tmp_ctx
= talloc_new(NULL
);
1361 if (!tmp_ctx
) return;
1363 status
= make_server_info_system(tmp_ctx
, &server_info
);
1364 if (!NT_STATUS_IS_OK(status
)) {
1365 DEBUG(0, ("do_drv_upgrade_printer: "
1366 "Could not create system server_info\n"));
1370 len
= MIN(data
->length
,sizeof(drivername
)-1);
1371 drivername
= talloc_strndup(tmp_ctx
, (const char *)data
->data
, len
);
1373 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1377 DEBUG(10, ("do_drv_upgrade_printer: "
1378 "Got message for new driver [%s]\n", drivername
));
1380 /* Iterate the printer list */
1382 for (snum
= 0; snum
< n_services
; snum
++) {
1383 if (!lp_snum_ok(snum
) || !lp_print_ok(snum
)) {
1387 result
= winreg_get_printer(tmp_ctx
, server_info
, NULL
,
1388 lp_const_servicename(snum
),
1391 if (!W_ERROR_IS_OK(result
)) {
1395 if (!pinfo2
->drivername
) {
1399 if (strcmp(drivername
, pinfo2
->drivername
) != 0) {
1403 DEBUG(6,("Updating printer [%s]\n", pinfo2
->printername
));
1405 /* all we care about currently is the change_id */
1406 result
= winreg_printer_update_changeid(tmp_ctx
,
1408 pinfo2
->printername
);
1410 if (!W_ERROR_IS_OK(result
)) {
1411 DEBUG(3, ("do_drv_upgrade_printer: "
1412 "Failed to update changeid [%s]\n",
1413 win_errstr(result
)));
1419 talloc_free(tmp_ctx
);
1422 /********************************************************************
1423 Update the cache for all printq's with a registered client
1425 ********************************************************************/
1427 void update_monitored_printq_cache( void )
1429 Printer_entry
*printer
= printers_list
;
1432 /* loop through all printers and update the cache where
1433 client_connected == true */
1436 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1437 && printer
->notify
.client_connected
)
1439 snum
= print_queue_snum(printer
->sharename
);
1440 print_queue_status( snum
, NULL
, NULL
);
1443 printer
= printer
->next
;
1449 /****************************************************************
1450 _spoolss_OpenPrinter
1451 ****************************************************************/
1453 WERROR
_spoolss_OpenPrinter(struct pipes_struct
*p
,
1454 struct spoolss_OpenPrinter
*r
)
1456 struct spoolss_OpenPrinterEx e
;
1459 ZERO_STRUCT(e
.in
.userlevel
);
1461 e
.in
.printername
= r
->in
.printername
;
1462 e
.in
.datatype
= r
->in
.datatype
;
1463 e
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
1464 e
.in
.access_mask
= r
->in
.access_mask
;
1467 e
.out
.handle
= r
->out
.handle
;
1469 werr
= _spoolss_OpenPrinterEx(p
, &e
);
1471 if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
1472 /* OpenPrinterEx returns this for a bad
1473 * printer name. We must return WERR_INVALID_PRINTER_NAME
1476 werr
= WERR_INVALID_PRINTER_NAME
;
1482 static WERROR
copy_devicemode(TALLOC_CTX
*mem_ctx
,
1483 struct spoolss_DeviceMode
*orig
,
1484 struct spoolss_DeviceMode
**dest
)
1486 struct spoolss_DeviceMode
*dm
;
1488 dm
= talloc(mem_ctx
, struct spoolss_DeviceMode
);
1493 /* copy all values, then duplicate strings and structs */
1496 dm
->devicename
= talloc_strdup(dm
, orig
->devicename
);
1497 if (!dm
->devicename
) {
1500 dm
->formname
= talloc_strdup(dm
, orig
->formname
);
1501 if (!dm
->formname
) {
1504 if (orig
->driverextra_data
.data
) {
1505 dm
->driverextra_data
.data
=
1506 (uint8_t *) talloc_memdup(dm
, orig
->driverextra_data
.data
,
1507 orig
->driverextra_data
.length
);
1508 if (!dm
->driverextra_data
.data
) {
1517 /****************************************************************
1518 _spoolss_OpenPrinterEx
1519 ****************************************************************/
1521 WERROR
_spoolss_OpenPrinterEx(struct pipes_struct
*p
,
1522 struct spoolss_OpenPrinterEx
*r
)
1525 Printer_entry
*Printer
=NULL
;
1527 if (!r
->in
.printername
) {
1528 return WERR_INVALID_PARAM
;
1531 /* some sanity check because you can open a printer or a print server */
1532 /* aka: \\server\printer or \\server */
1534 DEBUGADD(3,("checking name: %s\n", r
->in
.printername
));
1536 if (!open_printer_hnd(p
, r
->out
.handle
, r
->in
.printername
, 0)) {
1537 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1538 "for printer %s\n", r
->in
.printername
));
1539 ZERO_STRUCTP(r
->out
.handle
);
1540 return WERR_INVALID_PARAM
;
1543 Printer
= find_printer_index_by_hnd(p
, r
->out
.handle
);
1545 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1546 "handle we created for printer %s\n", r
->in
.printername
));
1547 close_printer_handle(p
, r
->out
.handle
);
1548 ZERO_STRUCTP(r
->out
.handle
);
1549 return WERR_INVALID_PARAM
;
1553 * First case: the user is opening the print server:
1555 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1556 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1558 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1559 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1560 * or if the user is listed in the smb.conf printer admin parameter.
1562 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1563 * client view printer folder, but does not show the MSAPW.
1565 * Note: this test needs code to check access rights here too. Jeremy
1566 * could you look at this?
1568 * Second case: the user is opening a printer:
1569 * NT doesn't let us connect to a printer if the connecting user
1570 * doesn't have print permission.
1572 * Third case: user is opening a Port Monitor
1573 * access checks same as opening a handle to the print server.
1576 switch (Printer
->printer_type
)
1579 case SPLHND_PORTMON_TCP
:
1580 case SPLHND_PORTMON_LOCAL
:
1581 /* Printserver handles use global struct... */
1585 /* Map standard access rights to object specific access rights */
1587 se_map_standard(&r
->in
.access_mask
,
1588 &printserver_std_mapping
);
1590 /* Deny any object specific bits that don't apply to print
1591 servers (i.e printer and job specific bits) */
1593 r
->in
.access_mask
&= SEC_MASK_SPECIFIC
;
1595 if (r
->in
.access_mask
&
1596 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1597 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1598 close_printer_handle(p
, r
->out
.handle
);
1599 ZERO_STRUCTP(r
->out
.handle
);
1600 return WERR_ACCESS_DENIED
;
1603 /* Allow admin access */
1605 if ( r
->in
.access_mask
& SERVER_ACCESS_ADMINISTER
)
1607 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1609 if (!lp_ms_add_printer_wizard()) {
1610 close_printer_handle(p
, r
->out
.handle
);
1611 ZERO_STRUCTP(r
->out
.handle
);
1612 return WERR_ACCESS_DENIED
;
1615 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1616 and not a printer admin, then fail */
1618 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
1619 !user_has_privileges(p
->server_info
->ptok
,
1621 !token_contains_name_in_list(
1622 uidtoname(p
->server_info
->utok
.uid
),
1623 p
->server_info
->info3
->base
.domain
.string
,
1625 p
->server_info
->ptok
,
1626 lp_printer_admin(snum
))) {
1627 close_printer_handle(p
, r
->out
.handle
);
1628 ZERO_STRUCTP(r
->out
.handle
);
1629 return WERR_ACCESS_DENIED
;
1632 r
->in
.access_mask
= SERVER_ACCESS_ADMINISTER
;
1636 r
->in
.access_mask
= SERVER_ACCESS_ENUMERATE
;
1639 DEBUG(4,("Setting print server access = %s\n", (r
->in
.access_mask
== SERVER_ACCESS_ADMINISTER
)
1640 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1642 /* We fall through to return WERR_OK */
1645 case SPLHND_PRINTER
:
1646 /* NT doesn't let us connect to a printer if the connecting user
1647 doesn't have print permission. */
1649 if (!get_printer_snum(p
, r
->out
.handle
, &snum
, NULL
)) {
1650 close_printer_handle(p
, r
->out
.handle
);
1651 ZERO_STRUCTP(r
->out
.handle
);
1655 if (r
->in
.access_mask
== SEC_FLAG_MAXIMUM_ALLOWED
) {
1656 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1659 se_map_standard(&r
->in
.access_mask
, &printer_std_mapping
);
1661 /* map an empty access mask to the minimum access mask */
1662 if (r
->in
.access_mask
== 0x0)
1663 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1666 * If we are not serving the printer driver for this printer,
1667 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1668 * will keep NT clients happy --jerry
1671 if (lp_use_client_driver(snum
)
1672 && (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
))
1674 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1677 /* check smb.conf parameters and the the sec_desc */
1679 if ( !check_access(get_client_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1680 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1681 ZERO_STRUCTP(r
->out
.handle
);
1682 return WERR_ACCESS_DENIED
;
1685 if (!user_ok_token(uidtoname(p
->server_info
->utok
.uid
), NULL
,
1686 p
->server_info
->ptok
, snum
) ||
1687 !print_access_check(p
->server_info
, snum
,
1688 r
->in
.access_mask
)) {
1689 DEBUG(3, ("access DENIED for printer open\n"));
1690 close_printer_handle(p
, r
->out
.handle
);
1691 ZERO_STRUCTP(r
->out
.handle
);
1692 return WERR_ACCESS_DENIED
;
1695 if ((r
->in
.access_mask
& SEC_MASK_SPECIFIC
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1696 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1697 close_printer_handle(p
, r
->out
.handle
);
1698 ZERO_STRUCTP(r
->out
.handle
);
1699 return WERR_ACCESS_DENIED
;
1702 if (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
)
1703 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1705 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1707 DEBUG(4,("Setting printer access = %s\n", (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1708 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1710 winreg_create_printer(p
->mem_ctx
,
1712 Printer
->servername
,
1713 lp_const_servicename(snum
));
1718 /* sanity check to prevent programmer error */
1719 ZERO_STRUCTP(r
->out
.handle
);
1723 Printer
->access_granted
= r
->in
.access_mask
;
1726 * If the client sent a devmode in the OpenPrinter() call, then
1727 * save it here in case we get a job submission on this handle
1730 if ((Printer
->printer_type
!= SPLHND_SERVER
) &&
1731 r
->in
.devmode_ctr
.devmode
) {
1732 copy_devicemode(NULL
, r
->in
.devmode_ctr
.devmode
,
1736 #if 0 /* JERRY -- I'm doubtful this is really effective */
1737 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1738 optimization in Windows 2000 clients --jerry */
1740 if ( (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1741 && (RA_WIN2K
== get_remote_arch()) )
1743 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1744 sys_usleep( 500000 );
1751 /****************************************************************
1752 _spoolss_ClosePrinter
1753 ****************************************************************/
1755 WERROR
_spoolss_ClosePrinter(struct pipes_struct
*p
,
1756 struct spoolss_ClosePrinter
*r
)
1758 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
1760 if (Printer
&& Printer
->document_started
) {
1761 struct spoolss_EndDocPrinter e
;
1763 e
.in
.handle
= r
->in
.handle
;
1765 _spoolss_EndDocPrinter(p
, &e
);
1768 if (!close_printer_handle(p
, r
->in
.handle
))
1771 /* clear the returned printer handle. Observed behavior
1772 from Win2k server. Don't think this really matters.
1773 Previous code just copied the value of the closed
1776 ZERO_STRUCTP(r
->out
.handle
);
1781 /****************************************************************
1782 _spoolss_DeletePrinter
1783 ****************************************************************/
1785 WERROR
_spoolss_DeletePrinter(struct pipes_struct
*p
,
1786 struct spoolss_DeletePrinter
*r
)
1788 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
1792 if (Printer
&& Printer
->document_started
) {
1793 struct spoolss_EndDocPrinter e
;
1795 e
.in
.handle
= r
->in
.handle
;
1797 _spoolss_EndDocPrinter(p
, &e
);
1800 if (get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
1801 winreg_delete_printer_key(p
->mem_ctx
,
1803 lp_const_servicename(snum
),
1807 result
= delete_printer_handle(p
, r
->in
.handle
);
1812 /*******************************************************************
1813 * static function to lookup the version id corresponding to an
1814 * long architecture string
1815 ******************************************************************/
1817 static const struct print_architecture_table_node archi_table
[]= {
1819 {"Windows 4.0", SPL_ARCH_WIN40
, 0 },
1820 {"Windows NT x86", SPL_ARCH_W32X86
, 2 },
1821 {"Windows NT R4000", SPL_ARCH_W32MIPS
, 2 },
1822 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA
, 2 },
1823 {"Windows NT PowerPC", SPL_ARCH_W32PPC
, 2 },
1824 {"Windows IA64", SPL_ARCH_IA64
, 3 },
1825 {"Windows x64", SPL_ARCH_X64
, 3 },
1829 static int get_version_id(const char *arch
)
1833 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1835 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1836 return (archi_table
[i
].version
);
1842 /****************************************************************
1843 _spoolss_DeletePrinterDriver
1844 ****************************************************************/
1846 WERROR
_spoolss_DeletePrinterDriver(struct pipes_struct
*p
,
1847 struct spoolss_DeletePrinterDriver
*r
)
1850 struct spoolss_DriverInfo8
*info
= NULL
;
1851 struct spoolss_DriverInfo8
*info_win2k
= NULL
;
1854 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1856 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1857 and not a printer admin, then fail */
1859 if ( (p
->server_info
->utok
.uid
!= sec_initial_uid())
1860 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
1861 && !token_contains_name_in_list(
1862 uidtoname(p
->server_info
->utok
.uid
),
1863 p
->server_info
->info3
->base
.domain
.string
,
1865 p
->server_info
->ptok
,
1866 lp_printer_admin(-1)) )
1868 return WERR_ACCESS_DENIED
;
1871 /* check that we have a valid driver name first */
1873 if ((version
= get_version_id(r
->in
.architecture
)) == -1)
1874 return WERR_INVALID_ENVIRONMENT
;
1876 status
= winreg_get_driver(p
->mem_ctx
, p
->server_info
,
1877 r
->in
.architecture
, r
->in
.driver
,
1879 if (!W_ERROR_IS_OK(status
)) {
1880 /* try for Win2k driver if "Windows NT x86" */
1882 if ( version
== 2 ) {
1885 status
= winreg_get_driver(p
->mem_ctx
, p
->server_info
,
1889 if (!W_ERROR_IS_OK(status
)) {
1890 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1894 /* otherwise it was a failure */
1896 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1902 if (printer_driver_in_use(p
->mem_ctx
, p
->server_info
, info
)) {
1903 status
= WERR_PRINTER_DRIVER_IN_USE
;
1908 status
= winreg_get_driver(p
->mem_ctx
, p
->server_info
,
1910 r
->in
.driver
, 3, &info_win2k
);
1911 if (W_ERROR_IS_OK(status
)) {
1912 /* if we get to here, we now have 2 driver info structures to remove */
1913 /* remove the Win2k driver first*/
1915 status
= winreg_del_driver(p
->mem_ctx
,
1918 talloc_free(info_win2k
);
1920 /* this should not have failed---if it did, report to client */
1921 if (!W_ERROR_IS_OK(status
)) {
1927 status
= winreg_del_driver(p
->mem_ctx
, p
->server_info
, info
, version
);
1935 /****************************************************************
1936 _spoolss_DeletePrinterDriverEx
1937 ****************************************************************/
1939 WERROR
_spoolss_DeletePrinterDriverEx(struct pipes_struct
*p
,
1940 struct spoolss_DeletePrinterDriverEx
*r
)
1942 struct spoolss_DriverInfo8
*info
= NULL
;
1943 struct spoolss_DriverInfo8
*info_win2k
= NULL
;
1947 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1949 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1950 and not a printer admin, then fail */
1952 if ( (p
->server_info
->utok
.uid
!= sec_initial_uid())
1953 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
1954 && !token_contains_name_in_list(
1955 uidtoname(p
->server_info
->utok
.uid
),
1956 p
->server_info
->info3
->base
.domain
.string
,
1958 p
->server_info
->ptok
, lp_printer_admin(-1)) )
1960 return WERR_ACCESS_DENIED
;
1963 /* check that we have a valid driver name first */
1964 if ((version
= get_version_id(r
->in
.architecture
)) == -1) {
1965 /* this is what NT returns */
1966 return WERR_INVALID_ENVIRONMENT
;
1969 if (r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
)
1970 version
= r
->in
.version
;
1972 status
= winreg_get_driver(p
->mem_ctx
, p
->server_info
,
1973 r
->in
.architecture
, r
->in
.driver
,
1975 if (!W_ERROR_IS_OK(status
)) {
1976 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1979 * if the client asked for a specific version,
1980 * or this is something other than Windows NT x86,
1984 if ( (r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
1987 /* try for Win2k driver if "Windows NT x86" */
1990 status
= winreg_get_driver(info
, p
->server_info
,
1994 if (!W_ERROR_IS_OK(status
)) {
1995 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2000 if (printer_driver_in_use(info
, p
->server_info
, info
)) {
2001 status
= WERR_PRINTER_DRIVER_IN_USE
;
2006 * we have a couple of cases to consider.
2007 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2008 * then the delete should fail if **any** files overlap with
2010 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2011 * non-overlapping files
2012 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2013 * is set, the do not delete any files
2014 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2017 delete_files
= r
->in
.delete_flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2019 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2022 (r
->in
.delete_flags
& DPD_DELETE_ALL_FILES
) &&
2023 printer_driver_files_in_use(info
, p
->server_info
, info
)) {
2024 /* no idea of the correct error here */
2025 status
= WERR_ACCESS_DENIED
;
2030 /* also check for W32X86/3 if necessary; maybe we already have? */
2032 if ( (version
== 2) && ((r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2033 status
= winreg_get_driver(info
, p
->server_info
,
2035 r
->in
.driver
, 3, &info_win2k
);
2036 if (W_ERROR_IS_OK(status
)) {
2039 (r
->in
.delete_flags
& DPD_DELETE_ALL_FILES
) &&
2040 printer_driver_files_in_use(info
, p
->server_info
,
2042 /* no idea of the correct error here */
2043 talloc_free(info_win2k
);
2044 status
= WERR_ACCESS_DENIED
;
2048 /* if we get to here, we now have 2 driver info structures to remove */
2049 /* remove the Win2k driver first*/
2051 status
= winreg_del_driver(info
, p
->server_info
,
2054 /* this should not have failed---if it did, report to client */
2056 if (!W_ERROR_IS_OK(status
)) {
2061 * now delete any associated files if delete_files is
2062 * true. Even if this part failes, we return succes
2063 * because the driver doesn not exist any more
2066 delete_driver_files(p
->server_info
,
2072 status
= winreg_del_driver(info
, p
->server_info
, info
, version
);
2073 if (!W_ERROR_IS_OK(status
)) {
2078 * now delete any associated files if delete_files is
2079 * true. Even if this part failes, we return succes
2080 * because the driver doesn not exist any more
2083 delete_driver_files(p
->server_info
, info
);
2092 /********************************************************************
2093 GetPrinterData on a printer server Handle.
2094 ********************************************************************/
2096 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*mem_ctx
,
2098 enum winreg_Type
*type
,
2099 union spoolss_PrinterData
*data
)
2101 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2103 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2109 if (!StrCaseCmp(value
, "BeepEnabled")) {
2115 if (!StrCaseCmp(value
, "EventLog")) {
2117 /* formally was 0x1b */
2122 if (!StrCaseCmp(value
, "NetPopup")) {
2128 if (!StrCaseCmp(value
, "MajorVersion")) {
2131 /* Windows NT 4.0 seems to not allow uploading of drivers
2132 to a server that reports 0x3 as the MajorVersion.
2133 need to investigate more how Win2k gets around this .
2136 if (RA_WINNT
== get_remote_arch()) {
2145 if (!StrCaseCmp(value
, "MinorVersion")) {
2152 * uint32_t size = 0x114
2153 * uint32_t major = 5
2154 * uint32_t minor = [0|1]
2155 * uint32_t build = [2195|2600]
2156 * extra unicode string = e.g. "Service Pack 3"
2158 if (!StrCaseCmp(value
, "OSVersion")) {
2160 enum ndr_err_code ndr_err
;
2161 struct spoolss_OSVersion os
;
2163 os
.major
= 5; /* Windows 2000 == 5.0 */
2165 os
.build
= 2195; /* build */
2166 os
.extra_string
= ""; /* leave extra string empty */
2168 ndr_err
= ndr_push_struct_blob(&blob
, mem_ctx
, &os
,
2169 (ndr_push_flags_fn_t
)ndr_push_spoolss_OSVersion
);
2170 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2171 return WERR_GENERAL_FAILURE
;
2175 data
->binary
= blob
;
2181 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2184 data
->string
= talloc_strdup(mem_ctx
, "C:\\PRINTERS");
2185 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2190 if (!StrCaseCmp(value
, "Architecture")) {
2192 data
->string
= talloc_strdup(mem_ctx
,
2193 lp_parm_const_string(GLOBAL_SECTION_SNUM
, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86
));
2194 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2199 if (!StrCaseCmp(value
, "DsPresent")) {
2202 /* only show the publish check box if we are a
2203 member of a AD domain */
2205 if (lp_security() == SEC_ADS
) {
2213 if (!StrCaseCmp(value
, "DNSMachineName")) {
2214 const char *hostname
= get_mydnsfullname();
2217 return WERR_BADFILE
;
2221 data
->string
= talloc_strdup(mem_ctx
, hostname
);
2222 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2229 return WERR_INVALID_PARAM
;
2232 /****************************************************************
2233 _spoolss_GetPrinterData
2234 ****************************************************************/
2236 WERROR
_spoolss_GetPrinterData(struct pipes_struct
*p
,
2237 struct spoolss_GetPrinterData
*r
)
2239 struct spoolss_GetPrinterDataEx r2
;
2241 r2
.in
.handle
= r
->in
.handle
;
2242 r2
.in
.key_name
= "PrinterDriverData";
2243 r2
.in
.value_name
= r
->in
.value_name
;
2244 r2
.in
.offered
= r
->in
.offered
;
2245 r2
.out
.type
= r
->out
.type
;
2246 r2
.out
.data
= r
->out
.data
;
2247 r2
.out
.needed
= r
->out
.needed
;
2249 return _spoolss_GetPrinterDataEx(p
, &r2
);
2252 /*********************************************************
2253 Connect to the client machine.
2254 **********************************************************/
2256 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2257 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2260 struct cli_state
*the_cli
;
2261 struct sockaddr_storage rm_addr
;
2262 char addr
[INET6_ADDRSTRLEN
];
2264 if ( is_zero_addr((struct sockaddr
*)client_ss
) ) {
2265 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2267 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20, false) ) {
2268 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2271 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2273 rm_addr
= *client_ss
;
2274 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2275 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2279 if (ismyaddr((struct sockaddr
*)&rm_addr
)) {
2280 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2285 /* setup the connection */
2286 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2287 &rm_addr
, 0, "IPC$", "IPC",
2291 0, lp_client_signing(), NULL
);
2293 if ( !NT_STATUS_IS_OK( ret
) ) {
2294 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2299 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2300 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2301 cli_shutdown(the_cli
);
2306 * Ok - we have an anonymous connection to the IPC$ share.
2307 * Now start the NT Domain stuff :-).
2310 ret
= cli_rpc_pipe_open_noauth(the_cli
, &ndr_table_spoolss
.syntax_id
, pp_pipe
);
2311 if (!NT_STATUS_IS_OK(ret
)) {
2312 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2313 remote_machine
, nt_errstr(ret
)));
2314 cli_shutdown(the_cli
);
2321 /***************************************************************************
2322 Connect to the client.
2323 ****************************************************************************/
2325 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2326 uint32_t localprinter
, uint32_t type
,
2327 struct policy_handle
*handle
,
2328 struct sockaddr_storage
*client_ss
)
2334 * If it's the first connection, contact the client
2335 * and connect to the IPC$ share anonymously
2337 if (smb_connections
==0) {
2338 fstring unix_printer
;
2340 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2342 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2345 messaging_register(smbd_messaging_context(), NULL
,
2346 MSG_PRINTER_NOTIFY2
,
2347 receive_notify2_message_list
);
2348 /* Tell the connections db we're now interested in printer
2349 * notify messages. */
2350 serverid_register_msg_flags(
2351 messaging_server_id(smbd_messaging_context()),
2352 true, FLAG_MSG_PRINT_NOTIFY
);
2356 * Tell the specific printing tdb we want messages for this printer
2357 * by registering our PID.
2360 if (!print_notify_register_pid(snum
))
2361 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2365 status
= rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe
, talloc_tos(),
2373 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
2374 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2375 win_errstr(result
)));
2377 return (W_ERROR_IS_OK(result
));
2380 /****************************************************************
2381 ****************************************************************/
2383 static struct spoolss_NotifyOption
*dup_spoolss_NotifyOption(TALLOC_CTX
*mem_ctx
,
2384 const struct spoolss_NotifyOption
*r
)
2386 struct spoolss_NotifyOption
*option
;
2393 option
= talloc_zero(mem_ctx
, struct spoolss_NotifyOption
);
2400 if (!option
->count
) {
2404 option
->types
= talloc_zero_array(option
,
2405 struct spoolss_NotifyOptionType
, option
->count
);
2406 if (!option
->types
) {
2407 talloc_free(option
);
2411 for (i
=0; i
< option
->count
; i
++) {
2412 option
->types
[i
] = r
->types
[i
];
2414 if (option
->types
[i
].count
) {
2415 option
->types
[i
].fields
= talloc_zero_array(option
,
2416 union spoolss_Field
, option
->types
[i
].count
);
2417 if (!option
->types
[i
].fields
) {
2418 talloc_free(option
);
2421 for (k
=0; k
<option
->types
[i
].count
; k
++) {
2422 option
->types
[i
].fields
[k
] =
2423 r
->types
[i
].fields
[k
];
2431 /****************************************************************
2432 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2434 * before replying OK: status=0 a rpc call is made to the workstation
2435 * asking ReplyOpenPrinter
2437 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2438 * called from api_spoolss_rffpcnex
2439 ****************************************************************/
2441 WERROR
_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct
*p
,
2442 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx
*r
)
2445 struct spoolss_NotifyOption
*option
= r
->in
.notify_options
;
2446 struct sockaddr_storage client_ss
;
2448 /* store the notify value in the printer struct */
2450 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
2453 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2454 "Invalid handle (%s:%u:%u).\n",
2455 OUR_HANDLE(r
->in
.handle
)));
2459 Printer
->notify
.flags
= r
->in
.flags
;
2460 Printer
->notify
.options
= r
->in
.options
;
2461 Printer
->notify
.printerlocal
= r
->in
.printer_local
;
2463 TALLOC_FREE(Printer
->notify
.option
);
2464 Printer
->notify
.option
= dup_spoolss_NotifyOption(Printer
, option
);
2466 fstrcpy(Printer
->notify
.localmachine
, r
->in
.local_machine
);
2468 /* Connect to the client machine and send a ReplyOpenPrinter */
2470 if ( Printer
->printer_type
== SPLHND_SERVER
)
2472 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2473 !get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
) )
2476 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2477 "client_address is %s\n", p
->client_address
));
2479 if (!interpret_string_addr(&client_ss
, p
->client_address
,
2481 return WERR_SERVER_UNAVAILABLE
;
2484 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2485 Printer
->notify
.printerlocal
, 1,
2486 &Printer
->notify
.client_hnd
, &client_ss
))
2487 return WERR_SERVER_UNAVAILABLE
;
2489 Printer
->notify
.client_connected
= true;
2494 /*******************************************************************
2495 * fill a notify_info_data with the servername
2496 ********************************************************************/
2498 static void spoolss_notify_server_name(int snum
,
2499 struct spoolss_Notify
*data
,
2500 print_queue_struct
*queue
,
2501 struct spoolss_PrinterInfo2
*pinfo2
,
2502 TALLOC_CTX
*mem_ctx
)
2504 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->servername
);
2507 /*******************************************************************
2508 * fill a notify_info_data with the printername (not including the servername).
2509 ********************************************************************/
2511 static void spoolss_notify_printer_name(int snum
,
2512 struct spoolss_Notify
*data
,
2513 print_queue_struct
*queue
,
2514 struct spoolss_PrinterInfo2
*pinfo2
,
2515 TALLOC_CTX
*mem_ctx
)
2517 /* the notify name should not contain the \\server\ part */
2518 const char *p
= strrchr(pinfo2
->printername
, '\\');
2521 p
= pinfo2
->printername
;
2526 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2529 /*******************************************************************
2530 * fill a notify_info_data with the servicename
2531 ********************************************************************/
2533 static void spoolss_notify_share_name(int snum
,
2534 struct spoolss_Notify
*data
,
2535 print_queue_struct
*queue
,
2536 struct spoolss_PrinterInfo2
*pinfo2
,
2537 TALLOC_CTX
*mem_ctx
)
2539 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, lp_servicename(snum
));
2542 /*******************************************************************
2543 * fill a notify_info_data with the port name
2544 ********************************************************************/
2546 static void spoolss_notify_port_name(int snum
,
2547 struct spoolss_Notify
*data
,
2548 print_queue_struct
*queue
,
2549 struct spoolss_PrinterInfo2
*pinfo2
,
2550 TALLOC_CTX
*mem_ctx
)
2552 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->portname
);
2555 /*******************************************************************
2556 * fill a notify_info_data with the printername
2557 * but it doesn't exist, have to see what to do
2558 ********************************************************************/
2560 static void spoolss_notify_driver_name(int snum
,
2561 struct spoolss_Notify
*data
,
2562 print_queue_struct
*queue
,
2563 struct spoolss_PrinterInfo2
*pinfo2
,
2564 TALLOC_CTX
*mem_ctx
)
2566 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->drivername
);
2569 /*******************************************************************
2570 * fill a notify_info_data with the comment
2571 ********************************************************************/
2573 static void spoolss_notify_comment(int snum
,
2574 struct spoolss_Notify
*data
,
2575 print_queue_struct
*queue
,
2576 struct spoolss_PrinterInfo2
*pinfo2
,
2577 TALLOC_CTX
*mem_ctx
)
2581 if (*pinfo2
->comment
== '\0') {
2582 p
= lp_comment(snum
);
2584 p
= pinfo2
->comment
;
2587 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2590 /*******************************************************************
2591 * fill a notify_info_data with the comment
2592 * location = "Room 1, floor 2, building 3"
2593 ********************************************************************/
2595 static void spoolss_notify_location(int snum
,
2596 struct spoolss_Notify
*data
,
2597 print_queue_struct
*queue
,
2598 struct spoolss_PrinterInfo2
*pinfo2
,
2599 TALLOC_CTX
*mem_ctx
)
2601 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->location
);
2604 /*******************************************************************
2605 * fill a notify_info_data with the device mode
2606 * jfm:xxxx don't to it for know but that's a real problem !!!
2607 ********************************************************************/
2609 static void spoolss_notify_devmode(int snum
,
2610 struct spoolss_Notify
*data
,
2611 print_queue_struct
*queue
,
2612 struct spoolss_PrinterInfo2
*pinfo2
,
2613 TALLOC_CTX
*mem_ctx
)
2615 /* for a dummy implementation we have to zero the fields */
2616 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data
, NULL
);
2619 /*******************************************************************
2620 * fill a notify_info_data with the separator file name
2621 ********************************************************************/
2623 static void spoolss_notify_sepfile(int snum
,
2624 struct spoolss_Notify
*data
,
2625 print_queue_struct
*queue
,
2626 struct spoolss_PrinterInfo2
*pinfo2
,
2627 TALLOC_CTX
*mem_ctx
)
2629 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->sepfile
);
2632 /*******************************************************************
2633 * fill a notify_info_data with the print processor
2634 * jfm:xxxx return always winprint to indicate we don't do anything to it
2635 ********************************************************************/
2637 static void spoolss_notify_print_processor(int snum
,
2638 struct spoolss_Notify
*data
,
2639 print_queue_struct
*queue
,
2640 struct spoolss_PrinterInfo2
*pinfo2
,
2641 TALLOC_CTX
*mem_ctx
)
2643 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->printprocessor
);
2646 /*******************************************************************
2647 * fill a notify_info_data with the print processor options
2648 * jfm:xxxx send an empty string
2649 ********************************************************************/
2651 static void spoolss_notify_parameters(int snum
,
2652 struct spoolss_Notify
*data
,
2653 print_queue_struct
*queue
,
2654 struct spoolss_PrinterInfo2
*pinfo2
,
2655 TALLOC_CTX
*mem_ctx
)
2657 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->parameters
);
2660 /*******************************************************************
2661 * fill a notify_info_data with the data type
2662 * jfm:xxxx always send RAW as data type
2663 ********************************************************************/
2665 static void spoolss_notify_datatype(int snum
,
2666 struct spoolss_Notify
*data
,
2667 print_queue_struct
*queue
,
2668 struct spoolss_PrinterInfo2
*pinfo2
,
2669 TALLOC_CTX
*mem_ctx
)
2671 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, pinfo2
->datatype
);
2674 /*******************************************************************
2675 * fill a notify_info_data with the security descriptor
2676 * jfm:xxxx send an null pointer to say no security desc
2677 * have to implement security before !
2678 ********************************************************************/
2680 static void spoolss_notify_security_desc(int snum
,
2681 struct spoolss_Notify
*data
,
2682 print_queue_struct
*queue
,
2683 struct spoolss_PrinterInfo2
*pinfo2
,
2684 TALLOC_CTX
*mem_ctx
)
2686 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data
, pinfo2
->secdesc
);
2689 /*******************************************************************
2690 * fill a notify_info_data with the attributes
2691 * jfm:xxxx a samba printer is always shared
2692 ********************************************************************/
2694 static void spoolss_notify_attributes(int snum
,
2695 struct spoolss_Notify
*data
,
2696 print_queue_struct
*queue
,
2697 struct spoolss_PrinterInfo2
*pinfo2
,
2698 TALLOC_CTX
*mem_ctx
)
2700 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, pinfo2
->attributes
);
2703 /*******************************************************************
2704 * fill a notify_info_data with the priority
2705 ********************************************************************/
2707 static void spoolss_notify_priority(int snum
,
2708 struct spoolss_Notify
*data
,
2709 print_queue_struct
*queue
,
2710 struct spoolss_PrinterInfo2
*pinfo2
,
2711 TALLOC_CTX
*mem_ctx
)
2713 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, pinfo2
->priority
);
2716 /*******************************************************************
2717 * fill a notify_info_data with the default priority
2718 ********************************************************************/
2720 static void spoolss_notify_default_priority(int snum
,
2721 struct spoolss_Notify
*data
,
2722 print_queue_struct
*queue
,
2723 struct spoolss_PrinterInfo2
*pinfo2
,
2724 TALLOC_CTX
*mem_ctx
)
2726 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, pinfo2
->defaultpriority
);
2729 /*******************************************************************
2730 * fill a notify_info_data with the start time
2731 ********************************************************************/
2733 static void spoolss_notify_start_time(int snum
,
2734 struct spoolss_Notify
*data
,
2735 print_queue_struct
*queue
,
2736 struct spoolss_PrinterInfo2
*pinfo2
,
2737 TALLOC_CTX
*mem_ctx
)
2739 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, pinfo2
->starttime
);
2742 /*******************************************************************
2743 * fill a notify_info_data with the until time
2744 ********************************************************************/
2746 static void spoolss_notify_until_time(int snum
,
2747 struct spoolss_Notify
*data
,
2748 print_queue_struct
*queue
,
2749 struct spoolss_PrinterInfo2
*pinfo2
,
2750 TALLOC_CTX
*mem_ctx
)
2752 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, pinfo2
->untiltime
);
2755 /*******************************************************************
2756 * fill a notify_info_data with the status
2757 ********************************************************************/
2759 static void spoolss_notify_status(int snum
,
2760 struct spoolss_Notify
*data
,
2761 print_queue_struct
*queue
,
2762 struct spoolss_PrinterInfo2
*pinfo2
,
2763 TALLOC_CTX
*mem_ctx
)
2765 print_status_struct status
;
2767 print_queue_length(snum
, &status
);
2768 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, status
.status
);
2771 /*******************************************************************
2772 * fill a notify_info_data with the number of jobs queued
2773 ********************************************************************/
2775 static void spoolss_notify_cjobs(int snum
,
2776 struct spoolss_Notify
*data
,
2777 print_queue_struct
*queue
,
2778 struct spoolss_PrinterInfo2
*pinfo2
,
2779 TALLOC_CTX
*mem_ctx
)
2781 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, print_queue_length(snum
, NULL
));
2784 /*******************************************************************
2785 * fill a notify_info_data with the average ppm
2786 ********************************************************************/
2788 static void spoolss_notify_average_ppm(int snum
,
2789 struct spoolss_Notify
*data
,
2790 print_queue_struct
*queue
,
2791 struct spoolss_PrinterInfo2
*pinfo2
,
2792 TALLOC_CTX
*mem_ctx
)
2794 /* always respond 8 pages per minutes */
2795 /* a little hard ! */
2796 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, pinfo2
->averageppm
);
2799 /*******************************************************************
2800 * fill a notify_info_data with username
2801 ********************************************************************/
2803 static void spoolss_notify_username(int snum
,
2804 struct spoolss_Notify
*data
,
2805 print_queue_struct
*queue
,
2806 struct spoolss_PrinterInfo2
*pinfo2
,
2807 TALLOC_CTX
*mem_ctx
)
2809 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_user
);
2812 /*******************************************************************
2813 * fill a notify_info_data with job status
2814 ********************************************************************/
2816 static void spoolss_notify_job_status(int snum
,
2817 struct spoolss_Notify
*data
,
2818 print_queue_struct
*queue
,
2819 struct spoolss_PrinterInfo2
*pinfo2
,
2820 TALLOC_CTX
*mem_ctx
)
2822 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, nt_printj_status(queue
->status
));
2825 /*******************************************************************
2826 * fill a notify_info_data with job name
2827 ********************************************************************/
2829 static void spoolss_notify_job_name(int snum
,
2830 struct spoolss_Notify
*data
,
2831 print_queue_struct
*queue
,
2832 struct spoolss_PrinterInfo2
*pinfo2
,
2833 TALLOC_CTX
*mem_ctx
)
2835 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_file
);
2838 /*******************************************************************
2839 * fill a notify_info_data with job status
2840 ********************************************************************/
2842 static void spoolss_notify_job_status_string(int snum
,
2843 struct spoolss_Notify
*data
,
2844 print_queue_struct
*queue
,
2845 struct spoolss_PrinterInfo2
*pinfo2
,
2846 TALLOC_CTX
*mem_ctx
)
2849 * Now we're returning job status codes we just return a "" here. JRA.
2854 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2857 switch (queue
->status
) {
2862 p
= ""; /* NT provides the paused string */
2871 #endif /* NO LONGER NEEDED. */
2873 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2876 /*******************************************************************
2877 * fill a notify_info_data with job time
2878 ********************************************************************/
2880 static void spoolss_notify_job_time(int snum
,
2881 struct spoolss_Notify
*data
,
2882 print_queue_struct
*queue
,
2883 struct spoolss_PrinterInfo2
*pinfo2
,
2884 TALLOC_CTX
*mem_ctx
)
2886 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
2889 /*******************************************************************
2890 * fill a notify_info_data with job size
2891 ********************************************************************/
2893 static void spoolss_notify_job_size(int snum
,
2894 struct spoolss_Notify
*data
,
2895 print_queue_struct
*queue
,
2896 struct spoolss_PrinterInfo2
*pinfo2
,
2897 TALLOC_CTX
*mem_ctx
)
2899 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->size
);
2902 /*******************************************************************
2903 * fill a notify_info_data with page info
2904 ********************************************************************/
2905 static void spoolss_notify_total_pages(int snum
,
2906 struct spoolss_Notify
*data
,
2907 print_queue_struct
*queue
,
2908 struct spoolss_PrinterInfo2
*pinfo2
,
2909 TALLOC_CTX
*mem_ctx
)
2911 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->page_count
);
2914 /*******************************************************************
2915 * fill a notify_info_data with pages printed info.
2916 ********************************************************************/
2917 static void spoolss_notify_pages_printed(int snum
,
2918 struct spoolss_Notify
*data
,
2919 print_queue_struct
*queue
,
2920 struct spoolss_PrinterInfo2
*pinfo2
,
2921 TALLOC_CTX
*mem_ctx
)
2923 /* Add code when back-end tracks this */
2924 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
2927 /*******************************************************************
2928 Fill a notify_info_data with job position.
2929 ********************************************************************/
2931 static void spoolss_notify_job_position(int snum
,
2932 struct spoolss_Notify
*data
,
2933 print_queue_struct
*queue
,
2934 struct spoolss_PrinterInfo2
*pinfo2
,
2935 TALLOC_CTX
*mem_ctx
)
2937 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->job
);
2940 /*******************************************************************
2941 Fill a notify_info_data with submitted time.
2942 ********************************************************************/
2944 static void spoolss_notify_submitted_time(int snum
,
2945 struct spoolss_Notify
*data
,
2946 print_queue_struct
*queue
,
2947 struct spoolss_PrinterInfo2
*pinfo2
,
2948 TALLOC_CTX
*mem_ctx
)
2950 data
->data
.string
.string
= NULL
;
2951 data
->data
.string
.size
= 0;
2953 init_systemtime_buffer(mem_ctx
, gmtime(&queue
->time
),
2954 &data
->data
.string
.string
,
2955 &data
->data
.string
.size
);
2959 struct s_notify_info_data_table
2961 enum spoolss_NotifyType type
;
2964 enum spoolss_NotifyTable variable_type
;
2965 void (*fn
) (int snum
, struct spoolss_Notify
*data
,
2966 print_queue_struct
*queue
,
2967 struct spoolss_PrinterInfo2
*pinfo2
,
2968 TALLOC_CTX
*mem_ctx
);
2971 /* A table describing the various print notification constants and
2972 whether the notification data is a pointer to a variable sized
2973 buffer, a one value uint32_t or a two value uint32_t. */
2975 static const struct s_notify_info_data_table notify_info_data_table
[] =
2977 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SERVER_NAME
, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
2978 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRINTER_NAME
, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
2979 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SHARE_NAME
, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_share_name
},
2980 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PORT_NAME
, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
2981 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DRIVER_NAME
, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
2982 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_COMMENT
, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING
, spoolss_notify_comment
},
2983 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_LOCATION
, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING
, spoolss_notify_location
},
2984 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DEVMODE
, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
2985 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SEPFILE
, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING
, spoolss_notify_sepfile
},
2986 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR
, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
2987 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PARAMETERS
, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
2988 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DATATYPE
, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
2989 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, spoolss_notify_security_desc
},
2990 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_ATTRIBUTES
, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD
, spoolss_notify_attributes
},
2991 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRIORITY
, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
2992 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_default_priority
},
2993 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_START_TIME
, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
2994 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_UNTIL_TIME
, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
2995 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_STATUS
, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_status
},
2996 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_STATUS_STRING
, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING
, NULL
},
2997 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_CJOBS
, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD
, spoolss_notify_cjobs
},
2998 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_AVERAGE_PPM
, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD
, spoolss_notify_average_ppm
},
2999 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_TOTAL_PAGES
, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, NULL
},
3000 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PAGES_PRINTED
, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
3001 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_TOTAL_BYTES
, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, NULL
},
3002 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_BYTES_PRINTED
, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
3003 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRINTER_NAME
, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
3004 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_MACHINE_NAME
, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
3005 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PORT_NAME
, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
3006 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_USER_NAME
, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
3007 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_NOTIFY_NAME
, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
3008 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DATATYPE
, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
3009 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRINT_PROCESSOR
, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
3010 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PARAMETERS
, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
3011 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DRIVER_NAME
, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
3012 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DEVMODE
, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
3013 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_STATUS
, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_job_status
},
3014 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_STATUS_STRING
, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING
, spoolss_notify_job_status_string
},
3015 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, NULL
},
3016 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DOCUMENT
, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING
, spoolss_notify_job_name
},
3017 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRIORITY
, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
3018 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_POSITION
, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD
, spoolss_notify_job_position
},
3019 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_SUBMITTED
, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME
, spoolss_notify_submitted_time
},
3020 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_START_TIME
, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
3021 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_UNTIL_TIME
, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
3022 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TIME
, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_job_time
},
3023 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TOTAL_PAGES
, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, spoolss_notify_total_pages
},
3024 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PAGES_PRINTED
, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, spoolss_notify_pages_printed
},
3025 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TOTAL_BYTES
, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, spoolss_notify_job_size
},
3028 /*******************************************************************
3029 Return the variable_type of info_data structure.
3030 ********************************************************************/
3032 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type
,
3037 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
3038 if ( (notify_info_data_table
[i
].type
== type
) &&
3039 (notify_info_data_table
[i
].field
== field
) ) {
3040 return notify_info_data_table
[i
].variable_type
;
3044 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3049 /****************************************************************************
3050 ****************************************************************************/
3052 static bool search_notify(enum spoolss_NotifyType type
,
3058 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
3059 if (notify_info_data_table
[i
].type
== type
&&
3060 notify_info_data_table
[i
].field
== field
&&
3061 notify_info_data_table
[i
].fn
!= NULL
) {
3070 /****************************************************************************
3071 ****************************************************************************/
3073 static void construct_info_data(struct spoolss_Notify
*info_data
,
3074 enum spoolss_NotifyType type
,
3075 uint16_t field
, int id
)
3077 info_data
->type
= type
;
3078 info_data
->field
.field
= field
;
3079 info_data
->variable_type
= variable_type_of_notify_info_data(type
, field
);
3080 info_data
->job_id
= id
;
3083 /*******************************************************************
3085 * fill a notify_info struct with info asked
3087 ********************************************************************/
3089 static bool construct_notify_printer_info(Printer_entry
*print_hnd
,
3090 struct spoolss_NotifyInfo
*info
,
3091 struct spoolss_PrinterInfo2
*pinfo2
,
3093 const struct spoolss_NotifyOptionType
*option_type
,
3095 TALLOC_CTX
*mem_ctx
)
3098 enum spoolss_NotifyType type
;
3101 struct spoolss_Notify
*current_data
;
3102 print_queue_struct
*queue
=NULL
;
3104 type
= option_type
->type
;
3106 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3107 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3108 option_type
->count
, lp_servicename(snum
)));
3110 for(field_num
=0; field_num
< option_type
->count
; field_num
++) {
3111 field
= option_type
->fields
[field_num
].field
;
3113 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3115 if (!search_notify(type
, field
, &j
) )
3118 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3119 struct spoolss_Notify
,
3121 if (info
->notifies
== NULL
) {
3122 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3126 current_data
= &info
->notifies
[info
->count
];
3128 construct_info_data(current_data
, type
, field
, id
);
3130 DEBUG(10, ("construct_notify_printer_info: "
3131 "calling [%s] snum=%d printername=[%s])\n",
3132 notify_info_data_table
[j
].name
, snum
,
3133 pinfo2
->printername
));
3135 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3144 /*******************************************************************
3146 * fill a notify_info struct with info asked
3148 ********************************************************************/
3150 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3151 struct spoolss_NotifyInfo
*info
,
3152 struct spoolss_PrinterInfo2
*pinfo2
,
3154 const struct spoolss_NotifyOptionType
*option_type
,
3156 TALLOC_CTX
*mem_ctx
)
3159 enum spoolss_NotifyType type
;
3161 struct spoolss_Notify
*current_data
;
3163 DEBUG(4,("construct_notify_jobs_info\n"));
3165 type
= option_type
->type
;
3167 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3168 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3169 option_type
->count
));
3171 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3172 field
= option_type
->fields
[field_num
].field
;
3174 if (!search_notify(type
, field
, &j
) )
3177 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3178 struct spoolss_Notify
,
3180 if (info
->notifies
== NULL
) {
3181 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3185 current_data
=&(info
->notifies
[info
->count
]);
3187 construct_info_data(current_data
, type
, field
, id
);
3188 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3197 * JFM: The enumeration is not that simple, it's even non obvious.
3199 * let's take an example: I want to monitor the PRINTER SERVER for
3200 * the printer's name and the number of jobs currently queued.
3201 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3202 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3204 * I have 3 printers on the back of my server.
3206 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3209 * 1 printer 1 name 1
3210 * 2 printer 1 cjob 1
3211 * 3 printer 2 name 2
3212 * 4 printer 2 cjob 2
3213 * 5 printer 3 name 3
3214 * 6 printer 3 name 3
3216 * that's the print server case, the printer case is even worse.
3219 /*******************************************************************
3221 * enumerate all printers on the printserver
3222 * fill a notify_info struct with info asked
3224 ********************************************************************/
3226 static WERROR
printserver_notify_info(struct pipes_struct
*p
,
3227 struct policy_handle
*hnd
,
3228 struct spoolss_NotifyInfo
*info
,
3229 TALLOC_CTX
*mem_ctx
)
3232 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
3233 int n_services
=lp_numservices();
3235 struct spoolss_NotifyOption
*option
;
3236 struct spoolss_NotifyOptionType option_type
;
3237 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
3240 DEBUG(4,("printserver_notify_info\n"));
3245 option
= Printer
->notify
.option
;
3248 info
->notifies
= NULL
;
3251 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3252 sending a ffpcn() request first */
3257 for (i
=0; i
<option
->count
; i
++) {
3258 option_type
= option
->types
[i
];
3260 if (option_type
.type
!= PRINTER_NOTIFY_TYPE
)
3263 for (snum
= 0; snum
< n_services
; snum
++) {
3264 if (!lp_browseable(snum
) ||
3265 !lp_snum_ok(snum
) ||
3266 !lp_print_ok(snum
)) {
3267 continue; /* skip */
3270 /* Maybe we should use the SYSTEM server_info here... */
3271 result
= winreg_get_printer(mem_ctx
, p
->server_info
,
3272 Printer
->servername
,
3273 lp_servicename(snum
),
3275 if (!W_ERROR_IS_OK(result
)) {
3276 DEBUG(4, ("printserver_notify_info: "
3277 "Failed to get printer [%s]\n",
3278 lp_servicename(snum
)));
3283 construct_notify_printer_info(Printer
, info
,
3288 TALLOC_FREE(pinfo2
);
3294 * Debugging information, don't delete.
3297 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3298 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3299 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3301 for (i
=0; i
<info
->count
; i
++) {
3302 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3303 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3304 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3311 /*******************************************************************
3313 * fill a notify_info struct with info asked
3315 ********************************************************************/
3317 static WERROR
printer_notify_info(struct pipes_struct
*p
,
3318 struct policy_handle
*hnd
,
3319 struct spoolss_NotifyInfo
*info
,
3320 TALLOC_CTX
*mem_ctx
)
3323 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
3326 struct spoolss_NotifyOption
*option
;
3327 struct spoolss_NotifyOptionType option_type
;
3329 print_queue_struct
*queue
=NULL
;
3330 print_status_struct status
;
3331 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
3334 DEBUG(4,("printer_notify_info\n"));
3339 option
= Printer
->notify
.option
;
3343 info
->notifies
= NULL
;
3346 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3347 sending a ffpcn() request first */
3352 get_printer_snum(p
, hnd
, &snum
, NULL
);
3354 /* Maybe we should use the SYSTEM server_info here... */
3355 result
= winreg_get_printer(mem_ctx
, p
->server_info
,
3356 Printer
->servername
,
3357 lp_servicename(snum
), &pinfo2
);
3358 if (!W_ERROR_IS_OK(result
)) {
3362 for (i
=0; i
<option
->count
; i
++) {
3363 option_type
= option
->types
[i
];
3365 switch (option_type
.type
) {
3366 case PRINTER_NOTIFY_TYPE
:
3367 if (construct_notify_printer_info(Printer
, info
,
3375 case JOB_NOTIFY_TYPE
:
3377 count
= print_queue_status(snum
, &queue
, &status
);
3379 for (j
=0; j
<count
; j
++) {
3380 construct_notify_jobs_info(&queue
[j
], info
,
3393 * Debugging information, don't delete.
3396 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3397 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3398 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3400 for (i=0; i<info->count; i++) {
3401 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3402 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3403 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3407 talloc_free(pinfo2
);
3411 /****************************************************************
3412 _spoolss_RouterRefreshPrinterChangeNotify
3413 ****************************************************************/
3415 WERROR
_spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct
*p
,
3416 struct spoolss_RouterRefreshPrinterChangeNotify
*r
)
3418 struct spoolss_NotifyInfo
*info
;
3420 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
3421 WERROR result
= WERR_BADFID
;
3423 /* we always have a spoolss_NotifyInfo struct */
3424 info
= talloc_zero(p
->mem_ctx
, struct spoolss_NotifyInfo
);
3426 result
= WERR_NOMEM
;
3430 *r
->out
.info
= info
;
3433 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3434 "Invalid handle (%s:%u:%u).\n",
3435 OUR_HANDLE(r
->in
.handle
)));
3439 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3442 * We are now using the change value, and
3443 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3444 * I don't have a global notification system, I'm sending back all the
3445 * informations even when _NOTHING_ has changed.
3448 /* We need to keep track of the change value to send back in
3449 RRPCN replies otherwise our updates are ignored. */
3451 Printer
->notify
.fnpcn
= true;
3453 if (Printer
->notify
.client_connected
) {
3454 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3455 "Saving change value in request [%x]\n",
3457 Printer
->notify
.change
= r
->in
.change_low
;
3460 /* just ignore the spoolss_NotifyOption */
3462 switch (Printer
->printer_type
) {
3464 result
= printserver_notify_info(p
, r
->in
.handle
,
3468 case SPLHND_PRINTER
:
3469 result
= printer_notify_info(p
, r
->in
.handle
,
3474 Printer
->notify
.fnpcn
= false;
3480 /********************************************************************
3481 * construct_printer_info_0
3482 * fill a printer_info_0 struct
3483 ********************************************************************/
3485 static WERROR
construct_printer_info0(TALLOC_CTX
*mem_ctx
,
3486 struct auth_serversupplied_info
*server_info
,
3487 struct spoolss_PrinterInfo2
*info2
,
3488 struct spoolss_PrinterInfo0
*r
,
3492 counter_printer_0
*session_counter
;
3493 struct timeval setuptime
;
3494 print_status_struct status
;
3496 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3497 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3499 r
->servername
= talloc_strdup(mem_ctx
, info2
->servername
);
3500 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3502 count
= print_queue_length(snum
, &status
);
3504 /* check if we already have a counter for this printer */
3505 for (session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3506 if (session_counter
->snum
== snum
)
3510 /* it's the first time, add it to the list */
3511 if (session_counter
== NULL
) {
3512 session_counter
= SMB_MALLOC_P(counter_printer_0
);
3513 W_ERROR_HAVE_NO_MEMORY(session_counter
);
3514 ZERO_STRUCTP(session_counter
);
3515 session_counter
->snum
= snum
;
3516 session_counter
->counter
= 0;
3517 DLIST_ADD(counter_list
, session_counter
);
3521 session_counter
->counter
++;
3527 get_startup_time(&setuptime
);
3528 init_systemtime(&r
->time
, gmtime(&setuptime
.tv_sec
));
3531 * the global_counter should be stored in a TDB as it's common to all the clients
3532 * and should be zeroed on samba startup
3534 r
->global_counter
= session_counter
->counter
;
3536 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3537 SSVAL(&r
->version
, 0, 0x0005); /* NT 5 */
3538 SSVAL(&r
->version
, 2, 0x0893); /* build 2195 */
3539 r
->free_build
= SPOOLSS_RELEASE_BUILD
;
3541 r
->max_spooling
= 0;
3542 r
->session_counter
= session_counter
->counter
;
3543 r
->num_error_out_of_paper
= 0x0;
3544 r
->num_error_not_ready
= 0x0; /* number of print failure */
3546 r
->number_of_processors
= 0x1;
3547 r
->processor_type
= PROCESSOR_INTEL_PENTIUM
; /* 586 Pentium ? */
3548 r
->high_part_total_bytes
= 0x0;
3549 winreg_printer_get_changeid(mem_ctx
, server_info
, info2
->sharename
, &r
->change_id
); /* ChangeID in milliseconds*/
3550 r
->last_error
= WERR_OK
;
3551 r
->status
= nt_printq_status(status
.status
);
3552 r
->enumerate_network_printers
= 0x0;
3553 r
->c_setprinter
= 0x0;
3554 r
->processor_architecture
= 0x0;
3555 r
->processor_level
= 0x6; /* 6 ???*/
3564 /********************************************************************
3565 * construct_printer_info1
3566 * fill a spoolss_PrinterInfo1 struct
3567 ********************************************************************/
3569 static WERROR
construct_printer_info1(TALLOC_CTX
*mem_ctx
,
3570 const struct spoolss_PrinterInfo2
*info2
,
3572 struct spoolss_PrinterInfo1
*r
,
3577 r
->description
= talloc_asprintf(mem_ctx
, "%s,%s,%s",
3581 W_ERROR_HAVE_NO_MEMORY(r
->description
);
3583 if (info2
->comment
== NULL
|| info2
->comment
[0] == '\0') {
3584 r
->comment
= talloc_strdup(mem_ctx
, lp_comment(snum
));
3586 r
->comment
= talloc_strdup(mem_ctx
, info2
->comment
); /* saved comment */
3588 W_ERROR_HAVE_NO_MEMORY(r
->comment
);
3590 r
->name
= talloc_strdup(mem_ctx
, info2
->printername
);
3591 W_ERROR_HAVE_NO_MEMORY(r
->name
);
3596 /********************************************************************
3597 * construct_printer_info2
3598 * fill a spoolss_PrinterInfo2 struct
3599 ********************************************************************/
3601 static WERROR
construct_printer_info2(TALLOC_CTX
*mem_ctx
,
3602 const struct spoolss_PrinterInfo2
*info2
,
3603 struct spoolss_PrinterInfo2
*r
,
3607 print_status_struct status
;
3609 count
= print_queue_length(snum
, &status
);
3611 r
->servername
= talloc_strdup(mem_ctx
, info2
->servername
);
3612 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3613 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3614 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3615 r
->sharename
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
3616 W_ERROR_HAVE_NO_MEMORY(r
->sharename
);
3617 r
->portname
= talloc_strdup(mem_ctx
, info2
->portname
);
3618 W_ERROR_HAVE_NO_MEMORY(r
->portname
);
3619 r
->drivername
= talloc_strdup(mem_ctx
, info2
->drivername
);
3620 W_ERROR_HAVE_NO_MEMORY(r
->drivername
);
3622 if (info2
->comment
[0] == '\0') {
3623 r
->comment
= talloc_strdup(mem_ctx
, lp_comment(snum
));
3625 r
->comment
= talloc_strdup(mem_ctx
, info2
->comment
);
3627 W_ERROR_HAVE_NO_MEMORY(r
->comment
);
3629 r
->location
= talloc_strdup(mem_ctx
, info2
->location
);
3630 W_ERROR_HAVE_NO_MEMORY(r
->location
);
3631 r
->sepfile
= talloc_strdup(mem_ctx
, info2
->sepfile
);
3632 W_ERROR_HAVE_NO_MEMORY(r
->sepfile
);
3633 r
->printprocessor
= talloc_strdup(mem_ctx
, info2
->printprocessor
);
3634 W_ERROR_HAVE_NO_MEMORY(r
->printprocessor
);
3635 r
->datatype
= talloc_strdup(mem_ctx
, info2
->datatype
);
3636 W_ERROR_HAVE_NO_MEMORY(r
->datatype
);
3637 r
->parameters
= talloc_strdup(mem_ctx
, info2
->parameters
);
3638 W_ERROR_HAVE_NO_MEMORY(r
->parameters
);
3640 r
->attributes
= info2
->attributes
;
3642 r
->priority
= info2
->priority
;
3643 r
->defaultpriority
= info2
->defaultpriority
;
3644 r
->starttime
= info2
->starttime
;
3645 r
->untiltime
= info2
->untiltime
;
3646 r
->status
= nt_printq_status(status
.status
);
3648 r
->averageppm
= info2
->averageppm
;
3650 copy_devicemode(mem_ctx
, info2
->devmode
, &r
->devmode
);
3652 DEBUG(8,("Returning NULL Devicemode!\n"));
3657 if (info2
->secdesc
!= NULL
) {
3658 /* don't use talloc_steal() here unless you do a deep steal of all
3659 the SEC_DESC members */
3661 r
->secdesc
= dup_sec_desc(mem_ctx
, info2
->secdesc
);
3667 /********************************************************************
3668 * construct_printer_info3
3669 * fill a spoolss_PrinterInfo3 struct
3670 ********************************************************************/
3672 static WERROR
construct_printer_info3(TALLOC_CTX
*mem_ctx
,
3673 const struct spoolss_PrinterInfo2
*info2
,
3674 struct spoolss_PrinterInfo3
*r
,
3677 /* These are the components of the SD we are returning. */
3679 if (info2
->secdesc
!= NULL
) {
3680 /* don't use talloc_steal() here unless you do a deep steal of all
3681 the SEC_DESC members */
3683 r
->secdesc
= dup_sec_desc(mem_ctx
, info2
->secdesc
);
3684 W_ERROR_HAVE_NO_MEMORY(r
->secdesc
);
3690 /********************************************************************
3691 * construct_printer_info4
3692 * fill a spoolss_PrinterInfo4 struct
3693 ********************************************************************/
3695 static WERROR
construct_printer_info4(TALLOC_CTX
*mem_ctx
,
3696 const struct spoolss_PrinterInfo2
*info2
,
3697 struct spoolss_PrinterInfo4
*r
,
3700 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3701 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3702 r
->servername
= talloc_strdup(mem_ctx
, info2
->servername
);
3703 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3705 r
->attributes
= info2
->attributes
;
3710 /********************************************************************
3711 * construct_printer_info5
3712 * fill a spoolss_PrinterInfo5 struct
3713 ********************************************************************/
3715 static WERROR
construct_printer_info5(TALLOC_CTX
*mem_ctx
,
3716 const struct spoolss_PrinterInfo2
*info2
,
3717 struct spoolss_PrinterInfo5
*r
,
3720 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3721 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3722 r
->portname
= talloc_strdup(mem_ctx
, info2
->portname
);
3723 W_ERROR_HAVE_NO_MEMORY(r
->portname
);
3725 r
->attributes
= info2
->attributes
;
3727 /* these two are not used by NT+ according to MSDN */
3728 r
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
3729 r
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
3734 /********************************************************************
3735 * construct_printer_info_6
3736 * fill a spoolss_PrinterInfo6 struct
3737 ********************************************************************/
3739 static WERROR
construct_printer_info6(TALLOC_CTX
*mem_ctx
,
3740 const struct spoolss_PrinterInfo2
*info2
,
3741 struct spoolss_PrinterInfo6
*r
,
3745 print_status_struct status
;
3747 count
= print_queue_length(snum
, &status
);
3749 r
->status
= nt_printq_status(status
.status
);
3754 /********************************************************************
3755 * construct_printer_info7
3756 * fill a spoolss_PrinterInfo7 struct
3757 ********************************************************************/
3759 static WERROR
construct_printer_info7(TALLOC_CTX
*mem_ctx
,
3760 Printer_entry
*print_hnd
,
3761 struct spoolss_PrinterInfo7
*r
,
3764 struct auth_serversupplied_info
*server_info
;
3768 status
= make_server_info_system(mem_ctx
, &server_info
);
3769 if (!NT_STATUS_IS_OK(status
)) {
3770 DEBUG(0, ("construct_printer_info7: "
3771 "Could not create system server_info\n"));
3775 if (is_printer_published(mem_ctx
, server_info
, print_hnd
->servername
,
3776 lp_servicename(snum
), &guid
, NULL
)) {
3777 r
->guid
= talloc_strdup_upper(mem_ctx
, GUID_string2(mem_ctx
, &guid
));
3778 r
->action
= DSPRINT_PUBLISH
;
3780 r
->guid
= talloc_strdup(mem_ctx
, "");
3781 r
->action
= DSPRINT_UNPUBLISH
;
3783 W_ERROR_HAVE_NO_MEMORY(r
->guid
);
3785 TALLOC_FREE(server_info
);
3789 /********************************************************************
3790 * construct_printer_info8
3791 * fill a spoolss_PrinterInfo8 struct
3792 ********************************************************************/
3794 static WERROR
construct_printer_info8(TALLOC_CTX
*mem_ctx
,
3795 const struct spoolss_PrinterInfo2
*info2
,
3796 struct spoolss_DeviceModeInfo
*r
,
3799 copy_devicemode(mem_ctx
, info2
->devmode
, &r
->devmode
);
3801 DEBUG(8,("Returning NULL Devicemode!\n"));
3808 /********************************************************************
3809 ********************************************************************/
3811 static bool snum_is_shared_printer(int snum
)
3813 return (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
));
3816 /********************************************************************
3817 Spoolss_enumprinters.
3818 ********************************************************************/
3820 static WERROR
enum_all_printers_info_level(TALLOC_CTX
*mem_ctx
,
3821 struct auth_serversupplied_info
*server_info
,
3824 union spoolss_PrinterInfo
**info_p
,
3828 int n_services
= lp_numservices();
3829 union spoolss_PrinterInfo
*info
= NULL
;
3831 WERROR result
= WERR_OK
;
3836 for (snum
= 0; snum
< n_services
; snum
++) {
3838 const char *printer
;
3839 struct spoolss_PrinterInfo2
*info2
;
3841 if (!snum_is_shared_printer(snum
)) {
3845 printer
= lp_const_servicename(snum
);
3847 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3850 result
= winreg_create_printer(mem_ctx
,
3854 if (!W_ERROR_IS_OK(result
)) {
3858 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
3859 union spoolss_PrinterInfo
,
3862 result
= WERR_NOMEM
;
3866 result
= winreg_get_printer(mem_ctx
, server_info
,
3867 NULL
, printer
, &info2
);
3868 if (!W_ERROR_IS_OK(result
)) {
3874 result
= construct_printer_info0(info
, server_info
, info2
,
3875 &info
[count
].info0
, snum
);
3878 result
= construct_printer_info1(info
, info2
, flags
,
3879 &info
[count
].info1
, snum
);
3882 result
= construct_printer_info2(info
, info2
,
3883 &info
[count
].info2
, snum
);
3886 result
= construct_printer_info4(info
, info2
,
3887 &info
[count
].info4
, snum
);
3890 result
= construct_printer_info5(info
, info2
,
3891 &info
[count
].info5
, snum
);
3895 result
= WERR_UNKNOWN_LEVEL
;
3899 if (!W_ERROR_IS_OK(result
)) {
3910 if (!W_ERROR_IS_OK(result
)) {
3920 /********************************************************************
3921 * handle enumeration of printers at level 0
3922 ********************************************************************/
3924 static WERROR
enumprinters_level0(TALLOC_CTX
*mem_ctx
,
3925 struct auth_serversupplied_info
*server_info
,
3927 const char *servername
,
3928 union spoolss_PrinterInfo
**info
,
3931 DEBUG(4,("enum_all_printers_info_0\n"));
3933 return enum_all_printers_info_level(mem_ctx
, server_info
, 0, flags
, info
, count
);
3937 /********************************************************************
3938 ********************************************************************/
3940 static WERROR
enum_all_printers_info_1(TALLOC_CTX
*mem_ctx
,
3941 struct auth_serversupplied_info
*server_info
,
3943 union spoolss_PrinterInfo
**info
,
3946 DEBUG(4,("enum_all_printers_info_1\n"));
3948 return enum_all_printers_info_level(mem_ctx
, server_info
, 1, flags
, info
, count
);
3951 /********************************************************************
3952 enum_all_printers_info_1_local.
3953 *********************************************************************/
3955 static WERROR
enum_all_printers_info_1_local(TALLOC_CTX
*mem_ctx
,
3956 struct auth_serversupplied_info
*server_info
,
3957 union spoolss_PrinterInfo
**info
,
3960 DEBUG(4,("enum_all_printers_info_1_local\n"));
3962 return enum_all_printers_info_1(mem_ctx
, server_info
, PRINTER_ENUM_ICON8
, info
, count
);
3965 /********************************************************************
3966 enum_all_printers_info_1_name.
3967 *********************************************************************/
3969 static WERROR
enum_all_printers_info_1_name(TALLOC_CTX
*mem_ctx
,
3970 struct auth_serversupplied_info
*server_info
,
3972 union spoolss_PrinterInfo
**info
,
3975 const char *s
= name
;
3977 DEBUG(4,("enum_all_printers_info_1_name\n"));
3979 if ((name
[0] == '\\') && (name
[1] == '\\')) {
3983 if (!is_myname_or_ipaddr(s
)) {
3984 return WERR_INVALID_NAME
;
3987 return enum_all_printers_info_1(mem_ctx
, server_info
, PRINTER_ENUM_ICON8
, info
, count
);
3990 /********************************************************************
3991 enum_all_printers_info_1_network.
3992 *********************************************************************/
3994 static WERROR
enum_all_printers_info_1_network(TALLOC_CTX
*mem_ctx
,
3995 struct auth_serversupplied_info
*server_info
,
3997 union spoolss_PrinterInfo
**info
,
4000 const char *s
= name
;
4002 DEBUG(4,("enum_all_printers_info_1_network\n"));
4004 /* If we respond to a enum_printers level 1 on our name with flags
4005 set to PRINTER_ENUM_REMOTE with a list of printers then these
4006 printers incorrectly appear in the APW browse list.
4007 Specifically the printers for the server appear at the workgroup
4008 level where all the other servers in the domain are
4009 listed. Windows responds to this call with a
4010 WERR_CAN_NOT_COMPLETE so we should do the same. */
4012 if (name
[0] == '\\' && name
[1] == '\\') {
4016 if (is_myname_or_ipaddr(s
)) {
4017 return WERR_CAN_NOT_COMPLETE
;
4020 return enum_all_printers_info_1(mem_ctx
, server_info
, PRINTER_ENUM_NAME
, info
, count
);
4023 /********************************************************************
4024 * api_spoolss_enumprinters
4026 * called from api_spoolss_enumprinters (see this to understand)
4027 ********************************************************************/
4029 static WERROR
enum_all_printers_info_2(TALLOC_CTX
*mem_ctx
,
4030 struct auth_serversupplied_info
*server_info
,
4031 union spoolss_PrinterInfo
**info
,
4034 DEBUG(4,("enum_all_printers_info_2\n"));
4036 return enum_all_printers_info_level(mem_ctx
, server_info
, 2, 0, info
, count
);
4039 /********************************************************************
4040 * handle enumeration of printers at level 1
4041 ********************************************************************/
4043 static WERROR
enumprinters_level1(TALLOC_CTX
*mem_ctx
,
4044 struct auth_serversupplied_info
*server_info
,
4047 union spoolss_PrinterInfo
**info
,
4050 /* Not all the flags are equals */
4052 if (flags
& PRINTER_ENUM_LOCAL
) {
4053 return enum_all_printers_info_1_local(mem_ctx
, server_info
, info
, count
);
4056 if (flags
& PRINTER_ENUM_NAME
) {
4057 return enum_all_printers_info_1_name(mem_ctx
, server_info
, name
, info
, count
);
4060 if (flags
& PRINTER_ENUM_NETWORK
) {
4061 return enum_all_printers_info_1_network(mem_ctx
, server_info
, name
, info
, count
);
4064 return WERR_OK
; /* NT4sp5 does that */
4067 /********************************************************************
4068 * handle enumeration of printers at level 2
4069 ********************************************************************/
4071 static WERROR
enumprinters_level2(TALLOC_CTX
*mem_ctx
,
4072 struct auth_serversupplied_info
*server_info
,
4074 const char *servername
,
4075 union spoolss_PrinterInfo
**info
,
4078 if (flags
& PRINTER_ENUM_LOCAL
) {
4079 return enum_all_printers_info_2(mem_ctx
, server_info
, info
, count
);
4082 if (flags
& PRINTER_ENUM_NAME
) {
4083 if (!is_myname_or_ipaddr(canon_servername(servername
))) {
4084 return WERR_INVALID_NAME
;
4087 return enum_all_printers_info_2(mem_ctx
, server_info
, info
, count
);
4090 if (flags
& PRINTER_ENUM_REMOTE
) {
4091 return WERR_UNKNOWN_LEVEL
;
4097 /********************************************************************
4098 * handle enumeration of printers at level 4
4099 ********************************************************************/
4101 static WERROR
enumprinters_level4(TALLOC_CTX
*mem_ctx
,
4102 struct auth_serversupplied_info
*server_info
,
4104 const char *servername
,
4105 union spoolss_PrinterInfo
**info
,
4108 DEBUG(4,("enum_all_printers_info_4\n"));
4110 return enum_all_printers_info_level(mem_ctx
, server_info
, 4, flags
, info
, count
);
4114 /********************************************************************
4115 * handle enumeration of printers at level 5
4116 ********************************************************************/
4118 static WERROR
enumprinters_level5(TALLOC_CTX
*mem_ctx
,
4119 struct auth_serversupplied_info
*server_info
,
4121 const char *servername
,
4122 union spoolss_PrinterInfo
**info
,
4125 DEBUG(4,("enum_all_printers_info_5\n"));
4127 return enum_all_printers_info_level(mem_ctx
, server_info
, 5, flags
, info
, count
);
4130 /****************************************************************
4131 _spoolss_EnumPrinters
4132 ****************************************************************/
4134 WERROR
_spoolss_EnumPrinters(struct pipes_struct
*p
,
4135 struct spoolss_EnumPrinters
*r
)
4137 const char *name
= NULL
;
4140 /* that's an [in out] buffer */
4142 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4143 return WERR_INVALID_PARAM
;
4146 DEBUG(4,("_spoolss_EnumPrinters\n"));
4150 *r
->out
.info
= NULL
;
4154 * flags==PRINTER_ENUM_NAME
4155 * if name=="" then enumerates all printers
4156 * if name!="" then enumerate the printer
4157 * flags==PRINTER_ENUM_REMOTE
4158 * name is NULL, enumerate printers
4159 * Level 2: name!="" enumerates printers, name can't be NULL
4160 * Level 3: doesn't exist
4161 * Level 4: does a local registry lookup
4162 * Level 5: same as Level 2
4166 name
= talloc_strdup_upper(p
->mem_ctx
, r
->in
.server
);
4167 W_ERROR_HAVE_NO_MEMORY(name
);
4170 switch (r
->in
.level
) {
4172 result
= enumprinters_level0(p
->mem_ctx
, p
->server_info
,
4174 r
->out
.info
, r
->out
.count
);
4177 result
= enumprinters_level1(p
->mem_ctx
, p
->server_info
,
4179 r
->out
.info
, r
->out
.count
);
4182 result
= enumprinters_level2(p
->mem_ctx
, p
->server_info
,
4184 r
->out
.info
, r
->out
.count
);
4187 result
= enumprinters_level4(p
->mem_ctx
, p
->server_info
,
4189 r
->out
.info
, r
->out
.count
);
4192 result
= enumprinters_level5(p
->mem_ctx
, p
->server_info
,
4194 r
->out
.info
, r
->out
.count
);
4197 return WERR_UNKNOWN_LEVEL
;
4200 if (!W_ERROR_IS_OK(result
)) {
4204 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
4205 spoolss_EnumPrinters
,
4206 *r
->out
.info
, r
->in
.level
,
4208 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
4209 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
4211 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4214 /****************************************************************
4216 ****************************************************************/
4218 WERROR
_spoolss_GetPrinter(struct pipes_struct
*p
,
4219 struct spoolss_GetPrinter
*r
)
4221 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
4222 struct spoolss_PrinterInfo2
*info2
= NULL
;
4223 WERROR result
= WERR_OK
;
4224 const char *servername
= NULL
;
4227 /* that's an [in out] buffer */
4229 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4230 return WERR_INVALID_PARAM
;
4235 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
4239 if (Printer
!= NULL
|| Printer
->servername
!= NULL
) {
4240 servername
= Printer
->servername
;
4243 result
= winreg_get_printer(p
->mem_ctx
,
4246 lp_const_servicename(snum
),
4248 if (!W_ERROR_IS_OK(result
)) {
4252 switch (r
->in
.level
) {
4254 result
= construct_printer_info0(p
->mem_ctx
, p
->server_info
,
4256 &r
->out
.info
->info0
, snum
);
4259 result
= construct_printer_info1(p
->mem_ctx
, info2
,
4261 &r
->out
.info
->info1
, snum
);
4264 result
= construct_printer_info2(p
->mem_ctx
, info2
,
4265 &r
->out
.info
->info2
, snum
);
4268 result
= construct_printer_info3(p
->mem_ctx
, info2
,
4269 &r
->out
.info
->info3
, snum
);
4272 result
= construct_printer_info4(p
->mem_ctx
, info2
,
4273 &r
->out
.info
->info4
, snum
);
4276 result
= construct_printer_info5(p
->mem_ctx
, info2
,
4277 &r
->out
.info
->info5
, snum
);
4280 result
= construct_printer_info6(p
->mem_ctx
, info2
,
4281 &r
->out
.info
->info6
, snum
);
4284 result
= construct_printer_info7(p
->mem_ctx
, Printer
,
4285 &r
->out
.info
->info7
, snum
);
4288 result
= construct_printer_info8(p
->mem_ctx
, info2
,
4289 &r
->out
.info
->info8
, snum
);
4292 result
= WERR_UNKNOWN_LEVEL
;
4297 if (!W_ERROR_IS_OK(result
)) {
4298 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4299 r
->in
.level
, win_errstr(result
)));
4300 TALLOC_FREE(r
->out
.info
);
4304 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo
,
4305 r
->out
.info
, r
->in
.level
);
4306 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
4308 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4311 /********************************************************************
4312 ********************************************************************/
4314 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4316 if (in && strlen(in)) { \
4317 out = talloc_strdup(mem_ctx, in); \
4319 out = talloc_strdup(mem_ctx, ""); \
4321 W_ERROR_HAVE_NO_MEMORY(out); \
4324 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4326 if (in && strlen(in)) { \
4327 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4329 out = talloc_strdup(mem_ctx, ""); \
4331 W_ERROR_HAVE_NO_MEMORY(out); \
4334 static WERROR
string_array_from_driver_info(TALLOC_CTX
*mem_ctx
,
4335 const char **string_array
,
4336 const char ***presult
,
4337 const char *cservername
,
4341 int i
, num_strings
= 0;
4342 const char **array
= NULL
;
4344 if (string_array
== NULL
) {
4345 return WERR_INVALID_PARAMETER
;;
4348 for (i
=0; string_array
[i
] && string_array
[i
][0] != '\0'; i
++) {
4349 const char *str
= NULL
;
4351 if (cservername
== NULL
|| arch
== NULL
) {
4352 FILL_DRIVER_STRING(mem_ctx
, string_array
[i
], str
);
4354 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
, arch
, version
, string_array
[i
], str
);
4357 if (!add_string_to_array(mem_ctx
, str
, &array
, &num_strings
)) {
4364 ADD_TO_ARRAY(mem_ctx
, const char *, NULL
,
4365 &array
, &num_strings
);
4375 /********************************************************************
4376 * fill a spoolss_DriverInfo1 struct
4377 ********************************************************************/
4379 static WERROR
fill_printer_driver_info1(TALLOC_CTX
*mem_ctx
,
4380 struct spoolss_DriverInfo1
*r
,
4381 const struct spoolss_DriverInfo8
*driver
,
4382 const char *servername
)
4384 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4385 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4390 /********************************************************************
4391 * fill a spoolss_DriverInfo2 struct
4392 ********************************************************************/
4394 static WERROR
fill_printer_driver_info2(TALLOC_CTX
*mem_ctx
,
4395 struct spoolss_DriverInfo2
*r
,
4396 const struct spoolss_DriverInfo8
*driver
,
4397 const char *servername
)
4400 const char *cservername
= canon_servername(servername
);
4402 r
->version
= driver
->version
;
4404 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4405 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4406 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4407 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4409 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4410 driver
->architecture
,
4412 driver
->driver_path
,
4415 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4416 driver
->architecture
,
4421 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4422 driver
->architecture
,
4424 driver
->config_file
,
4430 /********************************************************************
4431 * fill a spoolss_DriverInfo3 struct
4432 ********************************************************************/
4434 static WERROR
fill_printer_driver_info3(TALLOC_CTX
*mem_ctx
,
4435 struct spoolss_DriverInfo3
*r
,
4436 const struct spoolss_DriverInfo8
*driver
,
4437 const char *servername
)
4439 const char *cservername
= canon_servername(servername
);
4441 r
->version
= driver
->version
;
4443 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4444 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4445 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4446 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4448 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4449 driver
->architecture
,
4451 driver
->driver_path
,
4454 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4455 driver
->architecture
,
4460 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4461 driver
->architecture
,
4463 driver
->config_file
,
4466 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4467 driver
->architecture
,
4472 FILL_DRIVER_STRING(mem_ctx
,
4473 driver
->monitor_name
,
4476 FILL_DRIVER_STRING(mem_ctx
,
4477 driver
->default_datatype
,
4478 r
->default_datatype
);
4480 return string_array_from_driver_info(mem_ctx
,
4481 driver
->dependent_files
,
4482 &r
->dependent_files
,
4484 driver
->architecture
,
4488 /********************************************************************
4489 * fill a spoolss_DriverInfo4 struct
4490 ********************************************************************/
4492 static WERROR
fill_printer_driver_info4(TALLOC_CTX
*mem_ctx
,
4493 struct spoolss_DriverInfo4
*r
,
4494 const struct spoolss_DriverInfo8
*driver
,
4495 const char *servername
)
4497 const char *cservername
= canon_servername(servername
);
4500 r
->version
= driver
->version
;
4502 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4503 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4504 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4505 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4507 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4508 driver
->architecture
,
4510 driver
->driver_path
,
4513 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4514 driver
->architecture
,
4519 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4520 driver
->architecture
,
4522 driver
->config_file
,
4525 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4526 driver
->architecture
,
4531 result
= string_array_from_driver_info(mem_ctx
,
4532 driver
->dependent_files
,
4533 &r
->dependent_files
,
4535 driver
->architecture
,
4537 if (!W_ERROR_IS_OK(result
)) {
4541 FILL_DRIVER_STRING(mem_ctx
,
4542 driver
->monitor_name
,
4545 FILL_DRIVER_STRING(mem_ctx
,
4546 driver
->default_datatype
,
4547 r
->default_datatype
);
4550 result
= string_array_from_driver_info(mem_ctx
,
4551 driver
->previous_names
,
4558 /********************************************************************
4559 * fill a spoolss_DriverInfo5 struct
4560 ********************************************************************/
4562 static WERROR
fill_printer_driver_info5(TALLOC_CTX
*mem_ctx
,
4563 struct spoolss_DriverInfo5
*r
,
4564 const struct spoolss_DriverInfo8
*driver
,
4565 const char *servername
)
4567 const char *cservername
= canon_servername(servername
);
4569 r
->version
= driver
->version
;
4571 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4572 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4573 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4574 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4576 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4577 driver
->architecture
,
4579 driver
->driver_path
,
4582 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4583 driver
->architecture
,
4588 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4589 driver
->architecture
,
4591 driver
->config_file
,
4594 r
->driver_attributes
= 0;
4595 r
->config_version
= 0;
4596 r
->driver_version
= 0;
4600 /********************************************************************
4601 * fill a spoolss_DriverInfo6 struct
4602 ********************************************************************/
4604 static WERROR
fill_printer_driver_info6(TALLOC_CTX
*mem_ctx
,
4605 struct spoolss_DriverInfo6
*r
,
4606 const struct spoolss_DriverInfo8
*driver
,
4607 const char *servername
)
4609 const char *cservername
= canon_servername(servername
);
4612 r
->version
= driver
->version
;
4614 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4615 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4616 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4617 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4619 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4620 driver
->architecture
,
4622 driver
->driver_path
,
4625 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4626 driver
->architecture
,
4631 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4632 driver
->architecture
,
4634 driver
->config_file
,
4637 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4638 driver
->architecture
,
4643 FILL_DRIVER_STRING(mem_ctx
,
4644 driver
->monitor_name
,
4647 FILL_DRIVER_STRING(mem_ctx
,
4648 driver
->default_datatype
,
4649 r
->default_datatype
);
4651 result
= string_array_from_driver_info(mem_ctx
,
4652 driver
->dependent_files
,
4653 &r
->dependent_files
,
4655 driver
->architecture
,
4657 if (!W_ERROR_IS_OK(result
)) {
4661 result
= string_array_from_driver_info(mem_ctx
,
4662 driver
->previous_names
,
4665 if (!W_ERROR_IS_OK(result
)) {
4669 r
->driver_date
= driver
->driver_date
;
4670 r
->driver_version
= driver
->driver_version
;
4672 FILL_DRIVER_STRING(mem_ctx
,
4673 driver
->manufacturer_name
,
4674 r
->manufacturer_name
);
4675 FILL_DRIVER_STRING(mem_ctx
,
4676 driver
->manufacturer_url
,
4677 r
->manufacturer_url
);
4678 FILL_DRIVER_STRING(mem_ctx
,
4679 driver
->hardware_id
,
4681 FILL_DRIVER_STRING(mem_ctx
,
4688 /********************************************************************
4689 * fill a spoolss_DriverInfo8 struct
4690 ********************************************************************/
4692 static WERROR
fill_printer_driver_info8(TALLOC_CTX
*mem_ctx
,
4693 struct spoolss_DriverInfo8
*r
,
4694 const struct spoolss_DriverInfo8
*driver
,
4695 const char *servername
)
4697 const char *cservername
= canon_servername(servername
);
4700 r
->version
= driver
->version
;
4702 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4703 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4704 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4705 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4707 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4708 driver
->architecture
,
4710 driver
->driver_path
,
4713 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4714 driver
->architecture
,
4719 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4720 driver
->architecture
,
4722 driver
->config_file
,
4725 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4726 driver
->architecture
,
4731 FILL_DRIVER_STRING(mem_ctx
,
4732 driver
->monitor_name
,
4735 FILL_DRIVER_STRING(mem_ctx
,
4736 driver
->default_datatype
,
4737 r
->default_datatype
);
4739 result
= string_array_from_driver_info(mem_ctx
,
4740 driver
->dependent_files
,
4741 &r
->dependent_files
,
4743 driver
->architecture
,
4745 if (!W_ERROR_IS_OK(result
)) {
4749 result
= string_array_from_driver_info(mem_ctx
,
4750 driver
->previous_names
,
4753 if (!W_ERROR_IS_OK(result
)) {
4757 r
->driver_date
= driver
->driver_date
;
4758 r
->driver_version
= driver
->driver_version
;
4760 FILL_DRIVER_STRING(mem_ctx
,
4761 driver
->manufacturer_name
,
4762 r
->manufacturer_name
);
4763 FILL_DRIVER_STRING(mem_ctx
,
4764 driver
->manufacturer_url
,
4765 r
->manufacturer_url
);
4766 FILL_DRIVER_STRING(mem_ctx
,
4767 driver
->hardware_id
,
4769 FILL_DRIVER_STRING(mem_ctx
,
4773 FILL_DRIVER_STRING(mem_ctx
,
4774 driver
->print_processor
,
4775 r
->print_processor
);
4776 FILL_DRIVER_STRING(mem_ctx
,
4777 driver
->vendor_setup
,
4780 result
= string_array_from_driver_info(mem_ctx
,
4781 driver
->color_profiles
,
4784 if (!W_ERROR_IS_OK(result
)) {
4788 FILL_DRIVER_STRING(mem_ctx
,
4792 r
->printer_driver_attributes
= driver
->printer_driver_attributes
;
4794 result
= string_array_from_driver_info(mem_ctx
,
4795 driver
->core_driver_dependencies
,
4796 &r
->core_driver_dependencies
,
4798 if (!W_ERROR_IS_OK(result
)) {
4802 r
->min_inbox_driver_ver_date
= driver
->min_inbox_driver_ver_date
;
4803 r
->min_inbox_driver_ver_version
= driver
->min_inbox_driver_ver_version
;
4808 #if 0 /* disabled until marshalling issues are resolved - gd */
4809 /********************************************************************
4810 ********************************************************************/
4812 static WERROR
fill_spoolss_DriverFileInfo(TALLOC_CTX
*mem_ctx
,
4813 struct spoolss_DriverFileInfo
*r
,
4814 const char *cservername
,
4815 const char *file_name
,
4816 enum spoolss_DriverFileType file_type
,
4817 uint32_t file_version
)
4819 r
->file_name
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4820 cservername
, file_name
);
4821 W_ERROR_HAVE_NO_MEMORY(r
->file_name
);
4822 r
->file_type
= file_type
;
4823 r
->file_version
= file_version
;
4828 /********************************************************************
4829 ********************************************************************/
4831 static WERROR
spoolss_DriverFileInfo_from_driver(TALLOC_CTX
*mem_ctx
,
4832 const struct spoolss_DriverInfo8
*driver
,
4833 const char *cservername
,
4834 struct spoolss_DriverFileInfo
**info_p
,
4837 struct spoolss_DriverFileInfo
*info
= NULL
;
4845 if (strlen(driver
->driver_path
)) {
4846 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4847 struct spoolss_DriverFileInfo
,
4849 W_ERROR_HAVE_NO_MEMORY(info
);
4850 result
= fill_spoolss_DriverFileInfo(info
,
4853 driver
->driver_path
,
4854 SPOOLSS_DRIVER_FILE_TYPE_RENDERING
,
4856 W_ERROR_NOT_OK_RETURN(result
);
4860 if (strlen(driver
->config_file
)) {
4861 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4862 struct spoolss_DriverFileInfo
,
4864 W_ERROR_HAVE_NO_MEMORY(info
);
4865 result
= fill_spoolss_DriverFileInfo(info
,
4868 driver
->config_file
,
4869 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION
,
4871 W_ERROR_NOT_OK_RETURN(result
);
4875 if (strlen(driver
->data_file
)) {
4876 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4877 struct spoolss_DriverFileInfo
,
4879 W_ERROR_HAVE_NO_MEMORY(info
);
4880 result
= fill_spoolss_DriverFileInfo(info
,
4884 SPOOLSS_DRIVER_FILE_TYPE_DATA
,
4886 W_ERROR_NOT_OK_RETURN(result
);
4890 if (strlen(driver
->help_file
)) {
4891 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4892 struct spoolss_DriverFileInfo
,
4894 W_ERROR_HAVE_NO_MEMORY(info
);
4895 result
= fill_spoolss_DriverFileInfo(info
,
4899 SPOOLSS_DRIVER_FILE_TYPE_HELP
,
4901 W_ERROR_NOT_OK_RETURN(result
);
4905 for (i
=0; driver
->dependent_files
[i
] && driver
->dependent_files
[i
][0] != '\0'; i
++) {
4906 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4907 struct spoolss_DriverFileInfo
,
4909 W_ERROR_HAVE_NO_MEMORY(info
);
4910 result
= fill_spoolss_DriverFileInfo(info
,
4913 driver
->dependent_files
[i
],
4914 SPOOLSS_DRIVER_FILE_TYPE_OTHER
,
4916 W_ERROR_NOT_OK_RETURN(result
);
4926 /********************************************************************
4927 * fill a spoolss_DriverInfo101 struct
4928 ********************************************************************/
4930 static WERROR
fill_printer_driver_info101(TALLOC_CTX
*mem_ctx
,
4931 struct spoolss_DriverInfo101
*r
,
4932 const struct spoolss_DriverInfo8
*driver
,
4933 const char *servername
)
4935 const char *cservername
= canon_servername(servername
);
4938 r
->version
= driver
->version
;
4940 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4941 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4942 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4943 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4945 result
= spoolss_DriverFileInfo_from_driver(mem_ctx
, driver
,
4949 if (!W_ERROR_IS_OK(result
)) {
4953 FILL_DRIVER_STRING(mem_ctx
,
4954 driver
->monitor_name
,
4957 FILL_DRIVER_STRING(mem_ctx
,
4958 driver
->default_datatype
,
4959 r
->default_datatype
);
4961 result
= string_array_from_driver_info(mem_ctx
,
4962 driver
->previous_names
,
4965 if (!W_ERROR_IS_OK(result
)) {
4969 r
->driver_date
= driver
->driver_date
;
4970 r
->driver_version
= driver
->driver_version
;
4972 FILL_DRIVER_STRING(mem_ctx
,
4973 driver
->manufacturer_name
,
4974 r
->manufacturer_name
);
4975 FILL_DRIVER_STRING(mem_ctx
,
4976 driver
->manufacturer_url
,
4977 r
->manufacturer_url
);
4978 FILL_DRIVER_STRING(mem_ctx
,
4979 driver
->hardware_id
,
4981 FILL_DRIVER_STRING(mem_ctx
,
4988 /********************************************************************
4989 ********************************************************************/
4991 static WERROR
construct_printer_driver_info_level(TALLOC_CTX
*mem_ctx
,
4992 struct auth_serversupplied_info
*server_info
,
4994 union spoolss_DriverInfo
*r
,
4996 const char *servername
,
4997 const char *architecture
,
5000 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
5001 struct spoolss_DriverInfo8
*driver
;
5005 return WERR_UNKNOWN_LEVEL
;
5008 result
= winreg_get_printer(mem_ctx
,
5011 lp_const_servicename(snum
),
5014 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5015 win_errstr(result
)));
5017 if (!W_ERROR_IS_OK(result
)) {
5018 return WERR_INVALID_PRINTER_NAME
;
5021 result
= winreg_get_driver(mem_ctx
, server_info
, architecture
,
5022 pinfo2
->drivername
, version
, &driver
);
5024 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5025 win_errstr(result
)));
5027 if (!W_ERROR_IS_OK(result
)) {
5029 * Is this a W2k client ?
5033 talloc_free(pinfo2
);
5034 return WERR_UNKNOWN_PRINTER_DRIVER
;
5037 /* Yes - try again with a WinNT driver. */
5039 result
= winreg_get_driver(mem_ctx
, server_info
, architecture
,
5042 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5043 win_errstr(result
)));
5044 if (!W_ERROR_IS_OK(result
)) {
5045 talloc_free(pinfo2
);
5046 return WERR_UNKNOWN_PRINTER_DRIVER
;
5052 result
= fill_printer_driver_info1(mem_ctx
, &r
->info1
, driver
, servername
);
5055 result
= fill_printer_driver_info2(mem_ctx
, &r
->info2
, driver
, servername
);
5058 result
= fill_printer_driver_info3(mem_ctx
, &r
->info3
, driver
, servername
);
5061 result
= fill_printer_driver_info4(mem_ctx
, &r
->info4
, driver
, servername
);
5064 result
= fill_printer_driver_info5(mem_ctx
, &r
->info5
, driver
, servername
);
5067 result
= fill_printer_driver_info6(mem_ctx
, &r
->info6
, driver
, servername
);
5070 result
= fill_printer_driver_info8(mem_ctx
, &r
->info8
, driver
, servername
);
5072 #if 0 /* disabled until marshalling issues are resolved - gd */
5074 result
= fill_printer_driver_info101(mem_ctx
, &r
->info101
, driver
, servername
);
5078 result
= WERR_UNKNOWN_LEVEL
;
5082 talloc_free(pinfo2
);
5083 talloc_free(driver
);
5088 /****************************************************************
5089 _spoolss_GetPrinterDriver2
5090 ****************************************************************/
5092 WERROR
_spoolss_GetPrinterDriver2(struct pipes_struct
*p
,
5093 struct spoolss_GetPrinterDriver2
*r
)
5095 Printer_entry
*printer
;
5100 /* that's an [in out] buffer */
5102 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
5103 return WERR_INVALID_PARAM
;
5106 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5108 if (!(printer
= find_printer_index_by_hnd(p
, r
->in
.handle
))) {
5109 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5110 return WERR_INVALID_PRINTER_NAME
;
5114 *r
->out
.server_major_version
= 0;
5115 *r
->out
.server_minor_version
= 0;
5117 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5121 result
= construct_printer_driver_info_level(p
->mem_ctx
, p
->server_info
,
5122 r
->in
.level
, r
->out
.info
,
5123 snum
, printer
->servername
,
5125 r
->in
.client_major_version
);
5126 if (!W_ERROR_IS_OK(result
)) {
5127 TALLOC_FREE(r
->out
.info
);
5131 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_DriverInfo
,
5132 r
->out
.info
, r
->in
.level
);
5133 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
5135 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
5139 /****************************************************************
5140 _spoolss_StartPagePrinter
5141 ****************************************************************/
5143 WERROR
_spoolss_StartPagePrinter(struct pipes_struct
*p
,
5144 struct spoolss_StartPagePrinter
*r
)
5146 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5149 DEBUG(3,("_spoolss_StartPagePrinter: "
5150 "Error in startpageprinter printer handle\n"));
5154 Printer
->page_started
= true;
5158 /****************************************************************
5159 _spoolss_EndPagePrinter
5160 ****************************************************************/
5162 WERROR
_spoolss_EndPagePrinter(struct pipes_struct
*p
,
5163 struct spoolss_EndPagePrinter
*r
)
5167 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5170 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5171 OUR_HANDLE(r
->in
.handle
)));
5175 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5178 Printer
->page_started
= false;
5179 print_job_endpage(snum
, Printer
->jobid
);
5184 /****************************************************************
5185 _spoolss_StartDocPrinter
5186 ****************************************************************/
5188 WERROR
_spoolss_StartDocPrinter(struct pipes_struct
*p
,
5189 struct spoolss_StartDocPrinter
*r
)
5191 struct spoolss_DocumentInfo1
*info_1
;
5193 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5197 DEBUG(2,("_spoolss_StartDocPrinter: "
5198 "Invalid handle (%s:%u:%u)\n",
5199 OUR_HANDLE(r
->in
.handle
)));
5203 if (Printer
->jobid
) {
5204 DEBUG(2, ("_spoolss_StartDocPrinter: "
5205 "StartDocPrinter called twice! "
5206 "(existing jobid = %d)\n", Printer
->jobid
));
5207 return WERR_INVALID_HANDLE
;
5210 if (r
->in
.level
!= 1) {
5211 return WERR_UNKNOWN_LEVEL
;
5214 info_1
= r
->in
.info
.info1
;
5217 * a nice thing with NT is it doesn't listen to what you tell it.
5218 * when asked to send _only_ RAW datas, it tries to send datas
5221 * So I add checks like in NT Server ...
5224 if (info_1
->datatype
) {
5225 if (strcmp(info_1
->datatype
, "RAW") != 0) {
5227 return WERR_INVALID_DATATYPE
;
5231 /* get the share number of the printer */
5232 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5236 werr
= print_job_start(p
->server_info
, snum
,
5237 info_1
->document_name
, info_1
->output_file
,
5238 Printer
->devmode
, &Printer
->jobid
);
5240 /* An error occured in print_job_start() so return an appropriate
5243 if (!W_ERROR_IS_OK(werr
)) {
5247 Printer
->document_started
= true;
5248 *r
->out
.job_id
= Printer
->jobid
;
5253 /****************************************************************
5254 _spoolss_EndDocPrinter
5255 ****************************************************************/
5257 WERROR
_spoolss_EndDocPrinter(struct pipes_struct
*p
,
5258 struct spoolss_EndDocPrinter
*r
)
5260 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5265 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5266 OUR_HANDLE(r
->in
.handle
)));
5270 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5274 Printer
->document_started
= false;
5275 status
= print_job_end(snum
, Printer
->jobid
, NORMAL_CLOSE
);
5276 if (!NT_STATUS_IS_OK(status
)) {
5277 DEBUG(2, ("_spoolss_EndDocPrinter: "
5278 "print_job_end failed [%s]\n",
5279 nt_errstr(status
)));
5283 return ntstatus_to_werror(status
);
5286 /****************************************************************
5287 _spoolss_WritePrinter
5288 ****************************************************************/
5290 WERROR
_spoolss_WritePrinter(struct pipes_struct
*p
,
5291 struct spoolss_WritePrinter
*r
)
5293 ssize_t buffer_written
;
5295 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5298 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5299 OUR_HANDLE(r
->in
.handle
)));
5300 *r
->out
.num_written
= r
->in
._data_size
;
5304 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5307 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5308 buffer_written
= print_job_write(snum
, Printer
->jobid
,
5309 (const char *)r
->in
.data
.data
,
5311 (size_t)r
->in
._data_size
);
5312 if (buffer_written
== (ssize_t
)-1) {
5313 *r
->out
.num_written
= 0;
5314 if (errno
== ENOSPC
)
5315 return WERR_NO_SPOOL_SPACE
;
5317 return WERR_ACCESS_DENIED
;
5320 *r
->out
.num_written
= r
->in
._data_size
;
5325 /********************************************************************
5326 * api_spoolss_getprinter
5327 * called from the spoolss dispatcher
5329 ********************************************************************/
5331 static WERROR
control_printer(struct policy_handle
*handle
, uint32_t command
,
5332 struct pipes_struct
*p
)
5335 WERROR errcode
= WERR_BADFUNC
;
5336 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5339 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5340 OUR_HANDLE(handle
)));
5344 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5348 case SPOOLSS_PRINTER_CONTROL_PAUSE
:
5349 errcode
= print_queue_pause(p
->server_info
, snum
);
5351 case SPOOLSS_PRINTER_CONTROL_RESUME
:
5352 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
:
5353 errcode
= print_queue_resume(p
->server_info
, snum
);
5355 case SPOOLSS_PRINTER_CONTROL_PURGE
:
5356 errcode
= print_queue_purge(p
->server_info
, snum
);
5359 return WERR_UNKNOWN_LEVEL
;
5366 /****************************************************************
5367 _spoolss_AbortPrinter
5368 * From MSDN: "Deletes printer's spool file if printer is configured
5370 ****************************************************************/
5372 WERROR
_spoolss_AbortPrinter(struct pipes_struct
*p
,
5373 struct spoolss_AbortPrinter
*r
)
5375 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5377 WERROR errcode
= WERR_OK
;
5380 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5381 OUR_HANDLE(r
->in
.handle
)));
5385 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5388 if (!Printer
->document_started
) {
5389 return WERR_SPL_NO_STARTDOC
;
5392 errcode
= print_job_delete(p
->server_info
, snum
, Printer
->jobid
);
5397 /********************************************************************
5398 * called by spoolss_api_setprinter
5399 * when updating a printer description
5400 ********************************************************************/
5402 static WERROR
update_printer_sec(struct policy_handle
*handle
,
5403 struct pipes_struct
*p
,
5404 struct sec_desc_buf
*secdesc_ctr
)
5406 struct spoolss_security_descriptor
*new_secdesc
= NULL
;
5407 struct spoolss_security_descriptor
*old_secdesc
= NULL
;
5408 const char *printer
;
5412 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5414 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
5415 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5416 OUR_HANDLE(handle
)));
5418 result
= WERR_BADFID
;
5422 if (secdesc_ctr
== NULL
) {
5423 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5424 result
= WERR_INVALID_PARAM
;
5427 printer
= lp_const_servicename(snum
);
5429 /* Check the user has permissions to change the security
5430 descriptor. By experimentation with two NT machines, the user
5431 requires Full Access to the printer to change security
5434 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
5435 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5436 result
= WERR_ACCESS_DENIED
;
5440 /* NT seems to like setting the security descriptor even though
5441 nothing may have actually changed. */
5442 result
= winreg_get_printer_secdesc(p
->mem_ctx
,
5446 if (!W_ERROR_IS_OK(result
)) {
5447 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5448 result
= WERR_BADFID
;
5452 if (DEBUGLEVEL
>= 10) {
5453 struct security_acl
*the_acl
;
5456 the_acl
= old_secdesc
->dacl
;
5457 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5458 printer
, the_acl
->num_aces
));
5460 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5461 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5462 &the_acl
->aces
[i
].trustee
),
5463 the_acl
->aces
[i
].access_mask
));
5466 the_acl
= secdesc_ctr
->sd
->dacl
;
5469 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5470 printer
, the_acl
->num_aces
));
5472 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5473 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5474 &the_acl
->aces
[i
].trustee
),
5475 the_acl
->aces
[i
].access_mask
));
5478 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5482 new_secdesc
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
->sd
, old_secdesc
);
5483 if (new_secdesc
== NULL
) {
5484 result
= WERR_NOMEM
;
5488 if (security_descriptor_equal(new_secdesc
, old_secdesc
)) {
5493 result
= winreg_set_printer_secdesc(p
->mem_ctx
,
5502 /********************************************************************
5503 Canonicalize printer info from a client
5504 ********************************************************************/
5506 static bool check_printer_ok(TALLOC_CTX
*mem_ctx
,
5507 struct spoolss_SetPrinterInfo2
*info2
,
5510 fstring printername
;
5513 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5514 "portname=%s drivername=%s comment=%s location=%s\n",
5515 info2
->servername
, info2
->printername
, info2
->sharename
,
5516 info2
->portname
, info2
->drivername
, info2
->comment
,
5519 /* we force some elements to "correct" values */
5520 info2
->servername
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
5521 if (info2
->servername
== NULL
) {
5524 info2
->sharename
= talloc_strdup(mem_ctx
, lp_const_servicename(snum
));
5525 if (info2
->sharename
== NULL
) {
5529 /* check to see if we allow printername != sharename */
5530 if (lp_force_printername(snum
)) {
5531 info2
->printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
5532 global_myname(), info2
->sharename
);
5534 /* make sure printername is in \\server\printername format */
5535 fstrcpy(printername
, info2
->printername
);
5537 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
5538 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
5542 info2
->printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
5543 global_myname(), p
);
5545 if (info2
->printername
== NULL
) {
5549 info2
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
5550 info2
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
5555 /****************************************************************************
5556 ****************************************************************************/
5558 static WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
5560 char *cmd
= lp_addport_cmd();
5561 char *command
= NULL
;
5563 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
5564 bool is_print_op
= false;
5567 return WERR_ACCESS_DENIED
;
5570 command
= talloc_asprintf(ctx
,
5571 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
5577 is_print_op
= user_has_privileges( token
, &se_printop
);
5579 DEBUG(10,("Running [%s]\n", command
));
5581 /********* BEGIN SePrintOperatorPrivilege **********/
5586 ret
= smbrun(command
, NULL
);
5591 /********* END SePrintOperatorPrivilege **********/
5593 DEBUGADD(10,("returned [%d]\n", ret
));
5595 TALLOC_FREE(command
);
5598 return WERR_ACCESS_DENIED
;
5604 /****************************************************************************
5605 ****************************************************************************/
5607 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
,
5608 struct spoolss_SetPrinterInfo2
*info2
,
5609 const char *remote_machine
)
5611 char *cmd
= lp_addprinter_cmd();
5613 char *command
= NULL
;
5617 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
5618 bool is_print_op
= false;
5620 if (!remote_machine
) {
5624 command
= talloc_asprintf(ctx
,
5625 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5626 cmd
, info2
->printername
, info2
->sharename
,
5627 info2
->portname
, info2
->drivername
,
5628 info2
->location
, info2
->comment
, remote_machine
);
5634 is_print_op
= user_has_privileges( token
, &se_printop
);
5636 DEBUG(10,("Running [%s]\n", command
));
5638 /********* BEGIN SePrintOperatorPrivilege **********/
5643 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
5644 /* Tell everyone we updated smb.conf. */
5645 message_send_all(smbd_messaging_context(),
5646 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
5652 /********* END SePrintOperatorPrivilege **********/
5654 DEBUGADD(10,("returned [%d]\n", ret
));
5656 TALLOC_FREE(command
);
5664 /* reload our services immediately */
5666 reload_services(false);
5670 /* Get lines and convert them back to dos-codepage */
5671 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
5672 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5675 /* Set the portname to what the script says the portname should be. */
5676 /* but don't require anything to be return from the script exit a good error code */
5679 /* Set the portname to what the script says the portname should be. */
5680 info2
->portname
= talloc_strdup(ctx
, qlines
[0]);
5681 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
5684 TALLOC_FREE(qlines
);
5688 static WERROR
update_dsspooler(TALLOC_CTX
*mem_ctx
,
5689 struct auth_serversupplied_info
*server_info
,
5691 struct spoolss_SetPrinterInfo2
*printer
,
5692 struct spoolss_PrinterInfo2
*old_printer
)
5694 bool force_update
= (old_printer
== NULL
);
5695 const char *dnsdomname
;
5696 const char *longname
;
5697 const char *uncname
;
5698 const char *spooling
;
5700 WERROR result
= WERR_OK
;
5702 if (force_update
|| !strequal(printer
->drivername
, old_printer
->drivername
)) {
5703 push_reg_sz(mem_ctx
, &buffer
, printer
->drivername
);
5704 winreg_set_printer_dataex(mem_ctx
,
5707 SPOOL_DSSPOOLER_KEY
,
5708 SPOOL_REG_DRIVERNAME
,
5713 if (!force_update
) {
5714 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5715 printer
->drivername
));
5717 notify_printer_driver(snum
, printer
->drivername
);
5721 if (force_update
|| !strequal(printer
->comment
, old_printer
->comment
)) {
5722 push_reg_sz(mem_ctx
, &buffer
, printer
->comment
);
5723 winreg_set_printer_dataex(mem_ctx
,
5726 SPOOL_DSSPOOLER_KEY
,
5727 SPOOL_REG_DESCRIPTION
,
5732 if (!force_update
) {
5733 notify_printer_comment(snum
, printer
->comment
);
5737 if (force_update
|| !strequal(printer
->sharename
, old_printer
->sharename
)) {
5738 push_reg_sz(mem_ctx
, &buffer
, printer
->sharename
);
5739 winreg_set_printer_dataex(mem_ctx
,
5742 SPOOL_DSSPOOLER_KEY
,
5743 SPOOL_REG_PRINTSHARENAME
,
5748 if (!force_update
) {
5749 notify_printer_sharename(snum
, printer
->sharename
);
5753 if (force_update
|| !strequal(printer
->printername
, old_printer
->printername
)) {
5756 p
= strrchr(printer
->printername
, '\\' );
5760 p
= printer
->printername
;
5763 push_reg_sz(mem_ctx
, &buffer
, p
);
5764 winreg_set_printer_dataex(mem_ctx
,
5767 SPOOL_DSSPOOLER_KEY
,
5768 SPOOL_REG_PRINTERNAME
,
5773 if (!force_update
) {
5774 notify_printer_printername(snum
, p
);
5778 if (force_update
|| !strequal(printer
->portname
, old_printer
->portname
)) {
5779 push_reg_sz(mem_ctx
, &buffer
, printer
->portname
);
5780 winreg_set_printer_dataex(mem_ctx
,
5783 SPOOL_DSSPOOLER_KEY
,
5789 if (!force_update
) {
5790 notify_printer_port(snum
, printer
->portname
);
5794 if (force_update
|| !strequal(printer
->location
, old_printer
->location
)) {
5795 push_reg_sz(mem_ctx
, &buffer
, printer
->location
);
5796 winreg_set_printer_dataex(mem_ctx
,
5799 SPOOL_DSSPOOLER_KEY
,
5805 if (!force_update
) {
5806 notify_printer_location(snum
, printer
->location
);
5810 if (force_update
|| !strequal(printer
->sepfile
, old_printer
->sepfile
)) {
5811 push_reg_sz(mem_ctx
, &buffer
, printer
->sepfile
);
5812 winreg_set_printer_dataex(mem_ctx
,
5815 SPOOL_DSSPOOLER_KEY
,
5816 SPOOL_REG_PRINTSEPARATORFILE
,
5821 if (!force_update
) {
5822 notify_printer_location(snum
, printer
->location
);
5826 if (force_update
|| printer
->starttime
!= old_printer
->starttime
) {
5827 buffer
= data_blob_talloc(mem_ctx
, NULL
, 4);
5828 SIVAL(buffer
.data
, 0, printer
->starttime
);
5829 winreg_set_printer_dataex(mem_ctx
,
5832 SPOOL_DSSPOOLER_KEY
,
5833 SPOOL_REG_PRINTSTARTTIME
,
5839 if (force_update
|| printer
->untiltime
!= old_printer
->untiltime
) {
5840 buffer
= data_blob_talloc(mem_ctx
, NULL
, 4);
5841 SIVAL(buffer
.data
, 0, printer
->untiltime
);
5842 winreg_set_printer_dataex(mem_ctx
,
5845 SPOOL_DSSPOOLER_KEY
,
5846 SPOOL_REG_PRINTENDTIME
,
5852 if (force_update
|| printer
->priority
!= old_printer
->priority
) {
5853 buffer
= data_blob_talloc(mem_ctx
, NULL
, 4);
5854 SIVAL(buffer
.data
, 0, printer
->priority
);
5855 winreg_set_printer_dataex(mem_ctx
,
5858 SPOOL_DSSPOOLER_KEY
,
5865 if (force_update
|| printer
->attributes
!= old_printer
->attributes
) {
5866 buffer
= data_blob_talloc(mem_ctx
, NULL
, 4);
5867 SIVAL(buffer
.data
, 0, (printer
->attributes
&
5868 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS
));
5869 winreg_set_printer_dataex(mem_ctx
,
5872 SPOOL_DSSPOOLER_KEY
,
5873 SPOOL_REG_PRINTKEEPPRINTEDJOBS
,
5878 switch (printer
->attributes
& 0x3) {
5880 spooling
= SPOOL_REGVAL_PRINTWHILESPOOLING
;
5883 spooling
= SPOOL_REGVAL_PRINTAFTERSPOOLED
;
5886 spooling
= SPOOL_REGVAL_PRINTDIRECT
;
5889 spooling
= "unknown";
5891 push_reg_sz(mem_ctx
, &buffer
, spooling
);
5892 winreg_set_printer_dataex(mem_ctx
,
5895 SPOOL_DSSPOOLER_KEY
,
5896 SPOOL_REG_PRINTSPOOLING
,
5902 push_reg_sz(mem_ctx
, &buffer
, global_myname());
5903 winreg_set_printer_dataex(mem_ctx
,
5906 SPOOL_DSSPOOLER_KEY
,
5907 SPOOL_REG_SHORTSERVERNAME
,
5912 dnsdomname
= get_mydnsfullname();
5913 if (dnsdomname
!= NULL
&& dnsdomname
[0] != '\0') {
5914 longname
= talloc_strdup(mem_ctx
, dnsdomname
);
5916 longname
= talloc_strdup(mem_ctx
, global_myname());
5918 if (longname
== NULL
) {
5919 result
= WERR_NOMEM
;
5923 push_reg_sz(mem_ctx
, &buffer
, longname
);
5924 winreg_set_printer_dataex(mem_ctx
,
5927 SPOOL_DSSPOOLER_KEY
,
5928 SPOOL_REG_SERVERNAME
,
5933 uncname
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
5934 global_myname(), printer
->sharename
);
5935 push_reg_sz(mem_ctx
, &buffer
, uncname
);
5936 winreg_set_printer_dataex(mem_ctx
,
5939 SPOOL_DSSPOOLER_KEY
,
5949 /********************************************************************
5950 * Called by spoolss_api_setprinter
5951 * when updating a printer description.
5952 ********************************************************************/
5954 static WERROR
update_printer(struct pipes_struct
*p
,
5955 struct policy_handle
*handle
,
5956 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
5957 struct spoolss_DeviceMode
*devmode
)
5959 uint32_t printer_mask
= SPOOLSS_PRINTER_INFO_ALL
;
5960 struct spoolss_SetPrinterInfo2
*printer
= info_ctr
->info
.info2
;
5961 struct spoolss_PrinterInfo2
*old_printer
;
5962 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5963 const char *servername
= NULL
;
5965 WERROR result
= WERR_OK
;
5966 TALLOC_CTX
*tmp_ctx
;
5968 DEBUG(8,("update_printer\n"));
5970 tmp_ctx
= talloc_new(p
->mem_ctx
);
5971 if (tmp_ctx
== NULL
) {
5976 result
= WERR_BADFID
;
5980 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5981 result
= WERR_BADFID
;
5985 if (Printer
!= NULL
|| Printer
->servername
!= NULL
) {
5986 servername
= Printer
->servername
;
5989 result
= winreg_get_printer(tmp_ctx
,
5992 lp_const_servicename(snum
),
5994 if (!W_ERROR_IS_OK(result
)) {
5995 result
= WERR_BADFID
;
5999 /* Do sanity check on the requested changes for Samba */
6000 if (!check_printer_ok(tmp_ctx
, printer
, snum
)) {
6001 result
= WERR_INVALID_PARAM
;
6005 /* FIXME!!! If the driver has changed we really should verify that
6006 it is installed before doing much else --jerry */
6008 /* Check calling user has permission to update printer description */
6009 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6010 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6011 result
= WERR_ACCESS_DENIED
;
6015 /* Call addprinter hook */
6016 /* Check changes to see if this is really needed */
6018 if (*lp_addprinter_cmd() &&
6019 (!strequal(printer
->drivername
, old_printer
->drivername
) ||
6020 !strequal(printer
->comment
, old_printer
->comment
) ||
6021 !strequal(printer
->portname
, old_printer
->portname
) ||
6022 !strequal(printer
->location
, old_printer
->location
)) )
6024 /* add_printer_hook() will call reload_services() */
6025 if (!add_printer_hook(tmp_ctx
, p
->server_info
->ptok
,
6026 printer
, p
->client_address
) ) {
6027 result
= WERR_ACCESS_DENIED
;
6032 update_dsspooler(tmp_ctx
,
6038 printer_mask
&= ~SPOOLSS_PRINTER_INFO_SECDESC
;
6040 if (devmode
== NULL
) {
6041 printer_mask
&= ~SPOOLSS_PRINTER_INFO_DEVMODE
;
6043 result
= winreg_update_printer(tmp_ctx
,
6052 talloc_free(tmp_ctx
);
6057 /****************************************************************************
6058 ****************************************************************************/
6059 static WERROR
publish_or_unpublish_printer(struct pipes_struct
*p
,
6060 struct policy_handle
*handle
,
6061 struct spoolss_SetPrinterInfo7
*info7
)
6064 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
6067 Printer_entry
*Printer
;
6069 if ( lp_security() != SEC_ADS
) {
6070 return WERR_UNKNOWN_LEVEL
;
6073 Printer
= find_printer_index_by_hnd(p
, handle
);
6075 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6080 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6083 result
= winreg_get_printer(p
->mem_ctx
, p
->server_info
,
6084 Printer
->servername
,
6085 lp_servicename(snum
), &pinfo2
);
6086 if (!W_ERROR_IS_OK(result
)) {
6090 nt_printer_publish(pinfo2
, p
->server_info
, pinfo2
, info7
->action
);
6092 TALLOC_FREE(pinfo2
);
6095 return WERR_UNKNOWN_LEVEL
;
6099 /********************************************************************
6100 ********************************************************************/
6102 static WERROR
update_printer_devmode(struct pipes_struct
*p
,
6103 struct policy_handle
*handle
,
6104 struct spoolss_DeviceMode
*devmode
)
6107 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6108 uint32_t info2_mask
= SPOOLSS_PRINTER_INFO_DEVMODE
;
6110 DEBUG(8,("update_printer_devmode\n"));
6116 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6120 /* Check calling user has permission to update printer description */
6121 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6122 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6123 return WERR_ACCESS_DENIED
;
6126 return winreg_update_printer(p
->mem_ctx
,
6128 lp_const_servicename(snum
),
6136 /****************************************************************
6138 ****************************************************************/
6140 WERROR
_spoolss_SetPrinter(struct pipes_struct
*p
,
6141 struct spoolss_SetPrinter
*r
)
6145 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
6148 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6149 OUR_HANDLE(r
->in
.handle
)));
6153 /* check the level */
6154 switch (r
->in
.info_ctr
->level
) {
6156 return control_printer(r
->in
.handle
, r
->in
.command
, p
);
6158 result
= update_printer(p
, r
->in
.handle
,
6160 r
->in
.devmode_ctr
->devmode
);
6161 if (!W_ERROR_IS_OK(result
))
6163 if (r
->in
.secdesc_ctr
->sd
)
6164 result
= update_printer_sec(r
->in
.handle
, p
,
6168 return update_printer_sec(r
->in
.handle
, p
,
6171 return publish_or_unpublish_printer(p
, r
->in
.handle
,
6172 r
->in
.info_ctr
->info
.info7
);
6174 return update_printer_devmode(p
, r
->in
.handle
,
6175 r
->in
.devmode_ctr
->devmode
);
6177 return WERR_UNKNOWN_LEVEL
;
6181 /****************************************************************
6182 _spoolss_FindClosePrinterNotify
6183 ****************************************************************/
6185 WERROR
_spoolss_FindClosePrinterNotify(struct pipes_struct
*p
,
6186 struct spoolss_FindClosePrinterNotify
*r
)
6188 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
6191 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6192 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r
->in
.handle
)));
6196 if (Printer
->notify
.client_connected
== true) {
6199 if ( Printer
->printer_type
== SPLHND_SERVER
)
6201 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6202 !get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
) )
6205 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6208 Printer
->notify
.flags
=0;
6209 Printer
->notify
.options
=0;
6210 Printer
->notify
.localmachine
[0]='\0';
6211 Printer
->notify
.printerlocal
=0;
6212 TALLOC_FREE(Printer
->notify
.option
);
6213 Printer
->notify
.client_connected
= false;
6218 /****************************************************************
6220 ****************************************************************/
6222 WERROR
_spoolss_AddJob(struct pipes_struct
*p
,
6223 struct spoolss_AddJob
*r
)
6225 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6226 return WERR_INVALID_PARAM
;
6229 /* this is what a NT server returns for AddJob. AddJob must fail on
6230 * non-local printers */
6232 if (r
->in
.level
!= 1) {
6233 return WERR_UNKNOWN_LEVEL
;
6236 return WERR_INVALID_PARAM
;
6239 /****************************************************************************
6241 ****************************************************************************/
6243 static WERROR
fill_job_info1(TALLOC_CTX
*mem_ctx
,
6244 struct spoolss_JobInfo1
*r
,
6245 const print_queue_struct
*queue
,
6246 int position
, int snum
,
6247 struct spoolss_PrinterInfo2
*pinfo2
)
6251 t
= gmtime(&queue
->time
);
6253 r
->job_id
= queue
->job
;
6255 r
->printer_name
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
6256 W_ERROR_HAVE_NO_MEMORY(r
->printer_name
);
6257 r
->server_name
= talloc_strdup(mem_ctx
, pinfo2
->servername
);
6258 W_ERROR_HAVE_NO_MEMORY(r
->server_name
);
6259 r
->user_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
6260 W_ERROR_HAVE_NO_MEMORY(r
->user_name
);
6261 r
->document_name
= talloc_strdup(mem_ctx
, queue
->fs_file
);
6262 W_ERROR_HAVE_NO_MEMORY(r
->document_name
);
6263 r
->data_type
= talloc_strdup(mem_ctx
, "RAW");
6264 W_ERROR_HAVE_NO_MEMORY(r
->data_type
);
6265 r
->text_status
= talloc_strdup(mem_ctx
, "");
6266 W_ERROR_HAVE_NO_MEMORY(r
->text_status
);
6268 r
->status
= nt_printj_status(queue
->status
);
6269 r
->priority
= queue
->priority
;
6270 r
->position
= position
;
6271 r
->total_pages
= queue
->page_count
;
6272 r
->pages_printed
= 0; /* ??? */
6274 init_systemtime(&r
->submitted
, t
);
6279 /****************************************************************************
6281 ****************************************************************************/
6283 static WERROR
fill_job_info2(TALLOC_CTX
*mem_ctx
,
6284 struct spoolss_JobInfo2
*r
,
6285 const print_queue_struct
*queue
,
6286 int position
, int snum
,
6287 struct spoolss_PrinterInfo2
*pinfo2
,
6288 struct spoolss_DeviceMode
*devmode
)
6292 t
= gmtime(&queue
->time
);
6294 r
->job_id
= queue
->job
;
6296 r
->printer_name
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
6297 W_ERROR_HAVE_NO_MEMORY(r
->printer_name
);
6298 r
->server_name
= talloc_strdup(mem_ctx
, pinfo2
->servername
);
6299 W_ERROR_HAVE_NO_MEMORY(r
->server_name
);
6300 r
->user_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
6301 W_ERROR_HAVE_NO_MEMORY(r
->user_name
);
6302 r
->document_name
= talloc_strdup(mem_ctx
, queue
->fs_file
);
6303 W_ERROR_HAVE_NO_MEMORY(r
->document_name
);
6304 r
->notify_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
6305 W_ERROR_HAVE_NO_MEMORY(r
->notify_name
);
6306 r
->data_type
= talloc_strdup(mem_ctx
, "RAW");
6307 W_ERROR_HAVE_NO_MEMORY(r
->data_type
);
6308 r
->print_processor
= talloc_strdup(mem_ctx
, "winprint");
6309 W_ERROR_HAVE_NO_MEMORY(r
->print_processor
);
6310 r
->parameters
= talloc_strdup(mem_ctx
, "");
6311 W_ERROR_HAVE_NO_MEMORY(r
->parameters
);
6312 r
->driver_name
= talloc_strdup(mem_ctx
, pinfo2
->drivername
);
6313 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
6315 r
->devmode
= devmode
;
6317 r
->text_status
= talloc_strdup(mem_ctx
, "");
6318 W_ERROR_HAVE_NO_MEMORY(r
->text_status
);
6322 r
->status
= nt_printj_status(queue
->status
);
6323 r
->priority
= queue
->priority
;
6324 r
->position
= position
;
6327 r
->total_pages
= queue
->page_count
;
6328 r
->size
= queue
->size
;
6329 init_systemtime(&r
->submitted
, t
);
6331 r
->pages_printed
= 0; /* ??? */
6336 /****************************************************************************
6338 ****************************************************************************/
6340 static WERROR
fill_job_info3(TALLOC_CTX
*mem_ctx
,
6341 struct spoolss_JobInfo3
*r
,
6342 const print_queue_struct
*queue
,
6343 const print_queue_struct
*next_queue
,
6344 int position
, int snum
,
6345 struct spoolss_PrinterInfo2
*pinfo2
)
6347 r
->job_id
= queue
->job
;
6350 r
->next_job_id
= next_queue
->job
;
6357 /****************************************************************************
6358 Enumjobs at level 1.
6359 ****************************************************************************/
6361 static WERROR
enumjobs_level1(TALLOC_CTX
*mem_ctx
,
6362 const print_queue_struct
*queue
,
6363 uint32_t num_queues
, int snum
,
6364 struct spoolss_PrinterInfo2
*pinfo2
,
6365 union spoolss_JobInfo
**info_p
,
6368 union spoolss_JobInfo
*info
;
6370 WERROR result
= WERR_OK
;
6372 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6373 W_ERROR_HAVE_NO_MEMORY(info
);
6375 *count
= num_queues
;
6377 for (i
=0; i
<*count
; i
++) {
6378 result
= fill_job_info1(info
,
6384 if (!W_ERROR_IS_OK(result
)) {
6390 if (!W_ERROR_IS_OK(result
)) {
6401 /****************************************************************************
6402 Enumjobs at level 2.
6403 ****************************************************************************/
6405 static WERROR
enumjobs_level2(TALLOC_CTX
*mem_ctx
,
6406 const print_queue_struct
*queue
,
6407 uint32_t num_queues
, int snum
,
6408 struct spoolss_PrinterInfo2
*pinfo2
,
6409 union spoolss_JobInfo
**info_p
,
6412 union spoolss_JobInfo
*info
;
6414 WERROR result
= WERR_OK
;
6416 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6417 W_ERROR_HAVE_NO_MEMORY(info
);
6419 *count
= num_queues
;
6421 for (i
=0; i
<*count
; i
++) {
6422 struct spoolss_DeviceMode
*devmode
;
6424 result
= spoolss_create_default_devmode(info
,
6425 pinfo2
->printername
,
6427 if (!W_ERROR_IS_OK(result
)) {
6428 DEBUG(3, ("Can't proceed w/o a devmode!"));
6432 result
= fill_job_info2(info
,
6439 if (!W_ERROR_IS_OK(result
)) {
6445 if (!W_ERROR_IS_OK(result
)) {
6456 /****************************************************************************
6457 Enumjobs at level 3.
6458 ****************************************************************************/
6460 static WERROR
enumjobs_level3(TALLOC_CTX
*mem_ctx
,
6461 const print_queue_struct
*queue
,
6462 uint32_t num_queues
, int snum
,
6463 struct spoolss_PrinterInfo2
*pinfo2
,
6464 union spoolss_JobInfo
**info_p
,
6467 union spoolss_JobInfo
*info
;
6469 WERROR result
= WERR_OK
;
6471 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6472 W_ERROR_HAVE_NO_MEMORY(info
);
6474 *count
= num_queues
;
6476 for (i
=0; i
<*count
; i
++) {
6477 const print_queue_struct
*next_queue
= NULL
;
6480 next_queue
= &queue
[i
+1];
6483 result
= fill_job_info3(info
,
6490 if (!W_ERROR_IS_OK(result
)) {
6496 if (!W_ERROR_IS_OK(result
)) {
6507 /****************************************************************
6509 ****************************************************************/
6511 WERROR
_spoolss_EnumJobs(struct pipes_struct
*p
,
6512 struct spoolss_EnumJobs
*r
)
6515 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
6517 print_status_struct prt_status
;
6518 print_queue_struct
*queue
= NULL
;
6521 /* that's an [in out] buffer */
6523 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6524 return WERR_INVALID_PARAM
;
6527 DEBUG(4,("_spoolss_EnumJobs\n"));
6531 *r
->out
.info
= NULL
;
6533 /* lookup the printer snum and tdb entry */
6535 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
6539 result
= winreg_get_printer(p
->mem_ctx
, p
->server_info
, NULL
,
6540 lp_servicename(snum
), &pinfo2
);
6541 if (!W_ERROR_IS_OK(result
)) {
6545 count
= print_queue_status(snum
, &queue
, &prt_status
);
6546 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6547 count
, prt_status
.status
, prt_status
.message
));
6551 TALLOC_FREE(pinfo2
);
6555 switch (r
->in
.level
) {
6557 result
= enumjobs_level1(p
->mem_ctx
, queue
, count
, snum
,
6558 pinfo2
, r
->out
.info
, r
->out
.count
);
6561 result
= enumjobs_level2(p
->mem_ctx
, queue
, count
, snum
,
6562 pinfo2
, r
->out
.info
, r
->out
.count
);
6565 result
= enumjobs_level3(p
->mem_ctx
, queue
, count
, snum
,
6566 pinfo2
, r
->out
.info
, r
->out
.count
);
6569 result
= WERR_UNKNOWN_LEVEL
;
6574 TALLOC_FREE(pinfo2
);
6576 if (!W_ERROR_IS_OK(result
)) {
6580 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6582 *r
->out
.info
, r
->in
.level
,
6584 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6585 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6587 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6590 /****************************************************************
6591 _spoolss_ScheduleJob
6592 ****************************************************************/
6594 WERROR
_spoolss_ScheduleJob(struct pipes_struct
*p
,
6595 struct spoolss_ScheduleJob
*r
)
6600 /****************************************************************
6601 ****************************************************************/
6603 static WERROR
spoolss_setjob_1(TALLOC_CTX
*mem_ctx
,
6604 const char *printer_name
,
6606 struct spoolss_SetJobInfo1
*r
)
6610 if (!print_job_get_name(mem_ctx
, printer_name
, job_id
, &old_doc_name
)) {
6614 if (strequal(old_doc_name
, r
->document_name
)) {
6618 if (!print_job_set_name(printer_name
, job_id
, r
->document_name
)) {
6625 /****************************************************************
6627 ****************************************************************/
6629 WERROR
_spoolss_SetJob(struct pipes_struct
*p
,
6630 struct spoolss_SetJob
*r
)
6633 WERROR errcode
= WERR_BADFUNC
;
6635 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
6639 if (!print_job_exists(lp_const_servicename(snum
), r
->in
.job_id
)) {
6640 return WERR_INVALID_PRINTER_NAME
;
6643 switch (r
->in
.command
) {
6644 case SPOOLSS_JOB_CONTROL_CANCEL
:
6645 case SPOOLSS_JOB_CONTROL_DELETE
:
6646 errcode
= print_job_delete(p
->server_info
,
6647 snum
, r
->in
.job_id
);
6648 if (W_ERROR_EQUAL(errcode
, WERR_PRINTER_HAS_JOBS_QUEUED
)) {
6652 case SPOOLSS_JOB_CONTROL_PAUSE
:
6653 if (print_job_pause(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6657 case SPOOLSS_JOB_CONTROL_RESTART
:
6658 case SPOOLSS_JOB_CONTROL_RESUME
:
6659 if (print_job_resume(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6667 return WERR_UNKNOWN_LEVEL
;
6670 if (!W_ERROR_IS_OK(errcode
)) {
6674 if (r
->in
.ctr
== NULL
) {
6678 switch (r
->in
.ctr
->level
) {
6680 errcode
= spoolss_setjob_1(p
->mem_ctx
, lp_const_servicename(snum
),
6682 r
->in
.ctr
->info
.info1
);
6688 return WERR_UNKNOWN_LEVEL
;
6694 /****************************************************************************
6695 Enumerates all printer drivers by level and architecture.
6696 ****************************************************************************/
6698 static WERROR
enumprinterdrivers_level_by_architecture(TALLOC_CTX
*mem_ctx
,
6699 struct auth_serversupplied_info
*server_info
,
6700 const char *servername
,
6701 const char *architecture
,
6703 union spoolss_DriverInfo
**info_p
,
6708 struct spoolss_DriverInfo8
*driver
;
6709 union spoolss_DriverInfo
*info
= NULL
;
6711 WERROR result
= WERR_OK
;
6712 uint32_t num_drivers
;
6713 const char **drivers
;
6718 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6719 result
= winreg_get_driver_list(mem_ctx
, server_info
,
6720 architecture
, version
,
6721 &num_drivers
, &drivers
);
6722 if (!W_ERROR_IS_OK(result
)) {
6725 DEBUG(4, ("we have:[%d] drivers in environment"
6726 " [%s] and version [%d]\n",
6727 num_drivers
, architecture
, version
));
6729 if (num_drivers
!= 0) {
6730 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
6731 union spoolss_DriverInfo
,
6732 count
+ num_drivers
);
6734 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6735 "failed to enlarge driver info buffer!\n"));
6736 result
= WERR_NOMEM
;
6741 for (i
= 0; i
< num_drivers
; i
++) {
6742 DEBUG(5, ("\tdriver: [%s]\n", drivers
[i
]));
6744 result
= winreg_get_driver(mem_ctx
, server_info
,
6745 architecture
, drivers
[i
],
6747 if (!W_ERROR_IS_OK(result
)) {
6753 result
= fill_printer_driver_info1(info
, &info
[count
+i
].info1
,
6754 driver
, servername
);
6757 result
= fill_printer_driver_info2(info
, &info
[count
+i
].info2
,
6758 driver
, servername
);
6761 result
= fill_printer_driver_info3(info
, &info
[count
+i
].info3
,
6762 driver
, servername
);
6765 result
= fill_printer_driver_info4(info
, &info
[count
+i
].info4
,
6766 driver
, servername
);
6769 result
= fill_printer_driver_info5(info
, &info
[count
+i
].info5
,
6770 driver
, servername
);
6773 result
= fill_printer_driver_info6(info
, &info
[count
+i
].info6
,
6774 driver
, servername
);
6777 result
= fill_printer_driver_info8(info
, &info
[count
+i
].info8
,
6778 driver
, servername
);
6781 result
= WERR_UNKNOWN_LEVEL
;
6785 TALLOC_FREE(driver
);
6787 if (!W_ERROR_IS_OK(result
)) {
6792 count
+= num_drivers
;
6793 TALLOC_FREE(drivers
);
6797 TALLOC_FREE(drivers
);
6799 if (!W_ERROR_IS_OK(result
)) {
6810 /****************************************************************************
6811 Enumerates all printer drivers by level.
6812 ****************************************************************************/
6814 static WERROR
enumprinterdrivers_level(TALLOC_CTX
*mem_ctx
,
6815 struct auth_serversupplied_info
*server_info
,
6816 const char *servername
,
6817 const char *architecture
,
6819 union spoolss_DriverInfo
**info_p
,
6823 WERROR result
= WERR_OK
;
6825 if (strequal(architecture
, SPOOLSS_ARCHITECTURE_ALL
)) {
6827 for (a
=0; archi_table
[a
].long_archi
!= NULL
; a
++) {
6829 union spoolss_DriverInfo
*info
= NULL
;
6832 result
= enumprinterdrivers_level_by_architecture(mem_ctx
,
6835 archi_table
[a
].long_archi
,
6839 if (!W_ERROR_IS_OK(result
)) {
6843 for (i
=0; i
< count
; i
++) {
6844 ADD_TO_ARRAY(mem_ctx
, union spoolss_DriverInfo
,
6845 info
[i
], info_p
, count_p
);
6852 return enumprinterdrivers_level_by_architecture(mem_ctx
,
6861 /****************************************************************
6862 _spoolss_EnumPrinterDrivers
6863 ****************************************************************/
6865 WERROR
_spoolss_EnumPrinterDrivers(struct pipes_struct
*p
,
6866 struct spoolss_EnumPrinterDrivers
*r
)
6868 const char *cservername
;
6871 /* that's an [in out] buffer */
6873 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6874 return WERR_INVALID_PARAM
;
6877 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6881 *r
->out
.info
= NULL
;
6883 cservername
= canon_servername(r
->in
.server
);
6885 if (!is_myname_or_ipaddr(cservername
)) {
6886 return WERR_UNKNOWN_PRINTER_DRIVER
;
6889 result
= enumprinterdrivers_level(p
->mem_ctx
,
6896 if (!W_ERROR_IS_OK(result
)) {
6900 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6901 spoolss_EnumPrinterDrivers
,
6902 *r
->out
.info
, r
->in
.level
,
6904 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6905 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6907 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6910 /****************************************************************
6912 ****************************************************************/
6914 WERROR
_spoolss_EnumForms(struct pipes_struct
*p
,
6915 struct spoolss_EnumForms
*r
)
6921 *r
->out
.info
= NULL
;
6923 /* that's an [in out] buffer */
6925 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0) ) {
6926 return WERR_INVALID_PARAM
;
6929 DEBUG(4,("_spoolss_EnumForms\n"));
6930 DEBUGADD(5,("Offered buffer size [%d]\n", r
->in
.offered
));
6931 DEBUGADD(5,("Info level [%d]\n", r
->in
.level
));
6933 switch (r
->in
.level
) {
6935 result
= winreg_printer_enumforms1(p
->mem_ctx
,
6941 result
= WERR_UNKNOWN_LEVEL
;
6945 if (!W_ERROR_IS_OK(result
)) {
6949 if (*r
->out
.count
== 0) {
6950 return WERR_NO_MORE_ITEMS
;
6953 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6955 *r
->out
.info
, r
->in
.level
,
6957 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6958 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6960 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6963 /****************************************************************
6965 ****************************************************************/
6967 WERROR
_spoolss_GetForm(struct pipes_struct
*p
,
6968 struct spoolss_GetForm
*r
)
6972 /* that's an [in out] buffer */
6974 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6975 return WERR_INVALID_PARAM
;
6978 DEBUG(4,("_spoolss_GetForm\n"));
6979 DEBUGADD(5,("Offered buffer size [%d]\n", r
->in
.offered
));
6980 DEBUGADD(5,("Info level [%d]\n", r
->in
.level
));
6982 switch (r
->in
.level
) {
6984 result
= winreg_printer_getform1(p
->mem_ctx
,
6987 &r
->out
.info
->info1
);
6990 result
= WERR_UNKNOWN_LEVEL
;
6994 if (!W_ERROR_IS_OK(result
)) {
6995 TALLOC_FREE(r
->out
.info
);
6999 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_FormInfo
,
7000 r
->out
.info
, r
->in
.level
);
7001 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
7003 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7006 /****************************************************************************
7007 ****************************************************************************/
7009 static WERROR
fill_port_1(TALLOC_CTX
*mem_ctx
,
7010 struct spoolss_PortInfo1
*r
,
7013 r
->port_name
= talloc_strdup(mem_ctx
, name
);
7014 W_ERROR_HAVE_NO_MEMORY(r
->port_name
);
7019 /****************************************************************************
7020 TODO: This probably needs distinguish between TCP/IP and Local ports
7022 ****************************************************************************/
7024 static WERROR
fill_port_2(TALLOC_CTX
*mem_ctx
,
7025 struct spoolss_PortInfo2
*r
,
7028 r
->port_name
= talloc_strdup(mem_ctx
, name
);
7029 W_ERROR_HAVE_NO_MEMORY(r
->port_name
);
7031 r
->monitor_name
= talloc_strdup(mem_ctx
, "Local Monitor");
7032 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
7034 r
->description
= talloc_strdup(mem_ctx
, SPL_LOCAL_PORT
);
7035 W_ERROR_HAVE_NO_MEMORY(r
->description
);
7037 r
->port_type
= SPOOLSS_PORT_TYPE_WRITE
;
7044 /****************************************************************************
7045 wrapper around the enumer ports command
7046 ****************************************************************************/
7048 static WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7050 char *cmd
= lp_enumports_cmd();
7051 char **qlines
= NULL
;
7052 char *command
= NULL
;
7060 /* if no hook then just fill in the default port */
7063 if (!(qlines
= TALLOC_ARRAY( NULL
, char*, 2 ))) {
7066 if (!(qlines
[0] = talloc_strdup(qlines
, SAMBA_PRINTER_PORT_NAME
))) {
7067 TALLOC_FREE(qlines
);
7074 /* we have a valid enumport command */
7076 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7081 DEBUG(10,("Running [%s]\n", command
));
7082 ret
= smbrun(command
, &fd
);
7083 DEBUG(10,("Returned [%d]\n", ret
));
7084 TALLOC_FREE(command
);
7089 return WERR_ACCESS_DENIED
;
7093 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
7094 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7104 /****************************************************************************
7106 ****************************************************************************/
7108 static WERROR
enumports_level_1(TALLOC_CTX
*mem_ctx
,
7109 union spoolss_PortInfo
**info_p
,
7112 union spoolss_PortInfo
*info
= NULL
;
7114 WERROR result
= WERR_OK
;
7115 char **qlines
= NULL
;
7118 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7119 if (!W_ERROR_IS_OK(result
)) {
7124 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PortInfo
, numlines
);
7126 DEBUG(10,("Returning WERR_NOMEM\n"));
7127 result
= WERR_NOMEM
;
7131 for (i
=0; i
<numlines
; i
++) {
7132 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7133 result
= fill_port_1(info
, &info
[i
].info1
, qlines
[i
]);
7134 if (!W_ERROR_IS_OK(result
)) {
7139 TALLOC_FREE(qlines
);
7142 if (!W_ERROR_IS_OK(result
)) {
7144 TALLOC_FREE(qlines
);
7156 /****************************************************************************
7158 ****************************************************************************/
7160 static WERROR
enumports_level_2(TALLOC_CTX
*mem_ctx
,
7161 union spoolss_PortInfo
**info_p
,
7164 union spoolss_PortInfo
*info
= NULL
;
7166 WERROR result
= WERR_OK
;
7167 char **qlines
= NULL
;
7170 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7171 if (!W_ERROR_IS_OK(result
)) {
7176 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PortInfo
, numlines
);
7178 DEBUG(10,("Returning WERR_NOMEM\n"));
7179 result
= WERR_NOMEM
;
7183 for (i
=0; i
<numlines
; i
++) {
7184 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7185 result
= fill_port_2(info
, &info
[i
].info2
, qlines
[i
]);
7186 if (!W_ERROR_IS_OK(result
)) {
7191 TALLOC_FREE(qlines
);
7194 if (!W_ERROR_IS_OK(result
)) {
7196 TALLOC_FREE(qlines
);
7208 /****************************************************************
7210 ****************************************************************/
7212 WERROR
_spoolss_EnumPorts(struct pipes_struct
*p
,
7213 struct spoolss_EnumPorts
*r
)
7217 /* that's an [in out] buffer */
7219 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7220 return WERR_INVALID_PARAM
;
7223 DEBUG(4,("_spoolss_EnumPorts\n"));
7227 *r
->out
.info
= NULL
;
7229 switch (r
->in
.level
) {
7231 result
= enumports_level_1(p
->mem_ctx
, r
->out
.info
,
7235 result
= enumports_level_2(p
->mem_ctx
, r
->out
.info
,
7239 return WERR_UNKNOWN_LEVEL
;
7242 if (!W_ERROR_IS_OK(result
)) {
7246 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
7248 *r
->out
.info
, r
->in
.level
,
7250 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
7251 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
7253 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7256 /****************************************************************************
7257 ****************************************************************************/
7259 static WERROR
spoolss_addprinterex_level_2(struct pipes_struct
*p
,
7261 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
7262 struct spoolss_DeviceMode
*devmode
,
7263 struct security_descriptor
*secdesc
,
7264 struct spoolss_UserLevelCtr
*user_ctr
,
7265 struct policy_handle
*handle
)
7267 struct spoolss_SetPrinterInfo2
*info2
= info_ctr
->info
.info2
;
7268 uint32_t info2_mask
= SPOOLSS_PRINTER_INFO_ALL
;
7270 WERROR err
= WERR_OK
;
7272 /* samba does not have a concept of local, non-shared printers yet, so
7273 * make sure we always setup sharename - gd */
7274 if ((info2
->sharename
== NULL
|| info2
->sharename
[0] == '\0') &&
7275 (info2
->printername
!= NULL
&& info2
->printername
[0] != '\0')) {
7276 DEBUG(5, ("spoolss_addprinterex_level_2: "
7277 "no sharename has been set, setting printername %s as sharename\n",
7278 info2
->printername
));
7279 info2
->sharename
= info2
->printername
;
7282 /* check to see if the printer already exists */
7283 if ((snum
= print_queue_snum(info2
->sharename
)) != -1) {
7284 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7286 return WERR_PRINTER_ALREADY_EXISTS
;
7289 if (!lp_force_printername(GLOBAL_SECTION_SNUM
)) {
7290 if ((snum
= print_queue_snum(info2
->printername
)) != -1) {
7291 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7292 info2
->printername
));
7293 return WERR_PRINTER_ALREADY_EXISTS
;
7297 /* validate printer info struct */
7298 if (!info2
->printername
|| strlen(info2
->printername
) == 0) {
7299 return WERR_INVALID_PRINTER_NAME
;
7301 if (!info2
->portname
|| strlen(info2
->portname
) == 0) {
7302 return WERR_UNKNOWN_PORT
;
7304 if (!info2
->drivername
|| strlen(info2
->drivername
) == 0) {
7305 return WERR_UNKNOWN_PRINTER_DRIVER
;
7307 if (!info2
->printprocessor
|| strlen(info2
->printprocessor
) == 0) {
7308 return WERR_UNKNOWN_PRINTPROCESSOR
;
7311 /* FIXME!!! smbd should check to see if the driver is installed before
7312 trying to add a printer like this --jerry */
7314 if (*lp_addprinter_cmd() ) {
7315 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
7316 info2
, p
->client_address
) ) {
7317 return WERR_ACCESS_DENIED
;
7320 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7321 "smb.conf parameter \"addprinter command\" is defined. This"
7322 "parameter must exist for this call to succeed\n",
7323 info2
->sharename
));
7326 if ((snum
= print_queue_snum(info2
->sharename
)) == -1) {
7327 return WERR_ACCESS_DENIED
;
7330 /* you must be a printer admin to add a new printer */
7331 if (!print_access_check(p
->server_info
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7332 return WERR_ACCESS_DENIED
;
7336 * Do sanity check on the requested changes for Samba.
7339 if (!check_printer_ok(p
->mem_ctx
, info2
, snum
)) {
7340 return WERR_INVALID_PARAM
;
7343 if (devmode
== NULL
) {
7344 info2_mask
= ~SPOOLSS_PRINTER_INFO_DEVMODE
;
7347 update_dsspooler(p
->mem_ctx
,
7353 err
= winreg_update_printer(p
->mem_ctx
,
7360 if (!W_ERROR_IS_OK(err
)) {
7364 if (!open_printer_hnd(p
, handle
, info2
->printername
, PRINTER_ACCESS_ADMINISTER
)) {
7365 /* Handle open failed - remove addition. */
7366 ZERO_STRUCTP(handle
);
7367 return WERR_ACCESS_DENIED
;
7373 /****************************************************************
7374 _spoolss_AddPrinterEx
7375 ****************************************************************/
7377 WERROR
_spoolss_AddPrinterEx(struct pipes_struct
*p
,
7378 struct spoolss_AddPrinterEx
*r
)
7380 switch (r
->in
.info_ctr
->level
) {
7382 /* we don't handle yet */
7383 /* but I know what to do ... */
7384 return WERR_UNKNOWN_LEVEL
;
7386 return spoolss_addprinterex_level_2(p
, r
->in
.server
,
7388 r
->in
.devmode_ctr
->devmode
,
7389 r
->in
.secdesc_ctr
->sd
,
7390 r
->in
.userlevel_ctr
,
7393 return WERR_UNKNOWN_LEVEL
;
7397 /****************************************************************
7399 ****************************************************************/
7401 WERROR
_spoolss_AddPrinter(struct pipes_struct
*p
,
7402 struct spoolss_AddPrinter
*r
)
7404 struct spoolss_AddPrinterEx a
;
7405 struct spoolss_UserLevelCtr userlevel_ctr
;
7407 ZERO_STRUCT(userlevel_ctr
);
7409 userlevel_ctr
.level
= 1;
7411 a
.in
.server
= r
->in
.server
;
7412 a
.in
.info_ctr
= r
->in
.info_ctr
;
7413 a
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
7414 a
.in
.secdesc_ctr
= r
->in
.secdesc_ctr
;
7415 a
.in
.userlevel_ctr
= &userlevel_ctr
;
7416 a
.out
.handle
= r
->out
.handle
;
7418 return _spoolss_AddPrinterEx(p
, &a
);
7421 /****************************************************************
7422 _spoolss_AddPrinterDriverEx
7423 ****************************************************************/
7425 WERROR
_spoolss_AddPrinterDriverEx(struct pipes_struct
*p
,
7426 struct spoolss_AddPrinterDriverEx
*r
)
7428 WERROR err
= WERR_OK
;
7429 const char *driver_name
= NULL
;
7434 case NDR_SPOOLSS_ADDPRINTERDRIVER
:
7435 fn
= "_spoolss_AddPrinterDriver";
7437 case NDR_SPOOLSS_ADDPRINTERDRIVEREX
:
7438 fn
= "_spoolss_AddPrinterDriverEx";
7441 return WERR_INVALID_PARAM
;
7445 * we only support the semantics of AddPrinterDriver()
7446 * i.e. only copy files that are newer than existing ones
7449 if (r
->in
.flags
== 0) {
7450 return WERR_INVALID_PARAM
;
7453 if (r
->in
.flags
!= APD_COPY_NEW_FILES
) {
7454 return WERR_ACCESS_DENIED
;
7458 if (r
->in
.info_ctr
->level
!= 3 && r
->in
.info_ctr
->level
!= 6) {
7459 /* Clever hack from Martin Zielinski <mz@seh.de>
7460 * to allow downgrade from level 8 (Vista).
7462 DEBUG(0,("%s: level %d not yet implemented\n", fn
,
7463 r
->in
.info_ctr
->level
));
7464 return WERR_UNKNOWN_LEVEL
;
7467 DEBUG(5,("Cleaning driver's information\n"));
7468 err
= clean_up_driver_struct(p
->mem_ctx
, p
, r
->in
.info_ctr
);
7469 if (!W_ERROR_IS_OK(err
))
7472 DEBUG(5,("Moving driver to final destination\n"));
7473 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(p
, r
->in
.info_ctr
,
7478 err
= winreg_add_driver(p
->mem_ctx
, p
->server_info
,
7479 r
->in
.info_ctr
, &driver_name
, &version
);
7480 if (!W_ERROR_IS_OK(err
)) {
7485 * I think this is where he DrvUpgradePrinter() hook would be
7486 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7487 * server. Right now, we just need to send ourselves a message
7488 * to update each printer bound to this driver. --jerry
7491 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7492 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7500 /****************************************************************
7501 _spoolss_AddPrinterDriver
7502 ****************************************************************/
7504 WERROR
_spoolss_AddPrinterDriver(struct pipes_struct
*p
,
7505 struct spoolss_AddPrinterDriver
*r
)
7507 struct spoolss_AddPrinterDriverEx a
;
7509 switch (r
->in
.info_ctr
->level
) {
7516 return WERR_UNKNOWN_LEVEL
;
7519 a
.in
.servername
= r
->in
.servername
;
7520 a
.in
.info_ctr
= r
->in
.info_ctr
;
7521 a
.in
.flags
= APD_COPY_NEW_FILES
;
7523 return _spoolss_AddPrinterDriverEx(p
, &a
);
7526 /****************************************************************************
7527 ****************************************************************************/
7529 struct _spoolss_paths
{
7535 enum { SPOOLSS_DRIVER_PATH
, SPOOLSS_PRTPROCS_PATH
};
7537 static const struct _spoolss_paths spoolss_paths
[]= {
7538 { SPOOLSS_DRIVER_PATH
, "print$", "DRIVERS" },
7539 { SPOOLSS_PRTPROCS_PATH
, "prnproc$", "PRTPROCS" }
7542 static WERROR
compose_spoolss_server_path(TALLOC_CTX
*mem_ctx
,
7543 const char *servername
,
7544 const char *environment
,
7548 const char *pservername
= NULL
;
7549 const char *long_archi
= SPOOLSS_ARCHITECTURE_NT_X86
;
7550 const char *short_archi
;
7554 /* environment may be empty */
7555 if (environment
&& strlen(environment
)) {
7556 long_archi
= environment
;
7559 /* servername may be empty */
7560 if (servername
&& strlen(servername
)) {
7561 pservername
= canon_servername(servername
);
7563 if (!is_myname_or_ipaddr(pservername
)) {
7564 return WERR_INVALID_PARAM
;
7568 if (!(short_archi
= get_short_archi(long_archi
))) {
7569 return WERR_INVALID_ENVIRONMENT
;
7572 switch (component
) {
7573 case SPOOLSS_PRTPROCS_PATH
:
7574 case SPOOLSS_DRIVER_PATH
:
7576 *path
= talloc_asprintf(mem_ctx
,
7579 spoolss_paths
[component
].share
,
7582 *path
= talloc_asprintf(mem_ctx
, "%s\\%s\\%s",
7583 SPOOLSS_DEFAULT_SERVER_PATH
,
7584 spoolss_paths
[component
].dir
,
7589 return WERR_INVALID_PARAM
;
7599 /****************************************************************************
7600 ****************************************************************************/
7602 static WERROR
getprinterdriverdir_level_1(TALLOC_CTX
*mem_ctx
,
7603 const char *servername
,
7604 const char *environment
,
7605 struct spoolss_DriverDirectoryInfo1
*r
)
7610 werr
= compose_spoolss_server_path(mem_ctx
,
7613 SPOOLSS_DRIVER_PATH
,
7615 if (!W_ERROR_IS_OK(werr
)) {
7619 DEBUG(4,("printer driver directory: [%s]\n", path
));
7621 r
->directory_name
= path
;
7626 /****************************************************************
7627 _spoolss_GetPrinterDriverDirectory
7628 ****************************************************************/
7630 WERROR
_spoolss_GetPrinterDriverDirectory(struct pipes_struct
*p
,
7631 struct spoolss_GetPrinterDriverDirectory
*r
)
7635 /* that's an [in out] buffer */
7637 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7638 return WERR_INVALID_PARAM
;
7641 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7646 /* r->in.level is ignored */
7648 werror
= getprinterdriverdir_level_1(p
->mem_ctx
,
7651 &r
->out
.info
->info1
);
7652 if (!W_ERROR_IS_OK(werror
)) {
7653 TALLOC_FREE(r
->out
.info
);
7657 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo
,
7658 r
->out
.info
, r
->in
.level
);
7659 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
7661 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7664 /****************************************************************
7665 _spoolss_EnumPrinterData
7666 ****************************************************************/
7668 WERROR
_spoolss_EnumPrinterData(struct pipes_struct
*p
,
7669 struct spoolss_EnumPrinterData
*r
)
7672 struct spoolss_EnumPrinterDataEx r2
;
7674 struct spoolss_PrinterEnumValues
*info
, *val
= NULL
;
7677 r2
.in
.handle
= r
->in
.handle
;
7678 r2
.in
.key_name
= "PrinterDriverData";
7680 r2
.out
.count
= &count
;
7681 r2
.out
.info
= &info
;
7682 r2
.out
.needed
= &needed
;
7684 result
= _spoolss_EnumPrinterDataEx(p
, &r2
);
7685 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
7686 r2
.in
.offered
= needed
;
7687 result
= _spoolss_EnumPrinterDataEx(p
, &r2
);
7689 if (!W_ERROR_IS_OK(result
)) {
7694 * The NT machine wants to know the biggest size of value and data
7696 * cf: MSDN EnumPrinterData remark section
7699 if (!r
->in
.value_offered
&& !r
->in
.data_offered
) {
7700 uint32_t biggest_valuesize
= 0;
7701 uint32_t biggest_datasize
= 0;
7704 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7706 for (i
=0; i
<count
; i
++) {
7708 name_length
= strlen(info
[i
].value_name
);
7709 if (strlen(info
[i
].value_name
) > biggest_valuesize
) {
7710 biggest_valuesize
= name_length
;
7713 if (info
[i
].data_length
> biggest_datasize
) {
7714 biggest_datasize
= info
[i
].data_length
;
7717 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
7721 /* the value is an UNICODE string but real_value_size is the length
7722 in bytes including the trailing 0 */
7724 *r
->out
.value_needed
= 2 * (1 + biggest_valuesize
);
7725 *r
->out
.data_needed
= biggest_datasize
;
7727 DEBUG(6,("final values: [%d], [%d]\n",
7728 *r
->out
.value_needed
, *r
->out
.data_needed
));
7733 if (r
->in
.enum_index
< count
) {
7734 val
= &info
[r
->in
.enum_index
];
7738 /* out_value should default to "" or else NT4 has
7739 problems unmarshalling the response */
7741 if (r
->in
.value_offered
) {
7742 *r
->out
.value_needed
= 1;
7743 r
->out
.value_name
= talloc_strdup(r
, "");
7744 if (!r
->out
.value_name
) {
7748 r
->out
.value_name
= NULL
;
7749 *r
->out
.value_needed
= 0;
7752 /* the data is counted in bytes */
7754 *r
->out
.data_needed
= r
->in
.data_offered
;
7756 result
= WERR_NO_MORE_ITEMS
;
7760 * - counted in bytes in the request
7761 * - counted in UNICODE chars in the max reply
7762 * - counted in bytes in the real size
7764 * take a pause *before* coding not *during* coding
7768 if (r
->in
.value_offered
) {
7769 r
->out
.value_name
= talloc_strdup(r
, val
->value_name
);
7770 if (!r
->out
.value_name
) {
7773 *r
->out
.value_needed
= val
->value_name_len
;
7775 r
->out
.value_name
= NULL
;
7776 *r
->out
.value_needed
= 0;
7781 *r
->out
.type
= val
->type
;
7783 /* data - counted in bytes */
7786 * See the section "Dynamically Typed Query Parameters"
7790 if (r
->out
.data
&& val
->data
&& val
->data
->data
&&
7791 val
->data_length
&& r
->in
.data_offered
) {
7792 memcpy(r
->out
.data
, val
->data
->data
,
7793 MIN(val
->data_length
,r
->in
.data_offered
));
7796 *r
->out
.data_needed
= val
->data_length
;
7804 /****************************************************************
7805 _spoolss_SetPrinterData
7806 ****************************************************************/
7808 WERROR
_spoolss_SetPrinterData(struct pipes_struct
*p
,
7809 struct spoolss_SetPrinterData
*r
)
7811 struct spoolss_SetPrinterDataEx r2
;
7813 r2
.in
.handle
= r
->in
.handle
;
7814 r2
.in
.key_name
= "PrinterDriverData";
7815 r2
.in
.value_name
= r
->in
.value_name
;
7816 r2
.in
.type
= r
->in
.type
;
7817 r2
.in
.data
= r
->in
.data
;
7818 r2
.in
.offered
= r
->in
.offered
;
7820 return _spoolss_SetPrinterDataEx(p
, &r2
);
7823 /****************************************************************
7824 _spoolss_ResetPrinter
7825 ****************************************************************/
7827 WERROR
_spoolss_ResetPrinter(struct pipes_struct
*p
,
7828 struct spoolss_ResetPrinter
*r
)
7830 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7833 DEBUG(5,("_spoolss_ResetPrinter\n"));
7836 * All we do is to check to see if the handle and queue is valid.
7837 * This call really doesn't mean anything to us because we only
7838 * support RAW printing. --jerry
7842 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7843 OUR_HANDLE(r
->in
.handle
)));
7847 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
7851 /* blindly return success */
7855 /****************************************************************
7856 _spoolss_DeletePrinterData
7857 ****************************************************************/
7859 WERROR
_spoolss_DeletePrinterData(struct pipes_struct
*p
,
7860 struct spoolss_DeletePrinterData
*r
)
7862 struct spoolss_DeletePrinterDataEx r2
;
7864 r2
.in
.handle
= r
->in
.handle
;
7865 r2
.in
.key_name
= "PrinterDriverData";
7866 r2
.in
.value_name
= r
->in
.value_name
;
7868 return _spoolss_DeletePrinterDataEx(p
, &r2
);
7871 /****************************************************************
7873 ****************************************************************/
7875 WERROR
_spoolss_AddForm(struct pipes_struct
*p
,
7876 struct spoolss_AddForm
*r
)
7878 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
7880 WERROR status
= WERR_OK
;
7881 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
7883 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7885 DEBUG(5,("_spoolss_AddForm\n"));
7888 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7889 OUR_HANDLE(r
->in
.handle
)));
7893 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7894 and not a printer admin, then fail */
7896 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
7897 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
7898 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
7899 p
->server_info
->info3
->base
.domain
.string
,
7901 p
->server_info
->ptok
,
7902 lp_printer_admin(snum
))) {
7903 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7904 return WERR_ACCESS_DENIED
;
7907 switch (form
->flags
) {
7908 case SPOOLSS_FORM_USER
:
7909 case SPOOLSS_FORM_BUILTIN
:
7910 case SPOOLSS_FORM_PRINTER
:
7913 return WERR_INVALID_PARAM
;
7916 status
= winreg_printer_addform1(p
->mem_ctx
, p
->server_info
, form
);
7917 if (!W_ERROR_IS_OK(status
)) {
7922 * ChangeID must always be set if this is a printer
7924 if (Printer
->printer_type
== SPLHND_PRINTER
) {
7925 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
7929 status
= winreg_printer_update_changeid(p
->mem_ctx
,
7931 lp_const_servicename(snum
));
7932 if (!W_ERROR_IS_OK(status
)) {
7940 /****************************************************************
7942 ****************************************************************/
7944 WERROR
_spoolss_DeleteForm(struct pipes_struct
*p
,
7945 struct spoolss_DeleteForm
*r
)
7947 const char *form_name
= r
->in
.form_name
;
7948 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7950 WERROR status
= WERR_OK
;
7951 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
7953 DEBUG(5,("_spoolss_DeleteForm\n"));
7956 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7957 OUR_HANDLE(r
->in
.handle
)));
7961 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
7962 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
7963 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
7964 p
->server_info
->info3
->base
.domain
.string
,
7966 p
->server_info
->ptok
,
7967 lp_printer_admin(snum
))) {
7968 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7969 return WERR_ACCESS_DENIED
;
7972 status
= winreg_printer_deleteform1(p
->mem_ctx
,
7975 if (!W_ERROR_IS_OK(status
)) {
7980 * ChangeID must always be set if this is a printer
7982 if (Printer
->printer_type
== SPLHND_PRINTER
) {
7983 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
7987 status
= winreg_printer_update_changeid(p
->mem_ctx
,
7989 lp_const_servicename(snum
));
7990 if (!W_ERROR_IS_OK(status
)) {
7998 /****************************************************************
8000 ****************************************************************/
8002 WERROR
_spoolss_SetForm(struct pipes_struct
*p
,
8003 struct spoolss_SetForm
*r
)
8005 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8006 const char *form_name
= r
->in
.form_name
;
8008 WERROR status
= WERR_OK
;
8009 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
8011 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8013 DEBUG(5,("_spoolss_SetForm\n"));
8016 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8017 OUR_HANDLE(r
->in
.handle
)));
8021 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8022 and not a printer admin, then fail */
8024 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
8025 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
8026 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
8027 p
->server_info
->info3
->base
.domain
.string
,
8029 p
->server_info
->ptok
,
8030 lp_printer_admin(snum
))) {
8031 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8032 return WERR_ACCESS_DENIED
;
8035 status
= winreg_printer_setform1(p
->mem_ctx
,
8039 if (!W_ERROR_IS_OK(status
)) {
8044 * ChangeID must always be set if this is a printer
8046 if (Printer
->printer_type
== SPLHND_PRINTER
) {
8047 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8051 status
= winreg_printer_update_changeid(p
->mem_ctx
,
8053 lp_const_servicename(snum
));
8054 if (!W_ERROR_IS_OK(status
)) {
8062 /****************************************************************************
8063 fill_print_processor1
8064 ****************************************************************************/
8066 static WERROR
fill_print_processor1(TALLOC_CTX
*mem_ctx
,
8067 struct spoolss_PrintProcessorInfo1
*r
,
8068 const char *print_processor_name
)
8070 r
->print_processor_name
= talloc_strdup(mem_ctx
, print_processor_name
);
8071 W_ERROR_HAVE_NO_MEMORY(r
->print_processor_name
);
8076 /****************************************************************************
8077 enumprintprocessors level 1.
8078 ****************************************************************************/
8080 static WERROR
enumprintprocessors_level_1(TALLOC_CTX
*mem_ctx
,
8081 union spoolss_PrintProcessorInfo
**info_p
,
8084 union spoolss_PrintProcessorInfo
*info
;
8087 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PrintProcessorInfo
, 1);
8088 W_ERROR_HAVE_NO_MEMORY(info
);
8092 result
= fill_print_processor1(info
, &info
[0].info1
, "winprint");
8093 if (!W_ERROR_IS_OK(result
)) {
8098 if (!W_ERROR_IS_OK(result
)) {
8109 /****************************************************************
8110 _spoolss_EnumPrintProcessors
8111 ****************************************************************/
8113 WERROR
_spoolss_EnumPrintProcessors(struct pipes_struct
*p
,
8114 struct spoolss_EnumPrintProcessors
*r
)
8118 /* that's an [in out] buffer */
8120 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8121 return WERR_INVALID_PARAM
;
8124 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8127 * Enumerate the print processors ...
8129 * Just reply with "winprint", to keep NT happy
8130 * and I can use my nice printer checker.
8135 *r
->out
.info
= NULL
;
8137 if (!get_short_archi(r
->in
.environment
)) {
8138 return WERR_INVALID_ENVIRONMENT
;
8141 switch (r
->in
.level
) {
8143 result
= enumprintprocessors_level_1(p
->mem_ctx
, r
->out
.info
,
8147 return WERR_UNKNOWN_LEVEL
;
8150 if (!W_ERROR_IS_OK(result
)) {
8154 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8155 spoolss_EnumPrintProcessors
,
8156 *r
->out
.info
, r
->in
.level
,
8158 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8159 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8161 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8164 /****************************************************************************
8165 fill_printprocdatatype1
8166 ****************************************************************************/
8168 static WERROR
fill_printprocdatatype1(TALLOC_CTX
*mem_ctx
,
8169 struct spoolss_PrintProcDataTypesInfo1
*r
,
8170 const char *name_array
)
8172 r
->name_array
= talloc_strdup(mem_ctx
, name_array
);
8173 W_ERROR_HAVE_NO_MEMORY(r
->name_array
);
8178 /****************************************************************************
8179 enumprintprocdatatypes level 1.
8180 ****************************************************************************/
8182 static WERROR
enumprintprocdatatypes_level_1(TALLOC_CTX
*mem_ctx
,
8183 union spoolss_PrintProcDataTypesInfo
**info_p
,
8187 union spoolss_PrintProcDataTypesInfo
*info
;
8189 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PrintProcDataTypesInfo
, 1);
8190 W_ERROR_HAVE_NO_MEMORY(info
);
8194 result
= fill_printprocdatatype1(info
, &info
[0].info1
, "RAW");
8195 if (!W_ERROR_IS_OK(result
)) {
8200 if (!W_ERROR_IS_OK(result
)) {
8211 /****************************************************************
8212 _spoolss_EnumPrintProcDataTypes
8213 ****************************************************************/
8215 WERROR
_spoolss_EnumPrintProcDataTypes(struct pipes_struct
*p
,
8216 struct spoolss_EnumPrintProcDataTypes
*r
)
8220 /* that's an [in out] buffer */
8222 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8223 return WERR_INVALID_PARAM
;
8226 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8230 *r
->out
.info
= NULL
;
8232 if (r
->in
.print_processor_name
== NULL
||
8233 !strequal(r
->in
.print_processor_name
, "winprint")) {
8234 return WERR_UNKNOWN_PRINTPROCESSOR
;
8237 switch (r
->in
.level
) {
8239 result
= enumprintprocdatatypes_level_1(p
->mem_ctx
, r
->out
.info
,
8243 return WERR_UNKNOWN_LEVEL
;
8246 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8247 spoolss_EnumPrintProcDataTypes
,
8248 *r
->out
.info
, r
->in
.level
,
8250 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8251 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8253 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8256 /****************************************************************************
8258 ****************************************************************************/
8260 static WERROR
fill_monitor_1(TALLOC_CTX
*mem_ctx
,
8261 struct spoolss_MonitorInfo1
*r
,
8262 const char *monitor_name
)
8264 r
->monitor_name
= talloc_strdup(mem_ctx
, monitor_name
);
8265 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
8270 /****************************************************************************
8272 ****************************************************************************/
8274 static WERROR
fill_monitor_2(TALLOC_CTX
*mem_ctx
,
8275 struct spoolss_MonitorInfo2
*r
,
8276 const char *monitor_name
,
8277 const char *environment
,
8278 const char *dll_name
)
8280 r
->monitor_name
= talloc_strdup(mem_ctx
, monitor_name
);
8281 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
8282 r
->environment
= talloc_strdup(mem_ctx
, environment
);
8283 W_ERROR_HAVE_NO_MEMORY(r
->environment
);
8284 r
->dll_name
= talloc_strdup(mem_ctx
, dll_name
);
8285 W_ERROR_HAVE_NO_MEMORY(r
->dll_name
);
8290 /****************************************************************************
8291 enumprintmonitors level 1.
8292 ****************************************************************************/
8294 static WERROR
enumprintmonitors_level_1(TALLOC_CTX
*mem_ctx
,
8295 union spoolss_MonitorInfo
**info_p
,
8298 union spoolss_MonitorInfo
*info
;
8299 WERROR result
= WERR_OK
;
8301 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_MonitorInfo
, 2);
8302 W_ERROR_HAVE_NO_MEMORY(info
);
8306 result
= fill_monitor_1(info
, &info
[0].info1
,
8308 if (!W_ERROR_IS_OK(result
)) {
8312 result
= fill_monitor_1(info
, &info
[1].info1
,
8314 if (!W_ERROR_IS_OK(result
)) {
8319 if (!W_ERROR_IS_OK(result
)) {
8330 /****************************************************************************
8331 enumprintmonitors level 2.
8332 ****************************************************************************/
8334 static WERROR
enumprintmonitors_level_2(TALLOC_CTX
*mem_ctx
,
8335 union spoolss_MonitorInfo
**info_p
,
8338 union spoolss_MonitorInfo
*info
;
8339 WERROR result
= WERR_OK
;
8341 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_MonitorInfo
, 2);
8342 W_ERROR_HAVE_NO_MEMORY(info
);
8346 result
= fill_monitor_2(info
, &info
[0].info2
,
8348 "Windows NT X86", /* FIXME */
8350 if (!W_ERROR_IS_OK(result
)) {
8354 result
= fill_monitor_2(info
, &info
[1].info2
,
8356 "Windows NT X86", /* FIXME */
8358 if (!W_ERROR_IS_OK(result
)) {
8363 if (!W_ERROR_IS_OK(result
)) {
8374 /****************************************************************
8375 _spoolss_EnumMonitors
8376 ****************************************************************/
8378 WERROR
_spoolss_EnumMonitors(struct pipes_struct
*p
,
8379 struct spoolss_EnumMonitors
*r
)
8383 /* that's an [in out] buffer */
8385 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8386 return WERR_INVALID_PARAM
;
8389 DEBUG(5,("_spoolss_EnumMonitors\n"));
8392 * Enumerate the print monitors ...
8394 * Just reply with "Local Port", to keep NT happy
8395 * and I can use my nice printer checker.
8400 *r
->out
.info
= NULL
;
8402 switch (r
->in
.level
) {
8404 result
= enumprintmonitors_level_1(p
->mem_ctx
, r
->out
.info
,
8408 result
= enumprintmonitors_level_2(p
->mem_ctx
, r
->out
.info
,
8412 return WERR_UNKNOWN_LEVEL
;
8415 if (!W_ERROR_IS_OK(result
)) {
8419 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8420 spoolss_EnumMonitors
,
8421 *r
->out
.info
, r
->in
.level
,
8423 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8424 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8426 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8429 /****************************************************************************
8430 ****************************************************************************/
8432 static WERROR
getjob_level_1(TALLOC_CTX
*mem_ctx
,
8433 const print_queue_struct
*queue
,
8434 int count
, int snum
,
8435 struct spoolss_PrinterInfo2
*pinfo2
,
8437 struct spoolss_JobInfo1
*r
)
8442 for (i
=0; i
<count
; i
++) {
8443 if (queue
[i
].job
== (int)jobid
) {
8449 if (found
== false) {
8450 /* NT treats not found as bad param... yet another bad choice */
8451 return WERR_INVALID_PARAM
;
8454 return fill_job_info1(mem_ctx
,
8462 /****************************************************************************
8463 ****************************************************************************/
8465 static WERROR
getjob_level_2(TALLOC_CTX
*mem_ctx
,
8466 const print_queue_struct
*queue
,
8467 int count
, int snum
,
8468 struct spoolss_PrinterInfo2
*pinfo2
,
8470 struct spoolss_JobInfo2
*r
)
8474 struct spoolss_DeviceMode
*devmode
;
8477 for (i
=0; i
<count
; i
++) {
8478 if (queue
[i
].job
== (int)jobid
) {
8484 if (found
== false) {
8485 /* NT treats not found as bad param... yet another bad
8487 return WERR_INVALID_PARAM
;
8491 * if the print job does not have a DEVMODE associated with it,
8492 * just use the one for the printer. A NULL devicemode is not
8493 * a failure condition
8496 devmode
= print_job_devmode(lp_const_servicename(snum
), jobid
);
8498 result
= spoolss_create_default_devmode(mem_ctx
,
8499 pinfo2
->printername
,
8501 if (!W_ERROR_IS_OK(result
)) {
8502 DEBUG(3, ("Can't proceed w/o a devmode!"));
8507 return fill_job_info2(mem_ctx
,
8516 /****************************************************************
8518 ****************************************************************/
8520 WERROR
_spoolss_GetJob(struct pipes_struct
*p
,
8521 struct spoolss_GetJob
*r
)
8523 WERROR result
= WERR_OK
;
8524 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
8527 print_queue_struct
*queue
= NULL
;
8528 print_status_struct prt_status
;
8530 /* that's an [in out] buffer */
8532 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8533 return WERR_INVALID_PARAM
;
8536 DEBUG(5,("_spoolss_GetJob\n"));
8540 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8544 result
= winreg_get_printer(p
->mem_ctx
, p
->server_info
, NULL
,
8545 lp_servicename(snum
), &pinfo2
);
8546 if (!W_ERROR_IS_OK(result
)) {
8550 count
= print_queue_status(snum
, &queue
, &prt_status
);
8552 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8553 count
, prt_status
.status
, prt_status
.message
));
8555 switch (r
->in
.level
) {
8557 result
= getjob_level_1(p
->mem_ctx
,
8558 queue
, count
, snum
, pinfo2
,
8559 r
->in
.job_id
, &r
->out
.info
->info1
);
8562 result
= getjob_level_2(p
->mem_ctx
,
8563 queue
, count
, snum
, pinfo2
,
8564 r
->in
.job_id
, &r
->out
.info
->info2
);
8567 result
= WERR_UNKNOWN_LEVEL
;
8572 TALLOC_FREE(pinfo2
);
8574 if (!W_ERROR_IS_OK(result
)) {
8575 TALLOC_FREE(r
->out
.info
);
8579 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_JobInfo
, r
->out
.info
,
8581 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
8583 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8586 /****************************************************************
8587 _spoolss_GetPrinterDataEx
8588 ****************************************************************/
8590 WERROR
_spoolss_GetPrinterDataEx(struct pipes_struct
*p
,
8591 struct spoolss_GetPrinterDataEx
*r
)
8594 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8595 const char *printer
;
8597 WERROR result
= WERR_OK
;
8599 enum winreg_Type val_type
;
8604 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8606 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8607 r
->in
.key_name
, r
->in
.value_name
));
8609 /* in case of problem, return some default values */
8612 *r
->out
.type
= REG_NONE
;
8615 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8616 OUR_HANDLE(r
->in
.handle
)));
8617 result
= WERR_BADFID
;
8621 /* Is the handle to a printer or to the server? */
8623 if (Printer
->printer_type
== SPLHND_SERVER
) {
8625 union spoolss_PrinterData data
;
8627 result
= getprinterdata_printer_server(p
->mem_ctx
,
8631 if (!W_ERROR_IS_OK(result
)) {
8635 result
= push_spoolss_PrinterData(p
->mem_ctx
, &blob
,
8636 *r
->out
.type
, &data
);
8637 if (!W_ERROR_IS_OK(result
)) {
8641 *r
->out
.needed
= blob
.length
;
8643 if (r
->in
.offered
>= *r
->out
.needed
) {
8644 memcpy(r
->out
.data
, blob
.data
, blob
.length
);
8647 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
8650 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8653 printer
= lp_const_servicename(snum
);
8655 /* check to see if the keyname is valid */
8656 if (!strlen(r
->in
.key_name
)) {
8657 return WERR_INVALID_PARAM
;
8660 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8661 if (strequal(r
->in
.key_name
, SPOOL_PRINTERDATA_KEY
) &&
8662 strequal(r
->in
.value_name
, "ChangeId")) {
8663 *r
->out
.type
= REG_DWORD
;
8665 if (r
->in
.offered
>= *r
->out
.needed
) {
8666 uint32_t changeid
= 0;
8668 result
= winreg_printer_get_changeid(p
->mem_ctx
,
8672 if (!W_ERROR_IS_OK(result
)) {
8676 SIVAL(r
->out
.data
, 0, changeid
);
8682 result
= winreg_get_printer_dataex(p
->mem_ctx
,
8690 if (!W_ERROR_IS_OK(result
)) {
8694 *r
->out
.needed
= val_size
;
8695 *r
->out
.type
= val_type
;
8697 if (r
->in
.offered
>= *r
->out
.needed
) {
8698 memcpy(r
->out
.data
, val_data
, val_size
);
8702 /* retain type when returning WERR_MORE_DATA */
8703 r
->out
.data
= SPOOLSS_BUFFER_OK(r
->out
.data
, r
->out
.data
);
8705 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
8708 /****************************************************************
8709 _spoolss_SetPrinterDataEx
8710 ****************************************************************/
8712 WERROR
_spoolss_SetPrinterDataEx(struct pipes_struct
*p
,
8713 struct spoolss_SetPrinterDataEx
*r
)
8715 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
8717 WERROR result
= WERR_OK
;
8718 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8721 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8723 /* From MSDN documentation of SetPrinterDataEx: pass request to
8724 SetPrinterData if key is "PrinterDriverData" */
8727 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8728 OUR_HANDLE(r
->in
.handle
)));
8732 if (Printer
->printer_type
== SPLHND_SERVER
) {
8733 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8734 "Not implemented for server handles yet\n"));
8735 return WERR_INVALID_PARAM
;
8738 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8743 * Access check : NT returns "access denied" if you make a
8744 * SetPrinterData call without the necessary privildge.
8745 * we were originally returning OK if nothing changed
8746 * which made Win2k issue **a lot** of SetPrinterData
8747 * when connecting to a printer --jerry
8750 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8751 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8752 "change denied by handle access permissions\n"));
8753 return WERR_ACCESS_DENIED
;
8756 result
= winreg_get_printer(Printer
, p
->server_info
,
8757 Printer
->servername
,
8758 lp_servicename(snum
),
8760 if (!W_ERROR_IS_OK(result
)) {
8764 /* check for OID in valuename */
8766 oid_string
= strchr(r
->in
.value_name
, ',');
8772 /* save the registry data */
8774 result
= winreg_set_printer_dataex(p
->mem_ctx
,
8783 if (W_ERROR_IS_OK(result
)) {
8784 /* save the OID if one was specified */
8786 char *str
= talloc_asprintf(p
->mem_ctx
, "%s\\%s",
8787 r
->in
.key_name
, SPOOL_OID_KEY
);
8789 result
= WERR_NOMEM
;
8794 * I'm not checking the status here on purpose. Don't know
8795 * if this is right, but I'm returning the status from the
8796 * previous set_printer_dataex() call. I have no idea if
8797 * this is right. --jerry
8799 winreg_set_printer_dataex(p
->mem_ctx
,
8805 (uint8_t *) oid_string
,
8806 strlen(oid_string
) + 1);
8809 result
= winreg_printer_update_changeid(p
->mem_ctx
,
8811 lp_const_servicename(snum
));
8816 talloc_free(pinfo2
);
8820 /****************************************************************
8821 _spoolss_DeletePrinterDataEx
8822 ****************************************************************/
8824 WERROR
_spoolss_DeletePrinterDataEx(struct pipes_struct
*p
,
8825 struct spoolss_DeletePrinterDataEx
*r
)
8827 const char *printer
;
8829 WERROR status
= WERR_OK
;
8830 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8832 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8835 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8836 "Invalid handle (%s:%u:%u).\n",
8837 OUR_HANDLE(r
->in
.handle
)));
8841 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8842 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8843 "printer properties change denied by handle\n"));
8844 return WERR_ACCESS_DENIED
;
8847 if (!r
->in
.value_name
|| !r
->in
.key_name
) {
8851 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8854 printer
= lp_const_servicename(snum
);
8856 status
= winreg_delete_printer_dataex(p
->mem_ctx
,
8861 if (W_ERROR_IS_OK(status
)) {
8862 status
= winreg_printer_update_changeid(p
->mem_ctx
,
8870 /****************************************************************
8871 _spoolss_EnumPrinterKey
8872 ****************************************************************/
8874 WERROR
_spoolss_EnumPrinterKey(struct pipes_struct
*p
,
8875 struct spoolss_EnumPrinterKey
*r
)
8878 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8880 WERROR result
= WERR_BADFILE
;
8881 const char **array
= NULL
;
8884 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8887 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8888 OUR_HANDLE(r
->in
.handle
)));
8892 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8896 result
= winreg_enum_printer_key(p
->mem_ctx
,
8898 lp_const_servicename(snum
),
8902 if (!W_ERROR_IS_OK(result
)) {
8906 if (!push_reg_multi_sz(p
->mem_ctx
, &blob
, array
)) {
8907 result
= WERR_NOMEM
;
8911 *r
->out
._ndr_size
= r
->in
.offered
/ 2;
8912 *r
->out
.needed
= blob
.length
;
8914 if (r
->in
.offered
< *r
->out
.needed
) {
8915 result
= WERR_MORE_DATA
;
8918 r
->out
.key_buffer
->string_array
= array
;
8922 if (!W_ERROR_IS_OK(result
)) {
8924 if (!W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
8932 /****************************************************************
8933 _spoolss_DeletePrinterKey
8934 ****************************************************************/
8936 WERROR
_spoolss_DeletePrinterKey(struct pipes_struct
*p
,
8937 struct spoolss_DeletePrinterKey
*r
)
8939 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8942 const char *printer
;
8944 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8947 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8948 OUR_HANDLE(r
->in
.handle
)));
8952 /* if keyname == NULL, return error */
8953 if ( !r
->in
.key_name
)
8954 return WERR_INVALID_PARAM
;
8956 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8960 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8961 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8962 "printer properties change denied by handle\n"));
8963 return WERR_ACCESS_DENIED
;
8966 printer
= lp_const_servicename(snum
);
8968 /* delete the key and all subkeys */
8969 status
= winreg_delete_printer_key(p
->mem_ctx
,
8973 if (W_ERROR_IS_OK(status
)) {
8974 status
= winreg_printer_update_changeid(p
->mem_ctx
,
8982 /****************************************************************
8983 _spoolss_EnumPrinterDataEx
8984 ****************************************************************/
8986 WERROR
_spoolss_EnumPrinterDataEx(struct pipes_struct
*p
,
8987 struct spoolss_EnumPrinterDataEx
*r
)
8990 struct spoolss_PrinterEnumValues
*info
= NULL
;
8991 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8995 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8999 *r
->out
.info
= NULL
;
9002 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9003 OUR_HANDLE(r
->in
.handle
)));
9008 * first check for a keyname of NULL or "". Win2k seems to send
9009 * this a lot and we should send back WERR_INVALID_PARAM
9010 * no need to spend time looking up the printer in this case.
9014 if (!strlen(r
->in
.key_name
)) {
9015 result
= WERR_INVALID_PARAM
;
9019 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
9023 /* now look for a match on the key name */
9024 result
= winreg_enum_printer_dataex(p
->mem_ctx
,
9026 lp_const_servicename(snum
),
9030 if (!W_ERROR_IS_OK(result
)) {
9034 #if 0 /* FIXME - gd */
9035 /* housekeeping information in the reply */
9037 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9038 * the hand marshalled container size is a multiple
9039 * of 4 bytes for RPC alignment.
9043 needed
+= 4-(needed
% 4);
9046 *r
->out
.count
= count
;
9047 *r
->out
.info
= info
;
9050 if (!W_ERROR_IS_OK(result
)) {
9054 *r
->out
.needed
= SPOOLSS_BUFFER_ARRAY(p
->mem_ctx
,
9055 spoolss_EnumPrinterDataEx
,
9058 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
9059 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, *r
->out
.count
);
9061 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
9064 /****************************************************************************
9065 ****************************************************************************/
9067 static WERROR
getprintprocessordirectory_level_1(TALLOC_CTX
*mem_ctx
,
9068 const char *servername
,
9069 const char *environment
,
9070 struct spoolss_PrintProcessorDirectoryInfo1
*r
)
9075 werr
= compose_spoolss_server_path(mem_ctx
,
9078 SPOOLSS_PRTPROCS_PATH
,
9080 if (!W_ERROR_IS_OK(werr
)) {
9084 DEBUG(4,("print processor directory: [%s]\n", path
));
9086 r
->directory_name
= path
;
9091 /****************************************************************
9092 _spoolss_GetPrintProcessorDirectory
9093 ****************************************************************/
9095 WERROR
_spoolss_GetPrintProcessorDirectory(struct pipes_struct
*p
,
9096 struct spoolss_GetPrintProcessorDirectory
*r
)
9100 /* that's an [in out] buffer */
9102 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
9103 return WERR_INVALID_PARAM
;
9106 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9111 /* r->in.level is ignored */
9113 /* We always should reply with a local print processor directory so that
9114 * users are not forced to have a [prnproc$] share on the Samba spoolss
9115 * server - Guenther */
9117 result
= getprintprocessordirectory_level_1(p
->mem_ctx
,
9118 NULL
, /* r->in.server */
9120 &r
->out
.info
->info1
);
9121 if (!W_ERROR_IS_OK(result
)) {
9122 TALLOC_FREE(r
->out
.info
);
9126 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo
,
9127 r
->out
.info
, r
->in
.level
);
9128 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
9130 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
9133 /*******************************************************************
9134 ********************************************************************/
9136 static bool push_monitorui_buf(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*buf
,
9137 const char *dllname
)
9139 enum ndr_err_code ndr_err
;
9140 struct spoolss_MonitorUi ui
;
9142 ui
.dll_name
= dllname
;
9144 ndr_err
= ndr_push_struct_blob(buf
, mem_ctx
, &ui
,
9145 (ndr_push_flags_fn_t
)ndr_push_spoolss_MonitorUi
);
9146 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9147 NDR_PRINT_DEBUG(spoolss_MonitorUi
, &ui
);
9149 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9152 /*******************************************************************
9153 Streams the monitor UI DLL name in UNICODE
9154 *******************************************************************/
9156 static WERROR
xcvtcp_monitorui(TALLOC_CTX
*mem_ctx
,
9157 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9158 DATA_BLOB
*out
, uint32_t *needed
)
9160 const char *dllname
= "tcpmonui.dll";
9162 *needed
= (strlen(dllname
)+1) * 2;
9164 if (out
->length
< *needed
) {
9165 return WERR_INSUFFICIENT_BUFFER
;
9168 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
9175 /*******************************************************************
9176 ********************************************************************/
9178 static bool pull_port_data_1(TALLOC_CTX
*mem_ctx
,
9179 struct spoolss_PortData1
*port1
,
9180 const DATA_BLOB
*buf
)
9182 enum ndr_err_code ndr_err
;
9183 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, port1
,
9184 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData1
);
9185 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9186 NDR_PRINT_DEBUG(spoolss_PortData1
, port1
);
9188 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9191 /*******************************************************************
9192 ********************************************************************/
9194 static bool pull_port_data_2(TALLOC_CTX
*mem_ctx
,
9195 struct spoolss_PortData2
*port2
,
9196 const DATA_BLOB
*buf
)
9198 enum ndr_err_code ndr_err
;
9199 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, port2
,
9200 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData2
);
9201 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9202 NDR_PRINT_DEBUG(spoolss_PortData2
, port2
);
9204 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9207 /*******************************************************************
9208 Create a new TCP/IP port
9209 *******************************************************************/
9211 static WERROR
xcvtcp_addport(TALLOC_CTX
*mem_ctx
,
9212 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9213 DATA_BLOB
*out
, uint32_t *needed
)
9215 struct spoolss_PortData1 port1
;
9216 struct spoolss_PortData2 port2
;
9217 char *device_uri
= NULL
;
9220 const char *portname
;
9221 const char *hostaddress
;
9223 uint32_t port_number
;
9226 /* peek for spoolss_PortData version */
9228 if (!in
|| (in
->length
< (128 + 4))) {
9229 return WERR_GENERAL_FAILURE
;
9232 version
= IVAL(in
->data
, 128);
9238 if (!pull_port_data_1(mem_ctx
, &port1
, in
)) {
9242 portname
= port1
.portname
;
9243 hostaddress
= port1
.hostaddress
;
9244 queue
= port1
.queue
;
9245 protocol
= port1
.protocol
;
9246 port_number
= port1
.port_number
;
9252 if (!pull_port_data_2(mem_ctx
, &port2
, in
)) {
9256 portname
= port2
.portname
;
9257 hostaddress
= port2
.hostaddress
;
9258 queue
= port2
.queue
;
9259 protocol
= port2
.protocol
;
9260 port_number
= port2
.port_number
;
9264 DEBUG(1,("xcvtcp_addport: "
9265 "unknown version of port_data: %d\n", version
));
9266 return WERR_UNKNOWN_PORT
;
9269 /* create the device URI and call the add_port_hook() */
9272 case PROTOCOL_RAWTCP_TYPE
:
9273 device_uri
= talloc_asprintf(mem_ctx
,
9274 "socket://%s:%d/", hostaddress
,
9278 case PROTOCOL_LPR_TYPE
:
9279 device_uri
= talloc_asprintf(mem_ctx
,
9280 "lpr://%s/%s", hostaddress
, queue
);
9284 return WERR_UNKNOWN_PORT
;
9291 return add_port_hook(mem_ctx
, token
, portname
, device_uri
);
9294 /*******************************************************************
9295 *******************************************************************/
9297 struct xcv_api_table xcvtcp_cmds
[] = {
9298 { "MonitorUI", xcvtcp_monitorui
},
9299 { "AddPort", xcvtcp_addport
},
9303 static WERROR
process_xcvtcp_command(TALLOC_CTX
*mem_ctx
,
9304 NT_USER_TOKEN
*token
, const char *command
,
9311 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9313 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9314 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9315 return xcvtcp_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
9318 return WERR_BADFUNC
;
9321 /*******************************************************************
9322 *******************************************************************/
9323 #if 0 /* don't support management using the "Local Port" monitor */
9325 static WERROR
xcvlocal_monitorui(TALLOC_CTX
*mem_ctx
,
9326 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9327 DATA_BLOB
*out
, uint32_t *needed
)
9329 const char *dllname
= "localui.dll";
9331 *needed
= (strlen(dllname
)+1) * 2;
9333 if (out
->length
< *needed
) {
9334 return WERR_INSUFFICIENT_BUFFER
;
9337 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
9344 /*******************************************************************
9345 *******************************************************************/
9347 struct xcv_api_table xcvlocal_cmds
[] = {
9348 { "MonitorUI", xcvlocal_monitorui
},
9352 struct xcv_api_table xcvlocal_cmds
[] = {
9359 /*******************************************************************
9360 *******************************************************************/
9362 static WERROR
process_xcvlocal_command(TALLOC_CTX
*mem_ctx
,
9363 NT_USER_TOKEN
*token
, const char *command
,
9364 DATA_BLOB
*inbuf
, DATA_BLOB
*outbuf
,
9369 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9371 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9372 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9373 return xcvlocal_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
9375 return WERR_BADFUNC
;
9378 /****************************************************************
9380 ****************************************************************/
9382 WERROR
_spoolss_XcvData(struct pipes_struct
*p
,
9383 struct spoolss_XcvData
*r
)
9385 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9386 DATA_BLOB out_data
= data_blob_null
;
9390 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9391 OUR_HANDLE(r
->in
.handle
)));
9395 /* Has to be a handle to the TCP/IP port monitor */
9397 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9398 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9402 /* requires administrative access to the server */
9404 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9405 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9406 return WERR_ACCESS_DENIED
;
9409 /* Allocate the outgoing buffer */
9411 if (r
->in
.out_data_size
) {
9412 out_data
= data_blob_talloc_zero(p
->mem_ctx
, r
->in
.out_data_size
);
9413 if (out_data
.data
== NULL
) {
9418 switch ( Printer
->printer_type
) {
9419 case SPLHND_PORTMON_TCP
:
9420 werror
= process_xcvtcp_command(p
->mem_ctx
,
9421 p
->server_info
->ptok
,
9422 r
->in
.function_name
,
9423 &r
->in
.in_data
, &out_data
,
9426 case SPLHND_PORTMON_LOCAL
:
9427 werror
= process_xcvlocal_command(p
->mem_ctx
,
9428 p
->server_info
->ptok
,
9429 r
->in
.function_name
,
9430 &r
->in
.in_data
, &out_data
,
9434 werror
= WERR_INVALID_PRINT_MONITOR
;
9437 if (!W_ERROR_IS_OK(werror
)) {
9441 *r
->out
.status_code
= 0;
9443 if (r
->out
.out_data
&& out_data
.data
&& r
->in
.out_data_size
&& out_data
.length
) {
9444 memcpy(r
->out
.out_data
, out_data
.data
,
9445 MIN(r
->in
.out_data_size
, out_data
.length
));
9451 /****************************************************************
9452 _spoolss_AddPrintProcessor
9453 ****************************************************************/
9455 WERROR
_spoolss_AddPrintProcessor(struct pipes_struct
*p
,
9456 struct spoolss_AddPrintProcessor
*r
)
9458 /* for now, just indicate success and ignore the add. We'll
9459 automatically set the winprint processor for printer
9460 entries later. Used to debug the LexMark Optra S 1855 PCL
9466 /****************************************************************
9468 ****************************************************************/
9470 WERROR
_spoolss_AddPort(struct pipes_struct
*p
,
9471 struct spoolss_AddPort
*r
)
9473 /* do what w2k3 does */
9475 return WERR_NOT_SUPPORTED
;
9478 /****************************************************************
9479 _spoolss_GetPrinterDriver
9480 ****************************************************************/
9482 WERROR
_spoolss_GetPrinterDriver(struct pipes_struct
*p
,
9483 struct spoolss_GetPrinterDriver
*r
)
9485 p
->rng_fault_state
= true;
9486 return WERR_NOT_SUPPORTED
;
9489 /****************************************************************
9490 _spoolss_ReadPrinter
9491 ****************************************************************/
9493 WERROR
_spoolss_ReadPrinter(struct pipes_struct
*p
,
9494 struct spoolss_ReadPrinter
*r
)
9496 p
->rng_fault_state
= true;
9497 return WERR_NOT_SUPPORTED
;
9500 /****************************************************************
9501 _spoolss_WaitForPrinterChange
9502 ****************************************************************/
9504 WERROR
_spoolss_WaitForPrinterChange(struct pipes_struct
*p
,
9505 struct spoolss_WaitForPrinterChange
*r
)
9507 p
->rng_fault_state
= true;
9508 return WERR_NOT_SUPPORTED
;
9511 /****************************************************************
9512 _spoolss_ConfigurePort
9513 ****************************************************************/
9515 WERROR
_spoolss_ConfigurePort(struct pipes_struct
*p
,
9516 struct spoolss_ConfigurePort
*r
)
9518 p
->rng_fault_state
= true;
9519 return WERR_NOT_SUPPORTED
;
9522 /****************************************************************
9524 ****************************************************************/
9526 WERROR
_spoolss_DeletePort(struct pipes_struct
*p
,
9527 struct spoolss_DeletePort
*r
)
9529 p
->rng_fault_state
= true;
9530 return WERR_NOT_SUPPORTED
;
9533 /****************************************************************
9534 _spoolss_CreatePrinterIC
9535 ****************************************************************/
9537 WERROR
_spoolss_CreatePrinterIC(struct pipes_struct
*p
,
9538 struct spoolss_CreatePrinterIC
*r
)
9540 p
->rng_fault_state
= true;
9541 return WERR_NOT_SUPPORTED
;
9544 /****************************************************************
9545 _spoolss_PlayGDIScriptOnPrinterIC
9546 ****************************************************************/
9548 WERROR
_spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct
*p
,
9549 struct spoolss_PlayGDIScriptOnPrinterIC
*r
)
9551 p
->rng_fault_state
= true;
9552 return WERR_NOT_SUPPORTED
;
9555 /****************************************************************
9556 _spoolss_DeletePrinterIC
9557 ****************************************************************/
9559 WERROR
_spoolss_DeletePrinterIC(struct pipes_struct
*p
,
9560 struct spoolss_DeletePrinterIC
*r
)
9562 p
->rng_fault_state
= true;
9563 return WERR_NOT_SUPPORTED
;
9566 /****************************************************************
9567 _spoolss_AddPrinterConnection
9568 ****************************************************************/
9570 WERROR
_spoolss_AddPrinterConnection(struct pipes_struct
*p
,
9571 struct spoolss_AddPrinterConnection
*r
)
9573 p
->rng_fault_state
= true;
9574 return WERR_NOT_SUPPORTED
;
9577 /****************************************************************
9578 _spoolss_DeletePrinterConnection
9579 ****************************************************************/
9581 WERROR
_spoolss_DeletePrinterConnection(struct pipes_struct
*p
,
9582 struct spoolss_DeletePrinterConnection
*r
)
9584 p
->rng_fault_state
= true;
9585 return WERR_NOT_SUPPORTED
;
9588 /****************************************************************
9589 _spoolss_PrinterMessageBox
9590 ****************************************************************/
9592 WERROR
_spoolss_PrinterMessageBox(struct pipes_struct
*p
,
9593 struct spoolss_PrinterMessageBox
*r
)
9595 p
->rng_fault_state
= true;
9596 return WERR_NOT_SUPPORTED
;
9599 /****************************************************************
9601 ****************************************************************/
9603 WERROR
_spoolss_AddMonitor(struct pipes_struct
*p
,
9604 struct spoolss_AddMonitor
*r
)
9606 p
->rng_fault_state
= true;
9607 return WERR_NOT_SUPPORTED
;
9610 /****************************************************************
9611 _spoolss_DeleteMonitor
9612 ****************************************************************/
9614 WERROR
_spoolss_DeleteMonitor(struct pipes_struct
*p
,
9615 struct spoolss_DeleteMonitor
*r
)
9617 p
->rng_fault_state
= true;
9618 return WERR_NOT_SUPPORTED
;
9621 /****************************************************************
9622 _spoolss_DeletePrintProcessor
9623 ****************************************************************/
9625 WERROR
_spoolss_DeletePrintProcessor(struct pipes_struct
*p
,
9626 struct spoolss_DeletePrintProcessor
*r
)
9628 p
->rng_fault_state
= true;
9629 return WERR_NOT_SUPPORTED
;
9632 /****************************************************************
9633 _spoolss_AddPrintProvidor
9634 ****************************************************************/
9636 WERROR
_spoolss_AddPrintProvidor(struct pipes_struct
*p
,
9637 struct spoolss_AddPrintProvidor
*r
)
9639 p
->rng_fault_state
= true;
9640 return WERR_NOT_SUPPORTED
;
9643 /****************************************************************
9644 _spoolss_DeletePrintProvidor
9645 ****************************************************************/
9647 WERROR
_spoolss_DeletePrintProvidor(struct pipes_struct
*p
,
9648 struct spoolss_DeletePrintProvidor
*r
)
9650 p
->rng_fault_state
= true;
9651 return WERR_NOT_SUPPORTED
;
9654 /****************************************************************
9655 _spoolss_FindFirstPrinterChangeNotification
9656 ****************************************************************/
9658 WERROR
_spoolss_FindFirstPrinterChangeNotification(struct pipes_struct
*p
,
9659 struct spoolss_FindFirstPrinterChangeNotification
*r
)
9661 p
->rng_fault_state
= true;
9662 return WERR_NOT_SUPPORTED
;
9665 /****************************************************************
9666 _spoolss_FindNextPrinterChangeNotification
9667 ****************************************************************/
9669 WERROR
_spoolss_FindNextPrinterChangeNotification(struct pipes_struct
*p
,
9670 struct spoolss_FindNextPrinterChangeNotification
*r
)
9672 p
->rng_fault_state
= true;
9673 return WERR_NOT_SUPPORTED
;
9676 /****************************************************************
9677 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9678 ****************************************************************/
9680 WERROR
_spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct
*p
,
9681 struct spoolss_RouterFindFirstPrinterChangeNotificationOld
*r
)
9683 p
->rng_fault_state
= true;
9684 return WERR_NOT_SUPPORTED
;
9687 /****************************************************************
9688 _spoolss_ReplyOpenPrinter
9689 ****************************************************************/
9691 WERROR
_spoolss_ReplyOpenPrinter(struct pipes_struct
*p
,
9692 struct spoolss_ReplyOpenPrinter
*r
)
9694 p
->rng_fault_state
= true;
9695 return WERR_NOT_SUPPORTED
;
9698 /****************************************************************
9699 _spoolss_RouterReplyPrinter
9700 ****************************************************************/
9702 WERROR
_spoolss_RouterReplyPrinter(struct pipes_struct
*p
,
9703 struct spoolss_RouterReplyPrinter
*r
)
9705 p
->rng_fault_state
= true;
9706 return WERR_NOT_SUPPORTED
;
9709 /****************************************************************
9710 _spoolss_ReplyClosePrinter
9711 ****************************************************************/
9713 WERROR
_spoolss_ReplyClosePrinter(struct pipes_struct
*p
,
9714 struct spoolss_ReplyClosePrinter
*r
)
9716 p
->rng_fault_state
= true;
9717 return WERR_NOT_SUPPORTED
;
9720 /****************************************************************
9722 ****************************************************************/
9724 WERROR
_spoolss_AddPortEx(struct pipes_struct
*p
,
9725 struct spoolss_AddPortEx
*r
)
9727 p
->rng_fault_state
= true;
9728 return WERR_NOT_SUPPORTED
;
9731 /****************************************************************
9732 _spoolss_RouterFindFirstPrinterChangeNotification
9733 ****************************************************************/
9735 WERROR
_spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct
*p
,
9736 struct spoolss_RouterFindFirstPrinterChangeNotification
*r
)
9738 p
->rng_fault_state
= true;
9739 return WERR_NOT_SUPPORTED
;
9742 /****************************************************************
9743 _spoolss_SpoolerInit
9744 ****************************************************************/
9746 WERROR
_spoolss_SpoolerInit(struct pipes_struct
*p
,
9747 struct spoolss_SpoolerInit
*r
)
9749 p
->rng_fault_state
= true;
9750 return WERR_NOT_SUPPORTED
;
9753 /****************************************************************
9754 _spoolss_ResetPrinterEx
9755 ****************************************************************/
9757 WERROR
_spoolss_ResetPrinterEx(struct pipes_struct
*p
,
9758 struct spoolss_ResetPrinterEx
*r
)
9760 p
->rng_fault_state
= true;
9761 return WERR_NOT_SUPPORTED
;
9764 /****************************************************************
9765 _spoolss_RouterReplyPrinterEx
9766 ****************************************************************/
9768 WERROR
_spoolss_RouterReplyPrinterEx(struct pipes_struct
*p
,
9769 struct spoolss_RouterReplyPrinterEx
*r
)
9771 p
->rng_fault_state
= true;
9772 return WERR_NOT_SUPPORTED
;
9775 /****************************************************************
9777 ****************************************************************/
9779 WERROR
_spoolss_44(struct pipes_struct
*p
,
9780 struct spoolss_44
*r
)
9782 p
->rng_fault_state
= true;
9783 return WERR_NOT_SUPPORTED
;
9786 /****************************************************************
9788 ****************************************************************/
9790 WERROR
_spoolss_47(struct pipes_struct
*p
,
9791 struct spoolss_47
*r
)
9793 p
->rng_fault_state
= true;
9794 return WERR_NOT_SUPPORTED
;
9797 /****************************************************************
9799 ****************************************************************/
9801 WERROR
_spoolss_4a(struct pipes_struct
*p
,
9802 struct spoolss_4a
*r
)
9804 p
->rng_fault_state
= true;
9805 return WERR_NOT_SUPPORTED
;
9808 /****************************************************************
9810 ****************************************************************/
9812 WERROR
_spoolss_4b(struct pipes_struct
*p
,
9813 struct spoolss_4b
*r
)
9815 p
->rng_fault_state
= true;
9816 return WERR_NOT_SUPPORTED
;
9819 /****************************************************************
9821 ****************************************************************/
9823 WERROR
_spoolss_4c(struct pipes_struct
*p
,
9824 struct spoolss_4c
*r
)
9826 p
->rng_fault_state
= true;
9827 return WERR_NOT_SUPPORTED
;
9830 /****************************************************************
9832 ****************************************************************/
9834 WERROR
_spoolss_53(struct pipes_struct
*p
,
9835 struct spoolss_53
*r
)
9837 p
->rng_fault_state
= true;
9838 return WERR_NOT_SUPPORTED
;
9841 /****************************************************************
9843 ****************************************************************/
9845 WERROR
_spoolss_55(struct pipes_struct
*p
,
9846 struct spoolss_55
*r
)
9848 p
->rng_fault_state
= true;
9849 return WERR_NOT_SUPPORTED
;
9852 /****************************************************************
9854 ****************************************************************/
9856 WERROR
_spoolss_56(struct pipes_struct
*p
,
9857 struct spoolss_56
*r
)
9859 p
->rng_fault_state
= true;
9860 return WERR_NOT_SUPPORTED
;
9863 /****************************************************************
9865 ****************************************************************/
9867 WERROR
_spoolss_57(struct pipes_struct
*p
,
9868 struct spoolss_57
*r
)
9870 p
->rng_fault_state
= true;
9871 return WERR_NOT_SUPPORTED
;
9874 /****************************************************************
9876 ****************************************************************/
9878 WERROR
_spoolss_5a(struct pipes_struct
*p
,
9879 struct spoolss_5a
*r
)
9881 p
->rng_fault_state
= true;
9882 return WERR_NOT_SUPPORTED
;
9885 /****************************************************************
9887 ****************************************************************/
9889 WERROR
_spoolss_5b(struct pipes_struct
*p
,
9890 struct spoolss_5b
*r
)
9892 p
->rng_fault_state
= true;
9893 return WERR_NOT_SUPPORTED
;
9896 /****************************************************************
9898 ****************************************************************/
9900 WERROR
_spoolss_5c(struct pipes_struct
*p
,
9901 struct spoolss_5c
*r
)
9903 p
->rng_fault_state
= true;
9904 return WERR_NOT_SUPPORTED
;
9907 /****************************************************************
9909 ****************************************************************/
9911 WERROR
_spoolss_5d(struct pipes_struct
*p
,
9912 struct spoolss_5d
*r
)
9914 p
->rng_fault_state
= true;
9915 return WERR_NOT_SUPPORTED
;
9918 /****************************************************************
9920 ****************************************************************/
9922 WERROR
_spoolss_5e(struct pipes_struct
*p
,
9923 struct spoolss_5e
*r
)
9925 p
->rng_fault_state
= true;
9926 return WERR_NOT_SUPPORTED
;
9929 /****************************************************************
9931 ****************************************************************/
9933 WERROR
_spoolss_5f(struct pipes_struct
*p
,
9934 struct spoolss_5f
*r
)
9936 p
->rng_fault_state
= true;
9937 return WERR_NOT_SUPPORTED
;
9940 /****************************************************************
9942 ****************************************************************/
9944 WERROR
_spoolss_60(struct pipes_struct
*p
,
9945 struct spoolss_60
*r
)
9947 p
->rng_fault_state
= true;
9948 return WERR_NOT_SUPPORTED
;
9951 /****************************************************************
9953 ****************************************************************/
9955 WERROR
_spoolss_61(struct pipes_struct
*p
,
9956 struct spoolss_61
*r
)
9958 p
->rng_fault_state
= true;
9959 return WERR_NOT_SUPPORTED
;
9962 /****************************************************************
9964 ****************************************************************/
9966 WERROR
_spoolss_62(struct pipes_struct
*p
,
9967 struct spoolss_62
*r
)
9969 p
->rng_fault_state
= true;
9970 return WERR_NOT_SUPPORTED
;
9973 /****************************************************************
9975 ****************************************************************/
9977 WERROR
_spoolss_63(struct pipes_struct
*p
,
9978 struct spoolss_63
*r
)
9980 p
->rng_fault_state
= true;
9981 return WERR_NOT_SUPPORTED
;
9984 /****************************************************************
9986 ****************************************************************/
9988 WERROR
_spoolss_64(struct pipes_struct
*p
,
9989 struct spoolss_64
*r
)
9991 p
->rng_fault_state
= true;
9992 return WERR_NOT_SUPPORTED
;
9995 /****************************************************************
9997 ****************************************************************/
9999 WERROR
_spoolss_65(struct pipes_struct
*p
,
10000 struct spoolss_65
*r
)
10002 p
->rng_fault_state
= true;
10003 return WERR_NOT_SUPPORTED
;
10006 /****************************************************************
10007 _spoolss_GetCorePrinterDrivers
10008 ****************************************************************/
10010 WERROR
_spoolss_GetCorePrinterDrivers(struct pipes_struct
*p
,
10011 struct spoolss_GetCorePrinterDrivers
*r
)
10013 p
->rng_fault_state
= true;
10014 return WERR_NOT_SUPPORTED
;
10017 /****************************************************************
10019 ****************************************************************/
10021 WERROR
_spoolss_67(struct pipes_struct
*p
,
10022 struct spoolss_67
*r
)
10024 p
->rng_fault_state
= true;
10025 return WERR_NOT_SUPPORTED
;
10028 /****************************************************************
10029 _spoolss_GetPrinterDriverPackagePath
10030 ****************************************************************/
10032 WERROR
_spoolss_GetPrinterDriverPackagePath(struct pipes_struct
*p
,
10033 struct spoolss_GetPrinterDriverPackagePath
*r
)
10035 p
->rng_fault_state
= true;
10036 return WERR_NOT_SUPPORTED
;
10039 /****************************************************************
10041 ****************************************************************/
10043 WERROR
_spoolss_69(struct pipes_struct
*p
,
10044 struct spoolss_69
*r
)
10046 p
->rng_fault_state
= true;
10047 return WERR_NOT_SUPPORTED
;
10050 /****************************************************************
10052 ****************************************************************/
10054 WERROR
_spoolss_6a(struct pipes_struct
*p
,
10055 struct spoolss_6a
*r
)
10057 p
->rng_fault_state
= true;
10058 return WERR_NOT_SUPPORTED
;
10061 /****************************************************************
10063 ****************************************************************/
10065 WERROR
_spoolss_6b(struct pipes_struct
*p
,
10066 struct spoolss_6b
*r
)
10068 p
->rng_fault_state
= true;
10069 return WERR_NOT_SUPPORTED
;
10072 /****************************************************************
10074 ****************************************************************/
10076 WERROR
_spoolss_6c(struct pipes_struct
*p
,
10077 struct spoolss_6c
*r
)
10079 p
->rng_fault_state
= true;
10080 return WERR_NOT_SUPPORTED
;
10083 /****************************************************************
10085 ****************************************************************/
10087 WERROR
_spoolss_6d(struct pipes_struct
*p
,
10088 struct spoolss_6d
*r
)
10090 p
->rng_fault_state
= true;
10091 return WERR_NOT_SUPPORTED
;