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 "srv_spoolss_util.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/cli_spoolss.h"
34 #include "rpc_client/init_spoolss.h"
35 #include "librpc/gen_ndr/messaging.h"
37 #include "registry/reg_objects.h"
39 /* macros stolen from s4 spoolss server */
40 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
41 ((info)?ndr_size_##fn(info, level, 0):0)
43 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
44 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
46 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
47 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
49 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
52 extern userdom_struct current_user_info
;
55 #define DBGC_CLASS DBGC_RPC_SRV
57 #ifndef MAX_OPEN_PRINTER_EXS
58 #define MAX_OPEN_PRINTER_EXS 50
61 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
63 static Printer_entry
*printers_list
;
65 typedef struct _counter_printer_0
{
66 struct _counter_printer_0
*next
;
67 struct _counter_printer_0
*prev
;
73 static counter_printer_0
*counter_list
;
75 static struct rpc_pipe_client
*notify_cli_pipe
; /* print notify back-channel pipe handle*/
76 static uint32_t smb_connections
= 0;
79 /* in printing/nt_printing.c */
81 extern struct standard_mapping printer_std_mapping
, printserver_std_mapping
;
83 /* API table for Xcv Monitor functions */
85 struct xcv_api_table
{
87 WERROR(*fn
) (TALLOC_CTX
*mem_ctx
, NT_USER_TOKEN
*token
, DATA_BLOB
*in
, DATA_BLOB
*out
, uint32_t *needed
);
90 /********************************************************************
91 * Canonicalize servername.
92 ********************************************************************/
94 static const char *canon_servername(const char *servername
)
96 const char *pservername
= servername
;
97 while (*pservername
== '\\') {
103 /* translate between internal status numbers and NT status numbers */
104 static int nt_printj_status(int v
)
110 return JOB_STATUS_PAUSED
;
112 return JOB_STATUS_SPOOLING
;
114 return JOB_STATUS_PRINTING
;
116 return JOB_STATUS_ERROR
;
118 return JOB_STATUS_DELETING
;
120 return JOB_STATUS_OFFLINE
;
122 return JOB_STATUS_PAPEROUT
;
124 return JOB_STATUS_PRINTED
;
126 return JOB_STATUS_DELETED
;
128 return JOB_STATUS_BLOCKED_DEVQ
;
129 case LPQ_USER_INTERVENTION
:
130 return JOB_STATUS_USER_INTERVENTION
;
135 static int nt_printq_status(int v
)
139 return PRINTER_STATUS_PAUSED
;
148 /***************************************************************************
149 Disconnect from the client
150 ****************************************************************************/
152 static void srv_spoolss_replycloseprinter(int snum
, struct policy_handle
*handle
)
158 * Tell the specific printing tdb we no longer want messages for this printer
159 * by deregistering our PID.
162 if (!print_notify_deregister_pid(snum
))
163 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum
) ));
165 /* weird if the test succeds !!! */
166 if (smb_connections
==0) {
167 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
171 status
= rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe
, talloc_tos(),
174 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
175 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
176 win_errstr(result
)));
178 /* if it's the last connection, deconnect the IPC$ share */
179 if (smb_connections
==1) {
181 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe
) );
182 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
184 messaging_deregister(smbd_messaging_context(),
185 MSG_PRINTER_NOTIFY2
, NULL
);
187 /* Tell the connections db we're no longer interested in
188 * printer notify messages. */
190 serverid_register_msg_flags(
191 messaging_server_id(smbd_messaging_context()),
192 false, FLAG_MSG_PRINT_NOTIFY
);
198 /****************************************************************************
199 Functions to free a printer entry datastruct.
200 ****************************************************************************/
202 static int printer_entry_destructor(Printer_entry
*Printer
)
204 if (Printer
->notify
.client_connected
== true) {
207 if ( Printer
->printer_type
== SPLHND_SERVER
) {
209 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
210 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
211 snum
= print_queue_snum(Printer
->sharename
);
213 srv_spoolss_replycloseprinter(snum
,
214 &Printer
->notify
.client_hnd
);
218 Printer
->notify
.flags
=0;
219 Printer
->notify
.options
=0;
220 Printer
->notify
.localmachine
[0]='\0';
221 Printer
->notify
.printerlocal
=0;
222 TALLOC_FREE(Printer
->notify
.option
);
223 Printer
->notify
.client_connected
= false;
225 TALLOC_FREE(Printer
->devmode
);
226 free_a_printer( &Printer
->printer_info
, 2 );
228 /* Remove from the internal list. */
229 DLIST_REMOVE(printers_list
, Printer
);
233 /****************************************************************************
234 find printer index by handle
235 ****************************************************************************/
237 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
,
238 struct policy_handle
*hnd
)
240 Printer_entry
*find_printer
= NULL
;
242 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
243 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
250 /****************************************************************************
251 Close printer index by handle.
252 ****************************************************************************/
254 static bool close_printer_handle(pipes_struct
*p
, struct policy_handle
*hnd
)
256 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
259 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
264 close_policy_hnd(p
, hnd
);
269 /****************************************************************************
270 Delete a printer given a handle.
271 ****************************************************************************/
273 static WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
275 char *cmd
= lp_deleteprinter_cmd();
276 char *command
= NULL
;
278 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
279 bool is_print_op
= false;
281 /* can't fail if we don't try */
286 command
= talloc_asprintf(ctx
,
293 is_print_op
= user_has_privileges( token
, &se_printop
);
295 DEBUG(10,("Running [%s]\n", command
));
297 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
302 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
303 /* Tell everyone we updated smb.conf. */
304 message_send_all(smbd_messaging_context(),
305 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
311 /********** END SePrintOperatorPrivlege BLOCK **********/
313 DEBUGADD(10,("returned [%d]\n", ret
));
315 TALLOC_FREE(command
);
318 return WERR_BADFID
; /* What to return here? */
320 /* go ahead and re-read the services immediately */
322 reload_services(false);
325 if ( lp_servicenumber( sharename
) > 0 )
326 return WERR_ACCESS_DENIED
;
331 /****************************************************************************
332 Delete a printer given a handle.
333 ****************************************************************************/
335 static WERROR
delete_printer_handle(pipes_struct
*p
, struct policy_handle
*hnd
)
337 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
340 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
346 * It turns out that Windows allows delete printer on a handle
347 * opened by an admin user, then used on a pipe handle created
348 * by an anonymous user..... but they're working on security.... riiight !
352 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
353 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
354 return WERR_ACCESS_DENIED
;
357 /* this does not need a become root since the access check has been
358 done on the handle already */
360 if (del_a_printer( Printer
->sharename
) != 0) {
361 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
365 return delete_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
366 Printer
->sharename
);
369 /****************************************************************************
370 Return the snum of a printer corresponding to an handle.
371 ****************************************************************************/
373 static bool get_printer_snum(pipes_struct
*p
, struct policy_handle
*hnd
,
374 int *number
, struct share_params
**params
)
376 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
379 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
384 switch (Printer
->printer_type
) {
386 DEBUG(4,("short name:%s\n", Printer
->sharename
));
387 *number
= print_queue_snum(Printer
->sharename
);
388 return (*number
!= -1);
396 /****************************************************************************
397 Set printer handle type.
398 Check if it's \\server or \\server\printer
399 ****************************************************************************/
401 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, const char *handlename
)
403 DEBUG(3,("Setting printer type=%s\n", handlename
));
405 if ( strlen(handlename
) < 3 ) {
406 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
410 /* it's a print server */
411 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
412 DEBUGADD(4,("Printer is a print server\n"));
413 Printer
->printer_type
= SPLHND_SERVER
;
415 /* it's a printer (set_printer_hnd_name() will handle port monitors */
417 DEBUGADD(4,("Printer is a printer\n"));
418 Printer
->printer_type
= SPLHND_PRINTER
;
424 /****************************************************************************
425 Set printer handle name.. Accept names like \\server, \\server\printer,
426 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
427 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
428 XcvDataPort() interface.
429 ****************************************************************************/
431 static bool set_printer_hnd_name(TALLOC_CTX
*mem_ctx
,
432 struct auth_serversupplied_info
*server_info
,
433 Printer_entry
*Printer
,
434 const char *handlename
)
437 int n_services
=lp_numservices();
439 const char *printername
;
440 const char *servername
;
443 struct spoolss_PrinterInfo2
*info2
= NULL
;
446 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
,
447 (unsigned long)strlen(handlename
)));
449 aprinter
= CONST_DISCARD(char *, handlename
);
450 if ( *handlename
== '\\' ) {
451 servername
= canon_servername(handlename
);
452 if ( (aprinter
= strchr_m( servername
, '\\' )) != NULL
) {
456 if (!is_myname_or_ipaddr(servername
)) {
460 fstrcpy(Printer
->servername
, servername
);
463 if (Printer
->printer_type
== SPLHND_SERVER
) {
467 if (Printer
->printer_type
!= SPLHND_PRINTER
) {
471 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
473 /* check for the Port Monitor Interface */
474 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
475 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
476 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
479 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
480 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
481 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
485 /* Search all sharenames first as this is easier than pulling
486 the printer_info_2 off of disk. Don't use find_service() since
487 that calls out to map_username() */
489 /* do another loop to look for printernames */
490 for (snum
= 0; !found
&& snum
< n_services
; snum
++) {
491 const char *printer
= lp_const_servicename(snum
);
493 /* no point going on if this is not a printer */
494 if (!(lp_snum_ok(snum
) && lp_print_ok(snum
))) {
498 /* ignore [printers] share */
499 if (strequal(printer
, "printers")) {
503 fstrcpy(sname
, printer
);
504 if (strequal(aprinter
, printer
)) {
509 /* no point looking up the printer object if
510 we aren't allowing printername != sharename */
511 if (lp_force_printername(snum
)) {
515 result
= winreg_get_printer(mem_ctx
,
520 if ( !W_ERROR_IS_OK(result
) ) {
521 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
522 sname
, win_errstr(result
)));
526 printername
= strrchr(info2
->printername
, '\\');
527 if (printername
== NULL
) {
528 printername
= info2
->printername
;
533 if (strequal(printername
, aprinter
)) {
538 DEBUGADD(10, ("printername: %s\n", printername
));
544 DEBUGADD(4,("Printer not found\n"));
548 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
550 fstrcpy(Printer
->sharename
, sname
);
555 /****************************************************************************
556 Find first available printer slot. creates a printer handle for you.
557 ****************************************************************************/
559 static bool open_printer_hnd(pipes_struct
*p
, struct policy_handle
*hnd
,
560 const char *name
, uint32_t access_granted
)
562 Printer_entry
*new_printer
;
564 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
566 new_printer
= TALLOC_ZERO_P(NULL
, Printer_entry
);
567 if (new_printer
== NULL
) {
570 talloc_set_destructor(new_printer
, printer_entry_destructor
);
572 if (!create_policy_hnd(p
, hnd
, new_printer
)) {
573 TALLOC_FREE(new_printer
);
577 /* Add to the internal list. */
578 DLIST_ADD(printers_list
, new_printer
);
580 new_printer
->notify
.option
=NULL
;
582 if (!set_printer_hnd_printertype(new_printer
, name
)) {
583 close_printer_handle(p
, hnd
);
587 if (!set_printer_hnd_name(p
->mem_ctx
, p
->server_info
, new_printer
, name
)) {
588 close_printer_handle(p
, hnd
);
592 new_printer
->access_granted
= access_granted
;
594 DEBUG(5, ("%d printer handles active\n",
595 (int)num_pipe_handles(p
)));
600 /***************************************************************************
601 check to see if the client motify handle is monitoring the notification
602 given by (notify_type, notify_field).
603 **************************************************************************/
605 static bool is_monitoring_event_flags(uint32_t flags
, uint16_t notify_type
,
606 uint16_t notify_field
)
611 static bool is_monitoring_event(Printer_entry
*p
, uint16_t notify_type
,
612 uint16_t notify_field
)
614 struct spoolss_NotifyOption
*option
= p
->notify
.option
;
618 * Flags should always be zero when the change notify
619 * is registered by the client's spooler. A user Win32 app
620 * might use the flags though instead of the NOTIFY_OPTION_INFO
629 return is_monitoring_event_flags(
630 p
->notify
.flags
, notify_type
, notify_field
);
632 for (i
= 0; i
< option
->count
; i
++) {
634 /* Check match for notify_type */
636 if (option
->types
[i
].type
!= notify_type
)
639 /* Check match for field */
641 for (j
= 0; j
< option
->types
[i
].count
; j
++) {
642 if (option
->types
[i
].fields
[j
].field
== notify_field
) {
648 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
649 p
->servername
, p
->sharename
, notify_type
, notify_field
));
654 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
655 _data->data.integer[0] = _integer; \
656 _data->data.integer[1] = 0;
659 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
660 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
661 if (!_data->data.string.string) {\
662 _data->data.string.size = 0; \
664 _data->data.string.size = strlen_m_term(_p) * 2;
666 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
667 _data->data.devmode.devmode = _devmode;
669 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
670 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
671 if (!_data->data.sd.sd) { \
672 _data->data.sd.sd_size = 0; \
674 _data->data.sd.sd_size = _size;
676 static void init_systemtime_buffer(TALLOC_CTX
*mem_ctx
,
681 struct spoolss_Time st
;
685 if (!init_systemtime(&st
, t
)) {
689 p
= talloc_array(mem_ctx
, char, len
);
695 * Systemtime must be linearized as a set of UINT16's.
696 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
699 SSVAL(p
, 0, st
.year
);
700 SSVAL(p
, 2, st
.month
);
701 SSVAL(p
, 4, st
.day_of_week
);
703 SSVAL(p
, 8, st
.hour
);
704 SSVAL(p
, 10, st
.minute
);
705 SSVAL(p
, 12, st
.second
);
706 SSVAL(p
, 14, st
.millisecond
);
712 /* Convert a notification message to a struct spoolss_Notify */
714 static void notify_one_value(struct spoolss_notify_msg
*msg
,
715 struct spoolss_Notify
*data
,
718 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, msg
->notify
.value
[0]);
721 static void notify_string(struct spoolss_notify_msg
*msg
,
722 struct spoolss_Notify
*data
,
725 /* The length of the message includes the trailing \0 */
727 data
->data
.string
.size
= msg
->len
* 2;
728 data
->data
.string
.string
= talloc_strdup(mem_ctx
, msg
->notify
.data
);
729 if (!data
->data
.string
.string
) {
730 data
->data
.string
.size
= 0;
735 static void notify_system_time(struct spoolss_notify_msg
*msg
,
736 struct spoolss_Notify
*data
,
739 data
->data
.string
.string
= NULL
;
740 data
->data
.string
.size
= 0;
742 if (msg
->len
!= sizeof(time_t)) {
743 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
748 init_systemtime_buffer(mem_ctx
, gmtime((time_t *)msg
->notify
.data
),
749 &data
->data
.string
.string
,
750 &data
->data
.string
.size
);
753 struct notify2_message_table
{
755 void (*fn
)(struct spoolss_notify_msg
*msg
,
756 struct spoolss_Notify
*data
, TALLOC_CTX
*mem_ctx
);
759 static struct notify2_message_table printer_notify_table
[] = {
760 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string
},
761 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string
},
762 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string
},
763 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string
},
764 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string
},
765 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string
},
766 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string
},
767 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL
},
768 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string
},
769 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string
},
770 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL
},
771 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string
},
772 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL
},
773 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value
},
774 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value
},
775 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL
},
776 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL
},
777 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL
},
778 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value
},
781 static struct notify2_message_table job_notify_table
[] = {
782 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL
},
783 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL
},
784 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL
},
785 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string
},
786 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL
},
787 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL
},
788 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL
},
789 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL
},
790 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL
},
791 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL
},
792 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value
},
793 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL
},
794 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL
},
795 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string
},
796 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL
},
797 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL
},
798 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time
},
799 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL
},
800 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL
},
801 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL
},
802 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value
},
803 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL
},
804 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value
},
805 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL
},
809 /***********************************************************************
810 Allocate talloc context for container object
811 **********************************************************************/
813 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
818 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
823 /***********************************************************************
824 release all allocated memory and zero out structure
825 **********************************************************************/
827 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
833 talloc_destroy(ctr
->ctx
);
840 /***********************************************************************
841 **********************************************************************/
843 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
851 /***********************************************************************
852 **********************************************************************/
854 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32_t idx
)
856 if ( !ctr
|| !ctr
->msg_groups
)
859 if ( idx
>= ctr
->num_groups
)
862 return &ctr
->msg_groups
[idx
];
866 /***********************************************************************
867 How many groups of change messages do we have ?
868 **********************************************************************/
870 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
875 return ctr
->num_groups
;
878 /***********************************************************************
879 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
880 **********************************************************************/
882 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
884 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
885 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
886 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
892 /* loop over all groups looking for a matching printer name */
894 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
895 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
899 /* add a new group? */
901 if ( i
== ctr
->num_groups
) {
904 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
905 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
908 ctr
->msg_groups
= groups
;
910 /* clear the new entry and set the printer name */
912 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
913 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
916 /* add the change messages; 'i' is the correct index now regardless */
918 msg_grp
= &ctr
->msg_groups
[i
];
922 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
923 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
926 msg_grp
->msgs
= msg_list
;
928 new_slot
= msg_grp
->num_msgs
-1;
929 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
931 /* need to allocate own copy of data */
934 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
935 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
937 return ctr
->num_groups
;
940 void construct_info_data(struct spoolss_Notify
*info_data
,
941 enum spoolss_NotifyType type
,
945 /***********************************************************************
946 Send a change notication message on all handles which have a call
948 **********************************************************************/
950 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32_t idx
)
953 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
954 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
955 SPOOLSS_NOTIFY_MSG
*messages
;
956 int sending_msg_count
;
959 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
963 messages
= msg_group
->msgs
;
966 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
970 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
972 /* loop over all printers */
974 for (p
= printers_list
; p
; p
= p
->next
) {
975 struct spoolss_Notify
*notifies
;
980 /* Is there notification on this handle? */
982 if ( !p
->notify
.client_connected
)
985 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
987 /* For this printer? Print servers always receive
990 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
991 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
994 DEBUG(10,("Our printer\n"));
996 /* allocate the max entries possible */
998 notifies
= TALLOC_ZERO_ARRAY(mem_ctx
, struct spoolss_Notify
, msg_group
->num_msgs
);
1003 /* build the array of change notifications */
1005 sending_msg_count
= 0;
1007 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
1008 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
1010 /* Are we monitoring this event? */
1012 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1015 sending_msg_count
++;
1018 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1019 msg
->type
, msg
->field
, p
->sharename
));
1022 * if the is a printer notification handle and not a job notification
1023 * type, then set the id to 0. Other wise just use what was specified
1026 * When registering change notification on a print server handle
1027 * we always need to send back the id (snum) matching the printer
1028 * for which the change took place. For change notify registered
1029 * on a printer handle, this does not matter and the id should be 0.
1034 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1040 /* Convert unix jobid to smb jobid */
1042 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1043 id
= sysjob_to_jobid(msg
->id
);
1046 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1051 construct_info_data( ¬ifies
[count
], msg
->type
, msg
->field
, id
);
1054 case PRINTER_NOTIFY_TYPE
:
1055 if ( printer_notify_table
[msg
->field
].fn
)
1056 printer_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1059 case JOB_NOTIFY_TYPE
:
1060 if ( job_notify_table
[msg
->field
].fn
)
1061 job_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1065 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1072 if ( sending_msg_count
) {
1075 union spoolss_ReplyPrinterInfo info
;
1076 struct spoolss_NotifyInfo info0
;
1077 uint32_t reply_result
;
1079 info0
.version
= 0x2;
1080 info0
.flags
= count
? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED
;
1081 info0
.count
= count
;
1082 info0
.notifies
= notifies
;
1084 info
.info0
= &info0
;
1086 status
= rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe
, mem_ctx
,
1087 &p
->notify
.client_hnd
,
1088 p
->notify
.change
, /* color */
1091 0, /* reply_type, must be 0 */
1094 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(werr
)) {
1095 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1096 notify_cli_pipe
->srv_name_slash
,
1099 switch (reply_result
) {
1102 case PRINTER_NOTIFY_INFO_DISCARDED
:
1103 case PRINTER_NOTIFY_INFO_DISCARDNOTED
:
1104 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH
:
1113 DEBUG(8,("send_notify2_changes: Exit...\n"));
1117 /***********************************************************************
1118 **********************************************************************/
1120 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1123 uint32_t tv_sec
, tv_usec
;
1126 /* Unpack message */
1128 offset
+= tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "f",
1131 offset
+= tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "ddddddd",
1133 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1136 tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "dd",
1137 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1139 tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "B",
1140 &msg
->len
, &msg
->notify
.data
);
1142 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1143 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1145 tv
->tv_sec
= tv_sec
;
1146 tv
->tv_usec
= tv_usec
;
1149 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1150 msg
->notify
.value
[1]));
1152 dump_data(3, (uint8_t *)msg
->notify
.data
, msg
->len
);
1157 /********************************************************************
1158 Receive a notify2 message list
1159 ********************************************************************/
1161 static void receive_notify2_message_list(struct messaging_context
*msg
,
1164 struct server_id server_id
,
1167 size_t msg_count
, i
;
1168 char *buf
= (char *)data
->data
;
1171 SPOOLSS_NOTIFY_MSG notify
;
1172 SPOOLSS_NOTIFY_MSG_CTR messages
;
1175 if (data
->length
< 4) {
1176 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1180 msg_count
= IVAL(buf
, 0);
1183 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1185 if (msg_count
== 0) {
1186 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1190 /* initialize the container */
1192 ZERO_STRUCT( messages
);
1193 notify_msg_ctr_init( &messages
);
1196 * build message groups for each printer identified
1197 * in a change_notify msg. Remember that a PCN message
1198 * includes the handle returned for the srv_spoolss_replyopenprinter()
1199 * call. Therefore messages are grouped according to printer handle.
1202 for ( i
=0; i
<msg_count
; i
++ ) {
1203 struct timeval msg_tv
;
1205 if (msg_ptr
+ 4 - buf
> data
->length
) {
1206 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1210 msg_len
= IVAL(msg_ptr
,0);
1213 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1214 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1218 /* unpack messages */
1220 ZERO_STRUCT( notify
);
1221 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1224 /* add to correct list in container */
1226 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1228 /* free memory that might have been allocated by notify2_unpack_msg() */
1230 if ( notify
.len
!= 0 )
1231 SAFE_FREE( notify
.notify
.data
);
1234 /* process each group of messages */
1236 num_groups
= notify_msg_ctr_numgroups( &messages
);
1237 for ( i
=0; i
<num_groups
; i
++ )
1238 send_notify2_changes( &messages
, i
);
1243 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1244 (uint32_t)msg_count
));
1246 notify_msg_ctr_destroy( &messages
);
1251 /********************************************************************
1252 Send a message to ourself about new driver being installed
1253 so we can upgrade the information for each printer bound to this
1255 ********************************************************************/
1257 static bool srv_spoolss_drv_upgrade_printer(const char *drivername
)
1259 int len
= strlen(drivername
);
1264 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1267 messaging_send_buf(smbd_messaging_context(),
1268 messaging_server_id(smbd_messaging_context()),
1269 MSG_PRINTER_DRVUPGRADE
,
1270 (uint8_t *)drivername
, len
+1);
1275 /**********************************************************************
1276 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1277 over all printers, upgrading ones as necessary
1278 **********************************************************************/
1280 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1283 struct server_id server_id
,
1288 int n_services
= lp_numservices();
1291 len
= MIN(data
->length
,sizeof(drivername
)-1);
1292 strncpy(drivername
, (const char *)data
->data
, len
);
1294 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1296 /* Iterate the printer list */
1298 for (snum
=0; snum
<n_services
; snum
++)
1300 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1303 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1305 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1306 if (!W_ERROR_IS_OK(result
))
1309 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1311 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1313 /* all we care about currently is the change_id */
1315 result
= mod_a_printer(printer
, 2);
1316 if (!W_ERROR_IS_OK(result
)) {
1317 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1318 win_errstr(result
)));
1322 free_a_printer(&printer
, 2);
1329 /********************************************************************
1330 Update the cache for all printq's with a registered client
1332 ********************************************************************/
1334 void update_monitored_printq_cache( void )
1336 Printer_entry
*printer
= printers_list
;
1339 /* loop through all printers and update the cache where
1340 client_connected == true */
1343 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1344 && printer
->notify
.client_connected
)
1346 snum
= print_queue_snum(printer
->sharename
);
1347 print_queue_status( snum
, NULL
, NULL
);
1350 printer
= printer
->next
;
1356 /****************************************************************
1357 _spoolss_OpenPrinter
1358 ****************************************************************/
1360 WERROR
_spoolss_OpenPrinter(pipes_struct
*p
,
1361 struct spoolss_OpenPrinter
*r
)
1363 struct spoolss_OpenPrinterEx e
;
1366 ZERO_STRUCT(e
.in
.userlevel
);
1368 e
.in
.printername
= r
->in
.printername
;
1369 e
.in
.datatype
= r
->in
.datatype
;
1370 e
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
1371 e
.in
.access_mask
= r
->in
.access_mask
;
1374 e
.out
.handle
= r
->out
.handle
;
1376 werr
= _spoolss_OpenPrinterEx(p
, &e
);
1378 if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
1379 /* OpenPrinterEx returns this for a bad
1380 * printer name. We must return WERR_INVALID_PRINTER_NAME
1383 werr
= WERR_INVALID_PRINTER_NAME
;
1389 static WERROR
copy_devicemode(TALLOC_CTX
*mem_ctx
,
1390 struct spoolss_DeviceMode
*orig
,
1391 struct spoolss_DeviceMode
**dest
)
1393 struct spoolss_DeviceMode
*dm
;
1395 dm
= talloc(mem_ctx
, struct spoolss_DeviceMode
);
1400 /* copy all values, then duplicate strings and structs */
1403 dm
->devicename
= talloc_strdup(dm
, orig
->devicename
);
1404 if (!dm
->devicename
) {
1407 dm
->formname
= talloc_strdup(dm
, orig
->formname
);
1408 if (!dm
->formname
) {
1411 if (orig
->driverextra_data
.data
) {
1412 dm
->driverextra_data
.data
=
1413 (uint8_t *) talloc_memdup(dm
, orig
->driverextra_data
.data
,
1414 orig
->driverextra_data
.length
);
1415 if (!dm
->driverextra_data
.data
) {
1424 /****************************************************************
1425 _spoolss_OpenPrinterEx
1426 ****************************************************************/
1428 WERROR
_spoolss_OpenPrinterEx(pipes_struct
*p
,
1429 struct spoolss_OpenPrinterEx
*r
)
1432 Printer_entry
*Printer
=NULL
;
1434 if (!r
->in
.printername
) {
1435 return WERR_INVALID_PARAM
;
1438 /* some sanity check because you can open a printer or a print server */
1439 /* aka: \\server\printer or \\server */
1441 DEBUGADD(3,("checking name: %s\n", r
->in
.printername
));
1443 if (!open_printer_hnd(p
, r
->out
.handle
, r
->in
.printername
, 0)) {
1444 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1445 " for printer %s\n", r
->in
.printername
));
1446 ZERO_STRUCTP(r
->out
.handle
);
1447 return WERR_INVALID_PARAM
;
1450 Printer
= find_printer_index_by_hnd(p
, r
->out
.handle
);
1452 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1453 "handle we created for printer %s\n", r
->in
.printername
));
1454 close_printer_handle(p
, r
->out
.handle
);
1455 ZERO_STRUCTP(r
->out
.handle
);
1456 return WERR_INVALID_PARAM
;
1460 * First case: the user is opening the print server:
1462 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1463 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1465 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1466 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1467 * or if the user is listed in the smb.conf printer admin parameter.
1469 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1470 * client view printer folder, but does not show the MSAPW.
1472 * Note: this test needs code to check access rights here too. Jeremy
1473 * could you look at this?
1475 * Second case: the user is opening a printer:
1476 * NT doesn't let us connect to a printer if the connecting user
1477 * doesn't have print permission.
1479 * Third case: user is opening a Port Monitor
1480 * access checks same as opening a handle to the print server.
1483 switch (Printer
->printer_type
)
1486 case SPLHND_PORTMON_TCP
:
1487 case SPLHND_PORTMON_LOCAL
:
1488 /* Printserver handles use global struct... */
1492 /* Map standard access rights to object specific access rights */
1494 se_map_standard(&r
->in
.access_mask
,
1495 &printserver_std_mapping
);
1497 /* Deny any object specific bits that don't apply to print
1498 servers (i.e printer and job specific bits) */
1500 r
->in
.access_mask
&= SEC_MASK_SPECIFIC
;
1502 if (r
->in
.access_mask
&
1503 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1504 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1505 close_printer_handle(p
, r
->out
.handle
);
1506 ZERO_STRUCTP(r
->out
.handle
);
1507 return WERR_ACCESS_DENIED
;
1510 /* Allow admin access */
1512 if ( r
->in
.access_mask
& SERVER_ACCESS_ADMINISTER
)
1514 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1516 if (!lp_ms_add_printer_wizard()) {
1517 close_printer_handle(p
, r
->out
.handle
);
1518 ZERO_STRUCTP(r
->out
.handle
);
1519 return WERR_ACCESS_DENIED
;
1522 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1523 and not a printer admin, then fail */
1525 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
1526 !user_has_privileges(p
->server_info
->ptok
,
1528 !token_contains_name_in_list(
1529 uidtoname(p
->server_info
->utok
.uid
),
1530 p
->server_info
->info3
->base
.domain
.string
,
1532 p
->server_info
->ptok
,
1533 lp_printer_admin(snum
))) {
1534 close_printer_handle(p
, r
->out
.handle
);
1535 ZERO_STRUCTP(r
->out
.handle
);
1536 return WERR_ACCESS_DENIED
;
1539 r
->in
.access_mask
= SERVER_ACCESS_ADMINISTER
;
1543 r
->in
.access_mask
= SERVER_ACCESS_ENUMERATE
;
1546 DEBUG(4,("Setting print server access = %s\n", (r
->in
.access_mask
== SERVER_ACCESS_ADMINISTER
)
1547 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1549 /* We fall through to return WERR_OK */
1552 case SPLHND_PRINTER
:
1553 /* NT doesn't let us connect to a printer if the connecting user
1554 doesn't have print permission. */
1556 if (!get_printer_snum(p
, r
->out
.handle
, &snum
, NULL
)) {
1557 close_printer_handle(p
, r
->out
.handle
);
1558 ZERO_STRUCTP(r
->out
.handle
);
1562 if (r
->in
.access_mask
== SEC_FLAG_MAXIMUM_ALLOWED
) {
1563 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1566 se_map_standard(&r
->in
.access_mask
, &printer_std_mapping
);
1568 /* map an empty access mask to the minimum access mask */
1569 if (r
->in
.access_mask
== 0x0)
1570 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1573 * If we are not serving the printer driver for this printer,
1574 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1575 * will keep NT clients happy --jerry
1578 if (lp_use_client_driver(snum
)
1579 && (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
))
1581 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1584 /* check smb.conf parameters and the the sec_desc */
1586 if ( !check_access(get_client_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1587 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1588 ZERO_STRUCTP(r
->out
.handle
);
1589 return WERR_ACCESS_DENIED
;
1592 if (!user_ok_token(uidtoname(p
->server_info
->utok
.uid
), NULL
,
1593 p
->server_info
->ptok
, snum
) ||
1594 !print_access_check(p
->server_info
, snum
,
1595 r
->in
.access_mask
)) {
1596 DEBUG(3, ("access DENIED for printer open\n"));
1597 close_printer_handle(p
, r
->out
.handle
);
1598 ZERO_STRUCTP(r
->out
.handle
);
1599 return WERR_ACCESS_DENIED
;
1602 if ((r
->in
.access_mask
& SEC_MASK_SPECIFIC
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1603 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1604 close_printer_handle(p
, r
->out
.handle
);
1605 ZERO_STRUCTP(r
->out
.handle
);
1606 return WERR_ACCESS_DENIED
;
1609 if (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
)
1610 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1612 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1614 DEBUG(4,("Setting printer access = %s\n", (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1615 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1617 winreg_create_printer(p
->mem_ctx
,
1619 Printer
->servername
,
1620 lp_const_servicename(snum
));
1625 /* sanity check to prevent programmer error */
1626 ZERO_STRUCTP(r
->out
.handle
);
1630 Printer
->access_granted
= r
->in
.access_mask
;
1633 * If the client sent a devmode in the OpenPrinter() call, then
1634 * save it here in case we get a job submission on this handle
1637 if ((Printer
->printer_type
!= SPLHND_SERVER
) &&
1638 r
->in
.devmode_ctr
.devmode
) {
1639 copy_devicemode(NULL
, r
->in
.devmode_ctr
.devmode
,
1643 #if 0 /* JERRY -- I'm doubtful this is really effective */
1644 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1645 optimization in Windows 2000 clients --jerry */
1647 if ( (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1648 && (RA_WIN2K
== get_remote_arch()) )
1650 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1651 sys_usleep( 500000 );
1658 /****************************************************************
1659 _spoolss_ClosePrinter
1660 ****************************************************************/
1662 WERROR
_spoolss_ClosePrinter(pipes_struct
*p
,
1663 struct spoolss_ClosePrinter
*r
)
1665 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
1667 if (Printer
&& Printer
->document_started
) {
1668 struct spoolss_EndDocPrinter e
;
1670 e
.in
.handle
= r
->in
.handle
;
1672 _spoolss_EndDocPrinter(p
, &e
);
1675 if (!close_printer_handle(p
, r
->in
.handle
))
1678 /* clear the returned printer handle. Observed behavior
1679 from Win2k server. Don't think this really matters.
1680 Previous code just copied the value of the closed
1683 ZERO_STRUCTP(r
->out
.handle
);
1688 /****************************************************************
1689 _spoolss_DeletePrinter
1690 ****************************************************************/
1692 WERROR
_spoolss_DeletePrinter(pipes_struct
*p
,
1693 struct spoolss_DeletePrinter
*r
)
1695 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
1699 if (Printer
&& Printer
->document_started
) {
1700 struct spoolss_EndDocPrinter e
;
1702 e
.in
.handle
= r
->in
.handle
;
1704 _spoolss_EndDocPrinter(p
, &e
);
1707 if (get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
1708 winreg_delete_printer_key(p
->mem_ctx
,
1710 lp_const_servicename(snum
),
1714 result
= delete_printer_handle(p
, r
->in
.handle
);
1719 /*******************************************************************
1720 * static function to lookup the version id corresponding to an
1721 * long architecture string
1722 ******************************************************************/
1724 static const struct print_architecture_table_node archi_table
[]= {
1726 {"Windows 4.0", SPL_ARCH_WIN40
, 0 },
1727 {"Windows NT x86", SPL_ARCH_W32X86
, 2 },
1728 {"Windows NT R4000", SPL_ARCH_W32MIPS
, 2 },
1729 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA
, 2 },
1730 {"Windows NT PowerPC", SPL_ARCH_W32PPC
, 2 },
1731 {"Windows IA64", SPL_ARCH_IA64
, 3 },
1732 {"Windows x64", SPL_ARCH_X64
, 3 },
1736 static int get_version_id(const char *arch
)
1740 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1742 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1743 return (archi_table
[i
].version
);
1749 /****************************************************************
1750 _spoolss_DeletePrinterDriver
1751 ****************************************************************/
1753 WERROR
_spoolss_DeletePrinterDriver(pipes_struct
*p
,
1754 struct spoolss_DeletePrinterDriver
*r
)
1757 struct spoolss_DriverInfo8
*info
= NULL
;
1758 struct spoolss_DriverInfo8
*info_win2k
= NULL
;
1761 WERROR status_win2k
= WERR_ACCESS_DENIED
;
1762 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1764 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1765 and not a printer admin, then fail */
1767 if ( (p
->server_info
->utok
.uid
!= sec_initial_uid())
1768 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
1769 && !token_contains_name_in_list(
1770 uidtoname(p
->server_info
->utok
.uid
),
1771 p
->server_info
->info3
->base
.domain
.string
,
1773 p
->server_info
->ptok
,
1774 lp_printer_admin(-1)) )
1776 return WERR_ACCESS_DENIED
;
1779 /* check that we have a valid driver name first */
1781 if ((version
= get_version_id(r
->in
.architecture
)) == -1)
1782 return WERR_INVALID_ENVIRONMENT
;
1784 if (!W_ERROR_IS_OK(get_a_printer_driver(p
->mem_ctx
, &info
, r
->in
.driver
,
1788 /* try for Win2k driver if "Windows NT x86" */
1790 if ( version
== 2 ) {
1792 if (!W_ERROR_IS_OK(get_a_printer_driver(p
->mem_ctx
,
1797 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1801 /* otherwise it was a failure */
1803 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1809 if (printer_driver_in_use(info
)) {
1810 status
= WERR_PRINTER_DRIVER_IN_USE
;
1816 if (W_ERROR_IS_OK(get_a_printer_driver(p
->mem_ctx
,
1819 r
->in
.architecture
, 3)))
1821 /* if we get to here, we now have 2 driver info structures to remove */
1822 /* remove the Win2k driver first*/
1824 status_win2k
= delete_printer_driver(
1825 p
, info_win2k
, 3, false);
1826 free_a_printer_driver(info_win2k
);
1828 /* this should not have failed---if it did, report to client */
1829 if ( !W_ERROR_IS_OK(status_win2k
) )
1831 status
= status_win2k
;
1837 status
= delete_printer_driver(p
, info
, version
, false);
1839 /* if at least one of the deletes succeeded return OK */
1841 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
1845 free_a_printer_driver(info
);
1850 /****************************************************************
1851 _spoolss_DeletePrinterDriverEx
1852 ****************************************************************/
1854 WERROR
_spoolss_DeletePrinterDriverEx(pipes_struct
*p
,
1855 struct spoolss_DeletePrinterDriverEx
*r
)
1857 struct spoolss_DriverInfo8
*info
= NULL
;
1858 struct spoolss_DriverInfo8
*info_win2k
= NULL
;
1862 WERROR status_win2k
= WERR_ACCESS_DENIED
;
1863 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1865 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1866 and not a printer admin, then fail */
1868 if ( (p
->server_info
->utok
.uid
!= sec_initial_uid())
1869 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
1870 && !token_contains_name_in_list(
1871 uidtoname(p
->server_info
->utok
.uid
),
1872 p
->server_info
->info3
->base
.domain
.string
,
1874 p
->server_info
->ptok
, lp_printer_admin(-1)) )
1876 return WERR_ACCESS_DENIED
;
1879 /* check that we have a valid driver name first */
1880 if ((version
= get_version_id(r
->in
.architecture
)) == -1) {
1881 /* this is what NT returns */
1882 return WERR_INVALID_ENVIRONMENT
;
1885 if (r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
)
1886 version
= r
->in
.version
;
1888 status
= get_a_printer_driver(p
->mem_ctx
, &info
, r
->in
.driver
,
1889 r
->in
.architecture
, version
);
1891 if ( !W_ERROR_IS_OK(status
) )
1894 * if the client asked for a specific version,
1895 * or this is something other than Windows NT x86,
1899 if ( (r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
1902 /* try for Win2k driver if "Windows NT x86" */
1905 if (!W_ERROR_IS_OK(get_a_printer_driver(p
->mem_ctx
, &info
, r
->in
.driver
,
1908 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1913 if (printer_driver_in_use(info
)) {
1914 status
= WERR_PRINTER_DRIVER_IN_USE
;
1919 * we have a couple of cases to consider.
1920 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1921 * then the delete should fail if **any** files overlap with
1923 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1924 * non-overlapping files
1925 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1926 * is set, the do not delete any files
1927 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1930 delete_files
= r
->in
.delete_flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
1932 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1934 if (delete_files
&& printer_driver_files_in_use(info
, info
) & (r
->in
.delete_flags
& DPD_DELETE_ALL_FILES
)) {
1935 /* no idea of the correct error here */
1936 status
= WERR_ACCESS_DENIED
;
1941 /* also check for W32X86/3 if necessary; maybe we already have? */
1943 if ( (version
== 2) && ((r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
1944 if (W_ERROR_IS_OK(get_a_printer_driver(p
->mem_ctx
, &info_win2k
,
1946 r
->in
.architecture
, 3)))
1949 if (delete_files
&& printer_driver_files_in_use(info
, info_win2k
) & (r
->in
.delete_flags
& DPD_DELETE_ALL_FILES
) ) {
1950 /* no idea of the correct error here */
1951 free_a_printer_driver(info_win2k
);
1952 status
= WERR_ACCESS_DENIED
;
1956 /* if we get to here, we now have 2 driver info structures to remove */
1957 /* remove the Win2k driver first*/
1959 status_win2k
= delete_printer_driver(
1960 p
, info_win2k
, 3, delete_files
);
1961 free_a_printer_driver(info_win2k
);
1963 /* this should not have failed---if it did, report to client */
1965 if ( !W_ERROR_IS_OK(status_win2k
) )
1970 status
= delete_printer_driver(p
, info
, version
, delete_files
);
1972 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
1975 free_a_printer_driver(info
);
1981 /****************************************************************************
1982 Internal routine for storing printerdata
1983 ***************************************************************************/
1985 WERROR
set_printer_dataex(NT_PRINTER_INFO_LEVEL
*printer
,
1986 const char *key
, const char *value
,
1987 uint32_t type
, uint8_t *data
, int real_len
)
1989 /* the registry objects enforce uniqueness based on value name */
1991 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
1994 /********************************************************************
1995 GetPrinterData on a printer server Handle.
1996 ********************************************************************/
1998 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*mem_ctx
,
2000 enum winreg_Type
*type
,
2001 union spoolss_PrinterData
*data
)
2003 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2005 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2011 if (!StrCaseCmp(value
, "BeepEnabled")) {
2017 if (!StrCaseCmp(value
, "EventLog")) {
2019 /* formally was 0x1b */
2024 if (!StrCaseCmp(value
, "NetPopup")) {
2030 if (!StrCaseCmp(value
, "MajorVersion")) {
2033 /* Windows NT 4.0 seems to not allow uploading of drivers
2034 to a server that reports 0x3 as the MajorVersion.
2035 need to investigate more how Win2k gets around this .
2038 if (RA_WINNT
== get_remote_arch()) {
2047 if (!StrCaseCmp(value
, "MinorVersion")) {
2054 * uint32_t size = 0x114
2055 * uint32_t major = 5
2056 * uint32_t minor = [0|1]
2057 * uint32_t build = [2195|2600]
2058 * extra unicode string = e.g. "Service Pack 3"
2060 if (!StrCaseCmp(value
, "OSVersion")) {
2062 enum ndr_err_code ndr_err
;
2063 struct spoolss_OSVersion os
;
2065 os
.major
= 5; /* Windows 2000 == 5.0 */
2067 os
.build
= 2195; /* build */
2068 os
.extra_string
= ""; /* leave extra string empty */
2070 ndr_err
= ndr_push_struct_blob(&blob
, mem_ctx
, &os
,
2071 (ndr_push_flags_fn_t
)ndr_push_spoolss_OSVersion
);
2072 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2073 return WERR_GENERAL_FAILURE
;
2077 data
->binary
= blob
;
2083 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2086 data
->string
= talloc_strdup(mem_ctx
, "C:\\PRINTERS");
2087 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2092 if (!StrCaseCmp(value
, "Architecture")) {
2094 data
->string
= talloc_strdup(mem_ctx
,
2095 lp_parm_const_string(GLOBAL_SECTION_SNUM
, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86
));
2096 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2101 if (!StrCaseCmp(value
, "DsPresent")) {
2104 /* only show the publish check box if we are a
2105 member of a AD domain */
2107 if (lp_security() == SEC_ADS
) {
2115 if (!StrCaseCmp(value
, "DNSMachineName")) {
2116 const char *hostname
= get_mydnsfullname();
2119 return WERR_BADFILE
;
2123 data
->string
= talloc_strdup(mem_ctx
, hostname
);
2124 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2131 return WERR_INVALID_PARAM
;
2134 /****************************************************************
2135 _spoolss_GetPrinterData
2136 ****************************************************************/
2138 WERROR
_spoolss_GetPrinterData(pipes_struct
*p
,
2139 struct spoolss_GetPrinterData
*r
)
2141 struct spoolss_GetPrinterDataEx r2
;
2143 r2
.in
.handle
= r
->in
.handle
;
2144 r2
.in
.key_name
= "PrinterDriverData";
2145 r2
.in
.value_name
= r
->in
.value_name
;
2146 r2
.in
.offered
= r
->in
.offered
;
2147 r2
.out
.type
= r
->out
.type
;
2148 r2
.out
.data
= r
->out
.data
;
2149 r2
.out
.needed
= r
->out
.needed
;
2151 return _spoolss_GetPrinterDataEx(p
, &r2
);
2154 /*********************************************************
2155 Connect to the client machine.
2156 **********************************************************/
2158 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2159 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2162 struct cli_state
*the_cli
;
2163 struct sockaddr_storage rm_addr
;
2164 char addr
[INET6_ADDRSTRLEN
];
2166 if ( is_zero_addr((struct sockaddr
*)client_ss
) ) {
2167 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2169 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20, false) ) {
2170 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2173 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2175 rm_addr
= *client_ss
;
2176 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2177 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2181 if (ismyaddr((struct sockaddr
*)&rm_addr
)) {
2182 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2187 /* setup the connection */
2188 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2189 &rm_addr
, 0, "IPC$", "IPC",
2193 0, lp_client_signing(), NULL
);
2195 if ( !NT_STATUS_IS_OK( ret
) ) {
2196 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2201 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2202 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2203 cli_shutdown(the_cli
);
2208 * Ok - we have an anonymous connection to the IPC$ share.
2209 * Now start the NT Domain stuff :-).
2212 ret
= cli_rpc_pipe_open_noauth(the_cli
, &ndr_table_spoolss
.syntax_id
, pp_pipe
);
2213 if (!NT_STATUS_IS_OK(ret
)) {
2214 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2215 remote_machine
, nt_errstr(ret
)));
2216 cli_shutdown(the_cli
);
2223 /***************************************************************************
2224 Connect to the client.
2225 ****************************************************************************/
2227 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2228 uint32_t localprinter
, uint32_t type
,
2229 struct policy_handle
*handle
,
2230 struct sockaddr_storage
*client_ss
)
2236 * If it's the first connection, contact the client
2237 * and connect to the IPC$ share anonymously
2239 if (smb_connections
==0) {
2240 fstring unix_printer
;
2242 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2244 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2247 messaging_register(smbd_messaging_context(), NULL
,
2248 MSG_PRINTER_NOTIFY2
,
2249 receive_notify2_message_list
);
2250 /* Tell the connections db we're now interested in printer
2251 * notify messages. */
2252 serverid_register_msg_flags(
2253 messaging_server_id(smbd_messaging_context()),
2254 true, FLAG_MSG_PRINT_NOTIFY
);
2258 * Tell the specific printing tdb we want messages for this printer
2259 * by registering our PID.
2262 if (!print_notify_register_pid(snum
))
2263 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2267 status
= rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe
, talloc_tos(),
2275 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
2276 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2277 win_errstr(result
)));
2279 return (W_ERROR_IS_OK(result
));
2282 /****************************************************************
2283 ****************************************************************/
2285 static struct spoolss_NotifyOption
*dup_spoolss_NotifyOption(TALLOC_CTX
*mem_ctx
,
2286 const struct spoolss_NotifyOption
*r
)
2288 struct spoolss_NotifyOption
*option
;
2295 option
= talloc_zero(mem_ctx
, struct spoolss_NotifyOption
);
2302 if (!option
->count
) {
2306 option
->types
= talloc_zero_array(option
,
2307 struct spoolss_NotifyOptionType
, option
->count
);
2308 if (!option
->types
) {
2309 talloc_free(option
);
2313 for (i
=0; i
< option
->count
; i
++) {
2314 option
->types
[i
] = r
->types
[i
];
2316 if (option
->types
[i
].count
) {
2317 option
->types
[i
].fields
= talloc_zero_array(option
,
2318 union spoolss_Field
, option
->types
[i
].count
);
2319 if (!option
->types
[i
].fields
) {
2320 talloc_free(option
);
2323 for (k
=0; k
<option
->types
[i
].count
; k
++) {
2324 option
->types
[i
].fields
[k
] =
2325 r
->types
[i
].fields
[k
];
2333 /****************************************************************
2334 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2336 * before replying OK: status=0 a rpc call is made to the workstation
2337 * asking ReplyOpenPrinter
2339 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2340 * called from api_spoolss_rffpcnex
2341 ****************************************************************/
2343 WERROR
_spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct
*p
,
2344 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx
*r
)
2347 struct spoolss_NotifyOption
*option
= r
->in
.notify_options
;
2348 struct sockaddr_storage client_ss
;
2350 /* store the notify value in the printer struct */
2352 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
2355 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2356 "Invalid handle (%s:%u:%u).\n",
2357 OUR_HANDLE(r
->in
.handle
)));
2361 Printer
->notify
.flags
= r
->in
.flags
;
2362 Printer
->notify
.options
= r
->in
.options
;
2363 Printer
->notify
.printerlocal
= r
->in
.printer_local
;
2365 TALLOC_FREE(Printer
->notify
.option
);
2366 Printer
->notify
.option
= dup_spoolss_NotifyOption(Printer
, option
);
2368 fstrcpy(Printer
->notify
.localmachine
, r
->in
.local_machine
);
2370 /* Connect to the client machine and send a ReplyOpenPrinter */
2372 if ( Printer
->printer_type
== SPLHND_SERVER
)
2374 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2375 !get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
) )
2378 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2379 "client_address is %s\n", p
->client_address
));
2381 if (!interpret_string_addr(&client_ss
, p
->client_address
,
2383 return WERR_SERVER_UNAVAILABLE
;
2386 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2387 Printer
->notify
.printerlocal
, 1,
2388 &Printer
->notify
.client_hnd
, &client_ss
))
2389 return WERR_SERVER_UNAVAILABLE
;
2391 Printer
->notify
.client_connected
= true;
2396 /*******************************************************************
2397 * fill a notify_info_data with the servername
2398 ********************************************************************/
2400 static void spoolss_notify_server_name(int snum
,
2401 struct spoolss_Notify
*data
,
2402 print_queue_struct
*queue
,
2403 NT_PRINTER_INFO_LEVEL
*printer
,
2404 TALLOC_CTX
*mem_ctx
)
2406 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->servername
);
2409 /*******************************************************************
2410 * fill a notify_info_data with the printername (not including the servername).
2411 ********************************************************************/
2413 static void spoolss_notify_printer_name(int snum
,
2414 struct spoolss_Notify
*data
,
2415 print_queue_struct
*queue
,
2416 NT_PRINTER_INFO_LEVEL
*printer
,
2417 TALLOC_CTX
*mem_ctx
)
2419 /* the notify name should not contain the \\server\ part */
2420 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2423 p
= printer
->info_2
->printername
;
2428 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2431 /*******************************************************************
2432 * fill a notify_info_data with the servicename
2433 ********************************************************************/
2435 static void spoolss_notify_share_name(int snum
,
2436 struct spoolss_Notify
*data
,
2437 print_queue_struct
*queue
,
2438 NT_PRINTER_INFO_LEVEL
*printer
,
2439 TALLOC_CTX
*mem_ctx
)
2441 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, lp_servicename(snum
));
2444 /*******************************************************************
2445 * fill a notify_info_data with the port name
2446 ********************************************************************/
2448 static void spoolss_notify_port_name(int snum
,
2449 struct spoolss_Notify
*data
,
2450 print_queue_struct
*queue
,
2451 NT_PRINTER_INFO_LEVEL
*printer
,
2452 TALLOC_CTX
*mem_ctx
)
2454 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->portname
);
2457 /*******************************************************************
2458 * fill a notify_info_data with the printername
2459 * but it doesn't exist, have to see what to do
2460 ********************************************************************/
2462 static void spoolss_notify_driver_name(int snum
,
2463 struct spoolss_Notify
*data
,
2464 print_queue_struct
*queue
,
2465 NT_PRINTER_INFO_LEVEL
*printer
,
2466 TALLOC_CTX
*mem_ctx
)
2468 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->drivername
);
2471 /*******************************************************************
2472 * fill a notify_info_data with the comment
2473 ********************************************************************/
2475 static void spoolss_notify_comment(int snum
,
2476 struct spoolss_Notify
*data
,
2477 print_queue_struct
*queue
,
2478 NT_PRINTER_INFO_LEVEL
*printer
,
2479 TALLOC_CTX
*mem_ctx
)
2483 if (*printer
->info_2
->comment
== '\0') {
2484 p
= lp_comment(snum
);
2486 p
= printer
->info_2
->comment
;
2489 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->comment
);
2492 /*******************************************************************
2493 * fill a notify_info_data with the comment
2494 * location = "Room 1, floor 2, building 3"
2495 ********************************************************************/
2497 static void spoolss_notify_location(int snum
,
2498 struct spoolss_Notify
*data
,
2499 print_queue_struct
*queue
,
2500 NT_PRINTER_INFO_LEVEL
*printer
,
2501 TALLOC_CTX
*mem_ctx
)
2503 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->location
);
2506 /*******************************************************************
2507 * fill a notify_info_data with the device mode
2508 * jfm:xxxx don't to it for know but that's a real problem !!!
2509 ********************************************************************/
2511 static void spoolss_notify_devmode(int snum
,
2512 struct spoolss_Notify
*data
,
2513 print_queue_struct
*queue
,
2514 NT_PRINTER_INFO_LEVEL
*printer
,
2515 TALLOC_CTX
*mem_ctx
)
2517 /* for a dummy implementation we have to zero the fields */
2518 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data
, NULL
);
2521 /*******************************************************************
2522 * fill a notify_info_data with the separator file name
2523 ********************************************************************/
2525 static void spoolss_notify_sepfile(int snum
,
2526 struct spoolss_Notify
*data
,
2527 print_queue_struct
*queue
,
2528 NT_PRINTER_INFO_LEVEL
*printer
,
2529 TALLOC_CTX
*mem_ctx
)
2531 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->sepfile
);
2534 /*******************************************************************
2535 * fill a notify_info_data with the print processor
2536 * jfm:xxxx return always winprint to indicate we don't do anything to it
2537 ********************************************************************/
2539 static void spoolss_notify_print_processor(int snum
,
2540 struct spoolss_Notify
*data
,
2541 print_queue_struct
*queue
,
2542 NT_PRINTER_INFO_LEVEL
*printer
,
2543 TALLOC_CTX
*mem_ctx
)
2545 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->printprocessor
);
2548 /*******************************************************************
2549 * fill a notify_info_data with the print processor options
2550 * jfm:xxxx send an empty string
2551 ********************************************************************/
2553 static void spoolss_notify_parameters(int snum
,
2554 struct spoolss_Notify
*data
,
2555 print_queue_struct
*queue
,
2556 NT_PRINTER_INFO_LEVEL
*printer
,
2557 TALLOC_CTX
*mem_ctx
)
2559 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->parameters
);
2562 /*******************************************************************
2563 * fill a notify_info_data with the data type
2564 * jfm:xxxx always send RAW as data type
2565 ********************************************************************/
2567 static void spoolss_notify_datatype(int snum
,
2568 struct spoolss_Notify
*data
,
2569 print_queue_struct
*queue
,
2570 NT_PRINTER_INFO_LEVEL
*printer
,
2571 TALLOC_CTX
*mem_ctx
)
2573 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->datatype
);
2576 /*******************************************************************
2577 * fill a notify_info_data with the security descriptor
2578 * jfm:xxxx send an null pointer to say no security desc
2579 * have to implement security before !
2580 ********************************************************************/
2582 static void spoolss_notify_security_desc(int snum
,
2583 struct spoolss_Notify
*data
,
2584 print_queue_struct
*queue
,
2585 NT_PRINTER_INFO_LEVEL
*printer
,
2586 TALLOC_CTX
*mem_ctx
)
2588 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data
,
2589 printer
->info_2
->secdesc_buf
->sd_size
,
2590 printer
->info_2
->secdesc_buf
->sd
);
2593 /*******************************************************************
2594 * fill a notify_info_data with the attributes
2595 * jfm:xxxx a samba printer is always shared
2596 ********************************************************************/
2598 static void spoolss_notify_attributes(int snum
,
2599 struct spoolss_Notify
*data
,
2600 print_queue_struct
*queue
,
2601 NT_PRINTER_INFO_LEVEL
*printer
,
2602 TALLOC_CTX
*mem_ctx
)
2604 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->attributes
);
2607 /*******************************************************************
2608 * fill a notify_info_data with the priority
2609 ********************************************************************/
2611 static void spoolss_notify_priority(int snum
,
2612 struct spoolss_Notify
*data
,
2613 print_queue_struct
*queue
,
2614 NT_PRINTER_INFO_LEVEL
*printer
,
2615 TALLOC_CTX
*mem_ctx
)
2617 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->priority
);
2620 /*******************************************************************
2621 * fill a notify_info_data with the default priority
2622 ********************************************************************/
2624 static void spoolss_notify_default_priority(int snum
,
2625 struct spoolss_Notify
*data
,
2626 print_queue_struct
*queue
,
2627 NT_PRINTER_INFO_LEVEL
*printer
,
2628 TALLOC_CTX
*mem_ctx
)
2630 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->default_priority
);
2633 /*******************************************************************
2634 * fill a notify_info_data with the start time
2635 ********************************************************************/
2637 static void spoolss_notify_start_time(int snum
,
2638 struct spoolss_Notify
*data
,
2639 print_queue_struct
*queue
,
2640 NT_PRINTER_INFO_LEVEL
*printer
,
2641 TALLOC_CTX
*mem_ctx
)
2643 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->starttime
);
2646 /*******************************************************************
2647 * fill a notify_info_data with the until time
2648 ********************************************************************/
2650 static void spoolss_notify_until_time(int snum
,
2651 struct spoolss_Notify
*data
,
2652 print_queue_struct
*queue
,
2653 NT_PRINTER_INFO_LEVEL
*printer
,
2654 TALLOC_CTX
*mem_ctx
)
2656 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->untiltime
);
2659 /*******************************************************************
2660 * fill a notify_info_data with the status
2661 ********************************************************************/
2663 static void spoolss_notify_status(int snum
,
2664 struct spoolss_Notify
*data
,
2665 print_queue_struct
*queue
,
2666 NT_PRINTER_INFO_LEVEL
*printer
,
2667 TALLOC_CTX
*mem_ctx
)
2669 print_status_struct status
;
2671 print_queue_length(snum
, &status
);
2672 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, status
.status
);
2675 /*******************************************************************
2676 * fill a notify_info_data with the number of jobs queued
2677 ********************************************************************/
2679 static void spoolss_notify_cjobs(int snum
,
2680 struct spoolss_Notify
*data
,
2681 print_queue_struct
*queue
,
2682 NT_PRINTER_INFO_LEVEL
*printer
,
2683 TALLOC_CTX
*mem_ctx
)
2685 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, print_queue_length(snum
, NULL
));
2688 /*******************************************************************
2689 * fill a notify_info_data with the average ppm
2690 ********************************************************************/
2692 static void spoolss_notify_average_ppm(int snum
,
2693 struct spoolss_Notify
*data
,
2694 print_queue_struct
*queue
,
2695 NT_PRINTER_INFO_LEVEL
*printer
,
2696 TALLOC_CTX
*mem_ctx
)
2698 /* always respond 8 pages per minutes */
2699 /* a little hard ! */
2700 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->averageppm
);
2703 /*******************************************************************
2704 * fill a notify_info_data with username
2705 ********************************************************************/
2707 static void spoolss_notify_username(int snum
,
2708 struct spoolss_Notify
*data
,
2709 print_queue_struct
*queue
,
2710 NT_PRINTER_INFO_LEVEL
*printer
,
2711 TALLOC_CTX
*mem_ctx
)
2713 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_user
);
2716 /*******************************************************************
2717 * fill a notify_info_data with job status
2718 ********************************************************************/
2720 static void spoolss_notify_job_status(int snum
,
2721 struct spoolss_Notify
*data
,
2722 print_queue_struct
*queue
,
2723 NT_PRINTER_INFO_LEVEL
*printer
,
2724 TALLOC_CTX
*mem_ctx
)
2726 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, nt_printj_status(queue
->status
));
2729 /*******************************************************************
2730 * fill a notify_info_data with job name
2731 ********************************************************************/
2733 static void spoolss_notify_job_name(int snum
,
2734 struct spoolss_Notify
*data
,
2735 print_queue_struct
*queue
,
2736 NT_PRINTER_INFO_LEVEL
*printer
,
2737 TALLOC_CTX
*mem_ctx
)
2739 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_file
);
2742 /*******************************************************************
2743 * fill a notify_info_data with job status
2744 ********************************************************************/
2746 static void spoolss_notify_job_status_string(int snum
,
2747 struct spoolss_Notify
*data
,
2748 print_queue_struct
*queue
,
2749 NT_PRINTER_INFO_LEVEL
*printer
,
2750 TALLOC_CTX
*mem_ctx
)
2753 * Now we're returning job status codes we just return a "" here. JRA.
2758 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2761 switch (queue
->status
) {
2766 p
= ""; /* NT provides the paused string */
2775 #endif /* NO LONGER NEEDED. */
2777 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2780 /*******************************************************************
2781 * fill a notify_info_data with job time
2782 ********************************************************************/
2784 static void spoolss_notify_job_time(int snum
,
2785 struct spoolss_Notify
*data
,
2786 print_queue_struct
*queue
,
2787 NT_PRINTER_INFO_LEVEL
*printer
,
2788 TALLOC_CTX
*mem_ctx
)
2790 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
2793 /*******************************************************************
2794 * fill a notify_info_data with job size
2795 ********************************************************************/
2797 static void spoolss_notify_job_size(int snum
,
2798 struct spoolss_Notify
*data
,
2799 print_queue_struct
*queue
,
2800 NT_PRINTER_INFO_LEVEL
*printer
,
2801 TALLOC_CTX
*mem_ctx
)
2803 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->size
);
2806 /*******************************************************************
2807 * fill a notify_info_data with page info
2808 ********************************************************************/
2809 static void spoolss_notify_total_pages(int snum
,
2810 struct spoolss_Notify
*data
,
2811 print_queue_struct
*queue
,
2812 NT_PRINTER_INFO_LEVEL
*printer
,
2813 TALLOC_CTX
*mem_ctx
)
2815 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->page_count
);
2818 /*******************************************************************
2819 * fill a notify_info_data with pages printed info.
2820 ********************************************************************/
2821 static void spoolss_notify_pages_printed(int snum
,
2822 struct spoolss_Notify
*data
,
2823 print_queue_struct
*queue
,
2824 NT_PRINTER_INFO_LEVEL
*printer
,
2825 TALLOC_CTX
*mem_ctx
)
2827 /* Add code when back-end tracks this */
2828 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
2831 /*******************************************************************
2832 Fill a notify_info_data with job position.
2833 ********************************************************************/
2835 static void spoolss_notify_job_position(int snum
,
2836 struct spoolss_Notify
*data
,
2837 print_queue_struct
*queue
,
2838 NT_PRINTER_INFO_LEVEL
*printer
,
2839 TALLOC_CTX
*mem_ctx
)
2841 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->job
);
2844 /*******************************************************************
2845 Fill a notify_info_data with submitted time.
2846 ********************************************************************/
2848 static void spoolss_notify_submitted_time(int snum
,
2849 struct spoolss_Notify
*data
,
2850 print_queue_struct
*queue
,
2851 NT_PRINTER_INFO_LEVEL
*printer
,
2852 TALLOC_CTX
*mem_ctx
)
2854 data
->data
.string
.string
= NULL
;
2855 data
->data
.string
.size
= 0;
2857 init_systemtime_buffer(mem_ctx
, gmtime(&queue
->time
),
2858 &data
->data
.string
.string
,
2859 &data
->data
.string
.size
);
2863 struct s_notify_info_data_table
2865 enum spoolss_NotifyType type
;
2868 enum spoolss_NotifyTable variable_type
;
2869 void (*fn
) (int snum
, struct spoolss_Notify
*data
,
2870 print_queue_struct
*queue
,
2871 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
2874 /* A table describing the various print notification constants and
2875 whether the notification data is a pointer to a variable sized
2876 buffer, a one value uint32_t or a two value uint32_t. */
2878 static const struct s_notify_info_data_table notify_info_data_table
[] =
2880 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SERVER_NAME
, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
2881 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRINTER_NAME
, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
2882 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SHARE_NAME
, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_share_name
},
2883 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PORT_NAME
, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
2884 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DRIVER_NAME
, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
2885 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_COMMENT
, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING
, spoolss_notify_comment
},
2886 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_LOCATION
, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING
, spoolss_notify_location
},
2887 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DEVMODE
, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
2888 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SEPFILE
, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING
, spoolss_notify_sepfile
},
2889 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR
, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
2890 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PARAMETERS
, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
2891 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DATATYPE
, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
2892 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, spoolss_notify_security_desc
},
2893 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_ATTRIBUTES
, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD
, spoolss_notify_attributes
},
2894 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRIORITY
, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
2895 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_default_priority
},
2896 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_START_TIME
, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
2897 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_UNTIL_TIME
, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
2898 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_STATUS
, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_status
},
2899 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_STATUS_STRING
, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING
, NULL
},
2900 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_CJOBS
, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD
, spoolss_notify_cjobs
},
2901 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_AVERAGE_PPM
, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD
, spoolss_notify_average_ppm
},
2902 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_TOTAL_PAGES
, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, NULL
},
2903 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PAGES_PRINTED
, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
2904 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_TOTAL_BYTES
, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, NULL
},
2905 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_BYTES_PRINTED
, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
2906 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRINTER_NAME
, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
2907 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_MACHINE_NAME
, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
2908 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PORT_NAME
, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
2909 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_USER_NAME
, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
2910 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_NOTIFY_NAME
, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
2911 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DATATYPE
, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
2912 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRINT_PROCESSOR
, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
2913 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PARAMETERS
, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
2914 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DRIVER_NAME
, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
2915 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DEVMODE
, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
2916 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_STATUS
, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_job_status
},
2917 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_STATUS_STRING
, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING
, spoolss_notify_job_status_string
},
2918 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, NULL
},
2919 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DOCUMENT
, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING
, spoolss_notify_job_name
},
2920 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRIORITY
, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
2921 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_POSITION
, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD
, spoolss_notify_job_position
},
2922 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_SUBMITTED
, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME
, spoolss_notify_submitted_time
},
2923 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_START_TIME
, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
2924 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_UNTIL_TIME
, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
2925 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TIME
, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_job_time
},
2926 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TOTAL_PAGES
, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, spoolss_notify_total_pages
},
2927 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PAGES_PRINTED
, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, spoolss_notify_pages_printed
},
2928 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TOTAL_BYTES
, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, spoolss_notify_job_size
},
2931 /*******************************************************************
2932 Return the variable_type of info_data structure.
2933 ********************************************************************/
2935 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type
,
2940 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
2941 if ( (notify_info_data_table
[i
].type
== type
) &&
2942 (notify_info_data_table
[i
].field
== field
) ) {
2943 return notify_info_data_table
[i
].variable_type
;
2947 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
2952 /****************************************************************************
2953 ****************************************************************************/
2955 static bool search_notify(enum spoolss_NotifyType type
,
2961 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
2962 if (notify_info_data_table
[i
].type
== type
&&
2963 notify_info_data_table
[i
].field
== field
&&
2964 notify_info_data_table
[i
].fn
!= NULL
) {
2973 /****************************************************************************
2974 ****************************************************************************/
2976 void construct_info_data(struct spoolss_Notify
*info_data
,
2977 enum spoolss_NotifyType type
,
2981 info_data
->type
= type
;
2982 info_data
->field
.field
= field
;
2983 info_data
->variable_type
= variable_type_of_notify_info_data(type
, field
);
2984 info_data
->job_id
= id
;
2987 /*******************************************************************
2989 * fill a notify_info struct with info asked
2991 ********************************************************************/
2993 static bool construct_notify_printer_info(Printer_entry
*print_hnd
,
2994 struct spoolss_NotifyInfo
*info
,
2996 const struct spoolss_NotifyOptionType
*option_type
,
2998 TALLOC_CTX
*mem_ctx
)
3001 enum spoolss_NotifyType type
;
3004 struct spoolss_Notify
*current_data
;
3005 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3006 print_queue_struct
*queue
=NULL
;
3008 type
= option_type
->type
;
3010 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3011 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3012 option_type
->count
, lp_servicename(snum
)));
3014 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3017 for(field_num
=0; field_num
< option_type
->count
; field_num
++) {
3018 field
= option_type
->fields
[field_num
].field
;
3020 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3022 if (!search_notify(type
, field
, &j
) )
3025 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3026 struct spoolss_Notify
,
3028 if (info
->notifies
== NULL
) {
3029 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3030 free_a_printer(&printer
, 2);
3034 current_data
= &info
->notifies
[info
->count
];
3036 construct_info_data(current_data
, type
, field
, id
);
3038 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3039 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3041 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3047 free_a_printer(&printer
, 2);
3051 /*******************************************************************
3053 * fill a notify_info struct with info asked
3055 ********************************************************************/
3057 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3058 struct spoolss_NotifyInfo
*info
,
3059 NT_PRINTER_INFO_LEVEL
*printer
,
3061 const struct spoolss_NotifyOptionType
*option_type
,
3063 TALLOC_CTX
*mem_ctx
)
3066 enum spoolss_NotifyType type
;
3068 struct spoolss_Notify
*current_data
;
3070 DEBUG(4,("construct_notify_jobs_info\n"));
3072 type
= option_type
->type
;
3074 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3075 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3076 option_type
->count
));
3078 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3079 field
= option_type
->fields
[field_num
].field
;
3081 if (!search_notify(type
, field
, &j
) )
3084 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3085 struct spoolss_Notify
,
3087 if (info
->notifies
== NULL
) {
3088 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3092 current_data
=&(info
->notifies
[info
->count
]);
3094 construct_info_data(current_data
, type
, field
, id
);
3095 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3104 * JFM: The enumeration is not that simple, it's even non obvious.
3106 * let's take an example: I want to monitor the PRINTER SERVER for
3107 * the printer's name and the number of jobs currently queued.
3108 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3109 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3111 * I have 3 printers on the back of my server.
3113 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3116 * 1 printer 1 name 1
3117 * 2 printer 1 cjob 1
3118 * 3 printer 2 name 2
3119 * 4 printer 2 cjob 2
3120 * 5 printer 3 name 3
3121 * 6 printer 3 name 3
3123 * that's the print server case, the printer case is even worse.
3126 /*******************************************************************
3128 * enumerate all printers on the printserver
3129 * fill a notify_info struct with info asked
3131 ********************************************************************/
3133 static WERROR
printserver_notify_info(pipes_struct
*p
,
3134 struct policy_handle
*hnd
,
3135 struct spoolss_NotifyInfo
*info
,
3136 TALLOC_CTX
*mem_ctx
)
3139 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
3140 int n_services
=lp_numservices();
3142 struct spoolss_NotifyOption
*option
;
3143 struct spoolss_NotifyOptionType option_type
;
3145 DEBUG(4,("printserver_notify_info\n"));
3150 option
= Printer
->notify
.option
;
3153 info
->notifies
= NULL
;
3156 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3157 sending a ffpcn() request first */
3162 for (i
=0; i
<option
->count
; i
++) {
3163 option_type
= option
->types
[i
];
3165 if (option_type
.type
!= PRINTER_NOTIFY_TYPE
)
3168 for (snum
=0; snum
<n_services
; snum
++)
3170 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3171 construct_notify_printer_info ( Printer
, info
, snum
, &option_type
, snum
, mem_ctx
);
3177 * Debugging information, don't delete.
3180 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3181 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3182 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3184 for (i
=0; i
<info
->count
; i
++) {
3185 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3186 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3187 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3194 /*******************************************************************
3196 * fill a notify_info struct with info asked
3198 ********************************************************************/
3200 static WERROR
printer_notify_info(pipes_struct
*p
, struct policy_handle
*hnd
,
3201 struct spoolss_NotifyInfo
*info
,
3202 TALLOC_CTX
*mem_ctx
)
3205 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
3208 struct spoolss_NotifyOption
*option
;
3209 struct spoolss_NotifyOptionType option_type
;
3211 print_queue_struct
*queue
=NULL
;
3212 print_status_struct status
;
3214 DEBUG(4,("printer_notify_info\n"));
3219 option
= Printer
->notify
.option
;
3223 info
->notifies
= NULL
;
3226 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3227 sending a ffpcn() request first */
3232 get_printer_snum(p
, hnd
, &snum
, NULL
);
3234 for (i
=0; i
<option
->count
; i
++) {
3235 option_type
= option
->types
[i
];
3237 switch (option_type
.type
) {
3238 case PRINTER_NOTIFY_TYPE
:
3239 if(construct_notify_printer_info(Printer
, info
, snum
,
3245 case JOB_NOTIFY_TYPE
: {
3246 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3248 count
= print_queue_status(snum
, &queue
, &status
);
3250 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3253 for (j
=0; j
<count
; j
++) {
3254 construct_notify_jobs_info(&queue
[j
], info
,
3261 free_a_printer(&printer
, 2);
3271 * Debugging information, don't delete.
3274 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3275 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3276 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3278 for (i=0; i<info->count; i++) {
3279 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3280 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3281 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3287 /****************************************************************
3288 _spoolss_RouterRefreshPrinterChangeNotify
3289 ****************************************************************/
3291 WERROR
_spoolss_RouterRefreshPrinterChangeNotify(pipes_struct
*p
,
3292 struct spoolss_RouterRefreshPrinterChangeNotify
*r
)
3294 struct spoolss_NotifyInfo
*info
;
3296 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
3297 WERROR result
= WERR_BADFID
;
3299 /* we always have a spoolss_NotifyInfo struct */
3300 info
= talloc_zero(p
->mem_ctx
, struct spoolss_NotifyInfo
);
3302 result
= WERR_NOMEM
;
3306 *r
->out
.info
= info
;
3309 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3310 "Invalid handle (%s:%u:%u).\n",
3311 OUR_HANDLE(r
->in
.handle
)));
3315 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3318 * We are now using the change value, and
3319 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3320 * I don't have a global notification system, I'm sending back all the
3321 * informations even when _NOTHING_ has changed.
3324 /* We need to keep track of the change value to send back in
3325 RRPCN replies otherwise our updates are ignored. */
3327 Printer
->notify
.fnpcn
= true;
3329 if (Printer
->notify
.client_connected
) {
3330 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3331 "Saving change value in request [%x]\n",
3333 Printer
->notify
.change
= r
->in
.change_low
;
3336 /* just ignore the spoolss_NotifyOption */
3338 switch (Printer
->printer_type
) {
3340 result
= printserver_notify_info(p
, r
->in
.handle
,
3344 case SPLHND_PRINTER
:
3345 result
= printer_notify_info(p
, r
->in
.handle
,
3350 Printer
->notify
.fnpcn
= false;
3356 /********************************************************************
3357 * construct_printer_info_0
3358 * fill a printer_info_0 struct
3359 ********************************************************************/
3361 static WERROR
construct_printer_info0(TALLOC_CTX
*mem_ctx
,
3362 struct auth_serversupplied_info
*server_info
,
3363 struct spoolss_PrinterInfo2
*info2
,
3364 struct spoolss_PrinterInfo0
*r
,
3368 counter_printer_0
*session_counter
;
3369 struct timeval setuptime
;
3370 print_status_struct status
;
3372 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3373 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3375 r
->servername
= talloc_strdup(mem_ctx
, info2
->servername
);
3376 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3378 count
= print_queue_length(snum
, &status
);
3380 /* check if we already have a counter for this printer */
3381 for (session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3382 if (session_counter
->snum
== snum
)
3386 /* it's the first time, add it to the list */
3387 if (session_counter
== NULL
) {
3388 session_counter
= SMB_MALLOC_P(counter_printer_0
);
3389 W_ERROR_HAVE_NO_MEMORY(session_counter
);
3390 ZERO_STRUCTP(session_counter
);
3391 session_counter
->snum
= snum
;
3392 session_counter
->counter
= 0;
3393 DLIST_ADD(counter_list
, session_counter
);
3397 session_counter
->counter
++;
3403 get_startup_time(&setuptime
);
3404 init_systemtime(&r
->time
, gmtime(&setuptime
.tv_sec
));
3407 * the global_counter should be stored in a TDB as it's common to all the clients
3408 * and should be zeroed on samba startup
3410 r
->global_counter
= session_counter
->counter
;
3412 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3413 SSVAL(&r
->version
, 0, 0x0005); /* NT 5 */
3414 SSVAL(&r
->version
, 2, 0x0893); /* build 2195 */
3415 r
->free_build
= SPOOLSS_RELEASE_BUILD
;
3417 r
->max_spooling
= 0;
3418 r
->session_counter
= session_counter
->counter
;
3419 r
->num_error_out_of_paper
= 0x0;
3420 r
->num_error_not_ready
= 0x0; /* number of print failure */
3422 r
->number_of_processors
= 0x1;
3423 r
->processor_type
= PROCESSOR_INTEL_PENTIUM
; /* 586 Pentium ? */
3424 r
->high_part_total_bytes
= 0x0;
3425 winreg_printer_get_changeid(mem_ctx
, server_info
, info2
->sharename
, &r
->change_id
); /* ChangeID in milliseconds*/
3426 r
->last_error
= WERR_OK
;
3427 r
->status
= nt_printq_status(status
.status
);
3428 r
->enumerate_network_printers
= 0x0;
3429 r
->c_setprinter
= 0x0;
3430 r
->processor_architecture
= 0x0;
3431 r
->processor_level
= 0x6; /* 6 ???*/
3440 /****************************************************************************
3441 Create a spoolss_DeviceMode struct. Returns talloced memory.
3442 ****************************************************************************/
3444 struct spoolss_DeviceMode
*construct_dev_mode(TALLOC_CTX
*mem_ctx
,
3445 const char *servicename
)
3447 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3448 struct spoolss_DeviceMode
*devmode
= NULL
;
3450 DEBUG(7,("construct_dev_mode\n"));
3452 DEBUGADD(8,("getting printer characteristics\n"));
3454 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
3457 if (!printer
->info_2
->devmode
) {
3458 DEBUG(5, ("BONG! There was no device mode!\n"));
3462 devmode
= talloc_steal(mem_ctx
, printer
->info_2
->devmode
);
3465 free_a_printer(&printer
,2);
3470 /********************************************************************
3471 * construct_printer_info1
3472 * fill a spoolss_PrinterInfo1 struct
3473 ********************************************************************/
3475 static WERROR
construct_printer_info1(TALLOC_CTX
*mem_ctx
,
3476 const struct spoolss_PrinterInfo2
*info2
,
3478 struct spoolss_PrinterInfo1
*r
,
3483 r
->description
= talloc_asprintf(mem_ctx
, "%s,%s,%s",
3487 W_ERROR_HAVE_NO_MEMORY(r
->description
);
3489 if (info2
->comment
== NULL
|| info2
->comment
[0] == '\0') {
3490 r
->comment
= talloc_strdup(mem_ctx
, lp_comment(snum
));
3492 r
->comment
= talloc_strdup(mem_ctx
, info2
->comment
); /* saved comment */
3494 W_ERROR_HAVE_NO_MEMORY(r
->comment
);
3496 r
->name
= talloc_strdup(mem_ctx
, info2
->printername
);
3497 W_ERROR_HAVE_NO_MEMORY(r
->name
);
3502 /********************************************************************
3503 * construct_printer_info2
3504 * fill a spoolss_PrinterInfo2 struct
3505 ********************************************************************/
3507 static WERROR
construct_printer_info2(TALLOC_CTX
*mem_ctx
,
3508 const struct spoolss_PrinterInfo2
*info2
,
3509 struct spoolss_PrinterInfo2
*r
,
3513 print_status_struct status
;
3515 count
= print_queue_length(snum
, &status
);
3517 r
->servername
= talloc_strdup(mem_ctx
, info2
->servername
);
3518 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3519 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3520 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3521 r
->sharename
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
3522 W_ERROR_HAVE_NO_MEMORY(r
->sharename
);
3523 r
->portname
= talloc_strdup(mem_ctx
, info2
->portname
);
3524 W_ERROR_HAVE_NO_MEMORY(r
->portname
);
3525 r
->drivername
= talloc_strdup(mem_ctx
, info2
->drivername
);
3526 W_ERROR_HAVE_NO_MEMORY(r
->drivername
);
3528 if (info2
->comment
[0] == '\0') {
3529 r
->comment
= talloc_strdup(mem_ctx
, lp_comment(snum
));
3531 r
->comment
= talloc_strdup(mem_ctx
, info2
->comment
);
3533 W_ERROR_HAVE_NO_MEMORY(r
->comment
);
3535 r
->location
= talloc_strdup(mem_ctx
, info2
->location
);
3536 W_ERROR_HAVE_NO_MEMORY(r
->location
);
3537 r
->sepfile
= talloc_strdup(mem_ctx
, info2
->sepfile
);
3538 W_ERROR_HAVE_NO_MEMORY(r
->sepfile
);
3539 r
->printprocessor
= talloc_strdup(mem_ctx
, info2
->printprocessor
);
3540 W_ERROR_HAVE_NO_MEMORY(r
->printprocessor
);
3541 r
->datatype
= talloc_strdup(mem_ctx
, info2
->datatype
);
3542 W_ERROR_HAVE_NO_MEMORY(r
->datatype
);
3543 r
->parameters
= talloc_strdup(mem_ctx
, info2
->parameters
);
3544 W_ERROR_HAVE_NO_MEMORY(r
->parameters
);
3546 r
->attributes
= info2
->attributes
;
3548 r
->priority
= info2
->priority
;
3549 r
->defaultpriority
= info2
->defaultpriority
;
3550 r
->starttime
= info2
->starttime
;
3551 r
->untiltime
= info2
->untiltime
;
3552 r
->status
= nt_printq_status(status
.status
);
3554 r
->averageppm
= info2
->averageppm
;
3556 copy_devicemode(mem_ctx
, info2
->devmode
, &r
->devmode
);
3558 DEBUG(8,("Returning NULL Devicemode!\n"));
3563 if (info2
->secdesc
!= NULL
) {
3564 /* don't use talloc_steal() here unless you do a deep steal of all
3565 the SEC_DESC members */
3567 r
->secdesc
= dup_sec_desc(mem_ctx
, info2
->secdesc
);
3573 /********************************************************************
3574 * construct_printer_info3
3575 * fill a spoolss_PrinterInfo3 struct
3576 ********************************************************************/
3578 static WERROR
construct_printer_info3(TALLOC_CTX
*mem_ctx
,
3579 const struct spoolss_PrinterInfo2
*info2
,
3580 struct spoolss_PrinterInfo3
*r
,
3583 /* These are the components of the SD we are returning. */
3585 if (info2
->secdesc
!= NULL
) {
3586 /* don't use talloc_steal() here unless you do a deep steal of all
3587 the SEC_DESC members */
3589 r
->secdesc
= dup_sec_desc(mem_ctx
, info2
->secdesc
);
3590 W_ERROR_HAVE_NO_MEMORY(r
->secdesc
);
3596 /********************************************************************
3597 * construct_printer_info4
3598 * fill a spoolss_PrinterInfo4 struct
3599 ********************************************************************/
3601 static WERROR
construct_printer_info4(TALLOC_CTX
*mem_ctx
,
3602 const struct spoolss_PrinterInfo2
*info2
,
3603 struct spoolss_PrinterInfo4
*r
,
3606 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3607 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3608 r
->servername
= talloc_strdup(mem_ctx
, info2
->servername
);
3609 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3611 r
->attributes
= info2
->attributes
;
3616 /********************************************************************
3617 * construct_printer_info5
3618 * fill a spoolss_PrinterInfo5 struct
3619 ********************************************************************/
3621 static WERROR
construct_printer_info5(TALLOC_CTX
*mem_ctx
,
3622 const struct spoolss_PrinterInfo2
*info2
,
3623 struct spoolss_PrinterInfo5
*r
,
3626 r
->printername
= talloc_strdup(mem_ctx
, info2
->printername
);
3627 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3628 r
->portname
= talloc_strdup(mem_ctx
, info2
->portname
);
3629 W_ERROR_HAVE_NO_MEMORY(r
->portname
);
3631 r
->attributes
= info2
->attributes
;
3633 /* these two are not used by NT+ according to MSDN */
3634 r
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
3635 r
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
3640 /********************************************************************
3641 * construct_printer_info_6
3642 * fill a spoolss_PrinterInfo6 struct
3643 ********************************************************************/
3645 static WERROR
construct_printer_info6(TALLOC_CTX
*mem_ctx
,
3646 const struct spoolss_PrinterInfo2
*info2
,
3647 struct spoolss_PrinterInfo6
*r
,
3651 print_status_struct status
;
3653 count
= print_queue_length(snum
, &status
);
3655 r
->status
= nt_printq_status(status
.status
);
3660 /********************************************************************
3661 * construct_printer_info7
3662 * fill a spoolss_PrinterInfo7 struct
3663 ********************************************************************/
3665 static WERROR
construct_printer_info7(TALLOC_CTX
*mem_ctx
,
3666 Printer_entry
*print_hnd
,
3667 struct spoolss_PrinterInfo7
*r
,
3672 if (is_printer_published(print_hnd
, snum
, &guid
)) {
3673 r
->guid
= talloc_strdup_upper(mem_ctx
, GUID_string2(mem_ctx
, &guid
));
3674 r
->action
= DSPRINT_PUBLISH
;
3676 r
->guid
= talloc_strdup(mem_ctx
, "");
3677 r
->action
= DSPRINT_UNPUBLISH
;
3679 W_ERROR_HAVE_NO_MEMORY(r
->guid
);
3684 /********************************************************************
3685 * construct_printer_info8
3686 * fill a spoolss_PrinterInfo8 struct
3687 ********************************************************************/
3689 static WERROR
construct_printer_info8(TALLOC_CTX
*mem_ctx
,
3690 const struct spoolss_PrinterInfo2
*info2
,
3691 struct spoolss_DeviceModeInfo
*r
,
3694 copy_devicemode(mem_ctx
, info2
->devmode
, &r
->devmode
);
3696 DEBUG(8,("Returning NULL Devicemode!\n"));
3703 /********************************************************************
3704 ********************************************************************/
3706 static bool snum_is_shared_printer(int snum
)
3708 return (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
));
3711 /********************************************************************
3712 Spoolss_enumprinters.
3713 ********************************************************************/
3715 static WERROR
enum_all_printers_info_level(TALLOC_CTX
*mem_ctx
,
3716 struct auth_serversupplied_info
*server_info
,
3719 union spoolss_PrinterInfo
**info_p
,
3723 int n_services
= lp_numservices();
3724 union spoolss_PrinterInfo
*info
= NULL
;
3726 WERROR result
= WERR_OK
;
3731 for (snum
= 0; snum
< n_services
; snum
++) {
3733 const char *printer
;
3734 struct spoolss_PrinterInfo2
*info2
;
3736 if (!snum_is_shared_printer(snum
)) {
3740 printer
= lp_const_servicename(snum
);
3742 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3745 result
= winreg_create_printer(mem_ctx
,
3749 if (!W_ERROR_IS_OK(result
)) {
3753 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
3754 union spoolss_PrinterInfo
,
3757 result
= WERR_NOMEM
;
3761 result
= winreg_get_printer(mem_ctx
, server_info
,
3762 NULL
, printer
, &info2
);
3763 if (!W_ERROR_IS_OK(result
)) {
3769 result
= construct_printer_info0(info
, server_info
, info2
,
3770 &info
[count
].info0
, snum
);
3773 result
= construct_printer_info1(info
, info2
, flags
,
3774 &info
[count
].info1
, snum
);
3777 result
= construct_printer_info2(info
, info2
,
3778 &info
[count
].info2
, snum
);
3781 result
= construct_printer_info4(info
, info2
,
3782 &info
[count
].info4
, snum
);
3785 result
= construct_printer_info5(info
, info2
,
3786 &info
[count
].info5
, snum
);
3790 result
= WERR_UNKNOWN_LEVEL
;
3794 if (!W_ERROR_IS_OK(result
)) {
3805 if (!W_ERROR_IS_OK(result
)) {
3815 /********************************************************************
3816 * handle enumeration of printers at level 0
3817 ********************************************************************/
3819 static WERROR
enumprinters_level0(TALLOC_CTX
*mem_ctx
,
3820 struct auth_serversupplied_info
*server_info
,
3822 const char *servername
,
3823 union spoolss_PrinterInfo
**info
,
3826 DEBUG(4,("enum_all_printers_info_0\n"));
3828 return enum_all_printers_info_level(mem_ctx
, server_info
, 0, flags
, info
, count
);
3832 /********************************************************************
3833 ********************************************************************/
3835 static WERROR
enum_all_printers_info_1(TALLOC_CTX
*mem_ctx
,
3836 struct auth_serversupplied_info
*server_info
,
3838 union spoolss_PrinterInfo
**info
,
3841 DEBUG(4,("enum_all_printers_info_1\n"));
3843 return enum_all_printers_info_level(mem_ctx
, server_info
, 1, flags
, info
, count
);
3846 /********************************************************************
3847 enum_all_printers_info_1_local.
3848 *********************************************************************/
3850 static WERROR
enum_all_printers_info_1_local(TALLOC_CTX
*mem_ctx
,
3851 struct auth_serversupplied_info
*server_info
,
3852 union spoolss_PrinterInfo
**info
,
3855 DEBUG(4,("enum_all_printers_info_1_local\n"));
3857 return enum_all_printers_info_1(mem_ctx
, server_info
, PRINTER_ENUM_ICON8
, info
, count
);
3860 /********************************************************************
3861 enum_all_printers_info_1_name.
3862 *********************************************************************/
3864 static WERROR
enum_all_printers_info_1_name(TALLOC_CTX
*mem_ctx
,
3865 struct auth_serversupplied_info
*server_info
,
3867 union spoolss_PrinterInfo
**info
,
3870 const char *s
= name
;
3872 DEBUG(4,("enum_all_printers_info_1_name\n"));
3874 if ((name
[0] == '\\') && (name
[1] == '\\')) {
3878 if (!is_myname_or_ipaddr(s
)) {
3879 return WERR_INVALID_NAME
;
3882 return enum_all_printers_info_1(mem_ctx
, server_info
, PRINTER_ENUM_ICON8
, info
, count
);
3885 /********************************************************************
3886 enum_all_printers_info_1_network.
3887 *********************************************************************/
3889 static WERROR
enum_all_printers_info_1_network(TALLOC_CTX
*mem_ctx
,
3890 struct auth_serversupplied_info
*server_info
,
3892 union spoolss_PrinterInfo
**info
,
3895 const char *s
= name
;
3897 DEBUG(4,("enum_all_printers_info_1_network\n"));
3899 /* If we respond to a enum_printers level 1 on our name with flags
3900 set to PRINTER_ENUM_REMOTE with a list of printers then these
3901 printers incorrectly appear in the APW browse list.
3902 Specifically the printers for the server appear at the workgroup
3903 level where all the other servers in the domain are
3904 listed. Windows responds to this call with a
3905 WERR_CAN_NOT_COMPLETE so we should do the same. */
3907 if (name
[0] == '\\' && name
[1] == '\\') {
3911 if (is_myname_or_ipaddr(s
)) {
3912 return WERR_CAN_NOT_COMPLETE
;
3915 return enum_all_printers_info_1(mem_ctx
, server_info
, PRINTER_ENUM_NAME
, info
, count
);
3918 /********************************************************************
3919 * api_spoolss_enumprinters
3921 * called from api_spoolss_enumprinters (see this to understand)
3922 ********************************************************************/
3924 static WERROR
enum_all_printers_info_2(TALLOC_CTX
*mem_ctx
,
3925 struct auth_serversupplied_info
*server_info
,
3926 union spoolss_PrinterInfo
**info
,
3929 DEBUG(4,("enum_all_printers_info_2\n"));
3931 return enum_all_printers_info_level(mem_ctx
, server_info
, 2, 0, info
, count
);
3934 /********************************************************************
3935 * handle enumeration of printers at level 1
3936 ********************************************************************/
3938 static WERROR
enumprinters_level1(TALLOC_CTX
*mem_ctx
,
3939 struct auth_serversupplied_info
*server_info
,
3942 union spoolss_PrinterInfo
**info
,
3945 /* Not all the flags are equals */
3947 if (flags
& PRINTER_ENUM_LOCAL
) {
3948 return enum_all_printers_info_1_local(mem_ctx
, server_info
, info
, count
);
3951 if (flags
& PRINTER_ENUM_NAME
) {
3952 return enum_all_printers_info_1_name(mem_ctx
, server_info
, name
, info
, count
);
3955 if (flags
& PRINTER_ENUM_NETWORK
) {
3956 return enum_all_printers_info_1_network(mem_ctx
, server_info
, name
, info
, count
);
3959 return WERR_OK
; /* NT4sp5 does that */
3962 /********************************************************************
3963 * handle enumeration of printers at level 2
3964 ********************************************************************/
3966 static WERROR
enumprinters_level2(TALLOC_CTX
*mem_ctx
,
3967 struct auth_serversupplied_info
*server_info
,
3969 const char *servername
,
3970 union spoolss_PrinterInfo
**info
,
3973 if (flags
& PRINTER_ENUM_LOCAL
) {
3974 return enum_all_printers_info_2(mem_ctx
, server_info
, info
, count
);
3977 if (flags
& PRINTER_ENUM_NAME
) {
3978 if (!is_myname_or_ipaddr(canon_servername(servername
))) {
3979 return WERR_INVALID_NAME
;
3982 return enum_all_printers_info_2(mem_ctx
, server_info
, info
, count
);
3985 if (flags
& PRINTER_ENUM_REMOTE
) {
3986 return WERR_UNKNOWN_LEVEL
;
3992 /********************************************************************
3993 * handle enumeration of printers at level 4
3994 ********************************************************************/
3996 static WERROR
enumprinters_level4(TALLOC_CTX
*mem_ctx
,
3997 struct auth_serversupplied_info
*server_info
,
3999 const char *servername
,
4000 union spoolss_PrinterInfo
**info
,
4003 DEBUG(4,("enum_all_printers_info_4\n"));
4005 return enum_all_printers_info_level(mem_ctx
, server_info
, 4, flags
, info
, count
);
4009 /********************************************************************
4010 * handle enumeration of printers at level 5
4011 ********************************************************************/
4013 static WERROR
enumprinters_level5(TALLOC_CTX
*mem_ctx
,
4014 struct auth_serversupplied_info
*server_info
,
4016 const char *servername
,
4017 union spoolss_PrinterInfo
**info
,
4020 DEBUG(4,("enum_all_printers_info_5\n"));
4022 return enum_all_printers_info_level(mem_ctx
, server_info
, 5, flags
, info
, count
);
4025 /****************************************************************
4026 _spoolss_EnumPrinters
4027 ****************************************************************/
4029 WERROR
_spoolss_EnumPrinters(pipes_struct
*p
,
4030 struct spoolss_EnumPrinters
*r
)
4032 const char *name
= NULL
;
4035 /* that's an [in out] buffer */
4037 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4038 return WERR_INVALID_PARAM
;
4041 DEBUG(4,("_spoolss_EnumPrinters\n"));
4045 *r
->out
.info
= NULL
;
4049 * flags==PRINTER_ENUM_NAME
4050 * if name=="" then enumerates all printers
4051 * if name!="" then enumerate the printer
4052 * flags==PRINTER_ENUM_REMOTE
4053 * name is NULL, enumerate printers
4054 * Level 2: name!="" enumerates printers, name can't be NULL
4055 * Level 3: doesn't exist
4056 * Level 4: does a local registry lookup
4057 * Level 5: same as Level 2
4061 name
= talloc_strdup_upper(p
->mem_ctx
, r
->in
.server
);
4062 W_ERROR_HAVE_NO_MEMORY(name
);
4065 switch (r
->in
.level
) {
4067 result
= enumprinters_level0(p
->mem_ctx
, p
->server_info
,
4069 r
->out
.info
, r
->out
.count
);
4072 result
= enumprinters_level1(p
->mem_ctx
, p
->server_info
,
4074 r
->out
.info
, r
->out
.count
);
4077 result
= enumprinters_level2(p
->mem_ctx
, p
->server_info
,
4079 r
->out
.info
, r
->out
.count
);
4082 result
= enumprinters_level4(p
->mem_ctx
, p
->server_info
,
4084 r
->out
.info
, r
->out
.count
);
4087 result
= enumprinters_level5(p
->mem_ctx
, p
->server_info
,
4089 r
->out
.info
, r
->out
.count
);
4092 return WERR_UNKNOWN_LEVEL
;
4095 if (!W_ERROR_IS_OK(result
)) {
4099 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
4100 spoolss_EnumPrinters
,
4101 *r
->out
.info
, r
->in
.level
,
4103 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
4104 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
4106 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4109 /****************************************************************
4111 ****************************************************************/
4113 WERROR
_spoolss_GetPrinter(pipes_struct
*p
,
4114 struct spoolss_GetPrinter
*r
)
4116 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
4117 struct spoolss_PrinterInfo2
*info2
= NULL
;
4118 WERROR result
= WERR_OK
;
4119 const char *servername
= NULL
;
4122 /* that's an [in out] buffer */
4124 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4125 return WERR_INVALID_PARAM
;
4130 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
4134 if (Printer
!= NULL
|| Printer
->servername
!= NULL
) {
4135 servername
= Printer
->servername
;
4138 result
= winreg_get_printer(p
->mem_ctx
,
4141 lp_const_servicename(snum
),
4143 if (!W_ERROR_IS_OK(result
)) {
4147 switch (r
->in
.level
) {
4149 result
= construct_printer_info0(p
->mem_ctx
, p
->server_info
,
4151 &r
->out
.info
->info0
, snum
);
4154 result
= construct_printer_info1(p
->mem_ctx
, info2
,
4156 &r
->out
.info
->info1
, snum
);
4159 result
= construct_printer_info2(p
->mem_ctx
, info2
,
4160 &r
->out
.info
->info2
, snum
);
4163 result
= construct_printer_info3(p
->mem_ctx
, info2
,
4164 &r
->out
.info
->info3
, snum
);
4167 result
= construct_printer_info4(p
->mem_ctx
, info2
,
4168 &r
->out
.info
->info4
, snum
);
4171 result
= construct_printer_info5(p
->mem_ctx
, info2
,
4172 &r
->out
.info
->info5
, snum
);
4175 result
= construct_printer_info6(p
->mem_ctx
, info2
,
4176 &r
->out
.info
->info6
, snum
);
4179 result
= construct_printer_info7(p
->mem_ctx
, Printer
,
4180 &r
->out
.info
->info7
, snum
);
4183 result
= construct_printer_info8(p
->mem_ctx
, info2
,
4184 &r
->out
.info
->info8
, snum
);
4187 result
= WERR_UNKNOWN_LEVEL
;
4191 if (!W_ERROR_IS_OK(result
)) {
4192 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4193 r
->in
.level
, win_errstr(result
)));
4194 TALLOC_FREE(r
->out
.info
);
4198 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo
,
4199 r
->out
.info
, r
->in
.level
);
4200 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
4202 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4205 /********************************************************************
4206 ********************************************************************/
4208 static const char **string_array_from_driver_info(TALLOC_CTX
*mem_ctx
,
4209 const char **string_array
,
4210 const char *cservername
)
4212 int i
, num_strings
= 0;
4213 const char **array
= NULL
;
4215 if (!string_array
) {
4219 for (i
=0; string_array
[i
] && string_array
[i
][0] != '\0'; i
++) {
4221 const char *str
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4222 cservername
, string_array
[i
]);
4229 if (!add_string_to_array(mem_ctx
, str
, &array
, &num_strings
)) {
4236 ADD_TO_ARRAY(mem_ctx
, const char *, NULL
,
4237 &array
, &num_strings
);
4243 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4245 if (in && strlen(in)) { \
4246 out = talloc_strdup(mem_ctx, in); \
4247 W_ERROR_HAVE_NO_MEMORY(out); \
4253 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
4255 if (in && strlen(in)) { \
4256 out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
4258 out = talloc_strdup(mem_ctx, ""); \
4260 W_ERROR_HAVE_NO_MEMORY(out); \
4263 /********************************************************************
4264 * fill a spoolss_DriverInfo1 struct
4265 ********************************************************************/
4267 static WERROR
fill_printer_driver_info1(TALLOC_CTX
*mem_ctx
,
4268 struct spoolss_DriverInfo1
*r
,
4269 const struct spoolss_DriverInfo8
*driver
,
4270 const char *servername
)
4272 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4273 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4278 /********************************************************************
4279 * fill a spoolss_DriverInfo2 struct
4280 ********************************************************************/
4282 static WERROR
fill_printer_driver_info2(TALLOC_CTX
*mem_ctx
,
4283 struct spoolss_DriverInfo2
*r
,
4284 const struct spoolss_DriverInfo8
*driver
,
4285 const char *servername
)
4288 const char *cservername
= canon_servername(servername
);
4290 r
->version
= driver
->version
;
4292 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4293 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4294 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4295 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4297 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4298 driver
->driver_path
,
4301 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4305 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4306 driver
->config_file
,
4312 /********************************************************************
4313 * fill a spoolss_DriverInfo3 struct
4314 ********************************************************************/
4316 static WERROR
fill_printer_driver_info3(TALLOC_CTX
*mem_ctx
,
4317 struct spoolss_DriverInfo3
*r
,
4318 const struct spoolss_DriverInfo8
*driver
,
4319 const char *servername
)
4321 const char *cservername
= canon_servername(servername
);
4323 r
->version
= driver
->version
;
4325 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4326 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4327 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4328 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4330 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4331 driver
->driver_path
,
4334 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4338 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4339 driver
->config_file
,
4342 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4346 FILL_DRIVER_STRING(mem_ctx
,
4347 driver
->monitor_name
,
4350 FILL_DRIVER_STRING(mem_ctx
,
4351 driver
->default_datatype
,
4352 r
->default_datatype
);
4354 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
4355 driver
->dependent_files
,
4360 /********************************************************************
4361 * fill a spoolss_DriverInfo4 struct
4362 ********************************************************************/
4364 static WERROR
fill_printer_driver_info4(TALLOC_CTX
*mem_ctx
,
4365 struct spoolss_DriverInfo4
*r
,
4366 const struct spoolss_DriverInfo8
*driver
,
4367 const char *servername
)
4369 const char *cservername
= canon_servername(servername
);
4371 r
->version
= driver
->version
;
4373 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4374 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4375 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4376 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4378 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4379 driver
->driver_path
,
4382 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4386 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4387 driver
->config_file
,
4390 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4394 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
4395 driver
->dependent_files
,
4398 FILL_DRIVER_STRING(mem_ctx
,
4399 driver
->monitor_name
,
4402 FILL_DRIVER_STRING(mem_ctx
,
4403 driver
->default_datatype
,
4404 r
->default_datatype
);
4406 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
4407 driver
->previous_names
,
4413 /********************************************************************
4414 * fill a spoolss_DriverInfo5 struct
4415 ********************************************************************/
4417 static WERROR
fill_printer_driver_info5(TALLOC_CTX
*mem_ctx
,
4418 struct spoolss_DriverInfo5
*r
,
4419 const struct spoolss_DriverInfo8
*driver
,
4420 const char *servername
)
4422 const char *cservername
= canon_servername(servername
);
4424 r
->version
= driver
->version
;
4426 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4427 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4428 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4429 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4431 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4432 driver
->driver_path
,
4435 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4439 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4440 driver
->config_file
,
4443 r
->driver_attributes
= 0;
4444 r
->config_version
= 0;
4445 r
->driver_version
= 0;
4449 /********************************************************************
4450 * fill a spoolss_DriverInfo6 struct
4451 ********************************************************************/
4453 static WERROR
fill_printer_driver_info6(TALLOC_CTX
*mem_ctx
,
4454 struct spoolss_DriverInfo6
*r
,
4455 const struct spoolss_DriverInfo8
*driver
,
4456 const char *servername
)
4458 const char *cservername
= canon_servername(servername
);
4460 r
->version
= driver
->version
;
4462 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4463 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4464 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4465 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4467 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4468 driver
->driver_path
,
4471 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4475 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4476 driver
->config_file
,
4479 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4483 FILL_DRIVER_STRING(mem_ctx
,
4484 driver
->monitor_name
,
4487 FILL_DRIVER_STRING(mem_ctx
,
4488 driver
->default_datatype
,
4489 r
->default_datatype
);
4491 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
4492 driver
->dependent_files
,
4494 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
4495 driver
->previous_names
,
4498 r
->driver_date
= driver
->driver_date
;
4499 r
->driver_version
= driver
->driver_version
;
4501 FILL_DRIVER_STRING(mem_ctx
,
4502 driver
->manufacturer_name
,
4503 r
->manufacturer_name
);
4504 FILL_DRIVER_STRING(mem_ctx
,
4505 driver
->manufacturer_url
,
4506 r
->manufacturer_url
);
4507 FILL_DRIVER_STRING(mem_ctx
,
4508 driver
->hardware_id
,
4510 FILL_DRIVER_STRING(mem_ctx
,
4517 /********************************************************************
4518 * fill a spoolss_DriverInfo8 struct
4519 ********************************************************************/
4521 static WERROR
fill_printer_driver_info8(TALLOC_CTX
*mem_ctx
,
4522 struct spoolss_DriverInfo8
*r
,
4523 const struct spoolss_DriverInfo8
*driver
,
4524 const char *servername
)
4526 const char *cservername
= canon_servername(servername
);
4528 r
->version
= driver
->version
;
4530 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4531 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4532 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4533 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4535 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4536 driver
->driver_path
,
4539 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4543 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4544 driver
->config_file
,
4547 FILL_DRIVER_UNC_STRING(mem_ctx
, cservername
,
4551 FILL_DRIVER_STRING(mem_ctx
,
4552 driver
->monitor_name
,
4555 FILL_DRIVER_STRING(mem_ctx
,
4556 driver
->default_datatype
,
4557 r
->default_datatype
);
4559 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
4560 driver
->dependent_files
,
4562 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
4563 driver
->previous_names
,
4566 r
->driver_date
= driver
->driver_date
;
4567 r
->driver_version
= driver
->driver_version
;
4569 FILL_DRIVER_STRING(mem_ctx
,
4570 driver
->manufacturer_name
,
4571 r
->manufacturer_name
);
4572 FILL_DRIVER_STRING(mem_ctx
,
4573 driver
->manufacturer_url
,
4574 r
->manufacturer_url
);
4575 FILL_DRIVER_STRING(mem_ctx
,
4576 driver
->hardware_id
,
4578 FILL_DRIVER_STRING(mem_ctx
,
4582 FILL_DRIVER_STRING(mem_ctx
,
4583 driver
->print_processor
,
4584 r
->print_processor
);
4585 FILL_DRIVER_STRING(mem_ctx
,
4586 driver
->vendor_setup
,
4589 r
->color_profiles
= string_array_from_driver_info(mem_ctx
,
4590 driver
->color_profiles
,
4593 FILL_DRIVER_STRING(mem_ctx
,
4597 r
->printer_driver_attributes
= driver
->printer_driver_attributes
;
4599 r
->core_driver_dependencies
= string_array_from_driver_info(mem_ctx
,
4600 driver
->core_driver_dependencies
,
4603 r
->min_inbox_driver_ver_date
= driver
->min_inbox_driver_ver_date
;
4604 r
->min_inbox_driver_ver_version
= driver
->min_inbox_driver_ver_version
;
4609 #if 0 /* disabled until marshalling issues are resolved - gd */
4610 /********************************************************************
4611 ********************************************************************/
4613 static WERROR
fill_spoolss_DriverFileInfo(TALLOC_CTX
*mem_ctx
,
4614 struct spoolss_DriverFileInfo
*r
,
4615 const char *cservername
,
4616 const char *file_name
,
4617 enum spoolss_DriverFileType file_type
,
4618 uint32_t file_version
)
4620 r
->file_name
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4621 cservername
, file_name
);
4622 W_ERROR_HAVE_NO_MEMORY(r
->file_name
);
4623 r
->file_type
= file_type
;
4624 r
->file_version
= file_version
;
4629 /********************************************************************
4630 ********************************************************************/
4632 static WERROR
spoolss_DriverFileInfo_from_driver(TALLOC_CTX
*mem_ctx
,
4633 const struct spoolss_DriverInfo8
*driver
,
4634 const char *cservername
,
4635 struct spoolss_DriverFileInfo
**info_p
,
4638 struct spoolss_DriverFileInfo
*info
= NULL
;
4646 if (strlen(driver
->driver_path
)) {
4647 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4648 struct spoolss_DriverFileInfo
,
4650 W_ERROR_HAVE_NO_MEMORY(info
);
4651 result
= fill_spoolss_DriverFileInfo(info
,
4654 driver
->driver_path
,
4655 SPOOLSS_DRIVER_FILE_TYPE_RENDERING
,
4657 W_ERROR_NOT_OK_RETURN(result
);
4661 if (strlen(driver
->config_file
)) {
4662 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4663 struct spoolss_DriverFileInfo
,
4665 W_ERROR_HAVE_NO_MEMORY(info
);
4666 result
= fill_spoolss_DriverFileInfo(info
,
4669 driver
->config_file
,
4670 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION
,
4672 W_ERROR_NOT_OK_RETURN(result
);
4676 if (strlen(driver
->data_file
)) {
4677 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4678 struct spoolss_DriverFileInfo
,
4680 W_ERROR_HAVE_NO_MEMORY(info
);
4681 result
= fill_spoolss_DriverFileInfo(info
,
4685 SPOOLSS_DRIVER_FILE_TYPE_DATA
,
4687 W_ERROR_NOT_OK_RETURN(result
);
4691 if (strlen(driver
->help_file
)) {
4692 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4693 struct spoolss_DriverFileInfo
,
4695 W_ERROR_HAVE_NO_MEMORY(info
);
4696 result
= fill_spoolss_DriverFileInfo(info
,
4700 SPOOLSS_DRIVER_FILE_TYPE_HELP
,
4702 W_ERROR_NOT_OK_RETURN(result
);
4706 for (i
=0; driver
->dependent_files
[i
] && driver
->dependent_files
[i
][0] != '\0'; i
++) {
4707 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4708 struct spoolss_DriverFileInfo
,
4710 W_ERROR_HAVE_NO_MEMORY(info
);
4711 result
= fill_spoolss_DriverFileInfo(info
,
4714 driver
->dependent_files
[i
],
4715 SPOOLSS_DRIVER_FILE_TYPE_OTHER
,
4717 W_ERROR_NOT_OK_RETURN(result
);
4727 /********************************************************************
4728 * fill a spoolss_DriverInfo101 struct
4729 ********************************************************************/
4731 static WERROR
fill_printer_driver_info101(TALLOC_CTX
*mem_ctx
,
4732 struct spoolss_DriverInfo101
*r
,
4733 const struct spoolss_DriverInfo8
*driver
,
4734 const char *servername
)
4736 const char *cservername
= canon_servername(servername
);
4739 r
->version
= driver
->version
;
4741 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->driver_name
);
4742 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4743 r
->architecture
= talloc_strdup(mem_ctx
, driver
->architecture
);
4744 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4746 result
= spoolss_DriverFileInfo_from_driver(mem_ctx
, driver
,
4750 if (!W_ERROR_IS_OK(result
)) {
4754 FILL_DRIVER_STRING(mem_ctx
,
4755 driver
->monitor_name
,
4758 FILL_DRIVER_STRING(mem_ctx
,
4759 driver
->default_datatype
,
4760 r
->default_datatype
);
4762 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
4763 driver
->previous_names
,
4765 r
->driver_date
= driver
->driver_date
;
4766 r
->driver_version
= driver
->driver_version
;
4768 FILL_DRIVER_STRING(mem_ctx
,
4769 driver
->manufacturer_name
,
4770 r
->manufacturer_name
);
4771 FILL_DRIVER_STRING(mem_ctx
,
4772 driver
->manufacturer_url
,
4773 r
->manufacturer_url
);
4774 FILL_DRIVER_STRING(mem_ctx
,
4775 driver
->hardware_id
,
4777 FILL_DRIVER_STRING(mem_ctx
,
4784 /********************************************************************
4785 ********************************************************************/
4787 static WERROR
construct_printer_driver_info_level(TALLOC_CTX
*mem_ctx
,
4789 union spoolss_DriverInfo
*r
,
4791 const char *servername
,
4792 const char *architecture
,
4795 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4796 struct spoolss_DriverInfo8
*driver
;
4799 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
4801 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4802 win_errstr(result
)));
4804 if (!W_ERROR_IS_OK(result
)) {
4805 return WERR_INVALID_PRINTER_NAME
;
4808 result
= get_a_printer_driver(mem_ctx
, &driver
, printer
->info_2
->drivername
,
4809 architecture
, version
);
4811 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4812 win_errstr(result
)));
4814 if (!W_ERROR_IS_OK(result
)) {
4816 * Is this a W2k client ?
4820 free_a_printer(&printer
, 2);
4821 return WERR_UNKNOWN_PRINTER_DRIVER
;
4824 /* Yes - try again with a WinNT driver. */
4826 result
= get_a_printer_driver(mem_ctx
, &driver
, printer
->info_2
->drivername
,
4827 architecture
, version
);
4828 DEBUG(8,("construct_printer_driver_level: status: %s\n",
4829 win_errstr(result
)));
4830 if (!W_ERROR_IS_OK(result
)) {
4831 free_a_printer(&printer
, 2);
4832 return WERR_UNKNOWN_PRINTER_DRIVER
;
4838 result
= fill_printer_driver_info1(mem_ctx
, &r
->info1
, driver
, servername
);
4841 result
= fill_printer_driver_info2(mem_ctx
, &r
->info2
, driver
, servername
);
4844 result
= fill_printer_driver_info3(mem_ctx
, &r
->info3
, driver
, servername
);
4847 result
= fill_printer_driver_info4(mem_ctx
, &r
->info4
, driver
, servername
);
4850 result
= fill_printer_driver_info5(mem_ctx
, &r
->info5
, driver
, servername
);
4853 result
= fill_printer_driver_info6(mem_ctx
, &r
->info6
, driver
, servername
);
4856 result
= fill_printer_driver_info8(mem_ctx
, &r
->info8
, driver
, servername
);
4858 #if 0 /* disabled until marshalling issues are resolved - gd */
4860 result
= fill_printer_driver_info101(mem_ctx
, &r
->info101
, driver
, servername
);
4864 result
= WERR_UNKNOWN_LEVEL
;
4868 free_a_printer(&printer
, 2);
4869 free_a_printer_driver(driver
);
4874 /****************************************************************
4875 _spoolss_GetPrinterDriver2
4876 ****************************************************************/
4878 WERROR
_spoolss_GetPrinterDriver2(pipes_struct
*p
,
4879 struct spoolss_GetPrinterDriver2
*r
)
4881 Printer_entry
*printer
;
4884 const char *servername
;
4887 /* that's an [in out] buffer */
4889 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4890 return WERR_INVALID_PARAM
;
4893 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
4895 if (!(printer
= find_printer_index_by_hnd(p
, r
->in
.handle
))) {
4896 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
4897 return WERR_INVALID_PRINTER_NAME
;
4901 *r
->out
.server_major_version
= 0;
4902 *r
->out
.server_minor_version
= 0;
4904 servername
= get_server_name(printer
);
4906 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
4910 result
= construct_printer_driver_info_level(p
->mem_ctx
, r
->in
.level
,
4914 r
->in
.client_major_version
);
4915 if (!W_ERROR_IS_OK(result
)) {
4916 TALLOC_FREE(r
->out
.info
);
4920 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_DriverInfo
,
4921 r
->out
.info
, r
->in
.level
);
4922 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
4924 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4928 /****************************************************************
4929 _spoolss_StartPagePrinter
4930 ****************************************************************/
4932 WERROR
_spoolss_StartPagePrinter(pipes_struct
*p
,
4933 struct spoolss_StartPagePrinter
*r
)
4935 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
4938 DEBUG(3,("_spoolss_StartPagePrinter: "
4939 "Error in startpageprinter printer handle\n"));
4943 Printer
->page_started
= true;
4947 /****************************************************************
4948 _spoolss_EndPagePrinter
4949 ****************************************************************/
4951 WERROR
_spoolss_EndPagePrinter(pipes_struct
*p
,
4952 struct spoolss_EndPagePrinter
*r
)
4956 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
4959 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
4960 OUR_HANDLE(r
->in
.handle
)));
4964 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
4967 Printer
->page_started
= false;
4968 print_job_endpage(snum
, Printer
->jobid
);
4973 /****************************************************************
4974 _spoolss_StartDocPrinter
4975 ****************************************************************/
4977 WERROR
_spoolss_StartDocPrinter(pipes_struct
*p
,
4978 struct spoolss_StartDocPrinter
*r
)
4980 struct spoolss_DocumentInfo1
*info_1
;
4982 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
4985 DEBUG(2,("_spoolss_StartDocPrinter: "
4986 "Invalid handle (%s:%u:%u)\n",
4987 OUR_HANDLE(r
->in
.handle
)));
4991 if (r
->in
.level
!= 1) {
4992 return WERR_UNKNOWN_LEVEL
;
4995 info_1
= r
->in
.info
.info1
;
4998 * a nice thing with NT is it doesn't listen to what you tell it.
4999 * when asked to send _only_ RAW datas, it tries to send datas
5002 * So I add checks like in NT Server ...
5005 if (info_1
->datatype
) {
5006 if (strcmp(info_1
->datatype
, "RAW") != 0) {
5008 return WERR_INVALID_DATATYPE
;
5012 /* get the share number of the printer */
5013 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5017 Printer
->jobid
= print_job_start(p
->server_info
, snum
,
5018 info_1
->document_name
,
5021 /* An error occured in print_job_start() so return an appropriate
5024 if (Printer
->jobid
== -1) {
5025 return map_werror_from_unix(errno
);
5028 Printer
->document_started
= true;
5029 *r
->out
.job_id
= Printer
->jobid
;
5034 /****************************************************************
5035 _spoolss_EndDocPrinter
5036 ****************************************************************/
5038 WERROR
_spoolss_EndDocPrinter(pipes_struct
*p
,
5039 struct spoolss_EndDocPrinter
*r
)
5041 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5045 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5046 OUR_HANDLE(r
->in
.handle
)));
5050 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5054 Printer
->document_started
= false;
5055 print_job_end(snum
, Printer
->jobid
, NORMAL_CLOSE
);
5056 /* error codes unhandled so far ... */
5061 /****************************************************************
5062 _spoolss_WritePrinter
5063 ****************************************************************/
5065 WERROR
_spoolss_WritePrinter(pipes_struct
*p
,
5066 struct spoolss_WritePrinter
*r
)
5068 ssize_t buffer_written
;
5070 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5073 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5074 OUR_HANDLE(r
->in
.handle
)));
5075 *r
->out
.num_written
= r
->in
._data_size
;
5079 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5082 buffer_written
= print_job_write(snum
, Printer
->jobid
,
5083 (const char *)r
->in
.data
.data
,
5085 (size_t)r
->in
._data_size
);
5086 if (buffer_written
== (ssize_t
)-1) {
5087 *r
->out
.num_written
= 0;
5088 if (errno
== ENOSPC
)
5089 return WERR_NO_SPOOL_SPACE
;
5091 return WERR_ACCESS_DENIED
;
5094 *r
->out
.num_written
= r
->in
._data_size
;
5099 /********************************************************************
5100 * api_spoolss_getprinter
5101 * called from the spoolss dispatcher
5103 ********************************************************************/
5105 static WERROR
control_printer(struct policy_handle
*handle
, uint32_t command
,
5109 WERROR errcode
= WERR_BADFUNC
;
5110 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5113 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5114 OUR_HANDLE(handle
)));
5118 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5122 case SPOOLSS_PRINTER_CONTROL_PAUSE
:
5123 errcode
= print_queue_pause(p
->server_info
, snum
);
5125 case SPOOLSS_PRINTER_CONTROL_RESUME
:
5126 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
:
5127 errcode
= print_queue_resume(p
->server_info
, snum
);
5129 case SPOOLSS_PRINTER_CONTROL_PURGE
:
5130 errcode
= print_queue_purge(p
->server_info
, snum
);
5133 return WERR_UNKNOWN_LEVEL
;
5140 /****************************************************************
5141 _spoolss_AbortPrinter
5142 * From MSDN: "Deletes printer's spool file if printer is configured
5144 ****************************************************************/
5146 WERROR
_spoolss_AbortPrinter(pipes_struct
*p
,
5147 struct spoolss_AbortPrinter
*r
)
5149 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5151 WERROR errcode
= WERR_OK
;
5154 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5155 OUR_HANDLE(r
->in
.handle
)));
5159 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5162 print_job_delete(p
->server_info
, snum
, Printer
->jobid
, &errcode
);
5167 /********************************************************************
5168 * called by spoolss_api_setprinter
5169 * when updating a printer description
5170 ********************************************************************/
5172 static WERROR
update_printer_sec(struct policy_handle
*handle
,
5173 pipes_struct
*p
, struct sec_desc_buf
*secdesc_ctr
)
5175 struct spoolss_security_descriptor
*new_secdesc
= NULL
;
5176 struct spoolss_security_descriptor
*old_secdesc
= NULL
;
5177 const char *printer
;
5181 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5183 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
5184 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5185 OUR_HANDLE(handle
)));
5187 result
= WERR_BADFID
;
5191 if (secdesc_ctr
== NULL
) {
5192 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5193 result
= WERR_INVALID_PARAM
;
5196 printer
= lp_const_servicename(snum
);
5198 /* Check the user has permissions to change the security
5199 descriptor. By experimentation with two NT machines, the user
5200 requires Full Access to the printer to change security
5203 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
5204 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5205 result
= WERR_ACCESS_DENIED
;
5209 /* NT seems to like setting the security descriptor even though
5210 nothing may have actually changed. */
5211 result
= winreg_get_printer_secdesc(p
->mem_ctx
,
5215 if (!W_ERROR_IS_OK(result
)) {
5216 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5217 result
= WERR_BADFID
;
5221 if (DEBUGLEVEL
>= 10) {
5222 struct security_acl
*the_acl
;
5225 the_acl
= secdesc_ctr
->sd
->dacl
;
5226 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5227 printer
, the_acl
->num_aces
));
5229 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5230 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5231 &the_acl
->aces
[i
].trustee
),
5232 the_acl
->aces
[i
].access_mask
));
5235 the_acl
= secdesc_ctr
->sd
->dacl
;
5238 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5239 printer
, the_acl
->num_aces
));
5241 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5242 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5243 &the_acl
->aces
[i
].trustee
),
5244 the_acl
->aces
[i
].access_mask
));
5247 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5251 new_secdesc
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
->sd
, old_secdesc
);
5252 if (new_secdesc
== NULL
) {
5253 result
= WERR_NOMEM
;
5257 if (security_descriptor_equal(new_secdesc
, old_secdesc
)) {
5262 result
= winreg_set_printer_secdesc(p
->mem_ctx
,
5271 /********************************************************************
5272 Canonicalize printer info from a client
5274 ATTN: It does not matter what we set the servername to hear
5275 since we do the necessary work in get_a_printer() to set it to
5276 the correct value based on what the client sent in the
5277 _spoolss_open_printer_ex().
5278 ********************************************************************/
5280 static bool check_printer_ok(TALLOC_CTX
*mem_ctx
,
5281 struct spoolss_SetPrinterInfo2
*info2
,
5284 fstring printername
;
5287 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5288 "portname=%s drivername=%s comment=%s location=%s\n",
5289 info2
->servername
, info2
->printername
, info2
->sharename
,
5290 info2
->portname
, info2
->drivername
, info2
->comment
,
5293 /* we force some elements to "correct" values */
5294 info2
->servername
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
5295 if (info2
->servername
== NULL
) {
5298 info2
->sharename
= talloc_strdup(mem_ctx
, lp_const_servicename(snum
));
5299 if (info2
->sharename
== NULL
) {
5303 /* check to see if we allow printername != sharename */
5304 if (lp_force_printername(snum
)) {
5305 info2
->printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
5306 global_myname(), info2
->sharename
);
5308 /* make sure printername is in \\server\printername format */
5309 fstrcpy(printername
, info2
->printername
);
5311 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
5312 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
5316 info2
->printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
5317 global_myname(), p
);
5319 if (info2
->printername
== NULL
) {
5323 info2
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
5324 info2
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
5329 /****************************************************************************
5330 ****************************************************************************/
5332 static WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
5334 char *cmd
= lp_addport_cmd();
5335 char *command
= NULL
;
5337 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
5338 bool is_print_op
= false;
5341 return WERR_ACCESS_DENIED
;
5344 command
= talloc_asprintf(ctx
,
5345 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
5351 is_print_op
= user_has_privileges( token
, &se_printop
);
5353 DEBUG(10,("Running [%s]\n", command
));
5355 /********* BEGIN SePrintOperatorPrivilege **********/
5360 ret
= smbrun(command
, NULL
);
5365 /********* END SePrintOperatorPrivilege **********/
5367 DEBUGADD(10,("returned [%d]\n", ret
));
5369 TALLOC_FREE(command
);
5372 return WERR_ACCESS_DENIED
;
5378 /****************************************************************************
5379 ****************************************************************************/
5381 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
,
5382 struct spoolss_SetPrinterInfo2
*info2
)
5384 char *cmd
= lp_addprinter_cmd();
5386 char *command
= NULL
;
5390 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
5391 bool is_print_op
= false;
5392 char *remote_machine
= talloc_strdup(ctx
, "%m");
5394 if (!remote_machine
) {
5397 remote_machine
= talloc_sub_basic(ctx
,
5398 current_user_info
.smb_name
,
5399 current_user_info
.domain
,
5401 if (!remote_machine
) {
5405 command
= talloc_asprintf(ctx
,
5406 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5407 cmd
, info2
->printername
, info2
->sharename
,
5408 info2
->portname
, info2
->drivername
,
5409 info2
->location
, info2
->comment
, remote_machine
);
5415 is_print_op
= user_has_privileges( token
, &se_printop
);
5417 DEBUG(10,("Running [%s]\n", command
));
5419 /********* BEGIN SePrintOperatorPrivilege **********/
5424 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
5425 /* Tell everyone we updated smb.conf. */
5426 message_send_all(smbd_messaging_context(),
5427 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
5433 /********* END SePrintOperatorPrivilege **********/
5435 DEBUGADD(10,("returned [%d]\n", ret
));
5437 TALLOC_FREE(command
);
5438 TALLOC_FREE(remote_machine
);
5446 /* reload our services immediately */
5448 reload_services(false);
5452 /* Get lines and convert them back to dos-codepage */
5453 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
5454 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5457 /* Set the portname to what the script says the portname should be. */
5458 /* but don't require anything to be return from the script exit a good error code */
5461 /* Set the portname to what the script says the portname should be. */
5462 info2
->portname
= talloc_strdup(ctx
, qlines
[0]);
5463 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
5466 TALLOC_FREE(qlines
);
5471 /********************************************************************
5472 * Called by spoolss_api_setprinter
5473 * when updating a printer description.
5474 ********************************************************************/
5476 static WERROR
update_printer(pipes_struct
*p
, struct policy_handle
*handle
,
5477 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
5478 struct spoolss_DeviceMode
*devmode
)
5480 uint32_t printer_mask
= SPOOLSS_PRINTER_INFO_ALL
;
5481 struct spoolss_SetPrinterInfo2
*printer
= info_ctr
->info
.info2
;
5482 struct spoolss_PrinterInfo2
*old_printer
;
5483 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5484 const char *servername
= NULL
;
5490 DEBUG(8,("update_printer\n"));
5495 result
= WERR_BADFID
;
5499 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5500 result
= WERR_BADFID
;
5504 if (Printer
!= NULL
|| Printer
->servername
!= NULL
) {
5505 servername
= Printer
->servername
;
5508 result
= winreg_get_printer(p
->mem_ctx
,
5511 lp_const_servicename(snum
),
5513 if (!W_ERROR_IS_OK(result
)) {
5514 result
= WERR_BADFID
;
5518 /* Do sanity check on the requested changes for Samba */
5519 if (!check_printer_ok(p
->mem_ctx
, printer
, snum
)) {
5520 result
= WERR_INVALID_PARAM
;
5524 /* FIXME!!! If the driver has changed we really should verify that
5525 it is installed before doing much else --jerry */
5527 /* Check calling user has permission to update printer description */
5528 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
5529 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5530 result
= WERR_ACCESS_DENIED
;
5534 /* Call addprinter hook */
5535 /* Check changes to see if this is really needed */
5537 if (*lp_addprinter_cmd() &&
5538 (!strequal(printer
->drivername
, old_printer
->drivername
) ||
5539 !strequal(printer
->comment
, old_printer
->comment
) ||
5540 !strequal(printer
->portname
, old_printer
->portname
) ||
5541 !strequal(printer
->location
, old_printer
->location
)) )
5543 /* add_printer_hook() will call reload_services() */
5544 if (!add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
5546 result
= WERR_ACCESS_DENIED
;
5552 * When a *new* driver is bound to a printer, the drivername is used to
5553 * lookup previously saved driver initialization info, which is then
5554 * bound to the printer, simulating what happens in the Windows arch.
5556 if (!strequal(printer
->drivername
, old_printer
->drivername
)) {
5557 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5558 printer
->drivername
));
5560 notify_printer_driver(snum
, printer
->drivername
);
5564 * flag which changes actually occured. This is a small subset of
5565 * all the possible changes. We also have to update things in the
5568 if (!strequal(printer
->comment
, old_printer
->comment
)) {
5569 push_reg_sz(talloc_tos(), &buffer
, printer
->comment
);
5570 winreg_set_printer_dataex(p
->mem_ctx
,
5573 SPOOL_DSSPOOLER_KEY
,
5579 notify_printer_comment(snum
, printer
->comment
);
5582 if (!strequal(printer
->sharename
, old_printer
->sharename
)) {
5583 push_reg_sz(talloc_tos(), &buffer
, printer
->sharename
);
5584 winreg_set_printer_dataex(p
->mem_ctx
,
5587 SPOOL_DSSPOOLER_KEY
,
5593 notify_printer_sharename(snum
, printer
->sharename
);
5596 if (!strequal(printer
->printername
, old_printer
->printername
)) {
5599 if ( (pname
= strchr_m( printer
->printername
+2, '\\' )) != NULL
)
5602 pname
= printer
->printername
;
5604 push_reg_sz(talloc_tos(), &buffer
, pname
);
5605 winreg_set_printer_dataex(p
->mem_ctx
,
5608 SPOOL_DSSPOOLER_KEY
,
5614 notify_printer_printername( snum
, pname
);
5617 if (!strequal(printer
->portname
, old_printer
->portname
)) {
5618 push_reg_sz(talloc_tos(), &buffer
, printer
->portname
);
5619 winreg_set_printer_dataex(p
->mem_ctx
,
5622 SPOOL_DSSPOOLER_KEY
,
5628 notify_printer_port(snum
, printer
->portname
);
5631 if (!strequal(printer
->location
, old_printer
->location
)) {
5632 push_reg_sz(talloc_tos(), &buffer
, printer
->location
);
5633 winreg_set_printer_dataex(p
->mem_ctx
,
5636 SPOOL_DSSPOOLER_KEY
,
5642 notify_printer_location(snum
, printer
->location
);
5645 /* here we need to update some more DsSpooler keys */
5646 /* uNCName, serverName, shortServerName */
5648 push_reg_sz(talloc_tos(), &buffer
, global_myname());
5649 winreg_set_printer_dataex(p
->mem_ctx
,
5652 SPOOL_DSSPOOLER_KEY
,
5657 winreg_set_printer_dataex(p
->mem_ctx
,
5660 SPOOL_DSSPOOLER_KEY
,
5666 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
5667 global_myname(), printer
->sharename
);
5668 push_reg_sz(talloc_tos(), &buffer
, asc_buffer
);
5669 winreg_set_printer_dataex(p
->mem_ctx
,
5672 SPOOL_DSSPOOLER_KEY
,
5678 printer_mask
&= ~SPOOLSS_PRINTER_INFO_SECDESC
;
5680 if (devmode
== NULL
) {
5681 printer_mask
&= ~SPOOLSS_PRINTER_INFO_DEVMODE
;
5683 result
= winreg_update_printer(p
->mem_ctx
,
5692 talloc_free(old_printer
);
5697 /****************************************************************************
5698 ****************************************************************************/
5699 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
,
5700 struct policy_handle
*handle
,
5701 struct spoolss_SetPrinterInfo7
*info7
)
5705 Printer_entry
*Printer
;
5707 if ( lp_security() != SEC_ADS
) {
5708 return WERR_UNKNOWN_LEVEL
;
5711 Printer
= find_printer_index_by_hnd(p
, handle
);
5713 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
5718 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5721 nt_printer_publish(Printer
, snum
, info7
->action
);
5725 return WERR_UNKNOWN_LEVEL
;
5729 /********************************************************************
5730 ********************************************************************/
5732 static WERROR
update_printer_devmode(pipes_struct
*p
, struct policy_handle
*handle
,
5733 struct spoolss_DeviceMode
*devmode
)
5736 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5737 uint32_t info2_mask
= SPOOLSS_PRINTER_INFO_DEVMODE
;
5739 DEBUG(8,("update_printer_devmode\n"));
5745 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5749 /* Check calling user has permission to update printer description */
5750 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
5751 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5752 return WERR_ACCESS_DENIED
;
5755 return winreg_update_printer(p
->mem_ctx
,
5757 lp_const_servicename(snum
),
5765 /****************************************************************
5767 ****************************************************************/
5769 WERROR
_spoolss_SetPrinter(pipes_struct
*p
,
5770 struct spoolss_SetPrinter
*r
)
5774 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5777 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5778 OUR_HANDLE(r
->in
.handle
)));
5782 /* check the level */
5783 switch (r
->in
.info_ctr
->level
) {
5785 return control_printer(r
->in
.handle
, r
->in
.command
, p
);
5787 result
= update_printer(p
, r
->in
.handle
,
5789 r
->in
.devmode_ctr
->devmode
);
5790 if (!W_ERROR_IS_OK(result
))
5792 if (r
->in
.secdesc_ctr
->sd
)
5793 result
= update_printer_sec(r
->in
.handle
, p
,
5797 return update_printer_sec(r
->in
.handle
, p
,
5800 return publish_or_unpublish_printer(p
, r
->in
.handle
,
5801 r
->in
.info_ctr
->info
.info7
);
5803 return update_printer_devmode(p
, r
->in
.handle
,
5804 r
->in
.devmode_ctr
->devmode
);
5806 return WERR_UNKNOWN_LEVEL
;
5810 /****************************************************************
5811 _spoolss_FindClosePrinterNotify
5812 ****************************************************************/
5814 WERROR
_spoolss_FindClosePrinterNotify(pipes_struct
*p
,
5815 struct spoolss_FindClosePrinterNotify
*r
)
5817 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5820 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
5821 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r
->in
.handle
)));
5825 if (Printer
->notify
.client_connected
== true) {
5828 if ( Printer
->printer_type
== SPLHND_SERVER
)
5830 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
5831 !get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
) )
5834 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
5837 Printer
->notify
.flags
=0;
5838 Printer
->notify
.options
=0;
5839 Printer
->notify
.localmachine
[0]='\0';
5840 Printer
->notify
.printerlocal
=0;
5841 TALLOC_FREE(Printer
->notify
.option
);
5842 Printer
->notify
.client_connected
= false;
5847 /****************************************************************
5849 ****************************************************************/
5851 WERROR
_spoolss_AddJob(pipes_struct
*p
,
5852 struct spoolss_AddJob
*r
)
5854 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
5855 return WERR_INVALID_PARAM
;
5858 /* this is what a NT server returns for AddJob. AddJob must fail on
5859 * non-local printers */
5861 if (r
->in
.level
!= 1) {
5862 return WERR_UNKNOWN_LEVEL
;
5865 return WERR_INVALID_PARAM
;
5868 /****************************************************************************
5870 ****************************************************************************/
5872 static WERROR
fill_job_info1(TALLOC_CTX
*mem_ctx
,
5873 struct spoolss_JobInfo1
*r
,
5874 const print_queue_struct
*queue
,
5875 int position
, int snum
,
5876 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
5880 t
= gmtime(&queue
->time
);
5882 r
->job_id
= queue
->job
;
5884 r
->printer_name
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
5885 W_ERROR_HAVE_NO_MEMORY(r
->printer_name
);
5886 r
->server_name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
5887 W_ERROR_HAVE_NO_MEMORY(r
->server_name
);
5888 r
->user_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
5889 W_ERROR_HAVE_NO_MEMORY(r
->user_name
);
5890 r
->document_name
= talloc_strdup(mem_ctx
, queue
->fs_file
);
5891 W_ERROR_HAVE_NO_MEMORY(r
->document_name
);
5892 r
->data_type
= talloc_strdup(mem_ctx
, "RAW");
5893 W_ERROR_HAVE_NO_MEMORY(r
->data_type
);
5894 r
->text_status
= talloc_strdup(mem_ctx
, "");
5895 W_ERROR_HAVE_NO_MEMORY(r
->text_status
);
5897 r
->status
= nt_printj_status(queue
->status
);
5898 r
->priority
= queue
->priority
;
5899 r
->position
= position
;
5900 r
->total_pages
= queue
->page_count
;
5901 r
->pages_printed
= 0; /* ??? */
5903 init_systemtime(&r
->submitted
, t
);
5908 /****************************************************************************
5910 ****************************************************************************/
5912 static WERROR
fill_job_info2(TALLOC_CTX
*mem_ctx
,
5913 struct spoolss_JobInfo2
*r
,
5914 const print_queue_struct
*queue
,
5915 int position
, int snum
,
5916 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
5917 struct spoolss_DeviceMode
*devmode
)
5921 t
= gmtime(&queue
->time
);
5923 r
->job_id
= queue
->job
;
5925 r
->printer_name
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
5926 W_ERROR_HAVE_NO_MEMORY(r
->printer_name
);
5927 r
->server_name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
5928 W_ERROR_HAVE_NO_MEMORY(r
->server_name
);
5929 r
->user_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
5930 W_ERROR_HAVE_NO_MEMORY(r
->user_name
);
5931 r
->document_name
= talloc_strdup(mem_ctx
, queue
->fs_file
);
5932 W_ERROR_HAVE_NO_MEMORY(r
->document_name
);
5933 r
->notify_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
5934 W_ERROR_HAVE_NO_MEMORY(r
->notify_name
);
5935 r
->data_type
= talloc_strdup(mem_ctx
, "RAW");
5936 W_ERROR_HAVE_NO_MEMORY(r
->data_type
);
5937 r
->print_processor
= talloc_strdup(mem_ctx
, "winprint");
5938 W_ERROR_HAVE_NO_MEMORY(r
->print_processor
);
5939 r
->parameters
= talloc_strdup(mem_ctx
, "");
5940 W_ERROR_HAVE_NO_MEMORY(r
->parameters
);
5941 r
->driver_name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->drivername
);
5942 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
5944 r
->devmode
= devmode
;
5946 r
->text_status
= talloc_strdup(mem_ctx
, "");
5947 W_ERROR_HAVE_NO_MEMORY(r
->text_status
);
5951 r
->status
= nt_printj_status(queue
->status
);
5952 r
->priority
= queue
->priority
;
5953 r
->position
= position
;
5956 r
->total_pages
= queue
->page_count
;
5957 r
->size
= queue
->size
;
5958 init_systemtime(&r
->submitted
, t
);
5960 r
->pages_printed
= 0; /* ??? */
5965 /****************************************************************************
5967 ****************************************************************************/
5969 static WERROR
fill_job_info3(TALLOC_CTX
*mem_ctx
,
5970 struct spoolss_JobInfo3
*r
,
5971 const print_queue_struct
*queue
,
5972 const print_queue_struct
*next_queue
,
5973 int position
, int snum
,
5974 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
5976 r
->job_id
= queue
->job
;
5979 r
->next_job_id
= next_queue
->job
;
5986 /****************************************************************************
5987 Enumjobs at level 1.
5988 ****************************************************************************/
5990 static WERROR
enumjobs_level1(TALLOC_CTX
*mem_ctx
,
5991 const print_queue_struct
*queue
,
5992 uint32_t num_queues
, int snum
,
5993 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
5994 union spoolss_JobInfo
**info_p
,
5997 union spoolss_JobInfo
*info
;
5999 WERROR result
= WERR_OK
;
6001 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6002 W_ERROR_HAVE_NO_MEMORY(info
);
6004 *count
= num_queues
;
6006 for (i
=0; i
<*count
; i
++) {
6007 result
= fill_job_info1(info
,
6013 if (!W_ERROR_IS_OK(result
)) {
6019 if (!W_ERROR_IS_OK(result
)) {
6030 /****************************************************************************
6031 Enumjobs at level 2.
6032 ****************************************************************************/
6034 static WERROR
enumjobs_level2(TALLOC_CTX
*mem_ctx
,
6035 const print_queue_struct
*queue
,
6036 uint32_t num_queues
, int snum
,
6037 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6038 union spoolss_JobInfo
**info_p
,
6041 union spoolss_JobInfo
*info
;
6043 WERROR result
= WERR_OK
;
6045 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6046 W_ERROR_HAVE_NO_MEMORY(info
);
6048 *count
= num_queues
;
6050 for (i
=0; i
<*count
; i
++) {
6052 struct spoolss_DeviceMode
*devmode
;
6054 devmode
= construct_dev_mode(info
, lp_const_servicename(snum
));
6056 result
= WERR_NOMEM
;
6060 result
= fill_job_info2(info
,
6067 if (!W_ERROR_IS_OK(result
)) {
6073 if (!W_ERROR_IS_OK(result
)) {
6084 /****************************************************************************
6085 Enumjobs at level 3.
6086 ****************************************************************************/
6088 static WERROR
enumjobs_level3(TALLOC_CTX
*mem_ctx
,
6089 const print_queue_struct
*queue
,
6090 uint32_t num_queues
, int snum
,
6091 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6092 union spoolss_JobInfo
**info_p
,
6095 union spoolss_JobInfo
*info
;
6097 WERROR result
= WERR_OK
;
6099 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6100 W_ERROR_HAVE_NO_MEMORY(info
);
6102 *count
= num_queues
;
6104 for (i
=0; i
<*count
; i
++) {
6105 const print_queue_struct
*next_queue
= NULL
;
6108 next_queue
= &queue
[i
+1];
6111 result
= fill_job_info3(info
,
6118 if (!W_ERROR_IS_OK(result
)) {
6124 if (!W_ERROR_IS_OK(result
)) {
6135 /****************************************************************
6137 ****************************************************************/
6139 WERROR
_spoolss_EnumJobs(pipes_struct
*p
,
6140 struct spoolss_EnumJobs
*r
)
6143 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6145 print_status_struct prt_status
;
6146 print_queue_struct
*queue
= NULL
;
6149 /* that's an [in out] buffer */
6151 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6152 return WERR_INVALID_PARAM
;
6155 DEBUG(4,("_spoolss_EnumJobs\n"));
6159 *r
->out
.info
= NULL
;
6161 /* lookup the printer snum and tdb entry */
6163 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
6167 result
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6168 if (!W_ERROR_IS_OK(result
)) {
6172 count
= print_queue_status(snum
, &queue
, &prt_status
);
6173 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6174 count
, prt_status
.status
, prt_status
.message
));
6178 free_a_printer(&ntprinter
, 2);
6182 switch (r
->in
.level
) {
6184 result
= enumjobs_level1(p
->mem_ctx
, queue
, count
, snum
,
6185 ntprinter
, r
->out
.info
, r
->out
.count
);
6188 result
= enumjobs_level2(p
->mem_ctx
, queue
, count
, snum
,
6189 ntprinter
, r
->out
.info
, r
->out
.count
);
6192 result
= enumjobs_level3(p
->mem_ctx
, queue
, count
, snum
,
6193 ntprinter
, r
->out
.info
, r
->out
.count
);
6196 result
= WERR_UNKNOWN_LEVEL
;
6201 free_a_printer(&ntprinter
, 2);
6203 if (!W_ERROR_IS_OK(result
)) {
6207 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6209 *r
->out
.info
, r
->in
.level
,
6211 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6212 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6214 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6217 /****************************************************************
6218 _spoolss_ScheduleJob
6219 ****************************************************************/
6221 WERROR
_spoolss_ScheduleJob(pipes_struct
*p
,
6222 struct spoolss_ScheduleJob
*r
)
6227 /****************************************************************
6228 ****************************************************************/
6230 static WERROR
spoolss_setjob_1(TALLOC_CTX
*mem_ctx
,
6231 const char *printer_name
,
6233 struct spoolss_SetJobInfo1
*r
)
6237 if (!print_job_get_name(mem_ctx
, printer_name
, job_id
, &old_doc_name
)) {
6241 if (strequal(old_doc_name
, r
->document_name
)) {
6245 if (!print_job_set_name(printer_name
, job_id
, r
->document_name
)) {
6252 /****************************************************************
6254 ****************************************************************/
6256 WERROR
_spoolss_SetJob(pipes_struct
*p
,
6257 struct spoolss_SetJob
*r
)
6260 WERROR errcode
= WERR_BADFUNC
;
6262 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
6266 if (!print_job_exists(lp_const_servicename(snum
), r
->in
.job_id
)) {
6267 return WERR_INVALID_PRINTER_NAME
;
6270 switch (r
->in
.command
) {
6271 case SPOOLSS_JOB_CONTROL_CANCEL
:
6272 case SPOOLSS_JOB_CONTROL_DELETE
:
6273 if (print_job_delete(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6277 case SPOOLSS_JOB_CONTROL_PAUSE
:
6278 if (print_job_pause(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6282 case SPOOLSS_JOB_CONTROL_RESTART
:
6283 case SPOOLSS_JOB_CONTROL_RESUME
:
6284 if (print_job_resume(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6292 return WERR_UNKNOWN_LEVEL
;
6295 if (!W_ERROR_IS_OK(errcode
)) {
6299 if (r
->in
.ctr
== NULL
) {
6303 switch (r
->in
.ctr
->level
) {
6305 errcode
= spoolss_setjob_1(p
->mem_ctx
, lp_const_servicename(snum
),
6307 r
->in
.ctr
->info
.info1
);
6313 return WERR_UNKNOWN_LEVEL
;
6319 /****************************************************************************
6320 Enumerates all printer drivers by level and architecture.
6321 ****************************************************************************/
6323 static WERROR
enumprinterdrivers_level_by_architecture(TALLOC_CTX
*mem_ctx
,
6324 const char *servername
,
6325 const char *architecture
,
6327 union spoolss_DriverInfo
**info_p
,
6333 fstring
*list
= NULL
;
6334 struct spoolss_DriverInfo8
*driver
;
6335 union spoolss_DriverInfo
*info
= NULL
;
6337 WERROR result
= WERR_OK
;
6342 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6344 ndrivers
= get_ntdrivers(&list
, architecture
, version
);
6345 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6346 ndrivers
, architecture
, version
));
6348 if (ndrivers
== -1) {
6349 result
= WERR_NOMEM
;
6353 if (ndrivers
!= 0) {
6354 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
6355 union spoolss_DriverInfo
,
6358 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6359 "failed to enlarge driver info buffer!\n"));
6360 result
= WERR_NOMEM
;
6365 for (i
=0; i
<ndrivers
; i
++) {
6366 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6367 ZERO_STRUCT(driver
);
6368 result
= get_a_printer_driver(mem_ctx
, &driver
, list
[i
],
6369 architecture
, version
);
6370 if (!W_ERROR_IS_OK(result
)) {
6376 result
= fill_printer_driver_info1(info
, &info
[count
+i
].info1
,
6377 driver
, servername
);
6380 result
= fill_printer_driver_info2(info
, &info
[count
+i
].info2
,
6381 driver
, servername
);
6384 result
= fill_printer_driver_info3(info
, &info
[count
+i
].info3
,
6385 driver
, servername
);
6388 result
= fill_printer_driver_info4(info
, &info
[count
+i
].info4
,
6389 driver
, servername
);
6392 result
= fill_printer_driver_info5(info
, &info
[count
+i
].info5
,
6393 driver
, servername
);
6396 result
= fill_printer_driver_info6(info
, &info
[count
+i
].info6
,
6397 driver
, servername
);
6400 result
= fill_printer_driver_info8(info
, &info
[count
+i
].info8
,
6401 driver
, servername
);
6404 result
= WERR_UNKNOWN_LEVEL
;
6408 free_a_printer_driver(driver
);
6410 if (!W_ERROR_IS_OK(result
)) {
6422 if (!W_ERROR_IS_OK(result
)) {
6433 /****************************************************************************
6434 Enumerates all printer drivers by level.
6435 ****************************************************************************/
6437 static WERROR
enumprinterdrivers_level(TALLOC_CTX
*mem_ctx
,
6438 const char *servername
,
6439 const char *architecture
,
6441 union spoolss_DriverInfo
**info_p
,
6445 WERROR result
= WERR_OK
;
6447 if (strequal(architecture
, SPOOLSS_ARCHITECTURE_ALL
)) {
6449 for (a
=0; archi_table
[a
].long_archi
!= NULL
; a
++) {
6451 union spoolss_DriverInfo
*info
= NULL
;
6454 result
= enumprinterdrivers_level_by_architecture(mem_ctx
,
6456 archi_table
[a
].long_archi
,
6460 if (!W_ERROR_IS_OK(result
)) {
6464 for (i
=0; i
< count
; i
++) {
6465 ADD_TO_ARRAY(mem_ctx
, union spoolss_DriverInfo
,
6466 info
[i
], info_p
, count_p
);
6473 return enumprinterdrivers_level_by_architecture(mem_ctx
,
6481 /****************************************************************
6482 _spoolss_EnumPrinterDrivers
6483 ****************************************************************/
6485 WERROR
_spoolss_EnumPrinterDrivers(pipes_struct
*p
,
6486 struct spoolss_EnumPrinterDrivers
*r
)
6488 const char *cservername
;
6491 /* that's an [in out] buffer */
6493 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6494 return WERR_INVALID_PARAM
;
6497 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6501 *r
->out
.info
= NULL
;
6503 cservername
= canon_servername(r
->in
.server
);
6505 if (!is_myname_or_ipaddr(cservername
)) {
6506 return WERR_UNKNOWN_PRINTER_DRIVER
;
6509 result
= enumprinterdrivers_level(p
->mem_ctx
, cservername
,
6514 if (!W_ERROR_IS_OK(result
)) {
6518 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6519 spoolss_EnumPrinterDrivers
,
6520 *r
->out
.info
, r
->in
.level
,
6522 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6523 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6525 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6528 /****************************************************************
6530 ****************************************************************/
6532 WERROR
_spoolss_EnumForms(pipes_struct
*p
,
6533 struct spoolss_EnumForms
*r
)
6539 *r
->out
.info
= NULL
;
6541 /* that's an [in out] buffer */
6543 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0) ) {
6544 return WERR_INVALID_PARAM
;
6547 DEBUG(4,("_spoolss_EnumForms\n"));
6548 DEBUGADD(5,("Offered buffer size [%d]\n", r
->in
.offered
));
6549 DEBUGADD(5,("Info level [%d]\n", r
->in
.level
));
6551 switch (r
->in
.level
) {
6553 result
= winreg_printer_enumforms1(p
->mem_ctx
,
6559 result
= WERR_UNKNOWN_LEVEL
;
6563 if (!W_ERROR_IS_OK(result
)) {
6567 if (*r
->out
.count
== 0) {
6568 return WERR_NO_MORE_ITEMS
;
6571 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6573 *r
->out
.info
, r
->in
.level
,
6575 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6576 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6578 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6581 /****************************************************************
6583 ****************************************************************/
6585 WERROR
_spoolss_GetForm(pipes_struct
*p
,
6586 struct spoolss_GetForm
*r
)
6590 /* that's an [in out] buffer */
6592 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6593 return WERR_INVALID_PARAM
;
6596 DEBUG(4,("_spoolss_GetForm\n"));
6597 DEBUGADD(5,("Offered buffer size [%d]\n", r
->in
.offered
));
6598 DEBUGADD(5,("Info level [%d]\n", r
->in
.level
));
6600 switch (r
->in
.level
) {
6602 result
= winreg_printer_getform1(p
->mem_ctx
,
6605 &r
->out
.info
->info1
);
6608 result
= WERR_UNKNOWN_LEVEL
;
6612 if (!W_ERROR_IS_OK(result
)) {
6613 TALLOC_FREE(r
->out
.info
);
6617 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_FormInfo
,
6618 r
->out
.info
, r
->in
.level
);
6619 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
6621 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6624 /****************************************************************************
6625 ****************************************************************************/
6627 static WERROR
fill_port_1(TALLOC_CTX
*mem_ctx
,
6628 struct spoolss_PortInfo1
*r
,
6631 r
->port_name
= talloc_strdup(mem_ctx
, name
);
6632 W_ERROR_HAVE_NO_MEMORY(r
->port_name
);
6637 /****************************************************************************
6638 TODO: This probably needs distinguish between TCP/IP and Local ports
6640 ****************************************************************************/
6642 static WERROR
fill_port_2(TALLOC_CTX
*mem_ctx
,
6643 struct spoolss_PortInfo2
*r
,
6646 r
->port_name
= talloc_strdup(mem_ctx
, name
);
6647 W_ERROR_HAVE_NO_MEMORY(r
->port_name
);
6649 r
->monitor_name
= talloc_strdup(mem_ctx
, "Local Monitor");
6650 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
6652 r
->description
= talloc_strdup(mem_ctx
, SPL_LOCAL_PORT
);
6653 W_ERROR_HAVE_NO_MEMORY(r
->description
);
6655 r
->port_type
= SPOOLSS_PORT_TYPE_WRITE
;
6662 /****************************************************************************
6663 wrapper around the enumer ports command
6664 ****************************************************************************/
6666 static WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
6668 char *cmd
= lp_enumports_cmd();
6669 char **qlines
= NULL
;
6670 char *command
= NULL
;
6678 /* if no hook then just fill in the default port */
6681 if (!(qlines
= TALLOC_ARRAY( NULL
, char*, 2 ))) {
6684 if (!(qlines
[0] = talloc_strdup(qlines
, SAMBA_PRINTER_PORT_NAME
))) {
6685 TALLOC_FREE(qlines
);
6692 /* we have a valid enumport command */
6694 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
6699 DEBUG(10,("Running [%s]\n", command
));
6700 ret
= smbrun(command
, &fd
);
6701 DEBUG(10,("Returned [%d]\n", ret
));
6702 TALLOC_FREE(command
);
6707 return WERR_ACCESS_DENIED
;
6711 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
6712 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6722 /****************************************************************************
6724 ****************************************************************************/
6726 static WERROR
enumports_level_1(TALLOC_CTX
*mem_ctx
,
6727 union spoolss_PortInfo
**info_p
,
6730 union spoolss_PortInfo
*info
= NULL
;
6732 WERROR result
= WERR_OK
;
6733 char **qlines
= NULL
;
6736 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
6737 if (!W_ERROR_IS_OK(result
)) {
6742 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PortInfo
, numlines
);
6744 DEBUG(10,("Returning WERR_NOMEM\n"));
6745 result
= WERR_NOMEM
;
6749 for (i
=0; i
<numlines
; i
++) {
6750 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
6751 result
= fill_port_1(info
, &info
[i
].info1
, qlines
[i
]);
6752 if (!W_ERROR_IS_OK(result
)) {
6757 TALLOC_FREE(qlines
);
6760 if (!W_ERROR_IS_OK(result
)) {
6762 TALLOC_FREE(qlines
);
6774 /****************************************************************************
6776 ****************************************************************************/
6778 static WERROR
enumports_level_2(TALLOC_CTX
*mem_ctx
,
6779 union spoolss_PortInfo
**info_p
,
6782 union spoolss_PortInfo
*info
= NULL
;
6784 WERROR result
= WERR_OK
;
6785 char **qlines
= NULL
;
6788 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
6789 if (!W_ERROR_IS_OK(result
)) {
6794 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PortInfo
, numlines
);
6796 DEBUG(10,("Returning WERR_NOMEM\n"));
6797 result
= WERR_NOMEM
;
6801 for (i
=0; i
<numlines
; i
++) {
6802 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
6803 result
= fill_port_2(info
, &info
[i
].info2
, qlines
[i
]);
6804 if (!W_ERROR_IS_OK(result
)) {
6809 TALLOC_FREE(qlines
);
6812 if (!W_ERROR_IS_OK(result
)) {
6814 TALLOC_FREE(qlines
);
6826 /****************************************************************
6828 ****************************************************************/
6830 WERROR
_spoolss_EnumPorts(pipes_struct
*p
,
6831 struct spoolss_EnumPorts
*r
)
6835 /* that's an [in out] buffer */
6837 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6838 return WERR_INVALID_PARAM
;
6841 DEBUG(4,("_spoolss_EnumPorts\n"));
6845 *r
->out
.info
= NULL
;
6847 switch (r
->in
.level
) {
6849 result
= enumports_level_1(p
->mem_ctx
, r
->out
.info
,
6853 result
= enumports_level_2(p
->mem_ctx
, r
->out
.info
,
6857 return WERR_UNKNOWN_LEVEL
;
6860 if (!W_ERROR_IS_OK(result
)) {
6864 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6866 *r
->out
.info
, r
->in
.level
,
6868 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6869 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6871 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6874 /****************************************************************************
6875 ****************************************************************************/
6877 static WERROR
spoolss_addprinterex_level_2(pipes_struct
*p
,
6879 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
6880 struct spoolss_DeviceMode
*devmode
,
6881 struct security_descriptor
*secdesc
,
6882 struct spoolss_UserLevelCtr
*user_ctr
,
6883 struct policy_handle
*handle
)
6885 struct spoolss_SetPrinterInfo2
*info2
= info_ctr
->info
.info2
;
6886 uint32_t info2_mask
= SPOOLSS_PRINTER_INFO_ALL
;
6888 WERROR err
= WERR_OK
;
6890 /* samba does not have a concept of local, non-shared printers yet, so
6891 * make sure we always setup sharename - gd */
6892 if ((info2
->sharename
== NULL
|| info2
->sharename
[0] == '\0') &&
6893 (info2
->printername
!= NULL
&& info2
->printername
[0] != '\0')) {
6894 DEBUG(5, ("spoolss_addprinterex_level_2: "
6895 "no sharename has been set, setting printername %s as sharename\n",
6896 info2
->printername
));
6897 info2
->sharename
= info2
->printername
;
6900 /* check to see if the printer already exists */
6901 if ((snum
= print_queue_snum(info2
->sharename
)) != -1) {
6902 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
6904 return WERR_PRINTER_ALREADY_EXISTS
;
6907 if (!lp_force_printername(GLOBAL_SECTION_SNUM
)) {
6908 if ((snum
= print_queue_snum(info2
->printername
)) != -1) {
6909 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
6910 info2
->printername
));
6911 return WERR_PRINTER_ALREADY_EXISTS
;
6915 /* validate printer info struct */
6916 if (!info2
->printername
|| strlen(info2
->printername
) == 0) {
6917 return WERR_INVALID_PRINTER_NAME
;
6919 if (!info2
->portname
|| strlen(info2
->portname
) == 0) {
6920 return WERR_UNKNOWN_PORT
;
6922 if (!info2
->drivername
|| strlen(info2
->drivername
) == 0) {
6923 return WERR_UNKNOWN_PRINTER_DRIVER
;
6925 if (!info2
->printprocessor
|| strlen(info2
->printprocessor
) == 0) {
6926 return WERR_UNKNOWN_PRINTPROCESSOR
;
6929 /* FIXME!!! smbd should check to see if the driver is installed before
6930 trying to add a printer like this --jerry */
6932 if (*lp_addprinter_cmd() ) {
6933 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
6935 return WERR_ACCESS_DENIED
;
6938 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
6939 "smb.conf parameter \"addprinter command\" is defined. This"
6940 "parameter must exist for this call to succeed\n",
6941 info2
->sharename
));
6944 if ((snum
= print_queue_snum(info2
->sharename
)) == -1) {
6945 return WERR_ACCESS_DENIED
;
6948 /* you must be a printer admin to add a new printer */
6949 if (!print_access_check(p
->server_info
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6950 return WERR_ACCESS_DENIED
;
6954 * Do sanity check on the requested changes for Samba.
6957 if (!check_printer_ok(p
->mem_ctx
, info2
, snum
)) {
6958 return WERR_INVALID_PARAM
;
6961 if (devmode
== NULL
) {
6962 info2_mask
= ~SPOOLSS_PRINTER_INFO_DEVMODE
;
6965 err
= winreg_update_printer(p
->mem_ctx
,
6972 if (!W_ERROR_IS_OK(err
)) {
6976 if (!open_printer_hnd(p
, handle
, info2
->printername
, PRINTER_ACCESS_ADMINISTER
)) {
6977 /* Handle open failed - remove addition. */
6978 ZERO_STRUCTP(handle
);
6979 return WERR_ACCESS_DENIED
;
6985 /****************************************************************
6986 _spoolss_AddPrinterEx
6987 ****************************************************************/
6989 WERROR
_spoolss_AddPrinterEx(pipes_struct
*p
,
6990 struct spoolss_AddPrinterEx
*r
)
6992 switch (r
->in
.info_ctr
->level
) {
6994 /* we don't handle yet */
6995 /* but I know what to do ... */
6996 return WERR_UNKNOWN_LEVEL
;
6998 return spoolss_addprinterex_level_2(p
, r
->in
.server
,
7000 r
->in
.devmode_ctr
->devmode
,
7001 r
->in
.secdesc_ctr
->sd
,
7002 r
->in
.userlevel_ctr
,
7005 return WERR_UNKNOWN_LEVEL
;
7009 /****************************************************************
7011 ****************************************************************/
7013 WERROR
_spoolss_AddPrinter(pipes_struct
*p
,
7014 struct spoolss_AddPrinter
*r
)
7016 struct spoolss_AddPrinterEx a
;
7017 struct spoolss_UserLevelCtr userlevel_ctr
;
7019 ZERO_STRUCT(userlevel_ctr
);
7021 userlevel_ctr
.level
= 1;
7023 a
.in
.server
= r
->in
.server
;
7024 a
.in
.info_ctr
= r
->in
.info_ctr
;
7025 a
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
7026 a
.in
.secdesc_ctr
= r
->in
.secdesc_ctr
;
7027 a
.in
.userlevel_ctr
= &userlevel_ctr
;
7028 a
.out
.handle
= r
->out
.handle
;
7030 return _spoolss_AddPrinterEx(p
, &a
);
7033 /****************************************************************
7034 _spoolss_AddPrinterDriverEx
7035 ****************************************************************/
7037 WERROR
_spoolss_AddPrinterDriverEx(pipes_struct
*p
,
7038 struct spoolss_AddPrinterDriverEx
*r
)
7040 WERROR err
= WERR_OK
;
7041 char *driver_name
= NULL
;
7046 case NDR_SPOOLSS_ADDPRINTERDRIVER
:
7047 fn
= "_spoolss_AddPrinterDriver";
7049 case NDR_SPOOLSS_ADDPRINTERDRIVEREX
:
7050 fn
= "_spoolss_AddPrinterDriverEx";
7053 return WERR_INVALID_PARAM
;
7057 * we only support the semantics of AddPrinterDriver()
7058 * i.e. only copy files that are newer than existing ones
7061 if (r
->in
.flags
== 0) {
7062 return WERR_INVALID_PARAM
;
7065 if (r
->in
.flags
!= APD_COPY_NEW_FILES
) {
7066 return WERR_ACCESS_DENIED
;
7070 if (r
->in
.info_ctr
->level
!= 3 && r
->in
.info_ctr
->level
!= 6) {
7071 /* Clever hack from Martin Zielinski <mz@seh.de>
7072 * to allow downgrade from level 8 (Vista).
7074 DEBUG(0,("%s: level %d not yet implemented\n", fn
,
7075 r
->in
.info_ctr
->level
));
7076 return WERR_UNKNOWN_LEVEL
;
7079 DEBUG(5,("Cleaning driver's information\n"));
7080 err
= clean_up_driver_struct(p
->mem_ctx
, p
, r
->in
.info_ctr
);
7081 if (!W_ERROR_IS_OK(err
))
7084 DEBUG(5,("Moving driver to final destination\n"));
7085 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(p
, r
->in
.info_ctr
,
7090 if (add_a_printer_driver(p
->mem_ctx
, r
->in
.info_ctr
, &driver_name
, &version
)!=0) {
7091 err
= WERR_ACCESS_DENIED
;
7096 * I think this is where he DrvUpgradePrinter() hook would be
7097 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7098 * server. Right now, we just need to send ourselves a message
7099 * to update each printer bound to this driver. --jerry
7102 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7103 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7111 /****************************************************************
7112 _spoolss_AddPrinterDriver
7113 ****************************************************************/
7115 WERROR
_spoolss_AddPrinterDriver(pipes_struct
*p
,
7116 struct spoolss_AddPrinterDriver
*r
)
7118 struct spoolss_AddPrinterDriverEx a
;
7120 switch (r
->in
.info_ctr
->level
) {
7127 return WERR_UNKNOWN_LEVEL
;
7130 a
.in
.servername
= r
->in
.servername
;
7131 a
.in
.info_ctr
= r
->in
.info_ctr
;
7132 a
.in
.flags
= APD_COPY_NEW_FILES
;
7134 return _spoolss_AddPrinterDriverEx(p
, &a
);
7137 /****************************************************************************
7138 ****************************************************************************/
7140 struct _spoolss_paths
{
7146 enum { SPOOLSS_DRIVER_PATH
, SPOOLSS_PRTPROCS_PATH
};
7148 static const struct _spoolss_paths spoolss_paths
[]= {
7149 { SPOOLSS_DRIVER_PATH
, "print$", "DRIVERS" },
7150 { SPOOLSS_PRTPROCS_PATH
, "prnproc$", "PRTPROCS" }
7153 static WERROR
compose_spoolss_server_path(TALLOC_CTX
*mem_ctx
,
7154 const char *servername
,
7155 const char *environment
,
7159 const char *pservername
= NULL
;
7160 const char *long_archi
= SPOOLSS_ARCHITECTURE_NT_X86
;
7161 const char *short_archi
;
7165 /* environment may be empty */
7166 if (environment
&& strlen(environment
)) {
7167 long_archi
= environment
;
7170 /* servername may be empty */
7171 if (servername
&& strlen(servername
)) {
7172 pservername
= canon_servername(servername
);
7174 if (!is_myname_or_ipaddr(pservername
)) {
7175 return WERR_INVALID_PARAM
;
7179 if (!(short_archi
= get_short_archi(long_archi
))) {
7180 return WERR_INVALID_ENVIRONMENT
;
7183 switch (component
) {
7184 case SPOOLSS_PRTPROCS_PATH
:
7185 case SPOOLSS_DRIVER_PATH
:
7187 *path
= talloc_asprintf(mem_ctx
,
7190 spoolss_paths
[component
].share
,
7193 *path
= talloc_asprintf(mem_ctx
, "%s\\%s\\%s",
7194 SPOOLSS_DEFAULT_SERVER_PATH
,
7195 spoolss_paths
[component
].dir
,
7200 return WERR_INVALID_PARAM
;
7210 /****************************************************************************
7211 ****************************************************************************/
7213 static WERROR
getprinterdriverdir_level_1(TALLOC_CTX
*mem_ctx
,
7214 const char *servername
,
7215 const char *environment
,
7216 struct spoolss_DriverDirectoryInfo1
*r
)
7221 werr
= compose_spoolss_server_path(mem_ctx
,
7224 SPOOLSS_DRIVER_PATH
,
7226 if (!W_ERROR_IS_OK(werr
)) {
7230 DEBUG(4,("printer driver directory: [%s]\n", path
));
7232 r
->directory_name
= path
;
7237 /****************************************************************
7238 _spoolss_GetPrinterDriverDirectory
7239 ****************************************************************/
7241 WERROR
_spoolss_GetPrinterDriverDirectory(pipes_struct
*p
,
7242 struct spoolss_GetPrinterDriverDirectory
*r
)
7246 /* that's an [in out] buffer */
7248 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7249 return WERR_INVALID_PARAM
;
7252 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7257 /* r->in.level is ignored */
7259 werror
= getprinterdriverdir_level_1(p
->mem_ctx
,
7262 &r
->out
.info
->info1
);
7263 if (!W_ERROR_IS_OK(werror
)) {
7264 TALLOC_FREE(r
->out
.info
);
7268 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo
,
7269 r
->out
.info
, r
->in
.level
);
7270 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
7272 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7275 /****************************************************************
7276 _spoolss_EnumPrinterData
7277 ****************************************************************/
7279 WERROR
_spoolss_EnumPrinterData(pipes_struct
*p
,
7280 struct spoolss_EnumPrinterData
*r
)
7283 struct spoolss_EnumPrinterDataEx r2
;
7285 struct spoolss_PrinterEnumValues
*info
, *val
= NULL
;
7288 r2
.in
.handle
= r
->in
.handle
;
7289 r2
.in
.key_name
= "PrinterDriverData";
7291 r2
.out
.count
= &count
;
7292 r2
.out
.info
= &info
;
7293 r2
.out
.needed
= &needed
;
7295 result
= _spoolss_EnumPrinterDataEx(p
, &r2
);
7296 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
7297 r2
.in
.offered
= needed
;
7298 result
= _spoolss_EnumPrinterDataEx(p
, &r2
);
7300 if (!W_ERROR_IS_OK(result
)) {
7305 * The NT machine wants to know the biggest size of value and data
7307 * cf: MSDN EnumPrinterData remark section
7310 if (!r
->in
.value_offered
&& !r
->in
.data_offered
) {
7311 uint32_t biggest_valuesize
= 0;
7312 uint32_t biggest_datasize
= 0;
7315 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7317 for (i
=0; i
<count
; i
++) {
7319 name_length
= strlen(info
[i
].value_name
);
7320 if (strlen(info
[i
].value_name
) > biggest_valuesize
) {
7321 biggest_valuesize
= name_length
;
7324 if (info
[i
].data_length
> biggest_datasize
) {
7325 biggest_datasize
= info
[i
].data_length
;
7328 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
7332 /* the value is an UNICODE string but real_value_size is the length
7333 in bytes including the trailing 0 */
7335 *r
->out
.value_needed
= 2 * (1 + biggest_valuesize
);
7336 *r
->out
.data_needed
= biggest_datasize
;
7338 DEBUG(6,("final values: [%d], [%d]\n",
7339 *r
->out
.value_needed
, *r
->out
.data_needed
));
7344 if (r
->in
.enum_index
< count
) {
7345 val
= &info
[r
->in
.enum_index
];
7349 /* out_value should default to "" or else NT4 has
7350 problems unmarshalling the response */
7352 if (r
->in
.value_offered
) {
7353 *r
->out
.value_needed
= 1;
7354 r
->out
.value_name
= talloc_strdup(r
, "");
7355 if (!r
->out
.value_name
) {
7359 r
->out
.value_name
= NULL
;
7360 *r
->out
.value_needed
= 0;
7363 /* the data is counted in bytes */
7365 *r
->out
.data_needed
= r
->in
.data_offered
;
7367 result
= WERR_NO_MORE_ITEMS
;
7371 * - counted in bytes in the request
7372 * - counted in UNICODE chars in the max reply
7373 * - counted in bytes in the real size
7375 * take a pause *before* coding not *during* coding
7379 if (r
->in
.value_offered
) {
7380 r
->out
.value_name
= talloc_strdup(r
, val
->value_name
);
7381 if (!r
->out
.value_name
) {
7384 *r
->out
.value_needed
= val
->value_name_len
;
7386 r
->out
.value_name
= NULL
;
7387 *r
->out
.value_needed
= 0;
7392 *r
->out
.type
= val
->type
;
7394 /* data - counted in bytes */
7397 * See the section "Dynamically Typed Query Parameters"
7401 if (r
->out
.data
&& val
->data
&& val
->data
->data
&&
7402 val
->data_length
&& r
->in
.data_offered
) {
7403 memcpy(r
->out
.data
, val
->data
->data
,
7404 MIN(val
->data_length
,r
->in
.data_offered
));
7407 *r
->out
.data_needed
= val
->data_length
;
7415 /****************************************************************
7416 _spoolss_SetPrinterData
7417 ****************************************************************/
7419 WERROR
_spoolss_SetPrinterData(pipes_struct
*p
,
7420 struct spoolss_SetPrinterData
*r
)
7422 struct spoolss_SetPrinterDataEx r2
;
7424 r2
.in
.handle
= r
->in
.handle
;
7425 r2
.in
.key_name
= "PrinterDriverData";
7426 r2
.in
.value_name
= r
->in
.value_name
;
7427 r2
.in
.type
= r
->in
.type
;
7428 r2
.in
.data
= r
->in
.data
;
7429 r2
.in
.offered
= r
->in
.offered
;
7431 return _spoolss_SetPrinterDataEx(p
, &r2
);
7434 /****************************************************************
7435 _spoolss_ResetPrinter
7436 ****************************************************************/
7438 WERROR
_spoolss_ResetPrinter(pipes_struct
*p
,
7439 struct spoolss_ResetPrinter
*r
)
7441 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7444 DEBUG(5,("_spoolss_ResetPrinter\n"));
7447 * All we do is to check to see if the handle and queue is valid.
7448 * This call really doesn't mean anything to us because we only
7449 * support RAW printing. --jerry
7453 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7454 OUR_HANDLE(r
->in
.handle
)));
7458 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
7462 /* blindly return success */
7466 /****************************************************************
7467 _spoolss_DeletePrinterData
7468 ****************************************************************/
7470 WERROR
_spoolss_DeletePrinterData(pipes_struct
*p
,
7471 struct spoolss_DeletePrinterData
*r
)
7473 struct spoolss_DeletePrinterDataEx r2
;
7475 r2
.in
.handle
= r
->in
.handle
;
7476 r2
.in
.key_name
= "PrinterDriverData";
7477 r2
.in
.value_name
= r
->in
.value_name
;
7479 return _spoolss_DeletePrinterDataEx(p
, &r2
);
7482 /****************************************************************
7484 ****************************************************************/
7486 WERROR
_spoolss_AddForm(pipes_struct
*p
,
7487 struct spoolss_AddForm
*r
)
7489 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
7491 WERROR status
= WERR_OK
;
7492 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
7494 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7496 DEBUG(5,("_spoolss_AddForm\n"));
7499 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7500 OUR_HANDLE(r
->in
.handle
)));
7504 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7505 and not a printer admin, then fail */
7507 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
7508 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
7509 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
7510 p
->server_info
->info3
->base
.domain
.string
,
7512 p
->server_info
->ptok
,
7513 lp_printer_admin(snum
))) {
7514 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7515 return WERR_ACCESS_DENIED
;
7518 switch (form
->flags
) {
7519 case SPOOLSS_FORM_USER
:
7520 case SPOOLSS_FORM_BUILTIN
:
7521 case SPOOLSS_FORM_PRINTER
:
7524 return WERR_INVALID_PARAM
;
7527 status
= winreg_printer_addform1(p
->mem_ctx
, p
->server_info
, form
);
7528 if (!W_ERROR_IS_OK(status
)) {
7533 * ChangeID must always be set if this is a printer
7535 if (Printer
->printer_type
== SPLHND_PRINTER
) {
7536 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
7540 status
= winreg_printer_update_changeid(p
->mem_ctx
,
7542 lp_const_servicename(snum
));
7543 if (!W_ERROR_IS_OK(status
)) {
7551 /****************************************************************
7553 ****************************************************************/
7555 WERROR
_spoolss_DeleteForm(pipes_struct
*p
,
7556 struct spoolss_DeleteForm
*r
)
7558 const char *form_name
= r
->in
.form_name
;
7559 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7561 WERROR status
= WERR_OK
;
7562 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
7564 DEBUG(5,("_spoolss_DeleteForm\n"));
7567 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7568 OUR_HANDLE(r
->in
.handle
)));
7572 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
7573 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
7574 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
7575 p
->server_info
->info3
->base
.domain
.string
,
7577 p
->server_info
->ptok
,
7578 lp_printer_admin(snum
))) {
7579 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7580 return WERR_ACCESS_DENIED
;
7583 status
= winreg_printer_deleteform1(p
->mem_ctx
,
7586 if (!W_ERROR_IS_OK(status
)) {
7591 * ChangeID must always be set if this is a printer
7593 if (Printer
->printer_type
== SPLHND_PRINTER
) {
7594 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
7598 status
= winreg_printer_update_changeid(p
->mem_ctx
,
7600 lp_const_servicename(snum
));
7601 if (!W_ERROR_IS_OK(status
)) {
7609 /****************************************************************
7611 ****************************************************************/
7613 WERROR
_spoolss_SetForm(pipes_struct
*p
,
7614 struct spoolss_SetForm
*r
)
7616 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
7617 const char *form_name
= r
->in
.form_name
;
7619 WERROR status
= WERR_OK
;
7620 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
7622 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
7624 DEBUG(5,("_spoolss_SetForm\n"));
7627 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7628 OUR_HANDLE(r
->in
.handle
)));
7632 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7633 and not a printer admin, then fail */
7635 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
7636 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
7637 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
7638 p
->server_info
->info3
->base
.domain
.string
,
7640 p
->server_info
->ptok
,
7641 lp_printer_admin(snum
))) {
7642 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7643 return WERR_ACCESS_DENIED
;
7646 status
= winreg_printer_setform1(p
->mem_ctx
,
7650 if (!W_ERROR_IS_OK(status
)) {
7655 * ChangeID must always be set if this is a printer
7657 if (Printer
->printer_type
== SPLHND_PRINTER
) {
7658 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
7662 status
= winreg_printer_update_changeid(p
->mem_ctx
,
7664 lp_const_servicename(snum
));
7665 if (!W_ERROR_IS_OK(status
)) {
7673 /****************************************************************************
7674 fill_print_processor1
7675 ****************************************************************************/
7677 static WERROR
fill_print_processor1(TALLOC_CTX
*mem_ctx
,
7678 struct spoolss_PrintProcessorInfo1
*r
,
7679 const char *print_processor_name
)
7681 r
->print_processor_name
= talloc_strdup(mem_ctx
, print_processor_name
);
7682 W_ERROR_HAVE_NO_MEMORY(r
->print_processor_name
);
7687 /****************************************************************************
7688 enumprintprocessors level 1.
7689 ****************************************************************************/
7691 static WERROR
enumprintprocessors_level_1(TALLOC_CTX
*mem_ctx
,
7692 union spoolss_PrintProcessorInfo
**info_p
,
7695 union spoolss_PrintProcessorInfo
*info
;
7698 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PrintProcessorInfo
, 1);
7699 W_ERROR_HAVE_NO_MEMORY(info
);
7703 result
= fill_print_processor1(info
, &info
[0].info1
, "winprint");
7704 if (!W_ERROR_IS_OK(result
)) {
7709 if (!W_ERROR_IS_OK(result
)) {
7720 /****************************************************************
7721 _spoolss_EnumPrintProcessors
7722 ****************************************************************/
7724 WERROR
_spoolss_EnumPrintProcessors(pipes_struct
*p
,
7725 struct spoolss_EnumPrintProcessors
*r
)
7729 /* that's an [in out] buffer */
7731 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7732 return WERR_INVALID_PARAM
;
7735 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
7738 * Enumerate the print processors ...
7740 * Just reply with "winprint", to keep NT happy
7741 * and I can use my nice printer checker.
7746 *r
->out
.info
= NULL
;
7748 switch (r
->in
.level
) {
7750 result
= enumprintprocessors_level_1(p
->mem_ctx
, r
->out
.info
,
7754 return WERR_UNKNOWN_LEVEL
;
7757 if (!W_ERROR_IS_OK(result
)) {
7761 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
7762 spoolss_EnumPrintProcessors
,
7763 *r
->out
.info
, r
->in
.level
,
7765 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
7766 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
7768 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7771 /****************************************************************************
7772 fill_printprocdatatype1
7773 ****************************************************************************/
7775 static WERROR
fill_printprocdatatype1(TALLOC_CTX
*mem_ctx
,
7776 struct spoolss_PrintProcDataTypesInfo1
*r
,
7777 const char *name_array
)
7779 r
->name_array
= talloc_strdup(mem_ctx
, name_array
);
7780 W_ERROR_HAVE_NO_MEMORY(r
->name_array
);
7785 /****************************************************************************
7786 enumprintprocdatatypes level 1.
7787 ****************************************************************************/
7789 static WERROR
enumprintprocdatatypes_level_1(TALLOC_CTX
*mem_ctx
,
7790 union spoolss_PrintProcDataTypesInfo
**info_p
,
7794 union spoolss_PrintProcDataTypesInfo
*info
;
7796 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PrintProcDataTypesInfo
, 1);
7797 W_ERROR_HAVE_NO_MEMORY(info
);
7801 result
= fill_printprocdatatype1(info
, &info
[0].info1
, "RAW");
7802 if (!W_ERROR_IS_OK(result
)) {
7807 if (!W_ERROR_IS_OK(result
)) {
7818 /****************************************************************
7819 _spoolss_EnumPrintProcDataTypes
7820 ****************************************************************/
7822 WERROR
_spoolss_EnumPrintProcDataTypes(pipes_struct
*p
,
7823 struct spoolss_EnumPrintProcDataTypes
*r
)
7827 /* that's an [in out] buffer */
7829 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7830 return WERR_INVALID_PARAM
;
7833 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
7837 *r
->out
.info
= NULL
;
7839 switch (r
->in
.level
) {
7841 result
= enumprintprocdatatypes_level_1(p
->mem_ctx
, r
->out
.info
,
7845 return WERR_UNKNOWN_LEVEL
;
7848 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
7849 spoolss_EnumPrintProcDataTypes
,
7850 *r
->out
.info
, r
->in
.level
,
7852 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
7853 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
7855 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7858 /****************************************************************************
7860 ****************************************************************************/
7862 static WERROR
fill_monitor_1(TALLOC_CTX
*mem_ctx
,
7863 struct spoolss_MonitorInfo1
*r
,
7864 const char *monitor_name
)
7866 r
->monitor_name
= talloc_strdup(mem_ctx
, monitor_name
);
7867 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
7872 /****************************************************************************
7874 ****************************************************************************/
7876 static WERROR
fill_monitor_2(TALLOC_CTX
*mem_ctx
,
7877 struct spoolss_MonitorInfo2
*r
,
7878 const char *monitor_name
,
7879 const char *environment
,
7880 const char *dll_name
)
7882 r
->monitor_name
= talloc_strdup(mem_ctx
, monitor_name
);
7883 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
7884 r
->environment
= talloc_strdup(mem_ctx
, environment
);
7885 W_ERROR_HAVE_NO_MEMORY(r
->environment
);
7886 r
->dll_name
= talloc_strdup(mem_ctx
, dll_name
);
7887 W_ERROR_HAVE_NO_MEMORY(r
->dll_name
);
7892 /****************************************************************************
7893 enumprintmonitors level 1.
7894 ****************************************************************************/
7896 static WERROR
enumprintmonitors_level_1(TALLOC_CTX
*mem_ctx
,
7897 union spoolss_MonitorInfo
**info_p
,
7900 union spoolss_MonitorInfo
*info
;
7901 WERROR result
= WERR_OK
;
7903 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_MonitorInfo
, 2);
7904 W_ERROR_HAVE_NO_MEMORY(info
);
7908 result
= fill_monitor_1(info
, &info
[0].info1
,
7910 if (!W_ERROR_IS_OK(result
)) {
7914 result
= fill_monitor_1(info
, &info
[1].info1
,
7916 if (!W_ERROR_IS_OK(result
)) {
7921 if (!W_ERROR_IS_OK(result
)) {
7932 /****************************************************************************
7933 enumprintmonitors level 2.
7934 ****************************************************************************/
7936 static WERROR
enumprintmonitors_level_2(TALLOC_CTX
*mem_ctx
,
7937 union spoolss_MonitorInfo
**info_p
,
7940 union spoolss_MonitorInfo
*info
;
7941 WERROR result
= WERR_OK
;
7943 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_MonitorInfo
, 2);
7944 W_ERROR_HAVE_NO_MEMORY(info
);
7948 result
= fill_monitor_2(info
, &info
[0].info2
,
7950 "Windows NT X86", /* FIXME */
7952 if (!W_ERROR_IS_OK(result
)) {
7956 result
= fill_monitor_2(info
, &info
[1].info2
,
7958 "Windows NT X86", /* FIXME */
7960 if (!W_ERROR_IS_OK(result
)) {
7965 if (!W_ERROR_IS_OK(result
)) {
7976 /****************************************************************
7977 _spoolss_EnumMonitors
7978 ****************************************************************/
7980 WERROR
_spoolss_EnumMonitors(pipes_struct
*p
,
7981 struct spoolss_EnumMonitors
*r
)
7985 /* that's an [in out] buffer */
7987 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7988 return WERR_INVALID_PARAM
;
7991 DEBUG(5,("_spoolss_EnumMonitors\n"));
7994 * Enumerate the print monitors ...
7996 * Just reply with "Local Port", to keep NT happy
7997 * and I can use my nice printer checker.
8002 *r
->out
.info
= NULL
;
8004 switch (r
->in
.level
) {
8006 result
= enumprintmonitors_level_1(p
->mem_ctx
, r
->out
.info
,
8010 result
= enumprintmonitors_level_2(p
->mem_ctx
, r
->out
.info
,
8014 return WERR_UNKNOWN_LEVEL
;
8017 if (!W_ERROR_IS_OK(result
)) {
8021 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8022 spoolss_EnumMonitors
,
8023 *r
->out
.info
, r
->in
.level
,
8025 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8026 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8028 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8031 /****************************************************************************
8032 ****************************************************************************/
8034 static WERROR
getjob_level_1(TALLOC_CTX
*mem_ctx
,
8035 const print_queue_struct
*queue
,
8036 int count
, int snum
,
8037 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
8039 struct spoolss_JobInfo1
*r
)
8044 for (i
=0; i
<count
; i
++) {
8045 if (queue
[i
].job
== (int)jobid
) {
8051 if (found
== false) {
8052 /* NT treats not found as bad param... yet another bad choice */
8053 return WERR_INVALID_PARAM
;
8056 return fill_job_info1(mem_ctx
,
8064 /****************************************************************************
8065 ****************************************************************************/
8067 static WERROR
getjob_level_2(TALLOC_CTX
*mem_ctx
,
8068 const print_queue_struct
*queue
,
8069 int count
, int snum
,
8070 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
8072 struct spoolss_JobInfo2
*r
)
8076 struct spoolss_DeviceMode
*devmode
;
8078 for (i
=0; i
<count
; i
++) {
8079 if (queue
[i
].job
== (int)jobid
) {
8085 if (found
== false) {
8086 /* NT treats not found as bad param... yet another bad
8088 return WERR_INVALID_PARAM
;
8092 * if the print job does not have a DEVMODE associated with it,
8093 * just use the one for the printer. A NULL devicemode is not
8094 * a failure condition
8097 devmode
= print_job_devmode(lp_const_servicename(snum
), jobid
);
8099 devmode
= construct_dev_mode(mem_ctx
, lp_const_servicename(snum
));
8100 W_ERROR_HAVE_NO_MEMORY(devmode
);
8103 return fill_job_info2(mem_ctx
,
8112 /****************************************************************
8114 ****************************************************************/
8116 WERROR
_spoolss_GetJob(pipes_struct
*p
,
8117 struct spoolss_GetJob
*r
)
8119 WERROR result
= WERR_OK
;
8120 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
8123 print_queue_struct
*queue
= NULL
;
8124 print_status_struct prt_status
;
8126 /* that's an [in out] buffer */
8128 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8129 return WERR_INVALID_PARAM
;
8132 DEBUG(5,("_spoolss_GetJob\n"));
8136 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8140 result
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
8141 if (!W_ERROR_IS_OK(result
)) {
8145 count
= print_queue_status(snum
, &queue
, &prt_status
);
8147 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8148 count
, prt_status
.status
, prt_status
.message
));
8150 switch (r
->in
.level
) {
8152 result
= getjob_level_1(p
->mem_ctx
,
8153 queue
, count
, snum
, ntprinter
,
8154 r
->in
.job_id
, &r
->out
.info
->info1
);
8157 result
= getjob_level_2(p
->mem_ctx
,
8158 queue
, count
, snum
, ntprinter
,
8159 r
->in
.job_id
, &r
->out
.info
->info2
);
8162 result
= WERR_UNKNOWN_LEVEL
;
8167 free_a_printer(&ntprinter
, 2);
8169 if (!W_ERROR_IS_OK(result
)) {
8170 TALLOC_FREE(r
->out
.info
);
8174 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_JobInfo
, r
->out
.info
,
8176 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
8178 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8181 /****************************************************************
8182 _spoolss_GetPrinterDataEx
8183 ****************************************************************/
8185 WERROR
_spoolss_GetPrinterDataEx(pipes_struct
*p
,
8186 struct spoolss_GetPrinterDataEx
*r
)
8189 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8190 const char *printer
;
8192 WERROR result
= WERR_OK
;
8194 enum winreg_Type val_type
;
8199 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8201 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8202 r
->in
.key_name
, r
->in
.value_name
));
8204 /* in case of problem, return some default values */
8207 *r
->out
.type
= REG_NONE
;
8210 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8211 OUR_HANDLE(r
->in
.handle
)));
8212 result
= WERR_BADFID
;
8216 /* Is the handle to a printer or to the server? */
8218 if (Printer
->printer_type
== SPLHND_SERVER
) {
8220 union spoolss_PrinterData data
;
8222 result
= getprinterdata_printer_server(p
->mem_ctx
,
8226 if (!W_ERROR_IS_OK(result
)) {
8230 result
= push_spoolss_PrinterData(p
->mem_ctx
, &blob
,
8231 *r
->out
.type
, &data
);
8232 if (!W_ERROR_IS_OK(result
)) {
8236 *r
->out
.needed
= blob
.length
;
8238 if (r
->in
.offered
>= *r
->out
.needed
) {
8239 memcpy(r
->out
.data
, blob
.data
, blob
.length
);
8242 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
8245 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8248 printer
= lp_const_servicename(snum
);
8250 /* check to see if the keyname is valid */
8251 if (!strlen(r
->in
.key_name
)) {
8252 return WERR_INVALID_PARAM
;
8255 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8256 if (strequal(r
->in
.key_name
, SPOOL_PRINTERDATA_KEY
) &&
8257 strequal(r
->in
.value_name
, "ChangeId")) {
8258 *r
->out
.type
= REG_DWORD
;
8260 if (r
->in
.offered
>= *r
->out
.needed
) {
8261 uint32_t changeid
= 0;
8263 result
= winreg_printer_get_changeid(p
->mem_ctx
,
8267 if (!W_ERROR_IS_OK(result
)) {
8271 SIVAL(r
->out
.data
, 0, changeid
);
8277 result
= winreg_get_printer_dataex(p
->mem_ctx
,
8285 if (!W_ERROR_IS_OK(result
)) {
8289 *r
->out
.needed
= val_size
;
8290 *r
->out
.type
= val_type
;
8292 if (r
->in
.offered
>= *r
->out
.needed
) {
8293 memcpy(r
->out
.data
, val_data
, val_size
);
8297 *r
->out
.type
= SPOOLSS_BUFFER_OK(*r
->out
.type
, REG_NONE
);
8298 r
->out
.data
= SPOOLSS_BUFFER_OK(r
->out
.data
, r
->out
.data
);
8300 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
8303 /****************************************************************
8304 _spoolss_SetPrinterDataEx
8305 ****************************************************************/
8307 WERROR
_spoolss_SetPrinterDataEx(pipes_struct
*p
,
8308 struct spoolss_SetPrinterDataEx
*r
)
8310 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
8312 WERROR result
= WERR_OK
;
8313 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8316 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8318 /* From MSDN documentation of SetPrinterDataEx: pass request to
8319 SetPrinterData if key is "PrinterDriverData" */
8322 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8323 OUR_HANDLE(r
->in
.handle
)));
8327 if (Printer
->printer_type
== SPLHND_SERVER
) {
8328 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8329 "Not implemented for server handles yet\n"));
8330 return WERR_INVALID_PARAM
;
8333 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8338 * Access check : NT returns "access denied" if you make a
8339 * SetPrinterData call without the necessary privildge.
8340 * we were originally returning OK if nothing changed
8341 * which made Win2k issue **a lot** of SetPrinterData
8342 * when connecting to a printer --jerry
8345 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8346 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8347 "change denied by handle access permissions\n"));
8348 return WERR_ACCESS_DENIED
;
8351 result
= winreg_get_printer(Printer
, p
->server_info
,
8352 Printer
->servername
,
8353 lp_servicename(snum
),
8355 if (!W_ERROR_IS_OK(result
)) {
8359 /* check for OID in valuename */
8361 oid_string
= strchr(r
->in
.value_name
, ',');
8367 /* save the registry data */
8369 result
= winreg_set_printer_dataex(p
->mem_ctx
,
8378 if (W_ERROR_IS_OK(result
)) {
8379 /* save the OID if one was specified */
8381 char *str
= talloc_asprintf(p
->mem_ctx
, "%s\\%s",
8382 r
->in
.key_name
, SPOOL_OID_KEY
);
8384 result
= WERR_NOMEM
;
8389 * I'm not checking the status here on purpose. Don't know
8390 * if this is right, but I'm returning the status from the
8391 * previous set_printer_dataex() call. I have no idea if
8392 * this is right. --jerry
8394 winreg_set_printer_dataex(p
->mem_ctx
,
8400 (uint8_t *) oid_string
,
8401 strlen(oid_string
) + 1);
8404 result
= winreg_printer_update_changeid(p
->mem_ctx
,
8406 lp_const_servicename(snum
));
8411 talloc_free(pinfo2
);
8415 /****************************************************************
8416 _spoolss_DeletePrinterDataEx
8417 ****************************************************************/
8419 WERROR
_spoolss_DeletePrinterDataEx(pipes_struct
*p
,
8420 struct spoolss_DeletePrinterDataEx
*r
)
8422 const char *printer
;
8424 WERROR status
= WERR_OK
;
8425 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8427 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8430 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8431 "Invalid handle (%s:%u:%u).\n",
8432 OUR_HANDLE(r
->in
.handle
)));
8436 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8437 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8438 "printer properties change denied by handle\n"));
8439 return WERR_ACCESS_DENIED
;
8442 if (!r
->in
.value_name
|| !r
->in
.key_name
) {
8446 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8449 printer
= lp_const_servicename(snum
);
8451 status
= winreg_delete_printer_dataex(p
->mem_ctx
,
8456 if (W_ERROR_IS_OK(status
)) {
8457 status
= winreg_printer_update_changeid(p
->mem_ctx
,
8465 /****************************************************************
8466 _spoolss_EnumPrinterKey
8467 ****************************************************************/
8469 WERROR
_spoolss_EnumPrinterKey(pipes_struct
*p
,
8470 struct spoolss_EnumPrinterKey
*r
)
8473 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8475 WERROR result
= WERR_BADFILE
;
8476 const char **array
= NULL
;
8479 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8482 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8483 OUR_HANDLE(r
->in
.handle
)));
8487 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8491 result
= winreg_enum_printer_key(p
->mem_ctx
,
8493 lp_const_servicename(snum
),
8497 if (!W_ERROR_IS_OK(result
)) {
8501 if (!push_reg_multi_sz(p
->mem_ctx
, &blob
, array
)) {
8502 result
= WERR_NOMEM
;
8506 *r
->out
._ndr_size
= r
->in
.offered
/ 2;
8507 *r
->out
.needed
= blob
.length
;
8509 if (r
->in
.offered
< *r
->out
.needed
) {
8510 result
= WERR_MORE_DATA
;
8513 r
->out
.key_buffer
->string_array
= array
;
8517 if (!W_ERROR_IS_OK(result
)) {
8519 if (!W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
8527 /****************************************************************
8528 _spoolss_DeletePrinterKey
8529 ****************************************************************/
8531 WERROR
_spoolss_DeletePrinterKey(pipes_struct
*p
,
8532 struct spoolss_DeletePrinterKey
*r
)
8534 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8537 const char *printer
;
8539 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8542 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8543 OUR_HANDLE(r
->in
.handle
)));
8547 /* if keyname == NULL, return error */
8548 if ( !r
->in
.key_name
)
8549 return WERR_INVALID_PARAM
;
8551 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8555 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8556 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8557 "printer properties change denied by handle\n"));
8558 return WERR_ACCESS_DENIED
;
8561 printer
= lp_const_servicename(snum
);
8563 /* delete the key and all subkeys */
8564 status
= winreg_delete_printer_key(p
->mem_ctx
,
8568 if (W_ERROR_IS_OK(status
)) {
8569 status
= winreg_printer_update_changeid(p
->mem_ctx
,
8577 /****************************************************************
8578 _spoolss_EnumPrinterDataEx
8579 ****************************************************************/
8581 WERROR
_spoolss_EnumPrinterDataEx(pipes_struct
*p
,
8582 struct spoolss_EnumPrinterDataEx
*r
)
8585 struct spoolss_PrinterEnumValues
*info
= NULL
;
8586 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8590 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8594 *r
->out
.info
= NULL
;
8597 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8598 OUR_HANDLE(r
->in
.handle
)));
8603 * first check for a keyname of NULL or "". Win2k seems to send
8604 * this a lot and we should send back WERR_INVALID_PARAM
8605 * no need to spend time looking up the printer in this case.
8609 if (!strlen(r
->in
.key_name
)) {
8610 result
= WERR_INVALID_PARAM
;
8614 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8618 /* now look for a match on the key name */
8619 result
= winreg_enum_printer_dataex(p
->mem_ctx
,
8621 lp_const_servicename(snum
),
8625 if (!W_ERROR_IS_OK(result
)) {
8629 #if 0 /* FIXME - gd */
8630 /* housekeeping information in the reply */
8632 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8633 * the hand marshalled container size is a multiple
8634 * of 4 bytes for RPC alignment.
8638 needed
+= 4-(needed
% 4);
8641 *r
->out
.count
= count
;
8642 *r
->out
.info
= info
;
8645 if (!W_ERROR_IS_OK(result
)) {
8649 *r
->out
.needed
= SPOOLSS_BUFFER_ARRAY(p
->mem_ctx
,
8650 spoolss_EnumPrinterDataEx
,
8653 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8654 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, *r
->out
.count
);
8656 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
8659 /****************************************************************************
8660 ****************************************************************************/
8662 static WERROR
getprintprocessordirectory_level_1(TALLOC_CTX
*mem_ctx
,
8663 const char *servername
,
8664 const char *environment
,
8665 struct spoolss_PrintProcessorDirectoryInfo1
*r
)
8670 werr
= compose_spoolss_server_path(mem_ctx
,
8673 SPOOLSS_PRTPROCS_PATH
,
8675 if (!W_ERROR_IS_OK(werr
)) {
8679 DEBUG(4,("print processor directory: [%s]\n", path
));
8681 r
->directory_name
= path
;
8686 /****************************************************************
8687 _spoolss_GetPrintProcessorDirectory
8688 ****************************************************************/
8690 WERROR
_spoolss_GetPrintProcessorDirectory(pipes_struct
*p
,
8691 struct spoolss_GetPrintProcessorDirectory
*r
)
8695 /* that's an [in out] buffer */
8697 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8698 return WERR_INVALID_PARAM
;
8701 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
8706 /* r->in.level is ignored */
8708 /* We always should reply with a local print processor directory so that
8709 * users are not forced to have a [prnproc$] share on the Samba spoolss
8710 * server - Guenther */
8712 result
= getprintprocessordirectory_level_1(p
->mem_ctx
,
8713 NULL
, /* r->in.server */
8715 &r
->out
.info
->info1
);
8716 if (!W_ERROR_IS_OK(result
)) {
8717 TALLOC_FREE(r
->out
.info
);
8721 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo
,
8722 r
->out
.info
, r
->in
.level
);
8723 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
8725 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8728 /*******************************************************************
8729 ********************************************************************/
8731 static bool push_monitorui_buf(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*buf
,
8732 const char *dllname
)
8734 enum ndr_err_code ndr_err
;
8735 struct spoolss_MonitorUi ui
;
8737 ui
.dll_name
= dllname
;
8739 ndr_err
= ndr_push_struct_blob(buf
, mem_ctx
, &ui
,
8740 (ndr_push_flags_fn_t
)ndr_push_spoolss_MonitorUi
);
8741 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
8742 NDR_PRINT_DEBUG(spoolss_MonitorUi
, &ui
);
8744 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
8747 /*******************************************************************
8748 Streams the monitor UI DLL name in UNICODE
8749 *******************************************************************/
8751 static WERROR
xcvtcp_monitorui(TALLOC_CTX
*mem_ctx
,
8752 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
8753 DATA_BLOB
*out
, uint32_t *needed
)
8755 const char *dllname
= "tcpmonui.dll";
8757 *needed
= (strlen(dllname
)+1) * 2;
8759 if (out
->length
< *needed
) {
8760 return WERR_INSUFFICIENT_BUFFER
;
8763 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
8770 /*******************************************************************
8771 ********************************************************************/
8773 static bool pull_port_data_1(TALLOC_CTX
*mem_ctx
,
8774 struct spoolss_PortData1
*port1
,
8775 const DATA_BLOB
*buf
)
8777 enum ndr_err_code ndr_err
;
8778 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, port1
,
8779 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData1
);
8780 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
8781 NDR_PRINT_DEBUG(spoolss_PortData1
, port1
);
8783 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
8786 /*******************************************************************
8787 ********************************************************************/
8789 static bool pull_port_data_2(TALLOC_CTX
*mem_ctx
,
8790 struct spoolss_PortData2
*port2
,
8791 const DATA_BLOB
*buf
)
8793 enum ndr_err_code ndr_err
;
8794 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, port2
,
8795 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData2
);
8796 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
8797 NDR_PRINT_DEBUG(spoolss_PortData2
, port2
);
8799 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
8802 /*******************************************************************
8803 Create a new TCP/IP port
8804 *******************************************************************/
8806 static WERROR
xcvtcp_addport(TALLOC_CTX
*mem_ctx
,
8807 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
8808 DATA_BLOB
*out
, uint32_t *needed
)
8810 struct spoolss_PortData1 port1
;
8811 struct spoolss_PortData2 port2
;
8812 char *device_uri
= NULL
;
8815 const char *portname
;
8816 const char *hostaddress
;
8818 uint32_t port_number
;
8821 /* peek for spoolss_PortData version */
8823 if (!in
|| (in
->length
< (128 + 4))) {
8824 return WERR_GENERAL_FAILURE
;
8827 version
= IVAL(in
->data
, 128);
8833 if (!pull_port_data_1(mem_ctx
, &port1
, in
)) {
8837 portname
= port1
.portname
;
8838 hostaddress
= port1
.hostaddress
;
8839 queue
= port1
.queue
;
8840 protocol
= port1
.protocol
;
8841 port_number
= port1
.port_number
;
8847 if (!pull_port_data_2(mem_ctx
, &port2
, in
)) {
8851 portname
= port2
.portname
;
8852 hostaddress
= port2
.hostaddress
;
8853 queue
= port2
.queue
;
8854 protocol
= port2
.protocol
;
8855 port_number
= port2
.port_number
;
8859 DEBUG(1,("xcvtcp_addport: "
8860 "unknown version of port_data: %d\n", version
));
8861 return WERR_UNKNOWN_PORT
;
8864 /* create the device URI and call the add_port_hook() */
8867 case PROTOCOL_RAWTCP_TYPE
:
8868 device_uri
= talloc_asprintf(mem_ctx
,
8869 "socket://%s:%d/", hostaddress
,
8873 case PROTOCOL_LPR_TYPE
:
8874 device_uri
= talloc_asprintf(mem_ctx
,
8875 "lpr://%s/%s", hostaddress
, queue
);
8879 return WERR_UNKNOWN_PORT
;
8886 return add_port_hook(mem_ctx
, token
, portname
, device_uri
);
8889 /*******************************************************************
8890 *******************************************************************/
8892 struct xcv_api_table xcvtcp_cmds
[] = {
8893 { "MonitorUI", xcvtcp_monitorui
},
8894 { "AddPort", xcvtcp_addport
},
8898 static WERROR
process_xcvtcp_command(TALLOC_CTX
*mem_ctx
,
8899 NT_USER_TOKEN
*token
, const char *command
,
8906 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
8908 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
8909 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
8910 return xcvtcp_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
8913 return WERR_BADFUNC
;
8916 /*******************************************************************
8917 *******************************************************************/
8918 #if 0 /* don't support management using the "Local Port" monitor */
8920 static WERROR
xcvlocal_monitorui(TALLOC_CTX
*mem_ctx
,
8921 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
8922 DATA_BLOB
*out
, uint32_t *needed
)
8924 const char *dllname
= "localui.dll";
8926 *needed
= (strlen(dllname
)+1) * 2;
8928 if (out
->length
< *needed
) {
8929 return WERR_INSUFFICIENT_BUFFER
;
8932 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
8939 /*******************************************************************
8940 *******************************************************************/
8942 struct xcv_api_table xcvlocal_cmds
[] = {
8943 { "MonitorUI", xcvlocal_monitorui
},
8947 struct xcv_api_table xcvlocal_cmds
[] = {
8954 /*******************************************************************
8955 *******************************************************************/
8957 static WERROR
process_xcvlocal_command(TALLOC_CTX
*mem_ctx
,
8958 NT_USER_TOKEN
*token
, const char *command
,
8959 DATA_BLOB
*inbuf
, DATA_BLOB
*outbuf
,
8964 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
8966 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
8967 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
8968 return xcvlocal_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
8970 return WERR_BADFUNC
;
8973 /****************************************************************
8975 ****************************************************************/
8977 WERROR
_spoolss_XcvData(pipes_struct
*p
,
8978 struct spoolss_XcvData
*r
)
8980 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8981 DATA_BLOB out_data
= data_blob_null
;
8985 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
8986 OUR_HANDLE(r
->in
.handle
)));
8990 /* Has to be a handle to the TCP/IP port monitor */
8992 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
8993 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
8997 /* requires administrative access to the server */
8999 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9000 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9001 return WERR_ACCESS_DENIED
;
9004 /* Allocate the outgoing buffer */
9006 if (r
->in
.out_data_size
) {
9007 out_data
= data_blob_talloc_zero(p
->mem_ctx
, r
->in
.out_data_size
);
9008 if (out_data
.data
== NULL
) {
9013 switch ( Printer
->printer_type
) {
9014 case SPLHND_PORTMON_TCP
:
9015 werror
= process_xcvtcp_command(p
->mem_ctx
,
9016 p
->server_info
->ptok
,
9017 r
->in
.function_name
,
9018 &r
->in
.in_data
, &out_data
,
9021 case SPLHND_PORTMON_LOCAL
:
9022 werror
= process_xcvlocal_command(p
->mem_ctx
,
9023 p
->server_info
->ptok
,
9024 r
->in
.function_name
,
9025 &r
->in
.in_data
, &out_data
,
9029 werror
= WERR_INVALID_PRINT_MONITOR
;
9032 if (!W_ERROR_IS_OK(werror
)) {
9036 *r
->out
.status_code
= 0;
9038 if (r
->out
.out_data
&& out_data
.data
&& r
->in
.out_data_size
&& out_data
.length
) {
9039 memcpy(r
->out
.out_data
, out_data
.data
,
9040 MIN(r
->in
.out_data_size
, out_data
.length
));
9046 /****************************************************************
9047 _spoolss_AddPrintProcessor
9048 ****************************************************************/
9050 WERROR
_spoolss_AddPrintProcessor(pipes_struct
*p
,
9051 struct spoolss_AddPrintProcessor
*r
)
9053 /* for now, just indicate success and ignore the add. We'll
9054 automatically set the winprint processor for printer
9055 entries later. Used to debug the LexMark Optra S 1855 PCL
9061 /****************************************************************
9063 ****************************************************************/
9065 WERROR
_spoolss_AddPort(pipes_struct
*p
,
9066 struct spoolss_AddPort
*r
)
9068 /* do what w2k3 does */
9070 return WERR_NOT_SUPPORTED
;
9073 /****************************************************************
9074 _spoolss_GetPrinterDriver
9075 ****************************************************************/
9077 WERROR
_spoolss_GetPrinterDriver(pipes_struct
*p
,
9078 struct spoolss_GetPrinterDriver
*r
)
9080 p
->rng_fault_state
= true;
9081 return WERR_NOT_SUPPORTED
;
9084 /****************************************************************
9085 _spoolss_ReadPrinter
9086 ****************************************************************/
9088 WERROR
_spoolss_ReadPrinter(pipes_struct
*p
,
9089 struct spoolss_ReadPrinter
*r
)
9091 p
->rng_fault_state
= true;
9092 return WERR_NOT_SUPPORTED
;
9095 /****************************************************************
9096 _spoolss_WaitForPrinterChange
9097 ****************************************************************/
9099 WERROR
_spoolss_WaitForPrinterChange(pipes_struct
*p
,
9100 struct spoolss_WaitForPrinterChange
*r
)
9102 p
->rng_fault_state
= true;
9103 return WERR_NOT_SUPPORTED
;
9106 /****************************************************************
9107 _spoolss_ConfigurePort
9108 ****************************************************************/
9110 WERROR
_spoolss_ConfigurePort(pipes_struct
*p
,
9111 struct spoolss_ConfigurePort
*r
)
9113 p
->rng_fault_state
= true;
9114 return WERR_NOT_SUPPORTED
;
9117 /****************************************************************
9119 ****************************************************************/
9121 WERROR
_spoolss_DeletePort(pipes_struct
*p
,
9122 struct spoolss_DeletePort
*r
)
9124 p
->rng_fault_state
= true;
9125 return WERR_NOT_SUPPORTED
;
9128 /****************************************************************
9129 _spoolss_CreatePrinterIC
9130 ****************************************************************/
9132 WERROR
_spoolss_CreatePrinterIC(pipes_struct
*p
,
9133 struct spoolss_CreatePrinterIC
*r
)
9135 p
->rng_fault_state
= true;
9136 return WERR_NOT_SUPPORTED
;
9139 /****************************************************************
9140 _spoolss_PlayGDIScriptOnPrinterIC
9141 ****************************************************************/
9143 WERROR
_spoolss_PlayGDIScriptOnPrinterIC(pipes_struct
*p
,
9144 struct spoolss_PlayGDIScriptOnPrinterIC
*r
)
9146 p
->rng_fault_state
= true;
9147 return WERR_NOT_SUPPORTED
;
9150 /****************************************************************
9151 _spoolss_DeletePrinterIC
9152 ****************************************************************/
9154 WERROR
_spoolss_DeletePrinterIC(pipes_struct
*p
,
9155 struct spoolss_DeletePrinterIC
*r
)
9157 p
->rng_fault_state
= true;
9158 return WERR_NOT_SUPPORTED
;
9161 /****************************************************************
9162 _spoolss_AddPrinterConnection
9163 ****************************************************************/
9165 WERROR
_spoolss_AddPrinterConnection(pipes_struct
*p
,
9166 struct spoolss_AddPrinterConnection
*r
)
9168 p
->rng_fault_state
= true;
9169 return WERR_NOT_SUPPORTED
;
9172 /****************************************************************
9173 _spoolss_DeletePrinterConnection
9174 ****************************************************************/
9176 WERROR
_spoolss_DeletePrinterConnection(pipes_struct
*p
,
9177 struct spoolss_DeletePrinterConnection
*r
)
9179 p
->rng_fault_state
= true;
9180 return WERR_NOT_SUPPORTED
;
9183 /****************************************************************
9184 _spoolss_PrinterMessageBox
9185 ****************************************************************/
9187 WERROR
_spoolss_PrinterMessageBox(pipes_struct
*p
,
9188 struct spoolss_PrinterMessageBox
*r
)
9190 p
->rng_fault_state
= true;
9191 return WERR_NOT_SUPPORTED
;
9194 /****************************************************************
9196 ****************************************************************/
9198 WERROR
_spoolss_AddMonitor(pipes_struct
*p
,
9199 struct spoolss_AddMonitor
*r
)
9201 p
->rng_fault_state
= true;
9202 return WERR_NOT_SUPPORTED
;
9205 /****************************************************************
9206 _spoolss_DeleteMonitor
9207 ****************************************************************/
9209 WERROR
_spoolss_DeleteMonitor(pipes_struct
*p
,
9210 struct spoolss_DeleteMonitor
*r
)
9212 p
->rng_fault_state
= true;
9213 return WERR_NOT_SUPPORTED
;
9216 /****************************************************************
9217 _spoolss_DeletePrintProcessor
9218 ****************************************************************/
9220 WERROR
_spoolss_DeletePrintProcessor(pipes_struct
*p
,
9221 struct spoolss_DeletePrintProcessor
*r
)
9223 p
->rng_fault_state
= true;
9224 return WERR_NOT_SUPPORTED
;
9227 /****************************************************************
9228 _spoolss_AddPrintProvidor
9229 ****************************************************************/
9231 WERROR
_spoolss_AddPrintProvidor(pipes_struct
*p
,
9232 struct spoolss_AddPrintProvidor
*r
)
9234 p
->rng_fault_state
= true;
9235 return WERR_NOT_SUPPORTED
;
9238 /****************************************************************
9239 _spoolss_DeletePrintProvidor
9240 ****************************************************************/
9242 WERROR
_spoolss_DeletePrintProvidor(pipes_struct
*p
,
9243 struct spoolss_DeletePrintProvidor
*r
)
9245 p
->rng_fault_state
= true;
9246 return WERR_NOT_SUPPORTED
;
9249 /****************************************************************
9250 _spoolss_FindFirstPrinterChangeNotification
9251 ****************************************************************/
9253 WERROR
_spoolss_FindFirstPrinterChangeNotification(pipes_struct
*p
,
9254 struct spoolss_FindFirstPrinterChangeNotification
*r
)
9256 p
->rng_fault_state
= true;
9257 return WERR_NOT_SUPPORTED
;
9260 /****************************************************************
9261 _spoolss_FindNextPrinterChangeNotification
9262 ****************************************************************/
9264 WERROR
_spoolss_FindNextPrinterChangeNotification(pipes_struct
*p
,
9265 struct spoolss_FindNextPrinterChangeNotification
*r
)
9267 p
->rng_fault_state
= true;
9268 return WERR_NOT_SUPPORTED
;
9271 /****************************************************************
9272 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9273 ****************************************************************/
9275 WERROR
_spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct
*p
,
9276 struct spoolss_RouterFindFirstPrinterChangeNotificationOld
*r
)
9278 p
->rng_fault_state
= true;
9279 return WERR_NOT_SUPPORTED
;
9282 /****************************************************************
9283 _spoolss_ReplyOpenPrinter
9284 ****************************************************************/
9286 WERROR
_spoolss_ReplyOpenPrinter(pipes_struct
*p
,
9287 struct spoolss_ReplyOpenPrinter
*r
)
9289 p
->rng_fault_state
= true;
9290 return WERR_NOT_SUPPORTED
;
9293 /****************************************************************
9294 _spoolss_RouterReplyPrinter
9295 ****************************************************************/
9297 WERROR
_spoolss_RouterReplyPrinter(pipes_struct
*p
,
9298 struct spoolss_RouterReplyPrinter
*r
)
9300 p
->rng_fault_state
= true;
9301 return WERR_NOT_SUPPORTED
;
9304 /****************************************************************
9305 _spoolss_ReplyClosePrinter
9306 ****************************************************************/
9308 WERROR
_spoolss_ReplyClosePrinter(pipes_struct
*p
,
9309 struct spoolss_ReplyClosePrinter
*r
)
9311 p
->rng_fault_state
= true;
9312 return WERR_NOT_SUPPORTED
;
9315 /****************************************************************
9317 ****************************************************************/
9319 WERROR
_spoolss_AddPortEx(pipes_struct
*p
,
9320 struct spoolss_AddPortEx
*r
)
9322 p
->rng_fault_state
= true;
9323 return WERR_NOT_SUPPORTED
;
9326 /****************************************************************
9327 _spoolss_RouterFindFirstPrinterChangeNotification
9328 ****************************************************************/
9330 WERROR
_spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct
*p
,
9331 struct spoolss_RouterFindFirstPrinterChangeNotification
*r
)
9333 p
->rng_fault_state
= true;
9334 return WERR_NOT_SUPPORTED
;
9337 /****************************************************************
9338 _spoolss_SpoolerInit
9339 ****************************************************************/
9341 WERROR
_spoolss_SpoolerInit(pipes_struct
*p
,
9342 struct spoolss_SpoolerInit
*r
)
9344 p
->rng_fault_state
= true;
9345 return WERR_NOT_SUPPORTED
;
9348 /****************************************************************
9349 _spoolss_ResetPrinterEx
9350 ****************************************************************/
9352 WERROR
_spoolss_ResetPrinterEx(pipes_struct
*p
,
9353 struct spoolss_ResetPrinterEx
*r
)
9355 p
->rng_fault_state
= true;
9356 return WERR_NOT_SUPPORTED
;
9359 /****************************************************************
9360 _spoolss_RouterReplyPrinterEx
9361 ****************************************************************/
9363 WERROR
_spoolss_RouterReplyPrinterEx(pipes_struct
*p
,
9364 struct spoolss_RouterReplyPrinterEx
*r
)
9366 p
->rng_fault_state
= true;
9367 return WERR_NOT_SUPPORTED
;
9370 /****************************************************************
9372 ****************************************************************/
9374 WERROR
_spoolss_44(pipes_struct
*p
,
9375 struct spoolss_44
*r
)
9377 p
->rng_fault_state
= true;
9378 return WERR_NOT_SUPPORTED
;
9381 /****************************************************************
9383 ****************************************************************/
9385 WERROR
_spoolss_47(pipes_struct
*p
,
9386 struct spoolss_47
*r
)
9388 p
->rng_fault_state
= true;
9389 return WERR_NOT_SUPPORTED
;
9392 /****************************************************************
9394 ****************************************************************/
9396 WERROR
_spoolss_4a(pipes_struct
*p
,
9397 struct spoolss_4a
*r
)
9399 p
->rng_fault_state
= true;
9400 return WERR_NOT_SUPPORTED
;
9403 /****************************************************************
9405 ****************************************************************/
9407 WERROR
_spoolss_4b(pipes_struct
*p
,
9408 struct spoolss_4b
*r
)
9410 p
->rng_fault_state
= true;
9411 return WERR_NOT_SUPPORTED
;
9414 /****************************************************************
9416 ****************************************************************/
9418 WERROR
_spoolss_4c(pipes_struct
*p
,
9419 struct spoolss_4c
*r
)
9421 p
->rng_fault_state
= true;
9422 return WERR_NOT_SUPPORTED
;
9425 /****************************************************************
9427 ****************************************************************/
9429 WERROR
_spoolss_53(pipes_struct
*p
,
9430 struct spoolss_53
*r
)
9432 p
->rng_fault_state
= true;
9433 return WERR_NOT_SUPPORTED
;
9436 /****************************************************************
9438 ****************************************************************/
9440 WERROR
_spoolss_55(pipes_struct
*p
,
9441 struct spoolss_55
*r
)
9443 p
->rng_fault_state
= true;
9444 return WERR_NOT_SUPPORTED
;
9447 /****************************************************************
9449 ****************************************************************/
9451 WERROR
_spoolss_56(pipes_struct
*p
,
9452 struct spoolss_56
*r
)
9454 p
->rng_fault_state
= true;
9455 return WERR_NOT_SUPPORTED
;
9458 /****************************************************************
9460 ****************************************************************/
9462 WERROR
_spoolss_57(pipes_struct
*p
,
9463 struct spoolss_57
*r
)
9465 p
->rng_fault_state
= true;
9466 return WERR_NOT_SUPPORTED
;
9469 /****************************************************************
9471 ****************************************************************/
9473 WERROR
_spoolss_5a(pipes_struct
*p
,
9474 struct spoolss_5a
*r
)
9476 p
->rng_fault_state
= true;
9477 return WERR_NOT_SUPPORTED
;
9480 /****************************************************************
9482 ****************************************************************/
9484 WERROR
_spoolss_5b(pipes_struct
*p
,
9485 struct spoolss_5b
*r
)
9487 p
->rng_fault_state
= true;
9488 return WERR_NOT_SUPPORTED
;
9491 /****************************************************************
9493 ****************************************************************/
9495 WERROR
_spoolss_5c(pipes_struct
*p
,
9496 struct spoolss_5c
*r
)
9498 p
->rng_fault_state
= true;
9499 return WERR_NOT_SUPPORTED
;
9502 /****************************************************************
9504 ****************************************************************/
9506 WERROR
_spoolss_5d(pipes_struct
*p
,
9507 struct spoolss_5d
*r
)
9509 p
->rng_fault_state
= true;
9510 return WERR_NOT_SUPPORTED
;
9513 /****************************************************************
9515 ****************************************************************/
9517 WERROR
_spoolss_5e(pipes_struct
*p
,
9518 struct spoolss_5e
*r
)
9520 p
->rng_fault_state
= true;
9521 return WERR_NOT_SUPPORTED
;
9524 /****************************************************************
9526 ****************************************************************/
9528 WERROR
_spoolss_5f(pipes_struct
*p
,
9529 struct spoolss_5f
*r
)
9531 p
->rng_fault_state
= true;
9532 return WERR_NOT_SUPPORTED
;
9535 /****************************************************************
9537 ****************************************************************/
9539 WERROR
_spoolss_60(pipes_struct
*p
,
9540 struct spoolss_60
*r
)
9542 p
->rng_fault_state
= true;
9543 return WERR_NOT_SUPPORTED
;
9546 /****************************************************************
9548 ****************************************************************/
9550 WERROR
_spoolss_61(pipes_struct
*p
,
9551 struct spoolss_61
*r
)
9553 p
->rng_fault_state
= true;
9554 return WERR_NOT_SUPPORTED
;
9557 /****************************************************************
9559 ****************************************************************/
9561 WERROR
_spoolss_62(pipes_struct
*p
,
9562 struct spoolss_62
*r
)
9564 p
->rng_fault_state
= true;
9565 return WERR_NOT_SUPPORTED
;
9568 /****************************************************************
9570 ****************************************************************/
9572 WERROR
_spoolss_63(pipes_struct
*p
,
9573 struct spoolss_63
*r
)
9575 p
->rng_fault_state
= true;
9576 return WERR_NOT_SUPPORTED
;
9579 /****************************************************************
9581 ****************************************************************/
9583 WERROR
_spoolss_64(pipes_struct
*p
,
9584 struct spoolss_64
*r
)
9586 p
->rng_fault_state
= true;
9587 return WERR_NOT_SUPPORTED
;
9590 /****************************************************************
9592 ****************************************************************/
9594 WERROR
_spoolss_65(pipes_struct
*p
,
9595 struct spoolss_65
*r
)
9597 p
->rng_fault_state
= true;
9598 return WERR_NOT_SUPPORTED
;
9601 /****************************************************************
9602 _spoolss_GetCorePrinterDrivers
9603 ****************************************************************/
9605 WERROR
_spoolss_GetCorePrinterDrivers(pipes_struct
*p
,
9606 struct spoolss_GetCorePrinterDrivers
*r
)
9608 p
->rng_fault_state
= true;
9609 return WERR_NOT_SUPPORTED
;
9612 /****************************************************************
9614 ****************************************************************/
9616 WERROR
_spoolss_67(pipes_struct
*p
,
9617 struct spoolss_67
*r
)
9619 p
->rng_fault_state
= true;
9620 return WERR_NOT_SUPPORTED
;
9623 /****************************************************************
9624 _spoolss_GetPrinterDriverPackagePath
9625 ****************************************************************/
9627 WERROR
_spoolss_GetPrinterDriverPackagePath(pipes_struct
*p
,
9628 struct spoolss_GetPrinterDriverPackagePath
*r
)
9630 p
->rng_fault_state
= true;
9631 return WERR_NOT_SUPPORTED
;
9634 /****************************************************************
9636 ****************************************************************/
9638 WERROR
_spoolss_69(pipes_struct
*p
,
9639 struct spoolss_69
*r
)
9641 p
->rng_fault_state
= true;
9642 return WERR_NOT_SUPPORTED
;
9645 /****************************************************************
9647 ****************************************************************/
9649 WERROR
_spoolss_6a(pipes_struct
*p
,
9650 struct spoolss_6a
*r
)
9652 p
->rng_fault_state
= true;
9653 return WERR_NOT_SUPPORTED
;
9656 /****************************************************************
9658 ****************************************************************/
9660 WERROR
_spoolss_6b(pipes_struct
*p
,
9661 struct spoolss_6b
*r
)
9663 p
->rng_fault_state
= true;
9664 return WERR_NOT_SUPPORTED
;
9667 /****************************************************************
9669 ****************************************************************/
9671 WERROR
_spoolss_6c(pipes_struct
*p
,
9672 struct spoolss_6c
*r
)
9674 p
->rng_fault_state
= true;
9675 return WERR_NOT_SUPPORTED
;
9678 /****************************************************************
9680 ****************************************************************/
9682 WERROR
_spoolss_6d(pipes_struct
*p
,
9683 struct spoolss_6d
*r
)
9685 p
->rng_fault_state
= true;
9686 return WERR_NOT_SUPPORTED
;