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.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern userdom_struct current_user_info
;
33 #define DBGC_CLASS DBGC_RPC_SRV
35 #ifndef MAX_OPEN_PRINTER_EXS
36 #define MAX_OPEN_PRINTER_EXS 50
39 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
40 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
43 const char *long_archi
;
44 const char *short_archi
;
48 static Printer_entry
*printers_list
;
50 typedef struct _counter_printer_0
{
51 struct _counter_printer_0
*next
;
52 struct _counter_printer_0
*prev
;
58 static counter_printer_0
*counter_list
;
60 static struct rpc_pipe_client
*notify_cli_pipe
; /* print notify back-channel pipe handle*/
61 static uint32 smb_connections
=0;
64 /* in printing/nt_printing.c */
66 extern struct standard_mapping printer_std_mapping
, printserver_std_mapping
;
68 /* API table for Xcv Monitor functions */
70 struct xcv_api_table
{
72 WERROR(*fn
) (TALLOC_CTX
*mem_ctx
, NT_USER_TOKEN
*token
, DATA_BLOB
*in
, DATA_BLOB
*out
, uint32_t *needed
);
75 /********************************************************************
76 * Canonicalize servername.
77 ********************************************************************/
79 static const char *canon_servername(const char *servername
)
81 const char *pservername
= servername
;
82 while (*pservername
== '\\') {
88 /* translate between internal status numbers and NT status numbers */
89 static int nt_printj_status(int v
)
95 return JOB_STATUS_PAUSED
;
97 return JOB_STATUS_SPOOLING
;
99 return JOB_STATUS_PRINTING
;
101 return JOB_STATUS_ERROR
;
103 return JOB_STATUS_DELETING
;
105 return JOB_STATUS_OFFLINE
;
107 return JOB_STATUS_PAPEROUT
;
109 return JOB_STATUS_PRINTED
;
111 return JOB_STATUS_DELETED
;
113 return JOB_STATUS_BLOCKED
;
114 case LPQ_USER_INTERVENTION
:
115 return JOB_STATUS_USER_INTERVENTION
;
120 static int nt_printq_status(int v
)
124 return PRINTER_STATUS_PAUSED
;
133 /***************************************************************************
134 Disconnect from the client
135 ****************************************************************************/
137 static void srv_spoolss_replycloseprinter(int snum
, POLICY_HND
*handle
)
143 * Tell the specific printing tdb we no longer want messages for this printer
144 * by deregistering our PID.
147 if (!print_notify_deregister_pid(snum
))
148 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum
) ));
150 /* weird if the test succeds !!! */
151 if (smb_connections
==0) {
152 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
156 status
= rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe
, talloc_tos(),
159 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
160 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
161 win_errstr(result
)));
163 /* if it's the last connection, deconnect the IPC$ share */
164 if (smb_connections
==1) {
166 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe
) );
167 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
169 messaging_deregister(smbd_messaging_context(),
170 MSG_PRINTER_NOTIFY2
, NULL
);
172 /* Tell the connections db we're no longer interested in
173 * printer notify messages. */
175 register_message_flags( False
, FLAG_MSG_PRINT_NOTIFY
);
181 /****************************************************************************
182 Functions to free a printer entry datastruct.
183 ****************************************************************************/
185 static int printer_entry_destructor(Printer_entry
*Printer
)
187 if (Printer
->notify
.client_connected
==True
) {
190 if ( Printer
->printer_type
== SPLHND_SERVER
) {
192 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
193 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
194 snum
= print_queue_snum(Printer
->sharename
);
196 srv_spoolss_replycloseprinter(snum
,
197 &Printer
->notify
.client_hnd
);
201 Printer
->notify
.flags
=0;
202 Printer
->notify
.options
=0;
203 Printer
->notify
.localmachine
[0]='\0';
204 Printer
->notify
.printerlocal
=0;
205 TALLOC_FREE(Printer
->notify
.option
);
206 Printer
->notify
.client_connected
=False
;
208 free_nt_devicemode( &Printer
->nt_devmode
);
209 free_a_printer( &Printer
->printer_info
, 2 );
211 /* Remove from the internal list. */
212 DLIST_REMOVE(printers_list
, Printer
);
216 /****************************************************************************
217 find printer index by handle
218 ****************************************************************************/
220 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
222 Printer_entry
*find_printer
= NULL
;
224 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
225 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
232 /****************************************************************************
233 Close printer index by handle.
234 ****************************************************************************/
236 static bool close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
238 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
241 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
245 close_policy_hnd(p
, hnd
);
250 /****************************************************************************
251 Delete a printer given a handle.
252 ****************************************************************************/
254 WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
256 char *cmd
= lp_deleteprinter_cmd();
257 char *command
= NULL
;
259 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
260 bool is_print_op
= False
;
262 /* can't fail if we don't try */
267 command
= talloc_asprintf(ctx
,
274 is_print_op
= user_has_privileges( token
, &se_printop
);
276 DEBUG(10,("Running [%s]\n", command
));
278 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
283 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
284 /* Tell everyone we updated smb.conf. */
285 message_send_all(smbd_messaging_context(),
286 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
292 /********** END SePrintOperatorPrivlege BLOCK **********/
294 DEBUGADD(10,("returned [%d]\n", ret
));
296 TALLOC_FREE(command
);
299 return WERR_BADFID
; /* What to return here? */
301 /* go ahead and re-read the services immediately */
302 reload_services( False
);
304 if ( lp_servicenumber( sharename
) < 0 )
305 return WERR_ACCESS_DENIED
;
310 /****************************************************************************
311 Delete a printer given a handle.
312 ****************************************************************************/
314 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
316 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
319 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
324 * It turns out that Windows allows delete printer on a handle
325 * opened by an admin user, then used on a pipe handle created
326 * by an anonymous user..... but they're working on security.... riiight !
330 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
331 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
332 return WERR_ACCESS_DENIED
;
335 /* this does not need a become root since the access check has been
336 done on the handle already */
338 if (del_a_printer( Printer
->sharename
) != 0) {
339 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
343 return delete_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
344 Printer
->sharename
);
347 /****************************************************************************
348 Return the snum of a printer corresponding to an handle.
349 ****************************************************************************/
351 static bool get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
,
352 struct share_params
**params
)
354 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
357 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
361 switch (Printer
->printer_type
) {
363 DEBUG(4,("short name:%s\n", Printer
->sharename
));
364 *number
= print_queue_snum(Printer
->sharename
);
365 return (*number
!= -1);
373 /****************************************************************************
374 Set printer handle type.
375 Check if it's \\server or \\server\printer
376 ****************************************************************************/
378 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
380 DEBUG(3,("Setting printer type=%s\n", handlename
));
382 if ( strlen(handlename
) < 3 ) {
383 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
387 /* it's a print server */
388 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
389 DEBUGADD(4,("Printer is a print server\n"));
390 Printer
->printer_type
= SPLHND_SERVER
;
392 /* it's a printer (set_printer_hnd_name() will handle port monitors */
394 DEBUGADD(4,("Printer is a printer\n"));
395 Printer
->printer_type
= SPLHND_PRINTER
;
401 /****************************************************************************
402 Set printer handle name.. Accept names like \\server, \\server\printer,
403 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
404 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
405 XcvDataPort() interface.
406 ****************************************************************************/
408 static bool set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
411 int n_services
=lp_numservices();
412 char *aprinter
, *printername
;
413 const char *servername
;
416 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
419 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
, (unsigned long)strlen(handlename
)));
421 aprinter
= handlename
;
422 if ( *handlename
== '\\' ) {
423 servername
= canon_servername(handlename
);
424 if ( (aprinter
= strchr_m( servername
, '\\' )) != NULL
) {
432 /* save the servername to fill in replies on this handle */
434 if ( !is_myname_or_ipaddr( servername
) )
437 fstrcpy( Printer
->servername
, servername
);
439 if ( Printer
->printer_type
== SPLHND_SERVER
)
442 if ( Printer
->printer_type
!= SPLHND_PRINTER
)
445 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
447 /* check for the Port Monitor Interface */
449 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
450 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
451 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
454 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
455 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
456 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
460 /* Search all sharenames first as this is easier than pulling
461 the printer_info_2 off of disk. Don't use find_service() since
462 that calls out to map_username() */
464 /* do another loop to look for printernames */
466 for (snum
=0; !found
&& snum
<n_services
; snum
++) {
468 /* no point going on if this is not a printer */
470 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
)) )
473 fstrcpy(sname
, lp_servicename(snum
));
474 if ( strequal( aprinter
, sname
) ) {
479 /* no point looking up the printer object if
480 we aren't allowing printername != sharename */
482 if ( lp_force_printername(snum
) )
485 fstrcpy(sname
, lp_servicename(snum
));
489 /* This call doesn't fill in the location or comment from
490 * a CUPS server for efficiency with large numbers of printers.
494 result
= get_a_printer_search( NULL
, &printer
, 2, sname
);
495 if ( !W_ERROR_IS_OK(result
) ) {
496 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
497 sname
, win_errstr(result
)));
501 /* printername is always returned as \\server\printername */
502 if ( !(printername
= strchr_m(&printer
->info_2
->printername
[2], '\\')) ) {
503 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
504 printer
->info_2
->printername
));
505 free_a_printer( &printer
, 2);
511 if ( strequal(printername
, aprinter
) ) {
512 free_a_printer( &printer
, 2);
517 DEBUGADD(10, ("printername: %s\n", printername
));
519 free_a_printer( &printer
, 2);
522 free_a_printer( &printer
, 2);
525 DEBUGADD(4,("Printer not found\n"));
529 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
531 fstrcpy(Printer
->sharename
, sname
);
536 /****************************************************************************
537 Find first available printer slot. creates a printer handle for you.
538 ****************************************************************************/
540 static bool open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
, uint32 access_granted
)
542 Printer_entry
*new_printer
;
544 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
546 new_printer
= TALLOC_ZERO_P(NULL
, Printer_entry
);
547 if (new_printer
== NULL
) {
550 talloc_set_destructor(new_printer
, printer_entry_destructor
);
552 if (!create_policy_hnd(p
, hnd
, new_printer
)) {
553 TALLOC_FREE(new_printer
);
557 /* Add to the internal list. */
558 DLIST_ADD(printers_list
, new_printer
);
560 new_printer
->notify
.option
=NULL
;
562 if (!set_printer_hnd_printertype(new_printer
, name
)) {
563 close_printer_handle(p
, hnd
);
567 if (!set_printer_hnd_name(new_printer
, name
)) {
568 close_printer_handle(p
, hnd
);
572 new_printer
->access_granted
= access_granted
;
574 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
579 /***************************************************************************
580 check to see if the client motify handle is monitoring the notification
581 given by (notify_type, notify_field).
582 **************************************************************************/
584 static bool is_monitoring_event_flags(uint32 flags
, uint16 notify_type
,
590 static bool is_monitoring_event(Printer_entry
*p
, uint16 notify_type
,
593 struct spoolss_NotifyOption
*option
= p
->notify
.option
;
597 * Flags should always be zero when the change notify
598 * is registered by the client's spooler. A user Win32 app
599 * might use the flags though instead of the NOTIFY_OPTION_INFO
608 return is_monitoring_event_flags(
609 p
->notify
.flags
, notify_type
, notify_field
);
611 for (i
= 0; i
< option
->count
; i
++) {
613 /* Check match for notify_type */
615 if (option
->types
[i
].type
!= notify_type
)
618 /* Check match for field */
620 for (j
= 0; j
< option
->types
[i
].count
; j
++) {
621 if (option
->types
[i
].fields
[j
] == notify_field
) {
627 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
628 p
->servername
, p
->sharename
, notify_type
, notify_field
));
633 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
634 _data->data.integer[0] = _integer; \
635 _data->data.integer[1] = 0;
638 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
639 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
640 if (!_data->data.string.string) {\
641 _data->data.string.size = 0; \
643 _data->data.string.size = strlen_m_term(_p) * 2;
645 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
646 _data->data.devmode.devmode = _devmode;
648 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
649 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
650 if (!_data->data.sd.sd) { \
651 _data->data.sd.sd_size = 0; \
653 _data->data.sd.sd_size = _size;
655 static void init_systemtime_buffer(TALLOC_CTX
*mem_ctx
,
660 struct spoolss_Time st
;
664 if (!init_systemtime(&st
, t
)) {
668 p
= talloc_array(mem_ctx
, char, len
);
674 * Systemtime must be linearized as a set of UINT16's.
675 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
678 SSVAL(p
, 0, st
.year
);
679 SSVAL(p
, 2, st
.month
);
680 SSVAL(p
, 4, st
.day_of_week
);
682 SSVAL(p
, 8, st
.hour
);
683 SSVAL(p
, 10, st
.minute
);
684 SSVAL(p
, 12, st
.second
);
685 SSVAL(p
, 14, st
.millisecond
);
691 /* Convert a notification message to a struct spoolss_Notify */
693 static void notify_one_value(struct spoolss_notify_msg
*msg
,
694 struct spoolss_Notify
*data
,
697 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, msg
->notify
.value
[0]);
700 static void notify_string(struct spoolss_notify_msg
*msg
,
701 struct spoolss_Notify
*data
,
704 /* The length of the message includes the trailing \0 */
706 data
->data
.string
.size
= msg
->len
* 2;
707 data
->data
.string
.string
= talloc_strdup(mem_ctx
, msg
->notify
.data
);
708 if (!data
->data
.string
.string
) {
709 data
->data
.string
.size
= 0;
714 static void notify_system_time(struct spoolss_notify_msg
*msg
,
715 struct spoolss_Notify
*data
,
718 data
->data
.string
.string
= NULL
;
719 data
->data
.string
.size
= 0;
721 if (msg
->len
!= sizeof(time_t)) {
722 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
727 init_systemtime_buffer(mem_ctx
, gmtime((time_t *)msg
->notify
.data
),
728 &data
->data
.string
.string
,
729 &data
->data
.string
.size
);
732 struct notify2_message_table
{
734 void (*fn
)(struct spoolss_notify_msg
*msg
,
735 struct spoolss_Notify
*data
, TALLOC_CTX
*mem_ctx
);
738 static struct notify2_message_table printer_notify_table
[] = {
739 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string
},
740 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string
},
741 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string
},
742 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string
},
743 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string
},
744 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string
},
745 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string
},
746 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL
},
747 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string
},
748 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string
},
749 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL
},
750 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string
},
751 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
752 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value
},
753 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value
},
754 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL
},
755 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL
},
756 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL
},
757 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value
},
760 static struct notify2_message_table job_notify_table
[] = {
761 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL
},
762 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL
},
763 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL
},
764 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string
},
765 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL
},
766 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL
},
767 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL
},
768 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL
},
769 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL
},
770 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL
},
771 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value
},
772 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL
},
773 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
774 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string
},
775 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL
},
776 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL
},
777 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time
},
778 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL
},
779 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL
},
780 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL
},
781 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value
},
782 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL
},
783 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value
},
784 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL
},
788 /***********************************************************************
789 Allocate talloc context for container object
790 **********************************************************************/
792 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
797 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
802 /***********************************************************************
803 release all allocated memory and zero out structure
804 **********************************************************************/
806 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
812 talloc_destroy(ctr
->ctx
);
819 /***********************************************************************
820 **********************************************************************/
822 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
830 /***********************************************************************
831 **********************************************************************/
833 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
835 if ( !ctr
|| !ctr
->msg_groups
)
838 if ( idx
>= ctr
->num_groups
)
841 return &ctr
->msg_groups
[idx
];
845 /***********************************************************************
846 How many groups of change messages do we have ?
847 **********************************************************************/
849 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
854 return ctr
->num_groups
;
857 /***********************************************************************
858 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
859 **********************************************************************/
861 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
863 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
864 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
865 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
871 /* loop over all groups looking for a matching printer name */
873 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
874 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
878 /* add a new group? */
880 if ( i
== ctr
->num_groups
) {
883 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
884 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
887 ctr
->msg_groups
= groups
;
889 /* clear the new entry and set the printer name */
891 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
892 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
895 /* add the change messages; 'i' is the correct index now regardless */
897 msg_grp
= &ctr
->msg_groups
[i
];
901 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
902 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
905 msg_grp
->msgs
= msg_list
;
907 new_slot
= msg_grp
->num_msgs
-1;
908 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
910 /* need to allocate own copy of data */
913 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
914 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
916 return ctr
->num_groups
;
919 /***********************************************************************
920 Send a change notication message on all handles which have a call
922 **********************************************************************/
924 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
927 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
928 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
929 SPOOLSS_NOTIFY_MSG
*messages
;
930 int sending_msg_count
;
933 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
937 messages
= msg_group
->msgs
;
940 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
944 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
946 /* loop over all printers */
948 for (p
= printers_list
; p
; p
= p
->next
) {
949 struct spoolss_Notify
*notifies
;
954 /* Is there notification on this handle? */
956 if ( !p
->notify
.client_connected
)
959 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
961 /* For this printer? Print servers always receive
964 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
965 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
968 DEBUG(10,("Our printer\n"));
970 /* allocate the max entries possible */
972 notifies
= TALLOC_ZERO_ARRAY(mem_ctx
, struct spoolss_Notify
, msg_group
->num_msgs
);
977 /* build the array of change notifications */
979 sending_msg_count
= 0;
981 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
982 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
984 /* Are we monitoring this event? */
986 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
992 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
993 msg
->type
, msg
->field
, p
->sharename
));
996 * if the is a printer notification handle and not a job notification
997 * type, then set the id to 0. Other wise just use what was specified
1000 * When registering change notification on a print server handle
1001 * we always need to send back the id (snum) matching the printer
1002 * for which the change took place. For change notify registered
1003 * on a printer handle, this does not matter and the id should be 0.
1008 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1014 /* Convert unix jobid to smb jobid */
1016 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1017 id
= sysjob_to_jobid(msg
->id
);
1020 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1025 construct_info_data( ¬ifies
[count
], msg
->type
, msg
->field
, id
);
1028 case PRINTER_NOTIFY_TYPE
:
1029 if ( printer_notify_table
[msg
->field
].fn
)
1030 printer_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1033 case JOB_NOTIFY_TYPE
:
1034 if ( job_notify_table
[msg
->field
].fn
)
1035 job_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1039 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1046 if ( sending_msg_count
) {
1049 union spoolss_ReplyPrinterInfo info
;
1050 struct spoolss_NotifyInfo info0
;
1051 uint32_t reply_result
;
1053 info0
.version
= 0x2;
1054 info0
.flags
= count
? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED
;
1055 info0
.count
= count
;
1056 info0
.notifies
= notifies
;
1058 info
.info0
= &info0
;
1060 status
= rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe
, mem_ctx
,
1061 &p
->notify
.client_hnd
,
1062 p
->notify
.change
, /* color */
1065 0, /* reply_type, must be 0 */
1068 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(werr
)) {
1069 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1070 notify_cli_pipe
->srv_name_slash
,
1073 switch (reply_result
) {
1076 case PRINTER_NOTIFY_INFO_DISCARDED
:
1077 case PRINTER_NOTIFY_INFO_DISCARDNOTED
:
1078 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH
:
1087 DEBUG(8,("send_notify2_changes: Exit...\n"));
1091 /***********************************************************************
1092 **********************************************************************/
1094 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1097 uint32 tv_sec
, tv_usec
;
1100 /* Unpack message */
1102 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "f",
1105 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "ddddddd",
1107 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1110 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "dd",
1111 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1113 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "B",
1114 &msg
->len
, &msg
->notify
.data
);
1116 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1117 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1119 tv
->tv_sec
= tv_sec
;
1120 tv
->tv_usec
= tv_usec
;
1123 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1124 msg
->notify
.value
[1]));
1126 dump_data(3, (uint8
*)msg
->notify
.data
, msg
->len
);
1131 /********************************************************************
1132 Receive a notify2 message list
1133 ********************************************************************/
1135 static void receive_notify2_message_list(struct messaging_context
*msg
,
1138 struct server_id server_id
,
1141 size_t msg_count
, i
;
1142 char *buf
= (char *)data
->data
;
1145 SPOOLSS_NOTIFY_MSG notify
;
1146 SPOOLSS_NOTIFY_MSG_CTR messages
;
1149 if (data
->length
< 4) {
1150 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1154 msg_count
= IVAL(buf
, 0);
1157 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1159 if (msg_count
== 0) {
1160 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1164 /* initialize the container */
1166 ZERO_STRUCT( messages
);
1167 notify_msg_ctr_init( &messages
);
1170 * build message groups for each printer identified
1171 * in a change_notify msg. Remember that a PCN message
1172 * includes the handle returned for the srv_spoolss_replyopenprinter()
1173 * call. Therefore messages are grouped according to printer handle.
1176 for ( i
=0; i
<msg_count
; i
++ ) {
1177 struct timeval msg_tv
;
1179 if (msg_ptr
+ 4 - buf
> data
->length
) {
1180 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1184 msg_len
= IVAL(msg_ptr
,0);
1187 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1188 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1192 /* unpack messages */
1194 ZERO_STRUCT( notify
);
1195 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1198 /* add to correct list in container */
1200 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1202 /* free memory that might have been allocated by notify2_unpack_msg() */
1204 if ( notify
.len
!= 0 )
1205 SAFE_FREE( notify
.notify
.data
);
1208 /* process each group of messages */
1210 num_groups
= notify_msg_ctr_numgroups( &messages
);
1211 for ( i
=0; i
<num_groups
; i
++ )
1212 send_notify2_changes( &messages
, i
);
1217 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32
)msg_count
));
1219 notify_msg_ctr_destroy( &messages
);
1224 /********************************************************************
1225 Send a message to ourself about new driver being installed
1226 so we can upgrade the information for each printer bound to this
1228 ********************************************************************/
1230 static bool srv_spoolss_drv_upgrade_printer(char* drivername
)
1232 int len
= strlen(drivername
);
1237 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1240 messaging_send_buf(smbd_messaging_context(), procid_self(),
1241 MSG_PRINTER_DRVUPGRADE
,
1242 (uint8
*)drivername
, len
+1);
1247 /**********************************************************************
1248 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1249 over all printers, upgrading ones as necessary
1250 **********************************************************************/
1252 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1255 struct server_id server_id
,
1260 int n_services
= lp_numservices();
1263 len
= MIN(data
->length
,sizeof(drivername
)-1);
1264 strncpy(drivername
, (const char *)data
->data
, len
);
1266 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1268 /* Iterate the printer list */
1270 for (snum
=0; snum
<n_services
; snum
++)
1272 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1275 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1277 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1278 if (!W_ERROR_IS_OK(result
))
1281 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1283 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1285 /* all we care about currently is the change_id */
1287 result
= mod_a_printer(printer
, 2);
1288 if (!W_ERROR_IS_OK(result
)) {
1289 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1290 win_errstr(result
)));
1294 free_a_printer(&printer
, 2);
1301 /********************************************************************
1302 Update the cache for all printq's with a registered client
1304 ********************************************************************/
1306 void update_monitored_printq_cache( void )
1308 Printer_entry
*printer
= printers_list
;
1311 /* loop through all printers and update the cache where
1312 client_connected == True */
1315 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1316 && printer
->notify
.client_connected
)
1318 snum
= print_queue_snum(printer
->sharename
);
1319 print_queue_status( snum
, NULL
, NULL
);
1322 printer
= printer
->next
;
1327 /********************************************************************
1328 Send a message to ourself about new driver being installed
1329 so we can upgrade the information for each printer bound to this
1331 ********************************************************************/
1333 static bool srv_spoolss_reset_printerdata(char* drivername
)
1335 int len
= strlen(drivername
);
1340 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1343 messaging_send_buf(smbd_messaging_context(), procid_self(),
1344 MSG_PRINTERDATA_INIT_RESET
,
1345 (uint8
*)drivername
, len
+1);
1350 /**********************************************************************
1351 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1352 over all printers, resetting printer data as neessary
1353 **********************************************************************/
1355 void reset_all_printerdata(struct messaging_context
*msg
,
1358 struct server_id server_id
,
1363 int n_services
= lp_numservices();
1366 len
= MIN( data
->length
, sizeof(drivername
)-1 );
1367 strncpy( drivername
, (const char *)data
->data
, len
);
1369 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1371 /* Iterate the printer list */
1373 for ( snum
=0; snum
<n_services
; snum
++ )
1375 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1378 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1380 result
= get_a_printer( NULL
, &printer
, 2, lp_const_servicename(snum
) );
1381 if ( !W_ERROR_IS_OK(result
) )
1385 * if the printer is bound to the driver,
1386 * then reset to the new driver initdata
1389 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1391 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1393 if ( !set_driver_init(printer
, 2) ) {
1394 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1395 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1398 result
= mod_a_printer( printer
, 2 );
1399 if ( !W_ERROR_IS_OK(result
) ) {
1400 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1401 get_dos_error_msg(result
)));
1405 free_a_printer( &printer
, 2 );
1414 /****************************************************************
1415 _spoolss_OpenPrinter
1416 ****************************************************************/
1418 WERROR
_spoolss_OpenPrinter(pipes_struct
*p
,
1419 struct spoolss_OpenPrinter
*r
)
1421 struct spoolss_OpenPrinterEx e
;
1424 ZERO_STRUCT(e
.in
.userlevel
);
1426 e
.in
.printername
= r
->in
.printername
;
1427 e
.in
.datatype
= r
->in
.datatype
;
1428 e
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
1429 e
.in
.access_mask
= r
->in
.access_mask
;
1432 e
.out
.handle
= r
->out
.handle
;
1434 werr
= _spoolss_OpenPrinterEx(p
, &e
);
1436 if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
1437 /* OpenPrinterEx returns this for a bad
1438 * printer name. We must return WERR_INVALID_PRINTER_NAME
1441 werr
= WERR_INVALID_PRINTER_NAME
;
1447 /********************************************************************
1448 FIXME: temporary convert_devicemode_new function
1449 ********************************************************************/
1451 static bool convert_devicemode_new(const char *printername
,
1452 struct spoolss_DeviceMode
*devmode
,
1453 NT_DEVICEMODE
**pp_nt_devmode
)
1455 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1458 * Ensure nt_devmode is a valid pointer
1459 * as we will be overwriting it.
1462 if (nt_devmode
== NULL
) {
1463 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1464 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1468 rpcstr_push(nt_devmode
->devicename
, devmode
->devicename
, 31, 0);
1469 rpcstr_push(nt_devmode
->formname
, devmode
->formname
, 31, 0);
1471 nt_devmode
->specversion
= devmode
->specversion
;
1472 nt_devmode
->driverversion
= devmode
->driverversion
;
1473 nt_devmode
->size
= devmode
->size
;
1474 nt_devmode
->fields
= devmode
->fields
;
1475 nt_devmode
->orientation
= devmode
->orientation
;
1476 nt_devmode
->papersize
= devmode
->papersize
;
1477 nt_devmode
->paperlength
= devmode
->paperlength
;
1478 nt_devmode
->paperwidth
= devmode
->paperwidth
;
1479 nt_devmode
->scale
= devmode
->scale
;
1480 nt_devmode
->copies
= devmode
->copies
;
1481 nt_devmode
->defaultsource
= devmode
->defaultsource
;
1482 nt_devmode
->printquality
= devmode
->printquality
;
1483 nt_devmode
->color
= devmode
->color
;
1484 nt_devmode
->duplex
= devmode
->duplex
;
1485 nt_devmode
->yresolution
= devmode
->yresolution
;
1486 nt_devmode
->ttoption
= devmode
->ttoption
;
1487 nt_devmode
->collate
= devmode
->collate
;
1489 nt_devmode
->logpixels
= devmode
->logpixels
;
1490 nt_devmode
->bitsperpel
= devmode
->bitsperpel
;
1491 nt_devmode
->pelswidth
= devmode
->pelswidth
;
1492 nt_devmode
->pelsheight
= devmode
->pelsheight
;
1493 nt_devmode
->displayflags
= devmode
->displayflags
;
1494 nt_devmode
->displayfrequency
= devmode
->displayfrequency
;
1495 nt_devmode
->icmmethod
= devmode
->icmmethod
;
1496 nt_devmode
->icmintent
= devmode
->icmintent
;
1497 nt_devmode
->mediatype
= devmode
->mediatype
;
1498 nt_devmode
->dithertype
= devmode
->dithertype
;
1499 nt_devmode
->reserved1
= devmode
->reserved1
;
1500 nt_devmode
->reserved2
= devmode
->reserved2
;
1501 nt_devmode
->panningwidth
= devmode
->panningwidth
;
1502 nt_devmode
->panningheight
= devmode
->panningheight
;
1505 * Only change private and driverextra if the incoming devmode
1506 * has a new one. JRA.
1509 if ((devmode
->__driverextra_length
!= 0) && (devmode
->driverextra_data
.data
!= NULL
)) {
1510 SAFE_FREE(nt_devmode
->nt_dev_private
);
1511 nt_devmode
->driverextra
= devmode
->__driverextra_length
;
1512 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1514 memcpy(nt_devmode
->nt_dev_private
, devmode
->driverextra_data
.data
, nt_devmode
->driverextra
);
1517 *pp_nt_devmode
= nt_devmode
;
1522 /****************************************************************
1523 _spoolss_OpenPrinterEx
1524 ****************************************************************/
1526 WERROR
_spoolss_OpenPrinterEx(pipes_struct
*p
,
1527 struct spoolss_OpenPrinterEx
*r
)
1529 POLICY_HND
*handle
= r
->out
.handle
;
1530 char *name
= CONST_DISCARD(char *, r
->in
.printername
);
1532 Printer_entry
*Printer
=NULL
;
1535 return WERR_INVALID_PARAM
;
1538 /* some sanity check because you can open a printer or a print server */
1539 /* aka: \\server\printer or \\server */
1541 DEBUGADD(3,("checking name: %s\n",name
));
1543 if (!open_printer_hnd(p
, handle
, name
, 0)) {
1544 ZERO_STRUCTP(r
->out
.handle
);
1545 return WERR_INVALID_PARAM
;
1548 Printer
=find_printer_index_by_hnd(p
, handle
);
1550 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1551 "handle we created for printer %s\n", name
));
1552 close_printer_handle(p
,handle
);
1553 ZERO_STRUCTP(r
->out
.handle
);
1554 return WERR_INVALID_PARAM
;
1558 * First case: the user is opening the print server:
1560 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1561 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1563 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1564 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1565 * or if the user is listed in the smb.conf printer admin parameter.
1567 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1568 * client view printer folder, but does not show the MSAPW.
1570 * Note: this test needs code to check access rights here too. Jeremy
1571 * could you look at this?
1573 * Second case: the user is opening a printer:
1574 * NT doesn't let us connect to a printer if the connecting user
1575 * doesn't have print permission.
1577 * Third case: user is opening a Port Monitor
1578 * access checks same as opening a handle to the print server.
1581 switch (Printer
->printer_type
)
1584 case SPLHND_PORTMON_TCP
:
1585 case SPLHND_PORTMON_LOCAL
:
1586 /* Printserver handles use global struct... */
1590 /* Map standard access rights to object specific access rights */
1592 se_map_standard(&r
->in
.access_mask
,
1593 &printserver_std_mapping
);
1595 /* Deny any object specific bits that don't apply to print
1596 servers (i.e printer and job specific bits) */
1598 r
->in
.access_mask
&= SPECIFIC_RIGHTS_MASK
;
1600 if (r
->in
.access_mask
&
1601 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1602 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1603 close_printer_handle(p
, handle
);
1604 ZERO_STRUCTP(r
->out
.handle
);
1605 return WERR_ACCESS_DENIED
;
1608 /* Allow admin access */
1610 if ( r
->in
.access_mask
& SERVER_ACCESS_ADMINISTER
)
1612 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1614 if (!lp_ms_add_printer_wizard()) {
1615 close_printer_handle(p
, handle
);
1616 ZERO_STRUCTP(r
->out
.handle
);
1617 return WERR_ACCESS_DENIED
;
1620 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1621 and not a printer admin, then fail */
1623 if ((p
->server_info
->utok
.uid
!= 0) &&
1624 !user_has_privileges(p
->server_info
->ptok
,
1626 !token_contains_name_in_list(
1627 uidtoname(p
->server_info
->utok
.uid
),
1629 p
->server_info
->ptok
,
1630 lp_printer_admin(snum
))) {
1631 close_printer_handle(p
, handle
);
1632 ZERO_STRUCTP(r
->out
.handle
);
1633 return WERR_ACCESS_DENIED
;
1636 r
->in
.access_mask
= SERVER_ACCESS_ADMINISTER
;
1640 r
->in
.access_mask
= SERVER_ACCESS_ENUMERATE
;
1643 DEBUG(4,("Setting print server access = %s\n", (r
->in
.access_mask
== SERVER_ACCESS_ADMINISTER
)
1644 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1646 /* We fall through to return WERR_OK */
1649 case SPLHND_PRINTER
:
1650 /* NT doesn't let us connect to a printer if the connecting user
1651 doesn't have print permission. */
1653 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
1654 close_printer_handle(p
, handle
);
1655 ZERO_STRUCTP(r
->out
.handle
);
1659 se_map_standard(&r
->in
.access_mask
, &printer_std_mapping
);
1661 /* map an empty access mask to the minimum access mask */
1662 if (r
->in
.access_mask
== 0x0)
1663 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1666 * If we are not serving the printer driver for this printer,
1667 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1668 * will keep NT clients happy --jerry
1671 if (lp_use_client_driver(snum
)
1672 && (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
))
1674 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1677 /* check smb.conf parameters and the the sec_desc */
1679 if ( !check_access(get_client_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1680 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1681 ZERO_STRUCTP(r
->out
.handle
);
1682 return WERR_ACCESS_DENIED
;
1685 if (!user_ok_token(uidtoname(p
->server_info
->utok
.uid
), NULL
,
1686 p
->server_info
->ptok
, snum
) ||
1687 !print_access_check(p
->server_info
, snum
,
1688 r
->in
.access_mask
)) {
1689 DEBUG(3, ("access DENIED for printer open\n"));
1690 close_printer_handle(p
, handle
);
1691 ZERO_STRUCTP(r
->out
.handle
);
1692 return WERR_ACCESS_DENIED
;
1695 if ((r
->in
.access_mask
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1696 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1697 close_printer_handle(p
, handle
);
1698 ZERO_STRUCTP(r
->out
.handle
);
1699 return WERR_ACCESS_DENIED
;
1702 if (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
)
1703 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1705 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1707 DEBUG(4,("Setting printer access = %s\n", (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1708 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1713 /* sanity check to prevent programmer error */
1714 ZERO_STRUCTP(r
->out
.handle
);
1718 Printer
->access_granted
= r
->in
.access_mask
;
1721 * If the client sent a devmode in the OpenPrinter() call, then
1722 * save it here in case we get a job submission on this handle
1725 if ( (Printer
->printer_type
!= SPLHND_SERVER
)
1726 && r
->in
.devmode_ctr
.devmode
)
1728 convert_devicemode_new(Printer
->sharename
,
1729 r
->in
.devmode_ctr
.devmode
,
1730 &Printer
->nt_devmode
);
1733 #if 0 /* JERRY -- I'm doubtful this is really effective */
1734 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1735 optimization in Windows 2000 clients --jerry */
1737 if ( (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1738 && (RA_WIN2K
== get_remote_arch()) )
1740 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1741 sys_usleep( 500000 );
1748 /****************************************************************************
1749 ****************************************************************************/
1751 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2
*r
,
1752 NT_PRINTER_INFO_LEVEL_2
*d
)
1754 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1760 d
->attributes
= r
->attributes
;
1761 d
->priority
= r
->priority
;
1762 d
->default_priority
= r
->defaultpriority
;
1763 d
->starttime
= r
->starttime
;
1764 d
->untiltime
= r
->untiltime
;
1765 d
->status
= r
->status
;
1766 d
->cjobs
= r
->cjobs
;
1768 fstrcpy(d
->servername
, r
->servername
);
1769 fstrcpy(d
->printername
, r
->printername
);
1770 fstrcpy(d
->sharename
, r
->sharename
);
1771 fstrcpy(d
->portname
, r
->portname
);
1772 fstrcpy(d
->drivername
, r
->drivername
);
1773 slprintf(d
->comment
, sizeof(d
->comment
)-1, "%s", r
->comment
);
1774 fstrcpy(d
->location
, r
->location
);
1775 fstrcpy(d
->sepfile
, r
->sepfile
);
1776 fstrcpy(d
->printprocessor
, r
->printprocessor
);
1777 fstrcpy(d
->datatype
, r
->datatype
);
1778 fstrcpy(d
->parameters
, r
->parameters
);
1783 /****************************************************************************
1784 ****************************************************************************/
1786 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr
*info_ctr
,
1787 NT_PRINTER_INFO_LEVEL
*printer
)
1791 switch (info_ctr
->level
) {
1793 /* allocate memory if needed. Messy because
1794 convert_printer_info is used to update an existing
1795 printer or build a new one */
1797 if (!printer
->info_2
) {
1798 printer
->info_2
= TALLOC_ZERO_P(printer
, NT_PRINTER_INFO_LEVEL_2
);
1799 if (!printer
->info_2
) {
1800 DEBUG(0,("convert_printer_info_new: "
1801 "talloc() failed!\n"));
1806 ret
= printer_info2_to_nt_printer_info2(info_ctr
->info
.info2
,
1808 printer
->info_2
->setuptime
= time(NULL
);
1815 /*******************************************************************
1816 ********************************************************************/
1818 static bool string_array_to_fstring_array(const char **sarray
, fstring
**farray
)
1827 *farray
= SMB_MALLOC_ARRAY(fstring
, 1);
1832 for (i
=0; sarray
[i
] != NULL
; i
++) {
1833 *farray
= SMB_REALLOC_ARRAY(*farray
, fstring
, i
+2);
1837 fstrcpy((*farray
)[i
], sarray
[i
]);
1840 fstrcpy((*farray
)[i
], "");
1845 /*******************************************************************
1846 ********************************************************************/
1848 static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3
*r
,
1849 NT_PRINTER_DRIVER_INFO_LEVEL_3
**p
)
1851 NT_PRINTER_DRIVER_INFO_LEVEL_3
*d
;
1853 DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
1856 *p
= SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3
);
1865 d
->cversion
= r
->version
;
1867 fstrcpy(d
->name
, r
->driver_name
);
1868 fstrcpy(d
->environment
, r
->architecture
);
1869 fstrcpy(d
->driverpath
, r
->driver_path
);
1870 fstrcpy(d
->datafile
, r
->data_file
);
1871 fstrcpy(d
->configfile
, r
->config_file
);
1872 fstrcpy(d
->helpfile
, r
->help_file
);
1873 fstrcpy(d
->monitorname
, r
->monitor_name
);
1874 fstrcpy(d
->defaultdatatype
, r
->default_datatype
);
1876 DEBUGADD(8,( "version: %d\n", d
->cversion
));
1877 DEBUGADD(8,( "name: %s\n", d
->name
));
1878 DEBUGADD(8,( "environment: %s\n", d
->environment
));
1879 DEBUGADD(8,( "driverpath: %s\n", d
->driverpath
));
1880 DEBUGADD(8,( "datafile: %s\n", d
->datafile
));
1881 DEBUGADD(8,( "configfile: %s\n", d
->configfile
));
1882 DEBUGADD(8,( "helpfile: %s\n", d
->helpfile
));
1883 DEBUGADD(8,( "monitorname: %s\n", d
->monitorname
));
1884 DEBUGADD(8,( "defaultdatatype: %s\n", d
->defaultdatatype
));
1886 if (r
->dependent_files
) {
1887 if (!string_array_to_fstring_array(r
->dependent_files
->string
,
1888 &d
->dependentfiles
)) {
1897 /*******************************************************************
1898 ********************************************************************/
1900 static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6
*r
,
1901 NT_PRINTER_DRIVER_INFO_LEVEL_6
**p
)
1903 NT_PRINTER_DRIVER_INFO_LEVEL_6
*d
;
1905 DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
1908 *p
= SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6
);
1917 d
->version
= r
->version
;
1919 fstrcpy(d
->name
, r
->driver_name
);
1920 fstrcpy(d
->environment
, r
->architecture
);
1921 fstrcpy(d
->driverpath
, r
->driver_path
);
1922 fstrcpy(d
->datafile
, r
->data_file
);
1923 fstrcpy(d
->configfile
, r
->config_file
);
1924 fstrcpy(d
->helpfile
, r
->help_file
);
1925 fstrcpy(d
->monitorname
, r
->monitor_name
);
1926 fstrcpy(d
->defaultdatatype
, r
->default_datatype
);
1928 DEBUGADD(8,( "version: %d\n", d
->version
));
1929 DEBUGADD(8,( "name: %s\n", d
->name
));
1930 DEBUGADD(8,( "environment: %s\n", d
->environment
));
1931 DEBUGADD(8,( "driverpath: %s\n", d
->driverpath
));
1932 DEBUGADD(8,( "datafile: %s\n", d
->datafile
));
1933 DEBUGADD(8,( "configfile: %s\n", d
->configfile
));
1934 DEBUGADD(8,( "helpfile: %s\n", d
->helpfile
));
1935 DEBUGADD(8,( "monitorname: %s\n", d
->monitorname
));
1936 DEBUGADD(8,( "defaultdatatype: %s\n", d
->defaultdatatype
));
1938 if (r
->dependent_files
) {
1939 if (!string_array_to_fstring_array(r
->dependent_files
->string
,
1940 &d
->dependentfiles
)) {
1945 if (r
->previous_names
) {
1946 if (!string_array_to_fstring_array(r
->previous_names
->string
,
1947 &d
->previousnames
)) {
1959 /********************************************************************
1960 ********************************************************************/
1962 static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr
*r
,
1963 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
,
1968 printer
->info_3
= NULL
;
1969 if (!driver_info3_to_nt_driver_info3(r
->info
.info3
, &printer
->info_3
)) {
1974 printer
->info_6
= NULL
;
1975 if (!driver_info6_to_nt_driver_info6(r
->info
.info6
, &printer
->info_6
)) {
1986 bool convert_devicemode(const char *printername
, const DEVICEMODE
*devmode
,
1987 NT_DEVICEMODE
**pp_nt_devmode
)
1989 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1992 * Ensure nt_devmode is a valid pointer
1993 * as we will be overwriting it.
1996 if (nt_devmode
== NULL
) {
1997 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1998 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
2002 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
2003 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
2005 nt_devmode
->specversion
=devmode
->specversion
;
2006 nt_devmode
->driverversion
=devmode
->driverversion
;
2007 nt_devmode
->size
=devmode
->size
;
2008 nt_devmode
->fields
=devmode
->fields
;
2009 nt_devmode
->orientation
=devmode
->orientation
;
2010 nt_devmode
->papersize
=devmode
->papersize
;
2011 nt_devmode
->paperlength
=devmode
->paperlength
;
2012 nt_devmode
->paperwidth
=devmode
->paperwidth
;
2013 nt_devmode
->scale
=devmode
->scale
;
2014 nt_devmode
->copies
=devmode
->copies
;
2015 nt_devmode
->defaultsource
=devmode
->defaultsource
;
2016 nt_devmode
->printquality
=devmode
->printquality
;
2017 nt_devmode
->color
=devmode
->color
;
2018 nt_devmode
->duplex
=devmode
->duplex
;
2019 nt_devmode
->yresolution
=devmode
->yresolution
;
2020 nt_devmode
->ttoption
=devmode
->ttoption
;
2021 nt_devmode
->collate
=devmode
->collate
;
2023 nt_devmode
->logpixels
=devmode
->logpixels
;
2024 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
2025 nt_devmode
->pelswidth
=devmode
->pelswidth
;
2026 nt_devmode
->pelsheight
=devmode
->pelsheight
;
2027 nt_devmode
->displayflags
=devmode
->displayflags
;
2028 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
2029 nt_devmode
->icmmethod
=devmode
->icmmethod
;
2030 nt_devmode
->icmintent
=devmode
->icmintent
;
2031 nt_devmode
->mediatype
=devmode
->mediatype
;
2032 nt_devmode
->dithertype
=devmode
->dithertype
;
2033 nt_devmode
->reserved1
=devmode
->reserved1
;
2034 nt_devmode
->reserved2
=devmode
->reserved2
;
2035 nt_devmode
->panningwidth
=devmode
->panningwidth
;
2036 nt_devmode
->panningheight
=devmode
->panningheight
;
2039 * Only change private and driverextra if the incoming devmode
2040 * has a new one. JRA.
2043 if ((devmode
->driverextra
!= 0) && (devmode
->dev_private
!= NULL
)) {
2044 SAFE_FREE(nt_devmode
->nt_dev_private
);
2045 nt_devmode
->driverextra
=devmode
->driverextra
;
2046 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
2048 memcpy(nt_devmode
->nt_dev_private
, devmode
->dev_private
, nt_devmode
->driverextra
);
2051 *pp_nt_devmode
= nt_devmode
;
2056 /********************************************************************
2057 * _spoolss_enddocprinter_internal.
2058 ********************************************************************/
2060 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
2062 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2066 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
2070 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
2073 Printer
->document_started
=False
;
2074 print_job_end(snum
, Printer
->jobid
,NORMAL_CLOSE
);
2075 /* error codes unhandled so far ... */
2080 /****************************************************************
2081 _spoolss_ClosePrinter
2082 ****************************************************************/
2084 WERROR
_spoolss_ClosePrinter(pipes_struct
*p
,
2085 struct spoolss_ClosePrinter
*r
)
2087 POLICY_HND
*handle
= r
->in
.handle
;
2089 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2091 if (Printer
&& Printer
->document_started
)
2092 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
2094 if (!close_printer_handle(p
, handle
))
2097 /* clear the returned printer handle. Observed behavior
2098 from Win2k server. Don't think this really matters.
2099 Previous code just copied the value of the closed
2102 ZERO_STRUCTP(r
->out
.handle
);
2107 /****************************************************************
2108 _spoolss_DeletePrinter
2109 ****************************************************************/
2111 WERROR
_spoolss_DeletePrinter(pipes_struct
*p
,
2112 struct spoolss_DeletePrinter
*r
)
2114 POLICY_HND
*handle
= r
->in
.handle
;
2115 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2118 if (Printer
&& Printer
->document_started
)
2119 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
2121 result
= delete_printer_handle(p
, handle
);
2123 update_c_setprinter(False
);
2128 /*******************************************************************
2129 * static function to lookup the version id corresponding to an
2130 * long architecture string
2131 ******************************************************************/
2133 static int get_version_id (char * arch
)
2136 struct table_node archi_table
[]= {
2138 {"Windows 4.0", "WIN40", 0 },
2139 {"Windows NT x86", "W32X86", 2 },
2140 {"Windows NT R4000", "W32MIPS", 2 },
2141 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
2142 {"Windows NT PowerPC", "W32PPC", 2 },
2143 {"Windows IA64", "IA64", 3 },
2144 {"Windows x64", "x64", 3 },
2148 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
2150 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
2151 return (archi_table
[i
].version
);
2157 /****************************************************************
2158 _spoolss_DeletePrinterDriver
2159 ****************************************************************/
2161 WERROR
_spoolss_DeletePrinterDriver(pipes_struct
*p
,
2162 struct spoolss_DeletePrinterDriver
*r
)
2166 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2167 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2170 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2171 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2173 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2174 and not a printer admin, then fail */
2176 if ( (p
->server_info
->utok
.uid
!= 0)
2177 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
2178 && !token_contains_name_in_list(
2179 uidtoname(p
->server_info
->utok
.uid
), NULL
,
2180 NULL
, p
->server_info
->ptok
,
2181 lp_printer_admin(-1)) )
2183 return WERR_ACCESS_DENIED
;
2186 driver
= CONST_DISCARD(char *, r
->in
.driver
);
2187 arch
= CONST_DISCARD(char *, r
->in
.architecture
);
2189 /* check that we have a valid driver name first */
2191 if ((version
=get_version_id(arch
)) == -1)
2192 return WERR_INVALID_ENVIRONMENT
;
2195 ZERO_STRUCT(info_win2k
);
2197 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
2199 /* try for Win2k driver if "Windows NT x86" */
2201 if ( version
== 2 ) {
2203 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2204 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2208 /* otherwise it was a failure */
2210 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2216 if (printer_driver_in_use(info
.info_3
)) {
2217 status
= WERR_PRINTER_DRIVER_IN_USE
;
2223 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2225 /* if we get to here, we now have 2 driver info structures to remove */
2226 /* remove the Win2k driver first*/
2228 status_win2k
= delete_printer_driver(
2229 p
, info_win2k
.info_3
, 3, False
);
2230 free_a_printer_driver( info_win2k
, 3 );
2232 /* this should not have failed---if it did, report to client */
2233 if ( !W_ERROR_IS_OK(status_win2k
) )
2235 status
= status_win2k
;
2241 status
= delete_printer_driver(p
, info
.info_3
, version
, False
);
2243 /* if at least one of the deletes succeeded return OK */
2245 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2249 free_a_printer_driver( info
, 3 );
2254 /****************************************************************
2255 _spoolss_DeletePrinterDriverEx
2256 ****************************************************************/
2258 WERROR
_spoolss_DeletePrinterDriverEx(pipes_struct
*p
,
2259 struct spoolss_DeletePrinterDriverEx
*r
)
2263 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2264 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2266 uint32_t flags
= r
->in
.delete_flags
;
2269 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2270 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2272 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2273 and not a printer admin, then fail */
2275 if ( (p
->server_info
->utok
.uid
!= 0)
2276 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
2277 && !token_contains_name_in_list(
2278 uidtoname(p
->server_info
->utok
.uid
), NULL
, NULL
,
2279 p
->server_info
->ptok
, lp_printer_admin(-1)) )
2281 return WERR_ACCESS_DENIED
;
2284 driver
= CONST_DISCARD(char *, r
->in
.driver
);
2285 arch
= CONST_DISCARD(char *, r
->in
.architecture
);
2287 /* check that we have a valid driver name first */
2288 if ((version
=get_version_id(arch
)) == -1) {
2289 /* this is what NT returns */
2290 return WERR_INVALID_ENVIRONMENT
;
2293 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
2294 version
= r
->in
.version
;
2297 ZERO_STRUCT(info_win2k
);
2299 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
2301 if ( !W_ERROR_IS_OK(status
) )
2304 * if the client asked for a specific version,
2305 * or this is something other than Windows NT x86,
2309 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2312 /* try for Win2k driver if "Windows NT x86" */
2315 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2316 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2321 if ( printer_driver_in_use(info
.info_3
) ) {
2322 status
= WERR_PRINTER_DRIVER_IN_USE
;
2327 * we have a couple of cases to consider.
2328 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2329 * then the delete should fail if **any** files overlap with
2331 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2332 * non-overlapping files
2333 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2334 * is set, the do not delete any files
2335 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2338 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2340 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2342 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2343 /* no idea of the correct error here */
2344 status
= WERR_ACCESS_DENIED
;
2349 /* also check for W32X86/3 if necessary; maybe we already have? */
2351 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2352 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2355 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2356 /* no idea of the correct error here */
2357 free_a_printer_driver( info_win2k
, 3 );
2358 status
= WERR_ACCESS_DENIED
;
2362 /* if we get to here, we now have 2 driver info structures to remove */
2363 /* remove the Win2k driver first*/
2365 status_win2k
= delete_printer_driver(
2366 p
, info_win2k
.info_3
, 3, delete_files
);
2367 free_a_printer_driver( info_win2k
, 3 );
2369 /* this should not have failed---if it did, report to client */
2371 if ( !W_ERROR_IS_OK(status_win2k
) )
2376 status
= delete_printer_driver(p
, info
.info_3
, version
, delete_files
);
2378 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2381 free_a_printer_driver( info
, 3 );
2387 /****************************************************************************
2388 Internal routine for retreiving printerdata
2389 ***************************************************************************/
2391 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2392 const char *key
, const char *value
, uint32
*type
, uint8
**data
,
2393 uint32
*needed
, uint32 in_size
)
2395 REGISTRY_VALUE
*val
;
2399 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2400 return WERR_BADFILE
;
2402 *type
= regval_type( val
);
2404 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2406 size
= regval_size( val
);
2408 /* copy the min(in_size, len) */
2411 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2413 /* special case for 0 length values */
2415 if ( (*data
= (uint8
*)TALLOC_MEMDUP(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2419 if ( (*data
= (uint8
*)TALLOC_ZERO(ctx
, in_size
)) == NULL
)
2428 DEBUG(5,("get_printer_dataex: copy done\n"));
2433 /****************************************************************************
2434 Internal routine for removing printerdata
2435 ***************************************************************************/
2437 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2439 return delete_printer_data( printer
->info_2
, key
, value
);
2442 /****************************************************************************
2443 Internal routine for storing printerdata
2444 ***************************************************************************/
2446 WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
,
2447 uint32 type
, uint8
*data
, int real_len
)
2449 /* the registry objects enforce uniqueness based on value name */
2451 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2454 /********************************************************************
2455 GetPrinterData on a printer server Handle.
2456 ********************************************************************/
2458 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2462 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2464 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2466 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2468 SIVAL(*data
, 0, 0x00);
2473 if (!StrCaseCmp(value
, "BeepEnabled")) {
2475 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2477 SIVAL(*data
, 0, 0x00);
2482 if (!StrCaseCmp(value
, "EventLog")) {
2484 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2486 /* formally was 0x1b */
2487 SIVAL(*data
, 0, 0x0);
2492 if (!StrCaseCmp(value
, "NetPopup")) {
2494 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2496 SIVAL(*data
, 0, 0x00);
2501 if (!StrCaseCmp(value
, "MajorVersion")) {
2503 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2506 /* Windows NT 4.0 seems to not allow uploading of drivers
2507 to a server that reports 0x3 as the MajorVersion.
2508 need to investigate more how Win2k gets around this .
2511 if ( RA_WINNT
== get_remote_arch() )
2520 if (!StrCaseCmp(value
, "MinorVersion")) {
2522 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2530 * uint32 size = 0x114
2532 * uint32 minor = [0|1]
2533 * uint32 build = [2195|2600]
2534 * extra unicode string = e.g. "Service Pack 3"
2536 if (!StrCaseCmp(value
, "OSVersion")) {
2540 if ( !(*data
= TALLOC_ZERO_ARRAY(ctx
, uint8
, (*needed
> in_size
) ? *needed
:in_size
)) )
2543 SIVAL(*data
, 0, *needed
); /* size */
2544 SIVAL(*data
, 4, 5); /* Windows 2000 == 5.0 */
2546 SIVAL(*data
, 12, 2195); /* build */
2548 /* leave extra string empty */
2554 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2555 const char *string
="C:\\PRINTERS";
2557 *needed
= 2*(strlen(string
)+1);
2558 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2560 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2562 /* it's done by hand ready to go on the wire */
2563 for (i
=0; i
<strlen(string
); i
++) {
2564 (*data
)[2*i
]=string
[i
];
2565 (*data
)[2*i
+1]='\0';
2570 if (!StrCaseCmp(value
, "Architecture")) {
2571 const char *string
="Windows NT x86";
2573 *needed
= 2*(strlen(string
)+1);
2574 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2576 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2577 for (i
=0; i
<strlen(string
); i
++) {
2578 (*data
)[2*i
]=string
[i
];
2579 (*data
)[2*i
+1]='\0';
2584 if (!StrCaseCmp(value
, "DsPresent")) {
2586 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2589 /* only show the publish check box if we are a
2590 memeber of a AD domain */
2592 if ( lp_security() == SEC_ADS
)
2593 SIVAL(*data
, 0, 0x01);
2595 SIVAL(*data
, 0, 0x00);
2601 if (!StrCaseCmp(value
, "DNSMachineName")) {
2602 const char *hostname
= get_mydnsfullname();
2605 return WERR_BADFILE
;
2607 *needed
= 2*(strlen(hostname
)+1);
2608 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2610 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2611 for (i
=0; i
<strlen(hostname
); i
++) {
2612 (*data
)[2*i
]=hostname
[i
];
2613 (*data
)[2*i
+1]='\0';
2619 return WERR_BADFILE
;
2622 /********************************************************************
2623 * spoolss_getprinterdata
2624 ********************************************************************/
2626 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2628 POLICY_HND
*handle
= &q_u
->handle
;
2629 UNISTR2
*valuename
= &q_u
->valuename
;
2630 uint32 in_size
= q_u
->size
;
2631 uint32
*type
= &r_u
->type
;
2632 uint32
*out_size
= &r_u
->size
;
2633 uint8
**data
= &r_u
->data
;
2634 uint32
*needed
= &r_u
->needed
;
2637 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2638 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2642 * Reminder: when it's a string, the length is in BYTES
2643 * even if UNICODE is negociated.
2648 *out_size
= in_size
;
2650 /* in case of problem, return some default values */
2655 DEBUG(4,("_spoolss_getprinterdata\n"));
2658 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2659 status
= WERR_BADFID
;
2663 unistr2_to_ascii(value
, valuename
, sizeof(value
));
2665 if ( Printer
->printer_type
== SPLHND_SERVER
)
2666 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2669 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) ) {
2670 status
= WERR_BADFID
;
2674 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2675 if ( !W_ERROR_IS_OK(status
) )
2678 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2680 if ( strequal(value
, "ChangeId") ) {
2682 *needed
= sizeof(uint32
);
2683 if ( (*data
= (uint8
*)TALLOC(p
->mem_ctx
, sizeof(uint32
))) == NULL
) {
2684 status
= WERR_NOMEM
;
2687 SIVAL( *data
, 0, printer
->info_2
->changeid
);
2691 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2694 if (*needed
> *out_size
)
2695 status
= WERR_MORE_DATA
;
2698 if ( !W_ERROR_IS_OK(status
) )
2700 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status
),*out_size
));
2702 /* reply this param doesn't exist */
2705 if((*data
=(uint8
*)TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint8
, *out_size
)) == NULL
) {
2707 free_a_printer( &printer
, 2 );
2715 /* cleanup & exit */
2718 free_a_printer( &printer
, 2 );
2723 /*********************************************************
2724 Connect to the client machine.
2725 **********************************************************/
2727 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2728 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2731 struct cli_state
*the_cli
;
2732 struct sockaddr_storage rm_addr
;
2734 if ( is_zero_addr((struct sockaddr
*)client_ss
) ) {
2735 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20) ) {
2736 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2740 if (ismyaddr((struct sockaddr
*)&rm_addr
)) {
2741 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2745 char addr
[INET6_ADDRSTRLEN
];
2746 rm_addr
= *client_ss
;
2747 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2748 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2752 /* setup the connection */
2754 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2755 &rm_addr
, 0, "IPC$", "IPC",
2759 0, lp_client_signing(), NULL
);
2761 if ( !NT_STATUS_IS_OK( ret
) ) {
2762 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2767 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2768 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2769 cli_shutdown(the_cli
);
2774 * Ok - we have an anonymous connection to the IPC$ share.
2775 * Now start the NT Domain stuff :-).
2778 ret
= cli_rpc_pipe_open_noauth(the_cli
, &syntax_spoolss
, pp_pipe
);
2779 if (!NT_STATUS_IS_OK(ret
)) {
2780 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2781 remote_machine
, nt_errstr(ret
)));
2782 cli_shutdown(the_cli
);
2789 /***************************************************************************
2790 Connect to the client.
2791 ****************************************************************************/
2793 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2794 uint32 localprinter
, uint32 type
,
2795 POLICY_HND
*handle
, struct sockaddr_storage
*client_ss
)
2801 * If it's the first connection, contact the client
2802 * and connect to the IPC$ share anonymously
2804 if (smb_connections
==0) {
2805 fstring unix_printer
;
2807 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2809 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2812 messaging_register(smbd_messaging_context(), NULL
,
2813 MSG_PRINTER_NOTIFY2
,
2814 receive_notify2_message_list
);
2815 /* Tell the connections db we're now interested in printer
2816 * notify messages. */
2817 register_message_flags( True
, FLAG_MSG_PRINT_NOTIFY
);
2821 * Tell the specific printing tdb we want messages for this printer
2822 * by registering our PID.
2825 if (!print_notify_register_pid(snum
))
2826 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2830 status
= rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe
, talloc_tos(),
2838 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
2839 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2840 win_errstr(result
)));
2842 return (W_ERROR_IS_OK(result
));
2845 /****************************************************************
2846 ****************************************************************/
2848 static struct spoolss_NotifyOption
*dup_spoolss_NotifyOption(TALLOC_CTX
*mem_ctx
,
2849 const struct spoolss_NotifyOption
*r
)
2851 struct spoolss_NotifyOption
*option
;
2858 option
= talloc_zero(mem_ctx
, struct spoolss_NotifyOption
);
2865 if (!option
->count
) {
2869 option
->types
= talloc_zero_array(option
,
2870 struct spoolss_NotifyOptionType
, option
->count
);
2871 if (!option
->types
) {
2872 talloc_free(option
);
2876 for (i
=0; i
< option
->count
; i
++) {
2877 option
->types
[i
] = r
->types
[i
];
2879 if (option
->types
[i
].count
) {
2880 option
->types
[i
].fields
= talloc_zero_array(option
,
2881 enum spoolss_Field
, option
->types
[i
].count
);
2882 if (!option
->types
[i
].fields
) {
2883 talloc_free(option
);
2886 for (k
=0; k
<option
->types
[i
].count
; k
++) {
2887 option
->types
[i
].fields
[k
] =
2888 r
->types
[i
].fields
[k
];
2896 /****************************************************************
2897 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2899 * before replying OK: status=0 a rpc call is made to the workstation
2900 * asking ReplyOpenPrinter
2902 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2903 * called from api_spoolss_rffpcnex
2904 ****************************************************************/
2906 WERROR
_spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct
*p
,
2907 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx
*r
)
2909 POLICY_HND
*handle
= r
->in
.handle
;
2911 struct spoolss_NotifyOption
*option
= r
->in
.notify_options
;
2912 struct sockaddr_storage client_ss
;
2914 /* store the notify value in the printer struct */
2916 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2919 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2920 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2924 Printer
->notify
.flags
= r
->in
.flags
;
2925 Printer
->notify
.options
= r
->in
.options
;
2926 Printer
->notify
.printerlocal
= r
->in
.printer_local
;
2928 TALLOC_FREE(Printer
->notify
.option
);
2929 Printer
->notify
.option
= dup_spoolss_NotifyOption(Printer
, option
);
2931 fstrcpy(Printer
->notify
.localmachine
, r
->in
.local_machine
);
2933 /* Connect to the client machine and send a ReplyOpenPrinter */
2935 if ( Printer
->printer_type
== SPLHND_SERVER
)
2937 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2938 !get_printer_snum(p
, handle
, &snum
, NULL
) )
2941 if (!interpret_string_addr(&client_ss
, p
->client_address
,
2943 return WERR_SERVER_UNAVAILABLE
;
2946 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2947 Printer
->notify
.printerlocal
, 1,
2948 &Printer
->notify
.client_hnd
, &client_ss
))
2949 return WERR_SERVER_UNAVAILABLE
;
2951 Printer
->notify
.client_connected
=True
;
2956 /*******************************************************************
2957 * fill a notify_info_data with the servername
2958 ********************************************************************/
2960 void spoolss_notify_server_name(int snum
,
2961 struct spoolss_Notify
*data
,
2962 print_queue_struct
*queue
,
2963 NT_PRINTER_INFO_LEVEL
*printer
,
2964 TALLOC_CTX
*mem_ctx
)
2966 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->servername
);
2969 /*******************************************************************
2970 * fill a notify_info_data with the printername (not including the servername).
2971 ********************************************************************/
2973 void spoolss_notify_printer_name(int snum
,
2974 struct spoolss_Notify
*data
,
2975 print_queue_struct
*queue
,
2976 NT_PRINTER_INFO_LEVEL
*printer
,
2977 TALLOC_CTX
*mem_ctx
)
2979 /* the notify name should not contain the \\server\ part */
2980 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2983 p
= printer
->info_2
->printername
;
2988 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2991 /*******************************************************************
2992 * fill a notify_info_data with the servicename
2993 ********************************************************************/
2995 void spoolss_notify_share_name(int snum
,
2996 struct spoolss_Notify
*data
,
2997 print_queue_struct
*queue
,
2998 NT_PRINTER_INFO_LEVEL
*printer
,
2999 TALLOC_CTX
*mem_ctx
)
3001 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, lp_servicename(snum
));
3004 /*******************************************************************
3005 * fill a notify_info_data with the port name
3006 ********************************************************************/
3008 void spoolss_notify_port_name(int snum
,
3009 struct spoolss_Notify
*data
,
3010 print_queue_struct
*queue
,
3011 NT_PRINTER_INFO_LEVEL
*printer
,
3012 TALLOC_CTX
*mem_ctx
)
3014 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->portname
);
3017 /*******************************************************************
3018 * fill a notify_info_data with the printername
3019 * but it doesn't exist, have to see what to do
3020 ********************************************************************/
3022 void spoolss_notify_driver_name(int snum
,
3023 struct spoolss_Notify
*data
,
3024 print_queue_struct
*queue
,
3025 NT_PRINTER_INFO_LEVEL
*printer
,
3026 TALLOC_CTX
*mem_ctx
)
3028 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->drivername
);
3031 /*******************************************************************
3032 * fill a notify_info_data with the comment
3033 ********************************************************************/
3035 void spoolss_notify_comment(int snum
,
3036 struct spoolss_Notify
*data
,
3037 print_queue_struct
*queue
,
3038 NT_PRINTER_INFO_LEVEL
*printer
,
3039 TALLOC_CTX
*mem_ctx
)
3043 if (*printer
->info_2
->comment
== '\0') {
3044 p
= lp_comment(snum
);
3046 p
= printer
->info_2
->comment
;
3049 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->comment
);
3052 /*******************************************************************
3053 * fill a notify_info_data with the comment
3054 * location = "Room 1, floor 2, building 3"
3055 ********************************************************************/
3057 void spoolss_notify_location(int snum
,
3058 struct spoolss_Notify
*data
,
3059 print_queue_struct
*queue
,
3060 NT_PRINTER_INFO_LEVEL
*printer
,
3061 TALLOC_CTX
*mem_ctx
)
3063 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->location
);
3066 /*******************************************************************
3067 * fill a notify_info_data with the device mode
3068 * jfm:xxxx don't to it for know but that's a real problem !!!
3069 ********************************************************************/
3071 static void spoolss_notify_devmode(int snum
,
3072 struct spoolss_Notify
*data
,
3073 print_queue_struct
*queue
,
3074 NT_PRINTER_INFO_LEVEL
*printer
,
3075 TALLOC_CTX
*mem_ctx
)
3077 /* for a dummy implementation we have to zero the fields */
3078 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data
, NULL
);
3081 /*******************************************************************
3082 * fill a notify_info_data with the separator file name
3083 ********************************************************************/
3085 void spoolss_notify_sepfile(int snum
,
3086 struct spoolss_Notify
*data
,
3087 print_queue_struct
*queue
,
3088 NT_PRINTER_INFO_LEVEL
*printer
,
3089 TALLOC_CTX
*mem_ctx
)
3091 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->sepfile
);
3094 /*******************************************************************
3095 * fill a notify_info_data with the print processor
3096 * jfm:xxxx return always winprint to indicate we don't do anything to it
3097 ********************************************************************/
3099 void spoolss_notify_print_processor(int snum
,
3100 struct spoolss_Notify
*data
,
3101 print_queue_struct
*queue
,
3102 NT_PRINTER_INFO_LEVEL
*printer
,
3103 TALLOC_CTX
*mem_ctx
)
3105 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->printprocessor
);
3108 /*******************************************************************
3109 * fill a notify_info_data with the print processor options
3110 * jfm:xxxx send an empty string
3111 ********************************************************************/
3113 void spoolss_notify_parameters(int snum
,
3114 struct spoolss_Notify
*data
,
3115 print_queue_struct
*queue
,
3116 NT_PRINTER_INFO_LEVEL
*printer
,
3117 TALLOC_CTX
*mem_ctx
)
3119 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->parameters
);
3122 /*******************************************************************
3123 * fill a notify_info_data with the data type
3124 * jfm:xxxx always send RAW as data type
3125 ********************************************************************/
3127 void spoolss_notify_datatype(int snum
,
3128 struct spoolss_Notify
*data
,
3129 print_queue_struct
*queue
,
3130 NT_PRINTER_INFO_LEVEL
*printer
,
3131 TALLOC_CTX
*mem_ctx
)
3133 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->datatype
);
3136 /*******************************************************************
3137 * fill a notify_info_data with the security descriptor
3138 * jfm:xxxx send an null pointer to say no security desc
3139 * have to implement security before !
3140 ********************************************************************/
3142 static void spoolss_notify_security_desc(int snum
,
3143 struct spoolss_Notify
*data
,
3144 print_queue_struct
*queue
,
3145 NT_PRINTER_INFO_LEVEL
*printer
,
3146 TALLOC_CTX
*mem_ctx
)
3148 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data
,
3149 printer
->info_2
->secdesc_buf
->sd_size
,
3150 printer
->info_2
->secdesc_buf
->sd
);
3153 /*******************************************************************
3154 * fill a notify_info_data with the attributes
3155 * jfm:xxxx a samba printer is always shared
3156 ********************************************************************/
3158 void spoolss_notify_attributes(int snum
,
3159 struct spoolss_Notify
*data
,
3160 print_queue_struct
*queue
,
3161 NT_PRINTER_INFO_LEVEL
*printer
,
3162 TALLOC_CTX
*mem_ctx
)
3164 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->attributes
);
3167 /*******************************************************************
3168 * fill a notify_info_data with the priority
3169 ********************************************************************/
3171 static void spoolss_notify_priority(int snum
,
3172 struct spoolss_Notify
*data
,
3173 print_queue_struct
*queue
,
3174 NT_PRINTER_INFO_LEVEL
*printer
,
3175 TALLOC_CTX
*mem_ctx
)
3177 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->priority
);
3180 /*******************************************************************
3181 * fill a notify_info_data with the default priority
3182 ********************************************************************/
3184 static void spoolss_notify_default_priority(int snum
,
3185 struct spoolss_Notify
*data
,
3186 print_queue_struct
*queue
,
3187 NT_PRINTER_INFO_LEVEL
*printer
,
3188 TALLOC_CTX
*mem_ctx
)
3190 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->default_priority
);
3193 /*******************************************************************
3194 * fill a notify_info_data with the start time
3195 ********************************************************************/
3197 static void spoolss_notify_start_time(int snum
,
3198 struct spoolss_Notify
*data
,
3199 print_queue_struct
*queue
,
3200 NT_PRINTER_INFO_LEVEL
*printer
,
3201 TALLOC_CTX
*mem_ctx
)
3203 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->starttime
);
3206 /*******************************************************************
3207 * fill a notify_info_data with the until time
3208 ********************************************************************/
3210 static void spoolss_notify_until_time(int snum
,
3211 struct spoolss_Notify
*data
,
3212 print_queue_struct
*queue
,
3213 NT_PRINTER_INFO_LEVEL
*printer
,
3214 TALLOC_CTX
*mem_ctx
)
3216 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->untiltime
);
3219 /*******************************************************************
3220 * fill a notify_info_data with the status
3221 ********************************************************************/
3223 static void spoolss_notify_status(int snum
,
3224 struct spoolss_Notify
*data
,
3225 print_queue_struct
*queue
,
3226 NT_PRINTER_INFO_LEVEL
*printer
,
3227 TALLOC_CTX
*mem_ctx
)
3229 print_status_struct status
;
3231 print_queue_length(snum
, &status
);
3232 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, status
.status
);
3235 /*******************************************************************
3236 * fill a notify_info_data with the number of jobs queued
3237 ********************************************************************/
3239 void spoolss_notify_cjobs(int snum
,
3240 struct spoolss_Notify
*data
,
3241 print_queue_struct
*queue
,
3242 NT_PRINTER_INFO_LEVEL
*printer
,
3243 TALLOC_CTX
*mem_ctx
)
3245 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, print_queue_length(snum
, NULL
));
3248 /*******************************************************************
3249 * fill a notify_info_data with the average ppm
3250 ********************************************************************/
3252 static void spoolss_notify_average_ppm(int snum
,
3253 struct spoolss_Notify
*data
,
3254 print_queue_struct
*queue
,
3255 NT_PRINTER_INFO_LEVEL
*printer
,
3256 TALLOC_CTX
*mem_ctx
)
3258 /* always respond 8 pages per minutes */
3259 /* a little hard ! */
3260 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->averageppm
);
3263 /*******************************************************************
3264 * fill a notify_info_data with username
3265 ********************************************************************/
3267 static void spoolss_notify_username(int snum
,
3268 struct spoolss_Notify
*data
,
3269 print_queue_struct
*queue
,
3270 NT_PRINTER_INFO_LEVEL
*printer
,
3271 TALLOC_CTX
*mem_ctx
)
3273 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_user
);
3276 /*******************************************************************
3277 * fill a notify_info_data with job status
3278 ********************************************************************/
3280 static void spoolss_notify_job_status(int snum
,
3281 struct spoolss_Notify
*data
,
3282 print_queue_struct
*queue
,
3283 NT_PRINTER_INFO_LEVEL
*printer
,
3284 TALLOC_CTX
*mem_ctx
)
3286 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, nt_printj_status(queue
->status
));
3289 /*******************************************************************
3290 * fill a notify_info_data with job name
3291 ********************************************************************/
3293 static void spoolss_notify_job_name(int snum
,
3294 struct spoolss_Notify
*data
,
3295 print_queue_struct
*queue
,
3296 NT_PRINTER_INFO_LEVEL
*printer
,
3297 TALLOC_CTX
*mem_ctx
)
3299 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_file
);
3302 /*******************************************************************
3303 * fill a notify_info_data with job status
3304 ********************************************************************/
3306 static void spoolss_notify_job_status_string(int snum
,
3307 struct spoolss_Notify
*data
,
3308 print_queue_struct
*queue
,
3309 NT_PRINTER_INFO_LEVEL
*printer
,
3310 TALLOC_CTX
*mem_ctx
)
3313 * Now we're returning job status codes we just return a "" here. JRA.
3318 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3321 switch (queue
->status
) {
3326 p
= ""; /* NT provides the paused string */
3335 #endif /* NO LONGER NEEDED. */
3337 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
3340 /*******************************************************************
3341 * fill a notify_info_data with job time
3342 ********************************************************************/
3344 static void spoolss_notify_job_time(int snum
,
3345 struct spoolss_Notify
*data
,
3346 print_queue_struct
*queue
,
3347 NT_PRINTER_INFO_LEVEL
*printer
,
3348 TALLOC_CTX
*mem_ctx
)
3350 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
3353 /*******************************************************************
3354 * fill a notify_info_data with job size
3355 ********************************************************************/
3357 static void spoolss_notify_job_size(int snum
,
3358 struct spoolss_Notify
*data
,
3359 print_queue_struct
*queue
,
3360 NT_PRINTER_INFO_LEVEL
*printer
,
3361 TALLOC_CTX
*mem_ctx
)
3363 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->size
);
3366 /*******************************************************************
3367 * fill a notify_info_data with page info
3368 ********************************************************************/
3369 static void spoolss_notify_total_pages(int snum
,
3370 struct spoolss_Notify
*data
,
3371 print_queue_struct
*queue
,
3372 NT_PRINTER_INFO_LEVEL
*printer
,
3373 TALLOC_CTX
*mem_ctx
)
3375 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->page_count
);
3378 /*******************************************************************
3379 * fill a notify_info_data with pages printed info.
3380 ********************************************************************/
3381 static void spoolss_notify_pages_printed(int snum
,
3382 struct spoolss_Notify
*data
,
3383 print_queue_struct
*queue
,
3384 NT_PRINTER_INFO_LEVEL
*printer
,
3385 TALLOC_CTX
*mem_ctx
)
3387 /* Add code when back-end tracks this */
3388 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
3391 /*******************************************************************
3392 Fill a notify_info_data with job position.
3393 ********************************************************************/
3395 static void spoolss_notify_job_position(int snum
,
3396 struct spoolss_Notify
*data
,
3397 print_queue_struct
*queue
,
3398 NT_PRINTER_INFO_LEVEL
*printer
,
3399 TALLOC_CTX
*mem_ctx
)
3401 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->job
);
3404 /*******************************************************************
3405 Fill a notify_info_data with submitted time.
3406 ********************************************************************/
3408 static void spoolss_notify_submitted_time(int snum
,
3409 struct spoolss_Notify
*data
,
3410 print_queue_struct
*queue
,
3411 NT_PRINTER_INFO_LEVEL
*printer
,
3412 TALLOC_CTX
*mem_ctx
)
3414 data
->data
.string
.string
= NULL
;
3415 data
->data
.string
.size
= 0;
3417 init_systemtime_buffer(mem_ctx
, gmtime(&queue
->time
),
3418 &data
->data
.string
.string
,
3419 &data
->data
.string
.size
);
3423 struct s_notify_info_data_table
3425 enum spoolss_NotifyType type
;
3426 enum spoolss_Field field
;
3428 enum spoolss_NotifyTable variable_type
;
3429 void (*fn
) (int snum
, struct spoolss_Notify
*data
,
3430 print_queue_struct
*queue
,
3431 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3434 /* A table describing the various print notification constants and
3435 whether the notification data is a pointer to a variable sized
3436 buffer, a one value uint32 or a two value uint32. */
3438 static const struct s_notify_info_data_table notify_info_data_table
[] =
3440 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
3441 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
3442 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_share_name
},
3443 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
3444 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
3445 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING
, spoolss_notify_comment
},
3446 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING
, spoolss_notify_location
},
3447 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
3448 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING
, spoolss_notify_sepfile
},
3449 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
3450 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
3451 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
3452 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, spoolss_notify_security_desc
},
3453 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD
, spoolss_notify_attributes
},
3454 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
3455 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_default_priority
},
3456 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
3457 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
3458 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_status
},
3459 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING
, NULL
},
3460 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD
, spoolss_notify_cjobs
},
3461 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD
, spoolss_notify_average_ppm
},
3462 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, NULL
},
3463 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
3464 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, NULL
},
3465 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
3466 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
3467 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
3468 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
3469 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
3470 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
3471 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
3472 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
3473 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
3474 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
3475 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
3476 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_job_status
},
3477 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING
, spoolss_notify_job_status_string
},
3478 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, NULL
},
3479 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING
, spoolss_notify_job_name
},
3480 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
3481 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD
, spoolss_notify_job_position
},
3482 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME
, spoolss_notify_submitted_time
},
3483 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
3484 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
3485 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_job_time
},
3486 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, spoolss_notify_total_pages
},
3487 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, spoolss_notify_pages_printed
},
3488 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, spoolss_notify_job_size
},
3489 { PRINT_TABLE_END
, 0x0, NULL
, 0x0, NULL
},
3492 /*******************************************************************
3493 Return the variable_type of info_data structure.
3494 ********************************************************************/
3496 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type
,
3497 enum spoolss_Field field
)
3501 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
3502 if ( (notify_info_data_table
[i
].type
== type
) &&
3503 (notify_info_data_table
[i
].field
== field
) ) {
3504 return notify_info_data_table
[i
].variable_type
;
3508 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3513 /****************************************************************************
3514 ****************************************************************************/
3516 static bool search_notify(enum spoolss_NotifyType type
,
3517 enum spoolss_Field field
,
3522 for (i
= 0; notify_info_data_table
[i
].type
!= PRINT_TABLE_END
; i
++) {
3523 if (notify_info_data_table
[i
].type
== type
&&
3524 notify_info_data_table
[i
].field
== field
&&
3525 notify_info_data_table
[i
].fn
!= NULL
) {
3534 /****************************************************************************
3535 ****************************************************************************/
3537 void construct_info_data(struct spoolss_Notify
*info_data
,
3538 enum spoolss_NotifyType type
,
3539 enum spoolss_Field field
,
3542 info_data
->type
= type
;
3543 info_data
->field
= field
;
3544 info_data
->variable_type
= variable_type_of_notify_info_data(type
, field
);
3545 info_data
->job_id
= id
;
3548 /*******************************************************************
3550 * fill a notify_info struct with info asked
3552 ********************************************************************/
3554 static bool construct_notify_printer_info(Printer_entry
*print_hnd
,
3555 struct spoolss_NotifyInfo
*info
,
3557 const struct spoolss_NotifyOptionType
*option_type
,
3559 TALLOC_CTX
*mem_ctx
)
3562 enum spoolss_NotifyType type
;
3563 enum spoolss_Field field
;
3565 struct spoolss_Notify
*current_data
;
3566 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3567 print_queue_struct
*queue
=NULL
;
3569 type
= option_type
->type
;
3571 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3572 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3573 option_type
->count
, lp_servicename(snum
)));
3575 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3578 for(field_num
=0; field_num
< option_type
->count
; field_num
++) {
3579 field
= option_type
->fields
[field_num
];
3581 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3583 if (!search_notify(type
, field
, &j
) )
3586 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3587 struct spoolss_Notify
,
3589 if (info
->notifies
== NULL
) {
3590 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3591 free_a_printer(&printer
, 2);
3595 current_data
= &info
->notifies
[info
->count
];
3597 construct_info_data(current_data
, type
, field
, id
);
3599 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3600 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3602 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3608 free_a_printer(&printer
, 2);
3612 /*******************************************************************
3614 * fill a notify_info struct with info asked
3616 ********************************************************************/
3618 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3619 struct spoolss_NotifyInfo
*info
,
3620 NT_PRINTER_INFO_LEVEL
*printer
,
3622 const struct spoolss_NotifyOptionType
*option_type
,
3624 TALLOC_CTX
*mem_ctx
)
3627 enum spoolss_NotifyType type
;
3628 enum spoolss_Field field
;
3629 struct spoolss_Notify
*current_data
;
3631 DEBUG(4,("construct_notify_jobs_info\n"));
3633 type
= option_type
->type
;
3635 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3636 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3637 option_type
->count
));
3639 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3640 field
= option_type
->fields
[field_num
];
3642 if (!search_notify(type
, field
, &j
) )
3645 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3646 struct spoolss_Notify
,
3648 if (info
->notifies
== NULL
) {
3649 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3653 current_data
=&(info
->notifies
[info
->count
]);
3655 construct_info_data(current_data
, type
, field
, id
);
3656 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3665 * JFM: The enumeration is not that simple, it's even non obvious.
3667 * let's take an example: I want to monitor the PRINTER SERVER for
3668 * the printer's name and the number of jobs currently queued.
3669 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3670 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3672 * I have 3 printers on the back of my server.
3674 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3677 * 1 printer 1 name 1
3678 * 2 printer 1 cjob 1
3679 * 3 printer 2 name 2
3680 * 4 printer 2 cjob 2
3681 * 5 printer 3 name 3
3682 * 6 printer 3 name 3
3684 * that's the print server case, the printer case is even worse.
3687 /*******************************************************************
3689 * enumerate all printers on the printserver
3690 * fill a notify_info struct with info asked
3692 ********************************************************************/
3694 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
3695 struct spoolss_NotifyInfo
*info
,
3696 TALLOC_CTX
*mem_ctx
)
3699 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3700 int n_services
=lp_numservices();
3702 struct spoolss_NotifyOption
*option
;
3703 struct spoolss_NotifyOptionType option_type
;
3705 DEBUG(4,("printserver_notify_info\n"));
3710 option
= Printer
->notify
.option
;
3713 info
->notifies
= NULL
;
3716 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3717 sending a ffpcn() request first */
3722 for (i
=0; i
<option
->count
; i
++) {
3723 option_type
= option
->types
[i
];
3725 if (option_type
.type
!= PRINTER_NOTIFY_TYPE
)
3728 for (snum
=0; snum
<n_services
; snum
++)
3730 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3731 construct_notify_printer_info ( Printer
, info
, snum
, &option_type
, snum
, mem_ctx
);
3737 * Debugging information, don't delete.
3740 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3741 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3742 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3744 for (i
=0; i
<info
->count
; i
++) {
3745 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3746 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3747 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3754 /*******************************************************************
3756 * fill a notify_info struct with info asked
3758 ********************************************************************/
3760 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, struct spoolss_NotifyInfo
*info
,
3761 TALLOC_CTX
*mem_ctx
)
3764 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3767 struct spoolss_NotifyOption
*option
;
3768 struct spoolss_NotifyOptionType option_type
;
3770 print_queue_struct
*queue
=NULL
;
3771 print_status_struct status
;
3773 DEBUG(4,("printer_notify_info\n"));
3778 option
= Printer
->notify
.option
;
3782 info
->notifies
= NULL
;
3785 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3786 sending a ffpcn() request first */
3791 get_printer_snum(p
, hnd
, &snum
, NULL
);
3793 for (i
=0; i
<option
->count
; i
++) {
3794 option_type
= option
->types
[i
];
3796 switch (option_type
.type
) {
3797 case PRINTER_NOTIFY_TYPE
:
3798 if(construct_notify_printer_info(Printer
, info
, snum
,
3804 case JOB_NOTIFY_TYPE
: {
3805 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3807 count
= print_queue_status(snum
, &queue
, &status
);
3809 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3812 for (j
=0; j
<count
; j
++) {
3813 construct_notify_jobs_info(&queue
[j
], info
,
3820 free_a_printer(&printer
, 2);
3830 * Debugging information, don't delete.
3833 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3834 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3835 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3837 for (i=0; i<info->count; i++) {
3838 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3839 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3840 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3846 /****************************************************************
3847 _spoolss_RouterRefreshPrinterChangeNotify
3848 ****************************************************************/
3850 WERROR
_spoolss_RouterRefreshPrinterChangeNotify(pipes_struct
*p
,
3851 struct spoolss_RouterRefreshPrinterChangeNotify
*r
)
3853 POLICY_HND
*handle
= r
->in
.handle
;
3854 struct spoolss_NotifyInfo
*info
;
3856 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
3857 WERROR result
= WERR_BADFID
;
3859 /* we always have a spoolss_NotifyInfo struct */
3860 info
= talloc_zero(p
->mem_ctx
, struct spoolss_NotifyInfo
);
3862 result
= WERR_NOMEM
;
3866 *r
->out
.info
= info
;
3869 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3870 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
3874 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3877 * We are now using the change value, and
3878 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3879 * I don't have a global notification system, I'm sending back all the
3880 * informations even when _NOTHING_ has changed.
3883 /* We need to keep track of the change value to send back in
3884 RRPCN replies otherwise our updates are ignored. */
3886 Printer
->notify
.fnpcn
= True
;
3888 if (Printer
->notify
.client_connected
) {
3889 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3890 "Saving change value in request [%x]\n",
3892 Printer
->notify
.change
= r
->in
.change_low
;
3895 /* just ignore the spoolss_NotifyOption */
3897 switch (Printer
->printer_type
) {
3899 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
3902 case SPLHND_PRINTER
:
3903 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
3907 Printer
->notify
.fnpcn
= False
;
3913 /********************************************************************
3914 * construct_printer_info_0
3915 * fill a printer_info_0 struct
3916 ********************************************************************/
3918 static bool construct_printer_info_0(Printer_entry
*print_hnd
, PRINTER_INFO_0
*printer
, int snum
)
3920 char *chaine
= NULL
;
3922 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3923 counter_printer_0
*session_counter
;
3924 uint32 global_counter
;
3927 print_status_struct status
;
3928 TALLOC_CTX
*ctx
= talloc_tos();
3930 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
3933 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
3935 chaine
= talloc_asprintf(ctx
, "\\\\%s", get_server_name(print_hnd
));
3937 free_a_printer(&ntprinter
,2);
3941 count
= print_queue_length(snum
, &status
);
3943 /* check if we already have a counter for this printer */
3944 for(session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3945 if (session_counter
->snum
== snum
)
3949 init_unistr(&printer
->servername
, chaine
);
3951 /* it's the first time, add it to the list */
3952 if (session_counter
==NULL
) {
3953 if((session_counter
=SMB_MALLOC_P(counter_printer_0
)) == NULL
) {
3954 free_a_printer(&ntprinter
, 2);
3957 ZERO_STRUCTP(session_counter
);
3958 session_counter
->snum
=snum
;
3959 session_counter
->counter
=0;
3960 DLIST_ADD(counter_list
, session_counter
);
3964 session_counter
->counter
++;
3967 * the global_counter should be stored in a TDB as it's common to all the clients
3968 * and should be zeroed on samba startup
3970 global_counter
=session_counter
->counter
;
3971 printer
->cjobs
= count
;
3972 printer
->total_jobs
= 0;
3973 printer
->total_bytes
= 0;
3975 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
3976 t
=gmtime(&setuptime
);
3978 printer
->year
= t
->tm_year
+1900;
3979 printer
->month
= t
->tm_mon
+1;
3980 printer
->dayofweek
= t
->tm_wday
;
3981 printer
->day
= t
->tm_mday
;
3982 printer
->hour
= t
->tm_hour
;
3983 printer
->minute
= t
->tm_min
;
3984 printer
->second
= t
->tm_sec
;
3985 printer
->milliseconds
= 0;
3987 printer
->global_counter
= global_counter
;
3988 printer
->total_pages
= 0;
3990 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3991 printer
->major_version
= 0x0005; /* NT 5 */
3992 printer
->build_version
= 0x0893; /* build 2195 */
3994 printer
->unknown7
= 0x1;
3995 printer
->unknown8
= 0x0;
3996 printer
->unknown9
= 0x0;
3997 printer
->session_counter
= session_counter
->counter
;
3998 printer
->unknown11
= 0x0;
3999 printer
->printer_errors
= 0x0; /* number of print failure */
4000 printer
->unknown13
= 0x0;
4001 printer
->unknown14
= 0x1;
4002 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
4003 printer
->unknown16
= 0x0;
4004 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
4005 printer
->unknown18
= 0x0;
4006 printer
->status
= nt_printq_status(status
.status
);
4007 printer
->unknown20
= 0x0;
4008 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4009 printer
->unknown22
= 0x0;
4010 printer
->unknown23
= 0x6; /* 6 ???*/
4011 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
4012 printer
->unknown25
= 0;
4013 printer
->unknown26
= 0;
4014 printer
->unknown27
= 0;
4015 printer
->unknown28
= 0;
4016 printer
->unknown29
= 0;
4018 free_a_printer(&ntprinter
,2);
4022 /********************************************************************
4023 * construct_printer_info_1
4024 * fill a printer_info_1 struct
4025 ********************************************************************/
4026 static bool construct_printer_info_1(Printer_entry
*print_hnd
, uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
4028 char *chaine
= NULL
;
4029 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4030 TALLOC_CTX
*ctx
= talloc_tos();
4032 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4035 printer
->flags
=flags
;
4037 if (*ntprinter
->info_2
->comment
== '\0') {
4038 init_unistr(&printer
->comment
, lp_comment(snum
));
4039 chaine
= talloc_asprintf(ctx
,
4040 "%s,%s,%s", ntprinter
->info_2
->printername
,
4041 ntprinter
->info_2
->drivername
, lp_comment(snum
));
4044 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4045 chaine
= talloc_asprintf(ctx
,
4046 "%s,%s,%s", ntprinter
->info_2
->printername
,
4047 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
4051 free_a_printer(&ntprinter
,2);
4055 init_unistr(&printer
->description
, chaine
);
4056 init_unistr(&printer
->name
, ntprinter
->info_2
->printername
);
4058 free_a_printer(&ntprinter
,2);
4063 /****************************************************************************
4064 Free a DEVMODE struct.
4065 ****************************************************************************/
4067 static void free_dev_mode(DEVICEMODE
*dev
)
4072 SAFE_FREE(dev
->dev_private
);
4077 /****************************************************************************
4078 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4079 should be valid upon entry
4080 ****************************************************************************/
4082 static bool convert_nt_devicemode( DEVICEMODE
*devmode
, NT_DEVICEMODE
*ntdevmode
)
4084 if ( !devmode
|| !ntdevmode
)
4087 init_unistr(&devmode
->devicename
, ntdevmode
->devicename
);
4089 init_unistr(&devmode
->formname
, ntdevmode
->formname
);
4091 devmode
->specversion
= ntdevmode
->specversion
;
4092 devmode
->driverversion
= ntdevmode
->driverversion
;
4093 devmode
->size
= ntdevmode
->size
;
4094 devmode
->driverextra
= ntdevmode
->driverextra
;
4095 devmode
->fields
= ntdevmode
->fields
;
4097 devmode
->orientation
= ntdevmode
->orientation
;
4098 devmode
->papersize
= ntdevmode
->papersize
;
4099 devmode
->paperlength
= ntdevmode
->paperlength
;
4100 devmode
->paperwidth
= ntdevmode
->paperwidth
;
4101 devmode
->scale
= ntdevmode
->scale
;
4102 devmode
->copies
= ntdevmode
->copies
;
4103 devmode
->defaultsource
= ntdevmode
->defaultsource
;
4104 devmode
->printquality
= ntdevmode
->printquality
;
4105 devmode
->color
= ntdevmode
->color
;
4106 devmode
->duplex
= ntdevmode
->duplex
;
4107 devmode
->yresolution
= ntdevmode
->yresolution
;
4108 devmode
->ttoption
= ntdevmode
->ttoption
;
4109 devmode
->collate
= ntdevmode
->collate
;
4110 devmode
->icmmethod
= ntdevmode
->icmmethod
;
4111 devmode
->icmintent
= ntdevmode
->icmintent
;
4112 devmode
->mediatype
= ntdevmode
->mediatype
;
4113 devmode
->dithertype
= ntdevmode
->dithertype
;
4115 if (ntdevmode
->nt_dev_private
!= NULL
) {
4116 if ((devmode
->dev_private
=(uint8
*)memdup(ntdevmode
->nt_dev_private
, ntdevmode
->driverextra
)) == NULL
)
4123 /****************************************************************************
4124 Create a DEVMODE struct. Returns malloced memory.
4125 ****************************************************************************/
4127 DEVICEMODE
*construct_dev_mode(const char *servicename
)
4129 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4130 DEVICEMODE
*devmode
= NULL
;
4132 DEBUG(7,("construct_dev_mode\n"));
4134 DEBUGADD(8,("getting printer characteristics\n"));
4136 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
4139 if ( !printer
->info_2
->devmode
) {
4140 DEBUG(5, ("BONG! There was no device mode!\n"));
4144 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) == NULL
) {
4145 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4149 ZERO_STRUCTP(devmode
);
4151 DEBUGADD(8,("loading DEVICEMODE\n"));
4153 if ( !convert_nt_devicemode( devmode
, printer
->info_2
->devmode
) ) {
4154 free_dev_mode( devmode
);
4159 free_a_printer(&printer
,2);
4164 /********************************************************************
4165 * construct_printer_info_2
4166 * fill a printer_info_2 struct
4167 ********************************************************************/
4169 static bool construct_printer_info_2(Printer_entry
*print_hnd
, PRINTER_INFO_2
*printer
, int snum
)
4172 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4174 print_status_struct status
;
4176 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4179 count
= print_queue_length(snum
, &status
);
4181 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4182 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4183 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
4184 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
4185 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
4187 if (*ntprinter
->info_2
->comment
== '\0')
4188 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
4190 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4192 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
4193 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
4194 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
4195 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
4196 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
4198 printer
->attributes
= ntprinter
->info_2
->attributes
;
4200 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
4201 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
4202 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
4203 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
4204 printer
->status
= nt_printq_status(status
.status
); /* status */
4205 printer
->cjobs
= count
; /* jobs */
4206 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
4208 if ( !(printer
->devmode
= construct_dev_mode(
4209 lp_const_servicename(snum
))) )
4210 DEBUG(8, ("Returning NULL Devicemode!\n"));
4212 printer
->secdesc
= NULL
;
4214 if ( ntprinter
->info_2
->secdesc_buf
4215 && ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0 )
4217 /* don't use talloc_steal() here unless you do a deep steal of all
4218 the SEC_DESC members */
4220 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4221 ntprinter
->info_2
->secdesc_buf
->sd
);
4224 free_a_printer(&ntprinter
, 2);
4229 /********************************************************************
4230 * construct_printer_info_3
4231 * fill a printer_info_3 struct
4232 ********************************************************************/
4234 static bool construct_printer_info_3(Printer_entry
*print_hnd
, PRINTER_INFO_3
**pp_printer
, int snum
)
4236 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4237 PRINTER_INFO_3
*printer
= NULL
;
4239 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4243 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_3
)) == NULL
) {
4244 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4245 free_a_printer(&ntprinter
, 2);
4249 ZERO_STRUCTP(printer
);
4251 /* These are the components of the SD we are returning. */
4253 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
4254 /* don't use talloc_steal() here unless you do a deep steal of all
4255 the SEC_DESC members */
4257 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4258 ntprinter
->info_2
->secdesc_buf
->sd
);
4261 free_a_printer(&ntprinter
, 2);
4263 *pp_printer
= printer
;
4267 /********************************************************************
4268 * construct_printer_info_4
4269 * fill a printer_info_4 struct
4270 ********************************************************************/
4272 static bool construct_printer_info_4(Printer_entry
*print_hnd
, PRINTER_INFO_4
*printer
, int snum
)
4274 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4276 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4279 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4280 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4281 printer
->attributes
= ntprinter
->info_2
->attributes
;
4283 free_a_printer(&ntprinter
, 2);
4287 /********************************************************************
4288 * construct_printer_info_5
4289 * fill a printer_info_5 struct
4290 ********************************************************************/
4292 static bool construct_printer_info_5(Printer_entry
*print_hnd
, PRINTER_INFO_5
*printer
, int snum
)
4294 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4296 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4299 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
4300 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
);
4301 printer
->attributes
= ntprinter
->info_2
->attributes
;
4303 /* these two are not used by NT+ according to MSDN */
4305 printer
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
4306 printer
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
4308 free_a_printer(&ntprinter
, 2);
4313 /********************************************************************
4314 * construct_printer_info_6
4315 * fill a printer_info_6 struct
4316 ********************************************************************/
4318 static bool construct_printer_info_6(Printer_entry
*print_hnd
,
4319 PRINTER_INFO_6
*printer
,
4322 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4324 print_status_struct status
;
4326 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2,
4327 lp_const_servicename(snum
))))
4330 count
= print_queue_length(snum
, &status
);
4332 printer
->status
= nt_printq_status(status
.status
);
4334 free_a_printer(&ntprinter
, 2);
4339 /********************************************************************
4340 * construct_printer_info_7
4341 * fill a printer_info_7 struct
4342 ********************************************************************/
4344 static bool construct_printer_info_7(Printer_entry
*print_hnd
, PRINTER_INFO_7
*printer
, int snum
)
4346 char *guid_str
= NULL
;
4349 if (is_printer_published(print_hnd
, snum
, &guid
)) {
4350 if (asprintf(&guid_str
, "{%s}",
4351 GUID_string(talloc_tos(), &guid
)) == -1) {
4354 strupper_m(guid_str
);
4355 init_unistr(&printer
->guid
, guid_str
);
4356 SAFE_FREE(guid_str
);
4357 printer
->action
= SPOOL_DS_PUBLISH
;
4359 init_unistr(&printer
->guid
, "");
4360 printer
->action
= SPOOL_DS_UNPUBLISH
;
4366 /********************************************************************
4367 Spoolss_enumprinters.
4368 ********************************************************************/
4370 static WERROR
enum_all_printers_info_1(uint32 flags
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4374 int n_services
=lp_numservices();
4375 PRINTER_INFO_1
*printers
=NULL
;
4376 PRINTER_INFO_1 current_prt
;
4377 WERROR result
= WERR_OK
;
4379 DEBUG(4,("enum_all_printers_info_1\n"));
4381 for (snum
=0; snum
<n_services
; snum
++) {
4382 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4383 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4385 if (construct_printer_info_1(NULL
, flags
, ¤t_prt
, snum
)) {
4386 if((printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_1
, *returned
+1)) == NULL
) {
4387 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4391 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4393 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4399 /* check the required size. */
4400 for (i
=0; i
<*returned
; i
++)
4401 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4403 if (*needed
> offered
) {
4404 result
= WERR_INSUFFICIENT_BUFFER
;
4408 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4409 result
= WERR_NOMEM
;
4413 /* fill the buffer with the structures */
4414 for (i
=0; i
<*returned
; i
++)
4415 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4420 SAFE_FREE(printers
);
4422 if ( !W_ERROR_IS_OK(result
) )
4428 /********************************************************************
4429 enum_all_printers_info_1_local.
4430 *********************************************************************/
4432 static WERROR
enum_all_printers_info_1_local(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4434 DEBUG(4,("enum_all_printers_info_1_local\n"));
4436 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4439 /********************************************************************
4440 enum_all_printers_info_1_name.
4441 *********************************************************************/
4443 static WERROR
enum_all_printers_info_1_name(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4447 DEBUG(4,("enum_all_printers_info_1_name\n"));
4449 if ((name
[0] == '\\') && (name
[1] == '\\'))
4452 if (is_myname_or_ipaddr(s
)) {
4453 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4456 return WERR_INVALID_NAME
;
4459 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4460 /********************************************************************
4461 enum_all_printers_info_1_remote.
4462 *********************************************************************/
4464 static WERROR
enum_all_printers_info_1_remote(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4466 PRINTER_INFO_1
*printer
;
4467 fstring printername
;
4470 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4471 WERROR result
= WERR_OK
;
4473 /* JFM: currently it's more a place holder than anything else.
4474 * In the spooler world there is a notion of server registration.
4475 * the print servers are registered on the PDC (in the same domain)
4477 * We should have a TDB here. The registration is done thru an
4478 * undocumented RPC call.
4481 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4486 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", name
);
4487 slprintf(desc
, sizeof(desc
)-1,"%s", name
);
4488 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4490 init_unistr(&printer
->description
, desc
);
4491 init_unistr(&printer
->name
, printername
);
4492 init_unistr(&printer
->comment
, comment
);
4493 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4495 /* check the required size. */
4496 *needed
+= spoolss_size_printer_info_1(printer
);
4498 if (*needed
> offered
) {
4499 result
= WERR_INSUFFICIENT_BUFFER
;
4503 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4504 result
= WERR_NOMEM
;
4508 /* fill the buffer with the structures */
4509 smb_io_printer_info_1("", buffer
, printer
, 0);
4515 if ( !W_ERROR_IS_OK(result
) )
4523 /********************************************************************
4524 enum_all_printers_info_1_network.
4525 *********************************************************************/
4527 static WERROR
enum_all_printers_info_1_network(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4531 DEBUG(4,("enum_all_printers_info_1_network\n"));
4533 /* If we respond to a enum_printers level 1 on our name with flags
4534 set to PRINTER_ENUM_REMOTE with a list of printers then these
4535 printers incorrectly appear in the APW browse list.
4536 Specifically the printers for the server appear at the workgroup
4537 level where all the other servers in the domain are
4538 listed. Windows responds to this call with a
4539 WERR_CAN_NOT_COMPLETE so we should do the same. */
4541 if (name
[0] == '\\' && name
[1] == '\\')
4544 if (is_myname_or_ipaddr(s
))
4545 return WERR_CAN_NOT_COMPLETE
;
4547 return enum_all_printers_info_1(PRINTER_ENUM_NAME
, buffer
, offered
, needed
, returned
);
4550 /********************************************************************
4551 * api_spoolss_enumprinters
4553 * called from api_spoolss_enumprinters (see this to understand)
4554 ********************************************************************/
4556 static WERROR
enum_all_printers_info_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4560 int n_services
=lp_numservices();
4561 PRINTER_INFO_2
*printers
=NULL
;
4562 PRINTER_INFO_2 current_prt
;
4563 WERROR result
= WERR_OK
;
4567 for (snum
=0; snum
<n_services
; snum
++) {
4568 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4569 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4571 if (construct_printer_info_2(NULL
, ¤t_prt
, snum
)) {
4572 if ( !(printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_2
, *returned
+1)) ) {
4573 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4578 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
+ 1));
4580 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4587 /* check the required size. */
4588 for (i
=0; i
<*returned
; i
++)
4589 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4591 if (*needed
> offered
) {
4592 result
= WERR_INSUFFICIENT_BUFFER
;
4596 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4597 result
= WERR_NOMEM
;
4601 /* fill the buffer with the structures */
4602 for (i
=0; i
<*returned
; i
++)
4603 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4608 for (i
=0; i
<*returned
; i
++)
4609 free_devmode(printers
[i
].devmode
);
4611 SAFE_FREE(printers
);
4613 if ( !W_ERROR_IS_OK(result
) )
4619 /********************************************************************
4620 * handle enumeration of printers at level 1
4621 ********************************************************************/
4623 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4624 RPC_BUFFER
*buffer
, uint32 offered
,
4625 uint32
*needed
, uint32
*returned
)
4627 /* Not all the flags are equals */
4629 if (flags
& PRINTER_ENUM_LOCAL
)
4630 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4632 if (flags
& PRINTER_ENUM_NAME
)
4633 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4635 #if 0 /* JERRY - disabled for now */
4636 if (flags
& PRINTER_ENUM_REMOTE
)
4637 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4640 if (flags
& PRINTER_ENUM_NETWORK
)
4641 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4643 return WERR_OK
; /* NT4sp5 does that */
4646 /********************************************************************
4647 * handle enumeration of printers at level 2
4648 ********************************************************************/
4650 static WERROR
enumprinters_level2( uint32 flags
, const char *servername
,
4651 RPC_BUFFER
*buffer
, uint32 offered
,
4652 uint32
*needed
, uint32
*returned
)
4654 if (flags
& PRINTER_ENUM_LOCAL
) {
4655 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4658 if (flags
& PRINTER_ENUM_NAME
) {
4659 if (is_myname_or_ipaddr(canon_servername(servername
)))
4660 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4662 return WERR_INVALID_NAME
;
4665 if (flags
& PRINTER_ENUM_REMOTE
)
4666 return WERR_UNKNOWN_LEVEL
;
4671 /********************************************************************
4672 * handle enumeration of printers at level 5
4673 ********************************************************************/
4675 static WERROR
enumprinters_level5( uint32 flags
, const char *servername
,
4676 RPC_BUFFER
*buffer
, uint32 offered
,
4677 uint32
*needed
, uint32
*returned
)
4679 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4683 /********************************************************************
4684 * api_spoolss_enumprinters
4686 * called from api_spoolss_enumprinters (see this to understand)
4687 ********************************************************************/
4689 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4691 uint32 flags
= q_u
->flags
;
4692 UNISTR2
*servername
= &q_u
->servername
;
4693 uint32 level
= q_u
->level
;
4694 RPC_BUFFER
*buffer
= NULL
;
4695 uint32 offered
= q_u
->offered
;
4696 uint32
*needed
= &r_u
->needed
;
4697 uint32
*returned
= &r_u
->returned
;
4701 /* that's an [in out] buffer */
4703 if (!q_u
->buffer
&& (offered
!=0)) {
4704 return WERR_INVALID_PARAM
;
4707 if (offered
> MAX_RPC_DATA_SIZE
) {
4708 return WERR_INVALID_PARAM
;
4711 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
4712 buffer
= r_u
->buffer
;
4714 DEBUG(4,("_spoolss_enumprinters\n"));
4721 * flags==PRINTER_ENUM_NAME
4722 * if name=="" then enumerates all printers
4723 * if name!="" then enumerate the printer
4724 * flags==PRINTER_ENUM_REMOTE
4725 * name is NULL, enumerate printers
4726 * Level 2: name!="" enumerates printers, name can't be NULL
4727 * Level 3: doesn't exist
4728 * Level 4: does a local registry lookup
4729 * Level 5: same as Level 2
4732 unistr2_to_ascii(name
, servername
, sizeof(name
));
4737 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4739 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4741 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4746 return WERR_UNKNOWN_LEVEL
;
4749 /****************************************************************************
4750 ****************************************************************************/
4752 static WERROR
getprinter_level_0(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4754 PRINTER_INFO_0
*printer
=NULL
;
4755 WERROR result
= WERR_OK
;
4757 if((printer
=SMB_MALLOC_P(PRINTER_INFO_0
)) == NULL
)
4760 construct_printer_info_0(print_hnd
, printer
, snum
);
4762 /* check the required size. */
4763 *needed
+= spoolss_size_printer_info_0(printer
);
4765 if (*needed
> offered
) {
4766 result
= WERR_INSUFFICIENT_BUFFER
;
4770 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4771 result
= WERR_NOMEM
;
4775 /* fill the buffer with the structures */
4776 smb_io_printer_info_0("", buffer
, printer
, 0);
4786 /****************************************************************************
4787 ****************************************************************************/
4789 static WERROR
getprinter_level_1(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4791 PRINTER_INFO_1
*printer
=NULL
;
4792 WERROR result
= WERR_OK
;
4794 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4797 construct_printer_info_1(print_hnd
, PRINTER_ENUM_ICON8
, printer
, snum
);
4799 /* check the required size. */
4800 *needed
+= spoolss_size_printer_info_1(printer
);
4802 if (*needed
> offered
) {
4803 result
= WERR_INSUFFICIENT_BUFFER
;
4807 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4808 result
= WERR_NOMEM
;
4812 /* fill the buffer with the structures */
4813 smb_io_printer_info_1("", buffer
, printer
, 0);
4822 /****************************************************************************
4823 ****************************************************************************/
4825 static WERROR
getprinter_level_2(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4827 PRINTER_INFO_2
*printer
=NULL
;
4828 WERROR result
= WERR_OK
;
4830 if((printer
=SMB_MALLOC_P(PRINTER_INFO_2
))==NULL
)
4833 construct_printer_info_2(print_hnd
, printer
, snum
);
4835 /* check the required size. */
4836 *needed
+= spoolss_size_printer_info_2(printer
);
4838 if (*needed
> offered
) {
4839 result
= WERR_INSUFFICIENT_BUFFER
;
4843 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4844 result
= WERR_NOMEM
;
4848 /* fill the buffer with the structures */
4849 if (!smb_io_printer_info_2("", buffer
, printer
, 0))
4850 result
= WERR_NOMEM
;
4854 free_printer_info_2(printer
);
4859 /****************************************************************************
4860 ****************************************************************************/
4862 static WERROR
getprinter_level_3(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4864 PRINTER_INFO_3
*printer
=NULL
;
4865 WERROR result
= WERR_OK
;
4867 if (!construct_printer_info_3(print_hnd
, &printer
, snum
))
4870 /* check the required size. */
4871 *needed
+= spoolss_size_printer_info_3(printer
);
4873 if (*needed
> offered
) {
4874 result
= WERR_INSUFFICIENT_BUFFER
;
4878 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4879 result
= WERR_NOMEM
;
4883 /* fill the buffer with the structures */
4884 smb_io_printer_info_3("", buffer
, printer
, 0);
4888 free_printer_info_3(printer
);
4893 /****************************************************************************
4894 ****************************************************************************/
4896 static WERROR
getprinter_level_4(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4898 PRINTER_INFO_4
*printer
=NULL
;
4899 WERROR result
= WERR_OK
;
4901 if((printer
=SMB_MALLOC_P(PRINTER_INFO_4
))==NULL
)
4904 if (!construct_printer_info_4(print_hnd
, printer
, snum
)) {
4909 /* check the required size. */
4910 *needed
+= spoolss_size_printer_info_4(printer
);
4912 if (*needed
> offered
) {
4913 result
= WERR_INSUFFICIENT_BUFFER
;
4917 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4918 result
= WERR_NOMEM
;
4922 /* fill the buffer with the structures */
4923 smb_io_printer_info_4("", buffer
, printer
, 0);
4927 free_printer_info_4(printer
);
4932 /****************************************************************************
4933 ****************************************************************************/
4935 static WERROR
getprinter_level_5(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4937 PRINTER_INFO_5
*printer
=NULL
;
4938 WERROR result
= WERR_OK
;
4940 if((printer
=SMB_MALLOC_P(PRINTER_INFO_5
))==NULL
)
4943 if (!construct_printer_info_5(print_hnd
, printer
, snum
)) {
4944 free_printer_info_5(printer
);
4948 /* check the required size. */
4949 *needed
+= spoolss_size_printer_info_5(printer
);
4951 if (*needed
> offered
) {
4952 result
= WERR_INSUFFICIENT_BUFFER
;
4956 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4957 result
= WERR_NOMEM
;
4961 /* fill the buffer with the structures */
4962 smb_io_printer_info_5("", buffer
, printer
, 0);
4966 free_printer_info_5(printer
);
4971 static WERROR
getprinter_level_6(Printer_entry
*print_hnd
,
4973 RPC_BUFFER
*buffer
, uint32 offered
,
4976 PRINTER_INFO_6
*printer
;
4977 WERROR result
= WERR_OK
;
4979 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_6
)) == NULL
) {
4983 if (!construct_printer_info_6(print_hnd
, printer
, snum
)) {
4984 free_printer_info_6(printer
);
4988 /* check the required size. */
4989 *needed
+= spoolss_size_printer_info_6(printer
);
4991 if (*needed
> offered
) {
4992 result
= WERR_INSUFFICIENT_BUFFER
;
4996 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4997 result
= WERR_NOMEM
;
5001 /* fill the buffer with the structures */
5002 smb_io_printer_info_6("", buffer
, printer
, 0);
5006 free_printer_info_6(printer
);
5011 static WERROR
getprinter_level_7(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5013 PRINTER_INFO_7
*printer
=NULL
;
5014 WERROR result
= WERR_OK
;
5016 if((printer
=SMB_MALLOC_P(PRINTER_INFO_7
))==NULL
)
5019 if (!construct_printer_info_7(print_hnd
, printer
, snum
)) {
5020 result
= WERR_NOMEM
;
5024 /* check the required size. */
5025 *needed
+= spoolss_size_printer_info_7(printer
);
5027 if (*needed
> offered
) {
5028 result
= WERR_INSUFFICIENT_BUFFER
;
5032 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5033 result
= WERR_NOMEM
;
5038 /* fill the buffer with the structures */
5039 smb_io_printer_info_7("", buffer
, printer
, 0);
5043 free_printer_info_7(printer
);
5048 /****************************************************************************
5049 ****************************************************************************/
5051 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
5053 POLICY_HND
*handle
= &q_u
->handle
;
5054 uint32 level
= q_u
->level
;
5055 RPC_BUFFER
*buffer
= NULL
;
5056 uint32 offered
= q_u
->offered
;
5057 uint32
*needed
= &r_u
->needed
;
5058 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
5062 /* that's an [in out] buffer */
5064 if (!q_u
->buffer
&& (offered
!=0)) {
5065 return WERR_INVALID_PARAM
;
5068 if (offered
> MAX_RPC_DATA_SIZE
) {
5069 return WERR_INVALID_PARAM
;
5072 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5073 buffer
= r_u
->buffer
;
5077 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5082 return getprinter_level_0(Printer
, snum
, buffer
, offered
, needed
);
5084 return getprinter_level_1(Printer
, snum
, buffer
, offered
, needed
);
5086 return getprinter_level_2(Printer
, snum
, buffer
, offered
, needed
);
5088 return getprinter_level_3(Printer
, snum
, buffer
, offered
, needed
);
5090 return getprinter_level_4(Printer
, snum
, buffer
, offered
, needed
);
5092 return getprinter_level_5(Printer
, snum
, buffer
, offered
, needed
);
5094 return getprinter_level_6(Printer
, snum
, buffer
, offered
, needed
);
5096 return getprinter_level_7(Printer
, snum
, buffer
, offered
, needed
);
5098 return WERR_UNKNOWN_LEVEL
;
5101 /********************************************************************
5102 * fill a DRIVER_INFO_1 struct
5103 ********************************************************************/
5105 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
, fstring architecture
)
5107 init_unistr( &info
->name
, driver
.info_3
->name
);
5110 /********************************************************************
5111 * construct_printer_driver_info_1
5112 ********************************************************************/
5114 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5116 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5117 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5119 ZERO_STRUCT(driver
);
5121 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5122 return WERR_INVALID_PRINTER_NAME
;
5124 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5125 free_a_printer(&printer
, 2);
5126 return WERR_UNKNOWN_PRINTER_DRIVER
;
5129 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
5131 free_a_printer(&printer
,2);
5136 /********************************************************************
5137 * construct_printer_driver_info_2
5138 * fill a printer_info_2 struct
5139 ********************************************************************/
5141 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5143 TALLOC_CTX
*ctx
= talloc_tos();
5145 const char *cservername
= canon_servername(servername
);
5147 info
->version
=driver
.info_3
->cversion
;
5149 init_unistr( &info
->name
, driver
.info_3
->name
);
5150 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5152 if (strlen(driver
.info_3
->driverpath
)) {
5153 temp
= talloc_asprintf(ctx
,
5156 driver
.info_3
->driverpath
);
5157 init_unistr( &info
->driverpath
, temp
);
5159 init_unistr( &info
->driverpath
, "" );
5163 if (strlen(driver
.info_3
->datafile
)) {
5164 temp
= talloc_asprintf(ctx
,
5167 driver
.info_3
->datafile
);
5168 init_unistr( &info
->datafile
, temp
);
5170 init_unistr( &info
->datafile
, "" );
5173 if (strlen(driver
.info_3
->configfile
)) {
5174 temp
= talloc_asprintf(ctx
,
5177 driver
.info_3
->configfile
);
5178 init_unistr( &info
->configfile
, temp
);
5180 init_unistr( &info
->configfile
, "" );
5183 /********************************************************************
5184 * construct_printer_driver_info_2
5185 * fill a printer_info_2 struct
5186 ********************************************************************/
5188 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5190 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5191 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5193 ZERO_STRUCT(printer
);
5194 ZERO_STRUCT(driver
);
5196 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5197 return WERR_INVALID_PRINTER_NAME
;
5199 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5200 free_a_printer(&printer
, 2);
5201 return WERR_UNKNOWN_PRINTER_DRIVER
;
5204 fill_printer_driver_info_2(info
, driver
, servername
);
5206 free_a_printer(&printer
,2);
5211 /********************************************************************
5212 * copy a strings array and convert to UNICODE
5214 * convert an array of ascii string to a UNICODE string
5215 ********************************************************************/
5217 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, const char *servername
)
5223 TALLOC_CTX
*ctx
= talloc_tos();
5225 DEBUG(6,("init_unistr_array\n"));
5229 if ( !char_array
) {
5234 v
= ""; /* hack to handle null lists */
5237 /* hack to allow this to be used in places other than when generating
5238 the list of dependent files */
5242 line
= talloc_asprintf(ctx
,
5244 canon_servername(servername
),
5247 line
= talloc_strdup(ctx
, v
);
5251 SAFE_FREE(*uni_array
);
5254 DEBUGADD(6,("%d:%s:%lu\n", i
, line
, (unsigned long)strlen(line
)));
5256 /* add one extra unit16 for the second terminating NULL */
5258 if ( (*uni_array
=SMB_REALLOC_ARRAY(*uni_array
, uint16
, j
+1+strlen(line
)+2)) == NULL
) {
5259 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5266 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
5271 /* special case for ""; we need to add both NULL's here */
5273 (*uni_array
)[j
++]=0x0000;
5274 (*uni_array
)[j
]=0x0000;
5277 DEBUGADD(6,("last one:done\n"));
5279 /* return size of array in uint16's */
5284 /********************************************************************
5285 * construct_printer_info_3
5286 * fill a printer_info_3 struct
5287 ********************************************************************/
5289 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5292 TALLOC_CTX
*ctx
= talloc_tos();
5293 const char *cservername
= canon_servername(servername
);
5297 info
->version
=driver
.info_3
->cversion
;
5299 init_unistr( &info
->name
, driver
.info_3
->name
);
5300 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5302 if (strlen(driver
.info_3
->driverpath
)) {
5303 temp
= talloc_asprintf(ctx
,
5306 driver
.info_3
->driverpath
);
5307 init_unistr( &info
->driverpath
, temp
);
5309 init_unistr( &info
->driverpath
, "" );
5312 if (strlen(driver
.info_3
->datafile
)) {
5313 temp
= talloc_asprintf(ctx
,
5316 driver
.info_3
->datafile
);
5317 init_unistr( &info
->datafile
, temp
);
5319 init_unistr( &info
->datafile
, "" );
5322 if (strlen(driver
.info_3
->configfile
)) {
5323 temp
= talloc_asprintf(ctx
,
5326 driver
.info_3
->configfile
);
5327 init_unistr( &info
->configfile
, temp
);
5329 init_unistr( &info
->configfile
, "" );
5332 if (strlen(driver
.info_3
->helpfile
)) {
5333 temp
= talloc_asprintf(ctx
,
5336 driver
.info_3
->helpfile
);
5337 init_unistr( &info
->helpfile
, temp
);
5339 init_unistr( &info
->helpfile
, "" );
5342 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5343 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5345 info
->dependentfiles
=NULL
;
5346 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, cservername
);
5349 /********************************************************************
5350 * construct_printer_info_3
5351 * fill a printer_info_3 struct
5352 ********************************************************************/
5354 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5356 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5357 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5359 ZERO_STRUCT(driver
);
5361 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5362 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5363 if (!W_ERROR_IS_OK(status
))
5364 return WERR_INVALID_PRINTER_NAME
;
5366 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5367 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5372 * I put this code in during testing. Helpful when commenting out the
5373 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5374 * as win2k always queries the driver using an infor level of 6.
5375 * I've left it in (but ifdef'd out) because I'll probably
5376 * use it in experimentation again in the future. --jerry 22/01/2002
5379 if (!W_ERROR_IS_OK(status
)) {
5381 * Is this a W2k client ?
5384 /* Yes - try again with a WinNT driver. */
5386 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5387 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5391 if (!W_ERROR_IS_OK(status
)) {
5392 free_a_printer(&printer
,2);
5393 return WERR_UNKNOWN_PRINTER_DRIVER
;
5401 fill_printer_driver_info_3(info
, driver
, servername
);
5403 free_a_printer(&printer
,2);
5408 /********************************************************************
5409 * construct_printer_info_6
5410 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5411 ********************************************************************/
5413 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5417 TALLOC_CTX
*ctx
= talloc_tos();
5418 const char *cservername
= canon_servername(servername
);
5421 memset(&nullstr
, '\0', sizeof(fstring
));
5423 info
->version
=driver
.info_3
->cversion
;
5425 init_unistr( &info
->name
, driver
.info_3
->name
);
5426 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5428 if (strlen(driver
.info_3
->driverpath
)) {
5429 temp
= talloc_asprintf(ctx
,
5432 driver
.info_3
->driverpath
);
5433 init_unistr( &info
->driverpath
, temp
);
5435 init_unistr( &info
->driverpath
, "" );
5438 if (strlen(driver
.info_3
->datafile
)) {
5439 temp
= talloc_asprintf(ctx
,
5442 driver
.info_3
->datafile
);
5443 init_unistr( &info
->datafile
, temp
);
5445 init_unistr( &info
->datafile
, "" );
5448 if (strlen(driver
.info_3
->configfile
)) {
5449 temp
= talloc_asprintf(ctx
,
5452 driver
.info_3
->configfile
);
5453 init_unistr( &info
->configfile
, temp
);
5455 init_unistr( &info
->configfile
, "" );
5458 if (strlen(driver
.info_3
->helpfile
)) {
5459 temp
= talloc_asprintf(ctx
,
5462 driver
.info_3
->helpfile
);
5463 init_unistr( &info
->helpfile
, temp
);
5465 init_unistr( &info
->helpfile
, "" );
5468 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5469 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5471 info
->dependentfiles
= NULL
;
5472 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5474 info
->previousdrivernames
=NULL
;
5475 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
5477 info
->driver_date
=0;
5480 info
->driver_version_low
=0;
5481 info
->driver_version_high
=0;
5483 init_unistr( &info
->mfgname
, "");
5484 init_unistr( &info
->oem_url
, "");
5485 init_unistr( &info
->hardware_id
, "");
5486 init_unistr( &info
->provider
, "");
5489 /********************************************************************
5490 * construct_printer_info_6
5491 * fill a printer_info_6 struct
5492 ********************************************************************/
5494 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
5495 const char *servername
, fstring architecture
, uint32 version
)
5497 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5498 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5501 ZERO_STRUCT(driver
);
5503 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5505 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5507 if (!W_ERROR_IS_OK(status
))
5508 return WERR_INVALID_PRINTER_NAME
;
5510 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5512 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5514 if (!W_ERROR_IS_OK(status
))
5517 * Is this a W2k client ?
5521 free_a_printer(&printer
,2);
5522 return WERR_UNKNOWN_PRINTER_DRIVER
;
5525 /* Yes - try again with a WinNT driver. */
5527 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5528 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5529 if (!W_ERROR_IS_OK(status
)) {
5530 free_a_printer(&printer
,2);
5531 return WERR_UNKNOWN_PRINTER_DRIVER
;
5535 fill_printer_driver_info_6(info
, driver
, servername
);
5537 free_a_printer(&printer
,2);
5538 free_a_printer_driver(driver
, 3);
5543 /****************************************************************************
5544 ****************************************************************************/
5546 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5548 SAFE_FREE(info
->dependentfiles
);
5551 /****************************************************************************
5552 ****************************************************************************/
5554 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5556 SAFE_FREE(info
->dependentfiles
);
5559 /****************************************************************************
5560 ****************************************************************************/
5562 static WERROR
getprinterdriver2_level1(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5564 DRIVER_INFO_1
*info
=NULL
;
5567 if((info
=SMB_MALLOC_P(DRIVER_INFO_1
)) == NULL
)
5570 result
= construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5571 if (!W_ERROR_IS_OK(result
))
5574 /* check the required size. */
5575 *needed
+= spoolss_size_printer_driver_info_1(info
);
5577 if (*needed
> offered
) {
5578 result
= WERR_INSUFFICIENT_BUFFER
;
5582 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5583 result
= WERR_NOMEM
;
5587 /* fill the buffer with the structures */
5588 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5597 /****************************************************************************
5598 ****************************************************************************/
5600 static WERROR
getprinterdriver2_level2(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5602 DRIVER_INFO_2
*info
=NULL
;
5605 if((info
=SMB_MALLOC_P(DRIVER_INFO_2
)) == NULL
)
5608 result
= construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5609 if (!W_ERROR_IS_OK(result
))
5612 /* check the required size. */
5613 *needed
+= spoolss_size_printer_driver_info_2(info
);
5615 if (*needed
> offered
) {
5616 result
= WERR_INSUFFICIENT_BUFFER
;
5620 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5621 result
= WERR_NOMEM
;
5625 /* fill the buffer with the structures */
5626 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5635 /****************************************************************************
5636 ****************************************************************************/
5638 static WERROR
getprinterdriver2_level3(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5645 result
= construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5646 if (!W_ERROR_IS_OK(result
))
5649 /* check the required size. */
5650 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5652 if (*needed
> offered
) {
5653 result
= WERR_INSUFFICIENT_BUFFER
;
5657 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5658 result
= WERR_NOMEM
;
5662 /* fill the buffer with the structures */
5663 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5666 free_printer_driver_info_3(&info
);
5671 /****************************************************************************
5672 ****************************************************************************/
5674 static WERROR
getprinterdriver2_level6(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5681 result
= construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5682 if (!W_ERROR_IS_OK(result
))
5685 /* check the required size. */
5686 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5688 if (*needed
> offered
) {
5689 result
= WERR_INSUFFICIENT_BUFFER
;
5693 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5694 result
= WERR_NOMEM
;
5698 /* fill the buffer with the structures */
5699 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5702 free_printer_driver_info_6(&info
);
5707 /****************************************************************************
5708 ****************************************************************************/
5710 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5712 POLICY_HND
*handle
= &q_u
->handle
;
5713 UNISTR2
*uni_arch
= &q_u
->architecture
;
5714 uint32 level
= q_u
->level
;
5715 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5716 RPC_BUFFER
*buffer
= NULL
;
5717 uint32 offered
= q_u
->offered
;
5718 uint32
*needed
= &r_u
->needed
;
5719 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5720 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5721 Printer_entry
*printer
;
5724 fstring architecture
;
5727 /* that's an [in out] buffer */
5729 if (!q_u
->buffer
&& (offered
!=0)) {
5730 return WERR_INVALID_PARAM
;
5733 if (offered
> MAX_RPC_DATA_SIZE
) {
5734 return WERR_INVALID_PARAM
;
5737 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5738 buffer
= r_u
->buffer
;
5740 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5742 if ( !(printer
= find_printer_index_by_hnd( p
, handle
)) ) {
5743 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5744 return WERR_INVALID_PRINTER_NAME
;
5748 *servermajorversion
= 0;
5749 *serverminorversion
= 0;
5751 fstrcpy(servername
, get_server_name( printer
));
5752 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
));
5754 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5759 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5761 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5763 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5765 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5768 /* apparently this call is the equivalent of
5769 EnumPrinterDataEx() for the DsDriver key */
5774 return WERR_UNKNOWN_LEVEL
;
5778 /****************************************************************
5779 _spoolss_StartPagePrinter
5780 ****************************************************************/
5782 WERROR
_spoolss_StartPagePrinter(pipes_struct
*p
,
5783 struct spoolss_StartPagePrinter
*r
)
5785 POLICY_HND
*handle
= r
->in
.handle
;
5787 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5790 DEBUG(3,("_spoolss_StartPagePrinter: "
5791 "Error in startpageprinter printer handle\n"));
5795 Printer
->page_started
=True
;
5799 /****************************************************************
5800 _spoolss_EndPagePrinter
5801 ****************************************************************/
5803 WERROR
_spoolss_EndPagePrinter(pipes_struct
*p
,
5804 struct spoolss_EndPagePrinter
*r
)
5806 POLICY_HND
*handle
= r
->in
.handle
;
5809 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5812 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5813 OUR_HANDLE(handle
)));
5817 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5820 Printer
->page_started
=False
;
5821 print_job_endpage(snum
, Printer
->jobid
);
5826 /****************************************************************
5827 _spoolss_StartDocPrinter
5828 ****************************************************************/
5830 WERROR
_spoolss_StartDocPrinter(pipes_struct
*p
,
5831 struct spoolss_StartDocPrinter
*r
)
5833 POLICY_HND
*handle
= r
->in
.handle
;
5834 uint32_t *jobid
= r
->out
.job_id
;
5835 struct spoolss_DocumentInfo1
*info_1
;
5837 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5840 DEBUG(2,("_spoolss_StartDocPrinter: "
5841 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5845 if (r
->in
.level
!= 1) {
5846 return WERR_UNKNOWN_LEVEL
;
5849 info_1
= r
->in
.info
.info1
;
5852 * a nice thing with NT is it doesn't listen to what you tell it.
5853 * when asked to send _only_ RAW datas, it tries to send datas
5856 * So I add checks like in NT Server ...
5859 if (info_1
->datatype
) {
5860 if (strcmp(info_1
->datatype
, "RAW") != 0) {
5862 return WERR_INVALID_DATATYPE
;
5866 /* get the share number of the printer */
5867 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5871 Printer
->jobid
= print_job_start(p
->server_info
, snum
,
5872 CONST_DISCARD(char *,info_1
->document_name
),
5873 Printer
->nt_devmode
);
5875 /* An error occured in print_job_start() so return an appropriate
5878 if (Printer
->jobid
== -1) {
5879 return map_werror_from_unix(errno
);
5882 Printer
->document_started
=True
;
5883 (*jobid
) = Printer
->jobid
;
5888 /****************************************************************
5889 _spoolss_EndDocPrinter
5890 ****************************************************************/
5892 WERROR
_spoolss_EndDocPrinter(pipes_struct
*p
,
5893 struct spoolss_EndDocPrinter
*r
)
5895 POLICY_HND
*handle
= r
->in
.handle
;
5897 return _spoolss_enddocprinter_internal(p
, handle
);
5900 /****************************************************************
5901 _spoolss_WritePrinter
5902 ****************************************************************/
5904 WERROR
_spoolss_WritePrinter(pipes_struct
*p
,
5905 struct spoolss_WritePrinter
*r
)
5907 POLICY_HND
*handle
= r
->in
.handle
;
5908 uint32 buffer_size
= r
->in
._data_size
;
5909 uint8
*buffer
= r
->in
.data
.data
;
5910 uint32
*buffer_written
= &r
->in
._data_size
;
5912 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5915 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5916 OUR_HANDLE(handle
)));
5917 *r
->out
.num_written
= r
->in
._data_size
;
5921 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5924 (*buffer_written
) = (uint32
)print_job_write(snum
, Printer
->jobid
, (const char *)buffer
,
5925 (SMB_OFF_T
)-1, (size_t)buffer_size
);
5926 if (*buffer_written
== (uint32
)-1) {
5927 *r
->out
.num_written
= 0;
5928 if (errno
== ENOSPC
)
5929 return WERR_NO_SPOOL_SPACE
;
5931 return WERR_ACCESS_DENIED
;
5934 *r
->out
.num_written
= r
->in
._data_size
;
5939 /********************************************************************
5940 * api_spoolss_getprinter
5941 * called from the spoolss dispatcher
5943 ********************************************************************/
5945 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5949 WERROR errcode
= WERR_BADFUNC
;
5950 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5953 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5957 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5961 case SPOOLSS_PRINTER_CONTROL_PAUSE
:
5962 if (print_queue_pause(p
->server_info
, snum
, &errcode
)) {
5966 case SPOOLSS_PRINTER_CONTROL_RESUME
:
5967 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
:
5968 if (print_queue_resume(p
->server_info
, snum
, &errcode
)) {
5972 case SPOOLSS_PRINTER_CONTROL_PURGE
:
5973 if (print_queue_purge(p
->server_info
, snum
, &errcode
)) {
5978 return WERR_UNKNOWN_LEVEL
;
5985 /****************************************************************
5986 _spoolss_AbortPrinter
5987 * From MSDN: "Deletes printer's spool file if printer is configured
5989 ****************************************************************/
5991 WERROR
_spoolss_AbortPrinter(pipes_struct
*p
,
5992 struct spoolss_AbortPrinter
*r
)
5994 POLICY_HND
*handle
= r
->in
.handle
;
5995 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5997 WERROR errcode
= WERR_OK
;
6000 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6001 OUR_HANDLE(handle
)));
6005 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6008 print_job_delete(p
->server_info
, snum
, Printer
->jobid
, &errcode
);
6013 /********************************************************************
6014 * called by spoolss_api_setprinter
6015 * when updating a printer description
6016 ********************************************************************/
6018 static WERROR
update_printer_sec(POLICY_HND
*handle
,
6019 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
6021 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
6025 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6027 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
6028 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6029 OUR_HANDLE(handle
)));
6031 result
= WERR_BADFID
;
6036 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6037 result
= WERR_INVALID_PARAM
;
6041 /* Check the user has permissions to change the security
6042 descriptor. By experimentation with two NT machines, the user
6043 requires Full Access to the printer to change security
6046 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6047 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6048 result
= WERR_ACCESS_DENIED
;
6052 /* NT seems to like setting the security descriptor even though
6053 nothing may have actually changed. */
6055 if ( !nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
)) {
6056 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6057 result
= WERR_BADFID
;
6061 if (DEBUGLEVEL
>= 10) {
6065 the_acl
= old_secdesc_ctr
->sd
->dacl
;
6066 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6067 PRINTERNAME(snum
), the_acl
->num_aces
));
6069 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6070 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6071 &the_acl
->aces
[i
].trustee
),
6072 the_acl
->aces
[i
].access_mask
));
6075 the_acl
= secdesc_ctr
->sd
->dacl
;
6078 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6079 PRINTERNAME(snum
), the_acl
->num_aces
));
6081 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6082 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6083 &the_acl
->aces
[i
].trustee
),
6084 the_acl
->aces
[i
].access_mask
));
6087 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6091 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
6092 if (!new_secdesc_ctr
) {
6093 result
= WERR_NOMEM
;
6097 if (sec_desc_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
6102 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
6109 /********************************************************************
6110 Canonicalize printer info from a client
6112 ATTN: It does not matter what we set the servername to hear
6113 since we do the necessary work in get_a_printer() to set it to
6114 the correct value based on what the client sent in the
6115 _spoolss_open_printer_ex().
6116 ********************************************************************/
6118 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
6120 fstring printername
;
6123 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6124 "portname=%s drivername=%s comment=%s location=%s\n",
6125 info
->servername
, info
->printername
, info
->sharename
,
6126 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
6128 /* we force some elements to "correct" values */
6129 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
6130 fstrcpy(info
->sharename
, lp_servicename(snum
));
6132 /* check to see if we allow printername != sharename */
6134 if ( lp_force_printername(snum
) ) {
6135 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6136 global_myname(), info
->sharename
);
6139 /* make sure printername is in \\server\printername format */
6141 fstrcpy( printername
, info
->printername
);
6143 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
6144 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
6148 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6149 global_myname(), p
);
6152 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
6153 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
6160 /****************************************************************************
6161 ****************************************************************************/
6163 WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
6165 char *cmd
= lp_addport_cmd();
6166 char *command
= NULL
;
6168 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6169 bool is_print_op
= False
;
6172 return WERR_ACCESS_DENIED
;
6175 command
= talloc_asprintf(ctx
,
6176 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
6182 is_print_op
= user_has_privileges( token
, &se_printop
);
6184 DEBUG(10,("Running [%s]\n", command
));
6186 /********* BEGIN SePrintOperatorPrivilege **********/
6191 ret
= smbrun(command
, NULL
);
6196 /********* END SePrintOperatorPrivilege **********/
6198 DEBUGADD(10,("returned [%d]\n", ret
));
6200 TALLOC_FREE(command
);
6203 return WERR_ACCESS_DENIED
;
6209 /****************************************************************************
6210 ****************************************************************************/
6212 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
6214 char *cmd
= lp_addprinter_cmd();
6216 char *command
= NULL
;
6220 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6221 bool is_print_op
= False
;
6222 char *remote_machine
= talloc_strdup(ctx
, "%m");
6224 if (!remote_machine
) {
6227 remote_machine
= talloc_sub_basic(ctx
,
6228 current_user_info
.smb_name
,
6229 current_user_info
.domain
,
6231 if (!remote_machine
) {
6235 command
= talloc_asprintf(ctx
,
6236 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6237 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6238 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6239 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6245 is_print_op
= user_has_privileges( token
, &se_printop
);
6247 DEBUG(10,("Running [%s]\n", command
));
6249 /********* BEGIN SePrintOperatorPrivilege **********/
6254 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6255 /* Tell everyone we updated smb.conf. */
6256 message_send_all(smbd_messaging_context(),
6257 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6263 /********* END SePrintOperatorPrivilege **********/
6265 DEBUGADD(10,("returned [%d]\n", ret
));
6267 TALLOC_FREE(command
);
6268 TALLOC_FREE(remote_machine
);
6276 /* reload our services immediately */
6277 reload_services( False
);
6280 /* Get lines and convert them back to dos-codepage */
6281 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
6282 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6285 /* Set the portname to what the script says the portname should be. */
6286 /* but don't require anything to be return from the script exit a good error code */
6289 /* Set the portname to what the script says the portname should be. */
6290 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6291 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6294 TALLOC_FREE(qlines
);
6299 /********************************************************************
6300 * Called by spoolss_api_setprinter
6301 * when updating a printer description.
6302 ********************************************************************/
6304 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6305 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
6306 struct spoolss_DeviceMode
*devmode
)
6309 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6310 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6315 DEBUG(8,("update_printer\n"));
6320 result
= WERR_BADFID
;
6324 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6325 result
= WERR_BADFID
;
6329 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6330 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6331 result
= WERR_BADFID
;
6335 DEBUGADD(8,("Converting info_2 struct\n"));
6338 * convert_printer_info converts the incoming
6339 * info from the client and overwrites the info
6340 * just read from the tdb in the pointer 'printer'.
6343 if (!convert_printer_info_new(info_ctr
, printer
)) {
6344 result
= WERR_NOMEM
;
6349 /* we have a valid devmode
6350 convert it and link it*/
6352 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6353 if (!convert_devicemode_new(printer
->info_2
->printername
,
6355 &printer
->info_2
->devmode
)) {
6356 result
= WERR_NOMEM
;
6361 /* Do sanity check on the requested changes for Samba */
6363 if (!check_printer_ok(printer
->info_2
, snum
)) {
6364 result
= WERR_INVALID_PARAM
;
6368 /* FIXME!!! If the driver has changed we really should verify that
6369 it is installed before doing much else --jerry */
6371 /* Check calling user has permission to update printer description */
6373 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6374 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6375 result
= WERR_ACCESS_DENIED
;
6379 /* Call addprinter hook */
6380 /* Check changes to see if this is really needed */
6382 if ( *lp_addprinter_cmd()
6383 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6384 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6385 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6386 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6388 /* add_printer_hook() will call reload_services() */
6390 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
6392 result
= WERR_ACCESS_DENIED
;
6398 * When a *new* driver is bound to a printer, the drivername is used to
6399 * lookup previously saved driver initialization info, which is then
6400 * bound to the printer, simulating what happens in the Windows arch.
6402 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6404 if (!set_driver_init(printer
, 2))
6406 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6407 printer
->info_2
->drivername
));
6410 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6411 printer
->info_2
->drivername
));
6413 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6417 * flag which changes actually occured. This is a small subset of
6418 * all the possible changes. We also have to update things in the
6422 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6423 init_unistr2( &buffer
, printer
->info_2
->comment
, UNI_STR_TERMINATE
);
6424 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6425 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6427 notify_printer_comment(snum
, printer
->info_2
->comment
);
6430 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6431 init_unistr2( &buffer
, printer
->info_2
->sharename
, UNI_STR_TERMINATE
);
6432 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6433 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6435 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6438 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6441 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6444 pname
= printer
->info_2
->printername
;
6447 init_unistr2( &buffer
, pname
, UNI_STR_TERMINATE
);
6448 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6449 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6451 notify_printer_printername( snum
, pname
);
6454 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6455 init_unistr2( &buffer
, printer
->info_2
->portname
, UNI_STR_TERMINATE
);
6456 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6457 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6459 notify_printer_port(snum
, printer
->info_2
->portname
);
6462 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6463 init_unistr2( &buffer
, printer
->info_2
->location
, UNI_STR_TERMINATE
);
6464 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6465 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6467 notify_printer_location(snum
, printer
->info_2
->location
);
6470 /* here we need to update some more DsSpooler keys */
6471 /* uNCName, serverName, shortServerName */
6473 init_unistr2( &buffer
, global_myname(), UNI_STR_TERMINATE
);
6474 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6475 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6476 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6477 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6479 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6480 global_myname(), printer
->info_2
->sharename
);
6481 init_unistr2( &buffer
, asc_buffer
, UNI_STR_TERMINATE
);
6482 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6483 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6485 /* Update printer info */
6486 result
= mod_a_printer(printer
, 2);
6489 free_a_printer(&printer
, 2);
6490 free_a_printer(&old_printer
, 2);
6496 /****************************************************************************
6497 ****************************************************************************/
6498 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6499 struct spoolss_SetPrinterInfo7
*info7
)
6503 Printer_entry
*Printer
;
6505 if ( lp_security() != SEC_ADS
) {
6506 return WERR_UNKNOWN_LEVEL
;
6509 Printer
= find_printer_index_by_hnd(p
, handle
);
6511 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6516 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6519 nt_printer_publish(Printer
, snum
, info7
->action
);
6523 return WERR_UNKNOWN_LEVEL
;
6527 /****************************************************************
6529 ****************************************************************/
6531 WERROR
_spoolss_SetPrinter(pipes_struct
*p
,
6532 struct spoolss_SetPrinter
*r
)
6534 POLICY_HND
*handle
= r
->in
.handle
;
6537 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6540 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6541 OUR_HANDLE(handle
)));
6545 /* check the level */
6546 switch (r
->in
.info_ctr
->level
) {
6548 return control_printer(handle
, r
->in
.command
, p
);
6550 result
= update_printer(p
, handle
,
6552 r
->in
.devmode_ctr
->devmode
);
6553 if (!W_ERROR_IS_OK(result
))
6555 if (r
->in
.secdesc_ctr
->sd
)
6556 result
= update_printer_sec(handle
, p
,
6560 return update_printer_sec(handle
, p
,
6563 return publish_or_unpublish_printer(p
, handle
,
6564 r
->in
.info_ctr
->info
.info7
);
6566 return WERR_UNKNOWN_LEVEL
;
6570 /****************************************************************
6571 _spoolss_FindClosePrinterNotify
6572 ****************************************************************/
6574 WERROR
_spoolss_FindClosePrinterNotify(pipes_struct
*p
,
6575 struct spoolss_FindClosePrinterNotify
*r
)
6577 POLICY_HND
*handle
= r
->in
.handle
;
6578 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6581 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6582 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6586 if (Printer
->notify
.client_connected
==True
) {
6589 if ( Printer
->printer_type
== SPLHND_SERVER
)
6591 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6592 !get_printer_snum(p
, handle
, &snum
, NULL
) )
6595 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6598 Printer
->notify
.flags
=0;
6599 Printer
->notify
.options
=0;
6600 Printer
->notify
.localmachine
[0]='\0';
6601 Printer
->notify
.printerlocal
=0;
6602 TALLOC_FREE(Printer
->notify
.option
);
6603 Printer
->notify
.client_connected
=False
;
6608 /****************************************************************
6610 ****************************************************************/
6612 WERROR
_spoolss_AddJob(pipes_struct
*p
,
6613 struct spoolss_AddJob
*r
)
6615 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6616 return WERR_INVALID_PARAM
;
6619 /* this is what a NT server returns for AddJob. AddJob must fail on
6620 * non-local printers */
6622 return WERR_INVALID_PARAM
;
6625 /****************************************************************************
6626 ****************************************************************************/
6628 static void fill_job_info_1(JOB_INFO_1
*job_info
, const print_queue_struct
*queue
,
6629 int position
, int snum
,
6630 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6634 t
=gmtime(&queue
->time
);
6636 job_info
->jobid
=queue
->job
;
6637 init_unistr(&job_info
->printername
, lp_servicename(snum
));
6638 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6639 init_unistr(&job_info
->username
, queue
->fs_user
);
6640 init_unistr(&job_info
->document
, queue
->fs_file
);
6641 init_unistr(&job_info
->datatype
, "RAW");
6642 init_unistr(&job_info
->text_status
, "");
6643 job_info
->status
=nt_printj_status(queue
->status
);
6644 job_info
->priority
=queue
->priority
;
6645 job_info
->position
=position
;
6646 job_info
->totalpages
=queue
->page_count
;
6647 job_info
->pagesprinted
=0;
6649 make_systemtime(&job_info
->submitted
, t
);
6652 /****************************************************************************
6653 ****************************************************************************/
6655 static bool fill_job_info_2(JOB_INFO_2
*job_info
, const print_queue_struct
*queue
,
6656 int position
, int snum
,
6657 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6658 DEVICEMODE
*devmode
)
6662 t
=gmtime(&queue
->time
);
6664 job_info
->jobid
=queue
->job
;
6666 init_unistr(&job_info
->printername
, ntprinter
->info_2
->printername
);
6668 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6669 init_unistr(&job_info
->username
, queue
->fs_user
);
6670 init_unistr(&job_info
->document
, queue
->fs_file
);
6671 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
6672 init_unistr(&job_info
->datatype
, "RAW");
6673 init_unistr(&job_info
->printprocessor
, "winprint");
6674 init_unistr(&job_info
->parameters
, "");
6675 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
6676 init_unistr(&job_info
->text_status
, "");
6678 /* and here the security descriptor */
6680 job_info
->status
=nt_printj_status(queue
->status
);
6681 job_info
->priority
=queue
->priority
;
6682 job_info
->position
=position
;
6683 job_info
->starttime
=0;
6684 job_info
->untiltime
=0;
6685 job_info
->totalpages
=queue
->page_count
;
6686 job_info
->size
=queue
->size
;
6687 make_systemtime(&(job_info
->submitted
), t
);
6688 job_info
->timeelapsed
=0;
6689 job_info
->pagesprinted
=0;
6691 job_info
->devmode
= devmode
;
6696 /****************************************************************************
6697 Enumjobs at level 1.
6698 ****************************************************************************/
6700 static WERROR
enumjobs_level1(const print_queue_struct
*queue
, int snum
,
6701 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6702 RPC_BUFFER
*buffer
, uint32 offered
,
6703 uint32
*needed
, uint32
*returned
)
6707 WERROR result
= WERR_OK
;
6709 info
=SMB_MALLOC_ARRAY(JOB_INFO_1
,*returned
);
6715 for (i
=0; i
<*returned
; i
++)
6716 fill_job_info_1( &info
[i
], &queue
[i
], i
, snum
, ntprinter
);
6718 /* check the required size. */
6719 for (i
=0; i
<*returned
; i
++)
6720 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
6722 if (*needed
> offered
) {
6723 result
= WERR_INSUFFICIENT_BUFFER
;
6727 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6728 result
= WERR_NOMEM
;
6732 /* fill the buffer with the structures */
6733 for (i
=0; i
<*returned
; i
++)
6734 smb_io_job_info_1("", buffer
, &info
[i
], 0);
6740 if ( !W_ERROR_IS_OK(result
) )
6746 /****************************************************************************
6747 Enumjobs at level 2.
6748 ****************************************************************************/
6750 static WERROR
enumjobs_level2(const print_queue_struct
*queue
, int snum
,
6751 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6752 RPC_BUFFER
*buffer
, uint32 offered
,
6753 uint32
*needed
, uint32
*returned
)
6755 JOB_INFO_2
*info
= NULL
;
6757 WERROR result
= WERR_OK
;
6758 DEVICEMODE
*devmode
= NULL
;
6760 if ( !(info
= SMB_MALLOC_ARRAY(JOB_INFO_2
,*returned
)) ) {
6765 /* this should not be a failure condition if the devmode is NULL */
6767 devmode
= construct_dev_mode(lp_const_servicename(snum
));
6769 for (i
=0; i
<*returned
; i
++)
6770 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
, devmode
);
6772 /* check the required size. */
6773 for (i
=0; i
<*returned
; i
++)
6774 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6776 if (*needed
> offered
) {
6777 result
= WERR_INSUFFICIENT_BUFFER
;
6781 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6782 result
= WERR_NOMEM
;
6786 /* fill the buffer with the structures */
6787 for (i
=0; i
<*returned
; i
++)
6788 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6791 free_devmode(devmode
);
6794 if ( !W_ERROR_IS_OK(result
) )
6801 /****************************************************************************
6803 ****************************************************************************/
6805 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6807 POLICY_HND
*handle
= &q_u
->handle
;
6808 uint32 level
= q_u
->level
;
6809 RPC_BUFFER
*buffer
= NULL
;
6810 uint32 offered
= q_u
->offered
;
6811 uint32
*needed
= &r_u
->needed
;
6812 uint32
*returned
= &r_u
->returned
;
6814 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6816 print_status_struct prt_status
;
6817 print_queue_struct
*queue
=NULL
;
6819 /* that's an [in out] buffer */
6821 if (!q_u
->buffer
&& (offered
!=0)) {
6822 return WERR_INVALID_PARAM
;
6825 if (offered
> MAX_RPC_DATA_SIZE
) {
6826 return WERR_INVALID_PARAM
;
6829 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6830 buffer
= r_u
->buffer
;
6832 DEBUG(4,("_spoolss_enumjobs\n"));
6837 /* lookup the printer snum and tdb entry */
6839 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6842 wret
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6843 if ( !W_ERROR_IS_OK(wret
) )
6846 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6847 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6849 if (*returned
== 0) {
6851 free_a_printer(&ntprinter
, 2);
6857 wret
= enumjobs_level1(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6860 wret
= enumjobs_level2(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6864 wret
= WERR_UNKNOWN_LEVEL
;
6869 free_a_printer( &ntprinter
, 2 );
6873 /****************************************************************
6874 _spoolss_ScheduleJob
6875 ****************************************************************/
6877 WERROR
_spoolss_ScheduleJob(pipes_struct
*p
,
6878 struct spoolss_ScheduleJob
*r
)
6883 /****************************************************************
6885 ****************************************************************/
6887 WERROR
_spoolss_SetJob(pipes_struct
*p
,
6888 struct spoolss_SetJob
*r
)
6890 POLICY_HND
*handle
= r
->in
.handle
;
6891 uint32 jobid
= r
->in
.job_id
;
6892 uint32 command
= r
->in
.command
;
6895 WERROR errcode
= WERR_BADFUNC
;
6897 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6901 if (!print_job_exists(lp_const_servicename(snum
), jobid
)) {
6902 return WERR_INVALID_PRINTER_NAME
;
6906 case SPOOLSS_JOB_CONTROL_CANCEL
:
6907 case SPOOLSS_JOB_CONTROL_DELETE
:
6908 if (print_job_delete(p
->server_info
, snum
, jobid
, &errcode
)) {
6912 case SPOOLSS_JOB_CONTROL_PAUSE
:
6913 if (print_job_pause(p
->server_info
, snum
, jobid
, &errcode
)) {
6917 case SPOOLSS_JOB_CONTROL_RESTART
:
6918 case SPOOLSS_JOB_CONTROL_RESUME
:
6919 if (print_job_resume(p
->server_info
, snum
, jobid
, &errcode
)) {
6924 return WERR_UNKNOWN_LEVEL
;
6930 /****************************************************************************
6931 Enumerates all printer drivers at level 1.
6932 ****************************************************************************/
6934 static WERROR
enumprinterdrivers_level1(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6939 fstring
*list
= NULL
;
6940 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6941 DRIVER_INFO_1
*driver_info_1
=NULL
;
6942 WERROR result
= WERR_OK
;
6946 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6948 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6949 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6951 if(ndrivers
== -1) {
6952 SAFE_FREE(driver_info_1
);
6957 if((driver_info_1
=SMB_REALLOC_ARRAY(driver_info_1
, DRIVER_INFO_1
, *returned
+ndrivers
)) == NULL
) {
6958 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6964 for (i
=0; i
<ndrivers
; i
++) {
6966 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6967 ZERO_STRUCT(driver
);
6968 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6969 architecture
, version
);
6970 if (!W_ERROR_IS_OK(status
)) {
6972 SAFE_FREE(driver_info_1
);
6975 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6976 free_a_printer_driver(driver
, 3);
6979 *returned
+=ndrivers
;
6983 /* check the required size. */
6984 for (i
=0; i
<*returned
; i
++) {
6985 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6986 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6989 if (*needed
> offered
) {
6990 result
= WERR_INSUFFICIENT_BUFFER
;
6994 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6995 result
= WERR_NOMEM
;
6999 /* fill the buffer with the driver structures */
7000 for (i
=0; i
<*returned
; i
++) {
7001 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7002 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
7006 SAFE_FREE(driver_info_1
);
7008 if ( !W_ERROR_IS_OK(result
) )
7014 /****************************************************************************
7015 Enumerates all printer drivers at level 2.
7016 ****************************************************************************/
7018 static WERROR
enumprinterdrivers_level2(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7023 fstring
*list
= NULL
;
7024 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7025 DRIVER_INFO_2
*driver_info_2
=NULL
;
7026 WERROR result
= WERR_OK
;
7030 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7032 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7033 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7035 if(ndrivers
== -1) {
7036 SAFE_FREE(driver_info_2
);
7041 if((driver_info_2
=SMB_REALLOC_ARRAY(driver_info_2
, DRIVER_INFO_2
, *returned
+ndrivers
)) == NULL
) {
7042 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7048 for (i
=0; i
<ndrivers
; i
++) {
7051 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7052 ZERO_STRUCT(driver
);
7053 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7054 architecture
, version
);
7055 if (!W_ERROR_IS_OK(status
)) {
7057 SAFE_FREE(driver_info_2
);
7060 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
7061 free_a_printer_driver(driver
, 3);
7064 *returned
+=ndrivers
;
7068 /* check the required size. */
7069 for (i
=0; i
<*returned
; i
++) {
7070 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7071 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
7074 if (*needed
> offered
) {
7075 result
= WERR_INSUFFICIENT_BUFFER
;
7079 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7080 result
= WERR_NOMEM
;
7084 /* fill the buffer with the form structures */
7085 for (i
=0; i
<*returned
; i
++) {
7086 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7087 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
7091 SAFE_FREE(driver_info_2
);
7093 if ( !W_ERROR_IS_OK(result
) )
7099 /****************************************************************************
7100 Enumerates all printer drivers at level 3.
7101 ****************************************************************************/
7103 static WERROR
enumprinterdrivers_level3(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7108 fstring
*list
= NULL
;
7109 DRIVER_INFO_3
*driver_info_3
=NULL
;
7110 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7111 WERROR result
= WERR_OK
;
7115 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7117 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7118 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7120 if(ndrivers
== -1) {
7121 SAFE_FREE(driver_info_3
);
7126 if((driver_info_3
=SMB_REALLOC_ARRAY(driver_info_3
, DRIVER_INFO_3
, *returned
+ndrivers
)) == NULL
) {
7127 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7133 for (i
=0; i
<ndrivers
; i
++) {
7136 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7137 ZERO_STRUCT(driver
);
7138 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7139 architecture
, version
);
7140 if (!W_ERROR_IS_OK(status
)) {
7142 SAFE_FREE(driver_info_3
);
7145 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
7146 free_a_printer_driver(driver
, 3);
7149 *returned
+=ndrivers
;
7153 /* check the required size. */
7154 for (i
=0; i
<*returned
; i
++) {
7155 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7156 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
7159 if (*needed
> offered
) {
7160 result
= WERR_INSUFFICIENT_BUFFER
;
7164 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7165 result
= WERR_NOMEM
;
7169 /* fill the buffer with the driver structures */
7170 for (i
=0; i
<*returned
; i
++) {
7171 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7172 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
7176 for (i
=0; i
<*returned
; i
++) {
7177 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
7180 SAFE_FREE(driver_info_3
);
7182 if ( !W_ERROR_IS_OK(result
) )
7188 /****************************************************************************
7189 Enumerates all printer drivers.
7190 ****************************************************************************/
7192 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
7194 uint32 level
= q_u
->level
;
7195 RPC_BUFFER
*buffer
= NULL
;
7196 uint32 offered
= q_u
->offered
;
7197 uint32
*needed
= &r_u
->needed
;
7198 uint32
*returned
= &r_u
->returned
;
7199 const char *cservername
;
7201 fstring architecture
;
7203 /* that's an [in out] buffer */
7205 if (!q_u
->buffer
&& (offered
!=0)) {
7206 return WERR_INVALID_PARAM
;
7209 if (offered
> MAX_RPC_DATA_SIZE
) {
7210 return WERR_INVALID_PARAM
;
7213 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7214 buffer
= r_u
->buffer
;
7216 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7221 unistr2_to_ascii(architecture
, &q_u
->environment
, sizeof(architecture
));
7222 unistr2_to_ascii(servername
, &q_u
->name
, sizeof(servername
));
7224 cservername
= canon_servername(servername
);
7226 if (!is_myname_or_ipaddr(cservername
))
7227 return WERR_UNKNOWN_PRINTER_DRIVER
;
7231 return enumprinterdrivers_level1(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7233 return enumprinterdrivers_level2(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7235 return enumprinterdrivers_level3(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7237 return WERR_UNKNOWN_LEVEL
;
7241 /****************************************************************************
7242 ****************************************************************************/
7244 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
7246 form
->flag
=list
->flag
;
7247 init_unistr(&form
->name
, list
->name
);
7248 form
->width
=list
->width
;
7249 form
->length
=list
->length
;
7250 form
->left
=list
->left
;
7251 form
->top
=list
->top
;
7252 form
->right
=list
->right
;
7253 form
->bottom
=list
->bottom
;
7256 /****************************************************************************
7257 ****************************************************************************/
7259 static WERROR
fill_form_info_1(TALLOC_CTX
*mem_ctx
,
7260 struct spoolss_FormInfo1
*form
,
7261 nt_forms_struct
*list
)
7263 form
->form_name
= talloc_strdup(mem_ctx
, list
->name
);
7264 W_ERROR_HAVE_NO_MEMORY(form
->form_name
);
7266 form
->flags
= list
->flag
;
7267 form
->size
.width
= list
->width
;
7268 form
->size
.height
= list
->length
;
7269 form
->area
.left
= list
->left
;
7270 form
->area
.top
= list
->top
;
7271 form
->area
.right
= list
->right
;
7272 form
->area
.bottom
= list
->bottom
;
7277 /****************************************************************************
7278 ****************************************************************************/
7280 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
7282 uint32 level
= q_u
->level
;
7283 RPC_BUFFER
*buffer
= NULL
;
7284 uint32 offered
= q_u
->offered
;
7285 uint32
*needed
= &r_u
->needed
;
7286 uint32
*numofforms
= &r_u
->numofforms
;
7287 uint32 numbuiltinforms
;
7289 nt_forms_struct
*list
=NULL
;
7290 nt_forms_struct
*builtinlist
=NULL
;
7295 /* that's an [in out] buffer */
7297 if (!q_u
->buffer
&& (offered
!=0) ) {
7298 return WERR_INVALID_PARAM
;
7301 if (offered
> MAX_RPC_DATA_SIZE
) {
7302 return WERR_INVALID_PARAM
;
7305 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7306 buffer
= r_u
->buffer
;
7308 DEBUG(4,("_spoolss_enumforms\n"));
7309 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7310 DEBUGADD(5,("Info level [%d]\n", level
));
7312 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
7313 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
7314 *numofforms
= get_ntforms(&list
);
7315 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
7316 *numofforms
+= numbuiltinforms
;
7318 if (*numofforms
== 0) {
7319 SAFE_FREE(builtinlist
);
7321 return WERR_NO_MORE_ITEMS
;
7326 if ((forms_1
=SMB_MALLOC_ARRAY(FORM_1
, *numofforms
)) == NULL
) {
7327 SAFE_FREE(builtinlist
);
7333 /* construct the list of form structures */
7334 for (i
=0; i
<numbuiltinforms
; i
++) {
7335 DEBUGADD(6,("Filling form number [%d]\n",i
));
7336 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
7339 SAFE_FREE(builtinlist
);
7341 for (; i
<*numofforms
; i
++) {
7342 DEBUGADD(6,("Filling form number [%d]\n",i
));
7343 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
7348 /* check the required size. */
7349 for (i
=0; i
<numbuiltinforms
; i
++) {
7350 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7351 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7353 for (; i
<*numofforms
; i
++) {
7354 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7355 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7358 *needed
=buffer_size
;
7360 if (*needed
> offered
) {
7363 return WERR_INSUFFICIENT_BUFFER
;
7366 if (!rpcbuf_alloc_size(buffer
, buffer_size
)){
7372 /* fill the buffer with the form structures */
7373 for (i
=0; i
<numbuiltinforms
; i
++) {
7374 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7375 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7377 for (; i
<*numofforms
; i
++) {
7378 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7379 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7388 SAFE_FREE(builtinlist
);
7389 return WERR_UNKNOWN_LEVEL
;
7393 /****************************************************************
7395 ****************************************************************/
7397 WERROR
_spoolss_GetForm(pipes_struct
*p
,
7398 struct spoolss_GetForm
*r
)
7400 uint32 level
= r
->in
.level
;
7401 uint32 offered
= r
->in
.offered
;
7402 uint32
*needed
= r
->out
.needed
;
7404 nt_forms_struct
*list
=NULL
;
7405 nt_forms_struct builtin_form
;
7407 union spoolss_FormInfo info
;
7408 struct spoolss_FormInfo1 form_1
;
7409 int numofforms
=0, i
=0;
7411 /* that's an [in out] buffer */
7413 if (!r
->in
.buffer
&& (offered
!=0)) {
7414 return WERR_INVALID_PARAM
;
7417 DEBUG(4,("_spoolss_GetForm\n"));
7418 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7419 DEBUGADD(5,("Info level [%d]\n", level
));
7421 foundBuiltin
= get_a_builtin_ntform_by_string(r
->in
.form_name
, &builtin_form
);
7422 if (!foundBuiltin
) {
7423 numofforms
= get_ntforms(&list
);
7424 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
7426 if (numofforms
== 0)
7430 ZERO_STRUCT(form_1
);
7435 fill_form_info_1(p
->mem_ctx
, &form_1
, &builtin_form
);
7438 /* Check if the requested name is in the list of form structures */
7439 for (i
=0; i
<numofforms
; i
++) {
7441 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7442 list
[i
].name
, r
->in
.form_name
));
7444 if (strequal(r
->in
.form_name
, list
[i
].name
)) {
7445 DEBUGADD(6,("Found form %s number [%d]\n",
7446 r
->in
.form_name
, i
));
7447 fill_form_info_1(p
->mem_ctx
, &form_1
, &list
[i
]);
7453 if (i
== numofforms
) {
7457 /* check the required size. */
7459 info
.info1
= form_1
;
7461 *needed
= ndr_size_spoolss_FormInfo(&info
, 1, NULL
, 0);
7463 if (*needed
> offered
) {
7465 return WERR_INSUFFICIENT_BUFFER
;
7468 r
->out
.info
->info1
= form_1
;
7470 /* fill the buffer with the form structures */
7471 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7472 r
->in
.form_name
, i
));
7478 return WERR_UNKNOWN_LEVEL
;
7482 /****************************************************************************
7483 ****************************************************************************/
7485 static void fill_port_1(PORT_INFO_1
*port
, const char *name
)
7487 init_unistr(&port
->port_name
, name
);
7490 /****************************************************************************
7491 TODO: This probably needs distinguish between TCP/IP and Local ports
7493 ****************************************************************************/
7495 static void fill_port_2(PORT_INFO_2
*port
, const char *name
)
7497 init_unistr(&port
->port_name
, name
);
7498 init_unistr(&port
->monitor_name
, "Local Monitor");
7499 init_unistr(&port
->description
, SPL_LOCAL_PORT
);
7500 port
->port_type
=PORT_TYPE_WRITE
;
7505 /****************************************************************************
7506 wrapper around the enumer ports command
7507 ****************************************************************************/
7509 WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7511 char *cmd
= lp_enumports_cmd();
7512 char **qlines
= NULL
;
7513 char *command
= NULL
;
7521 /* if no hook then just fill in the default port */
7524 if (!(qlines
= TALLOC_ARRAY( NULL
, char*, 2 ))) {
7527 if (!(qlines
[0] = talloc_strdup(qlines
, SAMBA_PRINTER_PORT_NAME
))) {
7528 TALLOC_FREE(qlines
);
7535 /* we have a valid enumport command */
7537 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7542 DEBUG(10,("Running [%s]\n", command
));
7543 ret
= smbrun(command
, &fd
);
7544 DEBUG(10,("Returned [%d]\n", ret
));
7545 TALLOC_FREE(command
);
7550 return WERR_ACCESS_DENIED
;
7554 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
7555 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7565 /****************************************************************************
7567 ****************************************************************************/
7569 static WERROR
enumports_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7571 PORT_INFO_1
*ports
=NULL
;
7573 WERROR result
= WERR_OK
;
7574 char **qlines
= NULL
;
7577 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7578 if (!W_ERROR_IS_OK(result
)) {
7579 TALLOC_FREE(qlines
);
7584 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_1
, numlines
)) == NULL
) {
7585 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7586 win_errstr(WERR_NOMEM
)));
7587 TALLOC_FREE(qlines
);
7591 for (i
=0; i
<numlines
; i
++) {
7592 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7593 fill_port_1(&ports
[i
], qlines
[i
]);
7596 TALLOC_FREE(qlines
);
7598 *returned
= numlines
;
7600 /* check the required size. */
7601 for (i
=0; i
<*returned
; i
++) {
7602 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7603 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
7606 if (*needed
> offered
) {
7607 result
= WERR_INSUFFICIENT_BUFFER
;
7611 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7612 result
= WERR_NOMEM
;
7616 /* fill the buffer with the ports structures */
7617 for (i
=0; i
<*returned
; i
++) {
7618 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7619 smb_io_port_1("", buffer
, &ports
[i
], 0);
7625 if ( !W_ERROR_IS_OK(result
) )
7631 /****************************************************************************
7633 ****************************************************************************/
7635 static WERROR
enumports_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7637 PORT_INFO_2
*ports
=NULL
;
7639 WERROR result
= WERR_OK
;
7640 char **qlines
= NULL
;
7643 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7644 if ( !W_ERROR_IS_OK(result
)) {
7645 TALLOC_FREE(qlines
);
7650 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_2
, numlines
)) == NULL
) {
7651 TALLOC_FREE(qlines
);
7655 for (i
=0; i
<numlines
; i
++) {
7656 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7657 fill_port_2(&(ports
[i
]), qlines
[i
]);
7661 TALLOC_FREE(qlines
);
7663 *returned
= numlines
;
7665 /* check the required size. */
7666 for (i
=0; i
<*returned
; i
++) {
7667 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7668 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
7671 if (*needed
> offered
) {
7672 result
= WERR_INSUFFICIENT_BUFFER
;
7676 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7677 result
= WERR_NOMEM
;
7681 /* fill the buffer with the ports structures */
7682 for (i
=0; i
<*returned
; i
++) {
7683 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7684 smb_io_port_2("", buffer
, &ports
[i
], 0);
7690 if ( !W_ERROR_IS_OK(result
) )
7696 /****************************************************************************
7698 ****************************************************************************/
7700 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
7702 uint32 level
= q_u
->level
;
7703 RPC_BUFFER
*buffer
= NULL
;
7704 uint32 offered
= q_u
->offered
;
7705 uint32
*needed
= &r_u
->needed
;
7706 uint32
*returned
= &r_u
->returned
;
7708 /* that's an [in out] buffer */
7710 if (!q_u
->buffer
&& (offered
!=0)) {
7711 return WERR_INVALID_PARAM
;
7714 if (offered
> MAX_RPC_DATA_SIZE
) {
7715 return WERR_INVALID_PARAM
;
7718 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7719 buffer
= r_u
->buffer
;
7721 DEBUG(4,("_spoolss_enumports\n"));
7728 return enumports_level_1(buffer
, offered
, needed
, returned
);
7730 return enumports_level_2(buffer
, offered
, needed
, returned
);
7732 return WERR_UNKNOWN_LEVEL
;
7736 /****************************************************************************
7737 ****************************************************************************/
7739 static WERROR
spoolss_addprinterex_level_2(pipes_struct
*p
,
7741 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
7742 struct spoolss_DeviceMode
*devmode
,
7743 struct security_descriptor
*sec_desc
,
7744 struct spoolss_UserLevelCtr
*user_ctr
,
7747 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7750 WERROR err
= WERR_OK
;
7752 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7753 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7757 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7758 if (!convert_printer_info_new(info_ctr
, printer
)) {
7759 free_a_printer(&printer
, 2);
7763 /* check to see if the printer already exists */
7765 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7766 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7767 printer
->info_2
->sharename
));
7768 free_a_printer(&printer
, 2);
7769 return WERR_PRINTER_ALREADY_EXISTS
;
7772 /* FIXME!!! smbd should check to see if the driver is installed before
7773 trying to add a printer like this --jerry */
7775 if (*lp_addprinter_cmd() ) {
7776 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
7778 free_a_printer(&printer
,2);
7779 return WERR_ACCESS_DENIED
;
7782 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7783 "smb.conf parameter \"addprinter command\" is defined. This"
7784 "parameter must exist for this call to succeed\n",
7785 printer
->info_2
->sharename
));
7788 /* use our primary netbios name since get_a_printer() will convert
7789 it to what the client expects on a case by case basis */
7791 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7792 printer
->info_2
->sharename
);
7795 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7796 free_a_printer(&printer
,2);
7797 return WERR_ACCESS_DENIED
;
7800 /* you must be a printer admin to add a new printer */
7801 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7802 free_a_printer(&printer
,2);
7803 return WERR_ACCESS_DENIED
;
7807 * Do sanity check on the requested changes for Samba.
7810 if (!check_printer_ok(printer
->info_2
, snum
)) {
7811 free_a_printer(&printer
,2);
7812 return WERR_INVALID_PARAM
;
7816 * When a printer is created, the drivername bound to the printer is used
7817 * to lookup previously saved driver initialization info, which is then
7818 * bound to the new printer, simulating what happens in the Windows arch.
7823 set_driver_init(printer
, 2);
7827 /* A valid devmode was included, convert and link it
7829 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7831 if (!convert_devicemode_new(printer
->info_2
->printername
,
7833 &printer
->info_2
->devmode
))
7837 /* write the ASCII on disk */
7838 err
= mod_a_printer(printer
, 2);
7839 if (!W_ERROR_IS_OK(err
)) {
7840 free_a_printer(&printer
,2);
7844 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7845 /* Handle open failed - remove addition. */
7846 del_a_printer(printer
->info_2
->sharename
);
7847 free_a_printer(&printer
,2);
7848 ZERO_STRUCTP(handle
);
7849 return WERR_ACCESS_DENIED
;
7852 update_c_setprinter(False
);
7853 free_a_printer(&printer
,2);
7858 /****************************************************************
7859 _spoolss_AddPrinterEx
7860 ****************************************************************/
7862 WERROR
_spoolss_AddPrinterEx(pipes_struct
*p
,
7863 struct spoolss_AddPrinterEx
*r
)
7865 switch (r
->in
.info_ctr
->level
) {
7867 /* we don't handle yet */
7868 /* but I know what to do ... */
7869 return WERR_UNKNOWN_LEVEL
;
7871 return spoolss_addprinterex_level_2(p
, r
->in
.server
,
7873 r
->in
.devmode_ctr
->devmode
,
7874 r
->in
.secdesc_ctr
->sd
,
7875 r
->in
.userlevel_ctr
,
7878 return WERR_UNKNOWN_LEVEL
;
7882 /****************************************************************
7883 _spoolss_AddPrinterDriver
7884 ****************************************************************/
7886 WERROR
_spoolss_AddPrinterDriver(pipes_struct
*p
,
7887 struct spoolss_AddPrinterDriver
*r
)
7889 uint32_t level
= r
->in
.info_ctr
->level
;
7890 struct spoolss_AddDriverInfoCtr
*info
= r
->in
.info_ctr
;
7891 WERROR err
= WERR_OK
;
7892 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7893 fstring driver_name
;
7897 switch (p
->hdr_req
.opnum
) {
7898 case NDR_SPOOLSS_ADDPRINTERDRIVER
:
7899 fn
= "_spoolss_AddPrinterDriver";
7901 case NDR_SPOOLSS_ADDPRINTERDRIVEREX
:
7902 fn
= "_spoolss_AddPrinterDriverEx";
7905 return WERR_INVALID_PARAM
;
7910 if (level
!= 3 && level
!= 6) {
7911 /* Clever hack from Martin Zielinski <mz@seh.de>
7912 * to allow downgrade from level 8 (Vista).
7914 DEBUG(0,("%s: level %d not yet implemented\n", fn
, level
));
7915 return WERR_UNKNOWN_LEVEL
;
7918 ZERO_STRUCT(driver
);
7920 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7925 DEBUG(5,("Cleaning driver's information\n"));
7926 err
= clean_up_driver_struct(p
, driver
, level
);
7927 if (!W_ERROR_IS_OK(err
))
7930 DEBUG(5,("Moving driver to final destination\n"));
7931 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(p
, driver
, level
,
7936 if (add_a_printer_driver(driver
, level
)!=0) {
7937 err
= WERR_ACCESS_DENIED
;
7943 fstrcpy(driver_name
,
7944 driver
.info_3
->name
? driver
.info_3
->name
: "");
7947 fstrcpy(driver_name
,
7948 driver
.info_6
->name
? driver
.info_6
->name
: "");
7953 * I think this is where he DrvUpgradePrinter() hook would be
7954 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7955 * server. Right now, we just need to send ourselves a message
7956 * to update each printer bound to this driver. --jerry
7959 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7960 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7965 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7966 * decide if the driver init data should be deleted. The rules are:
7967 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7968 * 2) delete init data only if there is no 2k/Xp driver
7969 * 3) always delete init data
7970 * The generalized rule is always use init data from the highest order driver.
7971 * It is necessary to follow the driver install by an initialization step to
7972 * finish off this process.
7975 version
= driver
.info_3
->cversion
;
7976 else if (level
== 6)
7977 version
= driver
.info_6
->version
;
7982 * 9x printer driver - never delete init data
7985 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7990 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7991 * there is no 2k/Xp driver init data for this driver name.
7995 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7997 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7999 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
8001 if (!del_driver_init(driver_name
))
8002 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
8006 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
8008 free_a_printer_driver(driver1
,3);
8009 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
8016 * 2k or Xp printer driver - always delete init data
8019 if (!del_driver_init(driver_name
))
8020 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
8025 DEBUG(0,("%s: invalid level=%d\n", fn
, level
));
8031 free_a_printer_driver(driver
, level
);
8035 /****************************************************************
8036 _spoolss_AddPrinterDriverEx
8037 ****************************************************************/
8039 WERROR
_spoolss_AddPrinterDriverEx(pipes_struct
*p
,
8040 struct spoolss_AddPrinterDriverEx
*r
)
8042 struct spoolss_AddPrinterDriver a
;
8045 * we only support the semantics of AddPrinterDriver()
8046 * i.e. only copy files that are newer than existing ones
8049 if (r
->in
.flags
!= APD_COPY_NEW_FILES
) {
8050 return WERR_ACCESS_DENIED
;
8053 a
.in
.servername
= r
->in
.servername
;
8054 a
.in
.info_ctr
= r
->in
.info_ctr
;
8056 return _spoolss_AddPrinterDriver(p
, &a
);
8059 /****************************************************************************
8060 ****************************************************************************/
8062 struct _spoolss_paths
{
8068 enum { SPOOLSS_DRIVER_PATH
, SPOOLSS_PRTPROCS_PATH
};
8070 static const struct _spoolss_paths spoolss_paths
[]= {
8071 { SPOOLSS_DRIVER_PATH
, "print$", "DRIVERS" },
8072 { SPOOLSS_PRTPROCS_PATH
, "prnproc$", "PRTPROCS" }
8075 static WERROR
compose_spoolss_server_path(TALLOC_CTX
*mem_ctx
,
8076 const char *servername
,
8077 const char *environment
,
8081 const char *pservername
= NULL
;
8082 const char *long_archi
= SPOOLSS_ARCHITECTURE_NT_X86
;
8083 const char *short_archi
;
8087 /* environment may be empty */
8088 if (environment
&& strlen(environment
)) {
8089 long_archi
= environment
;
8092 /* servername may be empty */
8093 if (servername
&& strlen(servername
)) {
8094 pservername
= canon_servername(servername
);
8096 if (!is_myname_or_ipaddr(pservername
)) {
8097 return WERR_INVALID_PARAM
;
8101 if (!(short_archi
= get_short_archi(long_archi
))) {
8102 return WERR_INVALID_ENVIRONMENT
;
8105 switch (component
) {
8106 case SPOOLSS_PRTPROCS_PATH
:
8107 case SPOOLSS_DRIVER_PATH
:
8109 *path
= talloc_asprintf(mem_ctx
,
8112 spoolss_paths
[component
].share
,
8115 *path
= talloc_asprintf(mem_ctx
, "%s\\%s\\%s",
8116 SPOOLSS_DEFAULT_SERVER_PATH
,
8117 spoolss_paths
[component
].dir
,
8122 return WERR_INVALID_PARAM
;
8132 /****************************************************************************
8133 ****************************************************************************/
8135 static WERROR
getprinterdriverdir_level_1(TALLOC_CTX
*mem_ctx
,
8136 const char *servername
,
8137 const char *environment
,
8138 struct spoolss_DriverDirectoryInfo1
*r
,
8145 werr
= compose_spoolss_server_path(mem_ctx
,
8148 SPOOLSS_DRIVER_PATH
,
8150 if (!W_ERROR_IS_OK(werr
)) {
8154 DEBUG(4,("printer driver directory: [%s]\n", path
));
8156 r
->directory_name
= path
;
8158 *needed
+= ndr_size_spoolss_DriverDirectoryInfo1(r
, NULL
, 0);
8160 if (*needed
> offered
) {
8162 return WERR_INSUFFICIENT_BUFFER
;
8168 /****************************************************************
8169 _spoolss_GetPrinterDriverDirectory
8170 ****************************************************************/
8172 WERROR
_spoolss_GetPrinterDriverDirectory(pipes_struct
*p
,
8173 struct spoolss_GetPrinterDriverDirectory
*r
)
8177 /* that's an [in out] buffer */
8179 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8180 return WERR_INVALID_PARAM
;
8183 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
8188 /* r->in.level is ignored */
8190 werror
= getprinterdriverdir_level_1(p
->mem_ctx
,
8193 &r
->out
.info
->info1
,
8196 if (!W_ERROR_IS_OK(werror
)) {
8197 TALLOC_FREE(r
->out
.info
);
8203 /****************************************************************************
8204 ****************************************************************************/
8206 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
8208 POLICY_HND
*handle
= &q_u
->handle
;
8209 uint32 idx
= q_u
->index
;
8210 uint32 in_value_len
= q_u
->valuesize
;
8211 uint32 in_data_len
= q_u
->datasize
;
8212 uint32
*out_max_value_len
= &r_u
->valuesize
;
8213 uint16
**out_value
= &r_u
->value
;
8214 uint32
*out_value_len
= &r_u
->realvaluesize
;
8215 uint32
*out_type
= &r_u
->type
;
8216 uint32
*out_max_data_len
= &r_u
->datasize
;
8217 uint8
**data_out
= &r_u
->data
;
8218 uint32
*out_data_len
= &r_u
->realdatasize
;
8220 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8222 uint32 biggest_valuesize
;
8223 uint32 biggest_datasize
;
8225 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8228 REGISTRY_VALUE
*val
= NULL
;
8229 NT_PRINTER_DATA
*p_data
;
8230 int i
, key_index
, num_values
;
8235 *out_max_data_len
= 0;
8239 DEBUG(5,("spoolss_enumprinterdata\n"));
8242 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8246 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8249 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8250 if (!W_ERROR_IS_OK(result
))
8253 p_data
= printer
->info_2
->data
;
8254 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8259 * The NT machine wants to know the biggest size of value and data
8261 * cf: MSDN EnumPrinterData remark section
8264 if ( !in_value_len
&& !in_data_len
&& (key_index
!= -1) )
8266 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8268 biggest_valuesize
= 0;
8269 biggest_datasize
= 0;
8271 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8273 for ( i
=0; i
<num_values
; i
++ )
8275 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8277 name_length
= strlen(val
->valuename
);
8278 if ( strlen(val
->valuename
) > biggest_valuesize
)
8279 biggest_valuesize
= name_length
;
8281 if ( val
->size
> biggest_datasize
)
8282 biggest_datasize
= val
->size
;
8284 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8288 /* the value is an UNICODE string but real_value_size is the length
8289 in bytes including the trailing 0 */
8291 *out_value_len
= 2 * (1+biggest_valuesize
);
8292 *out_data_len
= biggest_datasize
;
8294 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
8300 * the value len is wrong in NT sp3
8301 * that's the number of bytes not the number of unicode chars
8304 if ( key_index
!= -1 )
8305 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, idx
);
8310 /* out_value should default to "" or else NT4 has
8311 problems unmarshalling the response */
8313 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8316 if((*out_value
=(uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8318 result
= WERR_NOMEM
;
8321 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
8327 /* the data is counted in bytes */
8329 *out_max_data_len
= in_data_len
;
8330 *out_data_len
= in_data_len
;
8332 /* only allocate when given a non-zero data_len */
8334 if ( in_data_len
&& ((*data_out
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
8336 result
= WERR_NOMEM
;
8340 result
= WERR_NO_MORE_ITEMS
;
8346 * - counted in bytes in the request
8347 * - counted in UNICODE chars in the max reply
8348 * - counted in bytes in the real size
8350 * take a pause *before* coding not *during* coding
8354 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8356 if ( (*out_value
= (uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8358 result
= WERR_NOMEM
;
8362 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), (size_t)in_value_len
, 0);
8370 *out_type
= regval_type( val
);
8372 /* data - counted in bytes */
8374 *out_max_data_len
= in_data_len
;
8375 if ( in_data_len
&& (*data_out
= (uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
8377 result
= WERR_NOMEM
;
8380 data_len
= regval_size(val
);
8381 if ( *data_out
&& data_len
)
8382 memcpy( *data_out
, regval_data_p(val
), data_len
);
8383 *out_data_len
= data_len
;
8387 free_a_printer(&printer
, 2);
8391 /****************************************************************************
8392 ****************************************************************************/
8394 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
8396 POLICY_HND
*handle
= &q_u
->handle
;
8397 UNISTR2
*value
= &q_u
->value
;
8398 uint32 type
= q_u
->type
;
8399 uint8
*data
= q_u
->data
;
8400 uint32 real_len
= q_u
->real_len
;
8402 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8404 WERROR status
= WERR_OK
;
8405 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8408 DEBUG(5,("spoolss_setprinterdata\n"));
8411 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8415 if ( Printer
->printer_type
== SPLHND_SERVER
) {
8416 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8417 return WERR_INVALID_PARAM
;
8420 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8424 * Access check : NT returns "access denied" if you make a
8425 * SetPrinterData call without the necessary privildge.
8426 * we were originally returning OK if nothing changed
8427 * which made Win2k issue **a lot** of SetPrinterData
8428 * when connecting to a printer --jerry
8431 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8433 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8434 status
= WERR_ACCESS_DENIED
;
8438 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8439 if (!W_ERROR_IS_OK(status
))
8442 unistr2_to_ascii(valuename
, value
, sizeof(valuename
));
8445 * When client side code sets a magic printer data key, detect it and save
8446 * the current printer data and the magic key's data (its the DEVMODE) for
8447 * future printer/driver initializations.
8449 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
8451 /* Set devmode and printer initialization info */
8452 status
= save_driver_init( printer
, 2, data
, real_len
);
8454 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
8458 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
8459 type
, data
, real_len
);
8460 if ( W_ERROR_IS_OK(status
) )
8461 status
= mod_a_printer(printer
, 2);
8465 free_a_printer(&printer
, 2);
8470 /****************************************************************
8471 _spoolss_ResetPrinter
8472 ****************************************************************/
8474 WERROR
_spoolss_ResetPrinter(pipes_struct
*p
,
8475 struct spoolss_ResetPrinter
*r
)
8477 POLICY_HND
*handle
= r
->in
.handle
;
8478 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8481 DEBUG(5,("_spoolss_ResetPrinter\n"));
8484 * All we do is to check to see if the handle and queue is valid.
8485 * This call really doesn't mean anything to us because we only
8486 * support RAW printing. --jerry
8490 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8491 OUR_HANDLE(handle
)));
8495 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8499 /* blindly return success */
8503 /****************************************************************
8504 _spoolss_DeletePrinterData
8505 ****************************************************************/
8507 WERROR
_spoolss_DeletePrinterData(pipes_struct
*p
,
8508 struct spoolss_DeletePrinterData
*r
)
8510 POLICY_HND
*handle
= r
->in
.handle
;
8511 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8513 WERROR status
= WERR_OK
;
8514 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8516 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8519 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8520 OUR_HANDLE(handle
)));
8524 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
8527 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8528 DEBUG(3, ("_spoolss_DeletePrinterData: "
8529 "printer properties change denied by handle\n"));
8530 return WERR_ACCESS_DENIED
;
8533 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8534 if (!W_ERROR_IS_OK(status
))
8537 if (!r
->in
.value_name
) {
8538 free_a_printer(&printer
, 2);
8542 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
,
8545 if ( W_ERROR_IS_OK(status
) )
8546 mod_a_printer( printer
, 2 );
8548 free_a_printer(&printer
, 2);
8553 /****************************************************************
8555 ****************************************************************/
8557 WERROR
_spoolss_AddForm(pipes_struct
*p
,
8558 struct spoolss_AddForm
*r
)
8560 POLICY_HND
*handle
= r
->in
.handle
;
8561 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8562 nt_forms_struct tmpForm
;
8564 WERROR status
= WERR_OK
;
8565 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8568 nt_forms_struct
*list
=NULL
;
8569 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8571 DEBUG(5,("_spoolss_AddForm\n"));
8574 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8575 OUR_HANDLE(handle
)));
8580 /* forms can be added on printer of on the print server handle */
8582 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8584 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8587 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8588 if (!W_ERROR_IS_OK(status
))
8592 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8593 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8594 status
= WERR_ACCESS_DENIED
;
8598 /* can't add if builtin */
8600 if (get_a_builtin_ntform_by_string(form
->form_name
, &tmpForm
)) {
8601 status
= WERR_FILE_EXISTS
;
8605 count
= get_ntforms(&list
);
8607 if(!add_a_form(&list
, form
, &count
)) {
8608 status
= WERR_NOMEM
;
8612 write_ntforms(&list
, count
);
8615 * ChangeID must always be set if this is a printer
8618 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8619 status
= mod_a_printer(printer
, 2);
8623 free_a_printer(&printer
, 2);
8629 /****************************************************************
8631 ****************************************************************/
8633 WERROR
_spoolss_DeleteForm(pipes_struct
*p
,
8634 struct spoolss_DeleteForm
*r
)
8636 POLICY_HND
*handle
= r
->in
.handle
;
8637 const char *form_name
= r
->in
.form_name
;
8638 nt_forms_struct tmpForm
;
8640 nt_forms_struct
*list
=NULL
;
8641 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8643 WERROR status
= WERR_OK
;
8644 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8646 DEBUG(5,("_spoolss_DeleteForm\n"));
8649 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8650 OUR_HANDLE(handle
)));
8654 /* forms can be deleted on printer of on the print server handle */
8656 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8658 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8661 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8662 if (!W_ERROR_IS_OK(status
))
8666 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8667 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8668 status
= WERR_ACCESS_DENIED
;
8672 /* can't delete if builtin */
8674 if (get_a_builtin_ntform_by_string(form_name
,&tmpForm
)) {
8675 status
= WERR_INVALID_PARAM
;
8679 count
= get_ntforms(&list
);
8681 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
8685 * ChangeID must always be set if this is a printer
8688 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8689 status
= mod_a_printer(printer
, 2);
8693 free_a_printer(&printer
, 2);
8699 /****************************************************************
8701 ****************************************************************/
8703 WERROR
_spoolss_SetForm(pipes_struct
*p
,
8704 struct spoolss_SetForm
*r
)
8706 POLICY_HND
*handle
= r
->in
.handle
;
8707 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8708 nt_forms_struct tmpForm
;
8710 WERROR status
= WERR_OK
;
8711 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8714 nt_forms_struct
*list
=NULL
;
8715 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8717 DEBUG(5,("_spoolss_SetForm\n"));
8720 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8721 OUR_HANDLE(handle
)));
8725 /* forms can be modified on printer of on the print server handle */
8727 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8729 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8732 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8733 if (!W_ERROR_IS_OK(status
))
8737 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8738 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8739 status
= WERR_ACCESS_DENIED
;
8743 /* can't set if builtin */
8744 if (get_a_builtin_ntform_by_string(form
->form_name
, &tmpForm
)) {
8745 status
= WERR_INVALID_PARAM
;
8749 count
= get_ntforms(&list
);
8750 update_a_form(&list
, form
, count
);
8751 write_ntforms(&list
, count
);
8754 * ChangeID must always be set if this is a printer
8757 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8758 status
= mod_a_printer(printer
, 2);
8763 free_a_printer(&printer
, 2);
8769 /****************************************************************************
8770 enumprintprocessors level 1.
8771 ****************************************************************************/
8773 static WERROR
enumprintprocessors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8775 PRINTPROCESSOR_1
*info_1
=NULL
;
8776 WERROR result
= WERR_OK
;
8778 if((info_1
= SMB_MALLOC_P(PRINTPROCESSOR_1
)) == NULL
)
8783 init_unistr(&info_1
->name
, "winprint");
8785 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
8787 if (*needed
> offered
) {
8788 result
= WERR_INSUFFICIENT_BUFFER
;
8792 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8793 result
= WERR_NOMEM
;
8797 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
8802 if ( !W_ERROR_IS_OK(result
) )
8808 /****************************************************************************
8809 ****************************************************************************/
8811 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
8813 uint32 level
= q_u
->level
;
8814 RPC_BUFFER
*buffer
= NULL
;
8815 uint32 offered
= q_u
->offered
;
8816 uint32
*needed
= &r_u
->needed
;
8817 uint32
*returned
= &r_u
->returned
;
8819 /* that's an [in out] buffer */
8821 if (!q_u
->buffer
&& (offered
!=0)) {
8822 return WERR_INVALID_PARAM
;
8825 if (offered
> MAX_RPC_DATA_SIZE
) {
8826 return WERR_INVALID_PARAM
;
8829 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8830 buffer
= r_u
->buffer
;
8832 DEBUG(5,("spoolss_enumprintprocessors\n"));
8835 * Enumerate the print processors ...
8837 * Just reply with "winprint", to keep NT happy
8838 * and I can use my nice printer checker.
8846 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
8848 return WERR_UNKNOWN_LEVEL
;
8852 /****************************************************************************
8853 enumprintprocdatatypes level 1.
8854 ****************************************************************************/
8856 static WERROR
enumprintprocdatatypes_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8858 PRINTPROCDATATYPE_1
*info_1
=NULL
;
8859 WERROR result
= WERR_OK
;
8861 if((info_1
= SMB_MALLOC_P(PRINTPROCDATATYPE_1
)) == NULL
)
8866 init_unistr(&info_1
->name
, "RAW");
8868 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
8870 if (*needed
> offered
) {
8871 result
= WERR_INSUFFICIENT_BUFFER
;
8875 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8876 result
= WERR_NOMEM
;
8880 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
8885 if ( !W_ERROR_IS_OK(result
) )
8891 /****************************************************************************
8892 ****************************************************************************/
8894 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
8896 uint32 level
= q_u
->level
;
8897 RPC_BUFFER
*buffer
= NULL
;
8898 uint32 offered
= q_u
->offered
;
8899 uint32
*needed
= &r_u
->needed
;
8900 uint32
*returned
= &r_u
->returned
;
8902 /* that's an [in out] buffer */
8904 if (!q_u
->buffer
&& (offered
!=0)) {
8905 return WERR_INVALID_PARAM
;
8908 if (offered
> MAX_RPC_DATA_SIZE
) {
8909 return WERR_INVALID_PARAM
;
8912 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8913 buffer
= r_u
->buffer
;
8915 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8922 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
8924 return WERR_UNKNOWN_LEVEL
;
8928 /****************************************************************************
8929 enumprintmonitors level 1.
8930 ****************************************************************************/
8932 static WERROR
enumprintmonitors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8934 PRINTMONITOR_1
*info_1
;
8935 WERROR result
= WERR_OK
;
8938 if((info_1
= SMB_MALLOC_ARRAY(PRINTMONITOR_1
, 2)) == NULL
)
8943 init_unistr(&(info_1
[0].name
), SPL_LOCAL_PORT
);
8944 init_unistr(&(info_1
[1].name
), SPL_TCPIP_PORT
);
8946 for ( i
=0; i
<*returned
; i
++ ) {
8947 *needed
+= spoolss_size_printmonitor_info_1(&info_1
[i
]);
8950 if (*needed
> offered
) {
8951 result
= WERR_INSUFFICIENT_BUFFER
;
8955 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8956 result
= WERR_NOMEM
;
8960 for ( i
=0; i
<*returned
; i
++ ) {
8961 smb_io_printmonitor_info_1("", buffer
, &info_1
[i
], 0);
8967 if ( !W_ERROR_IS_OK(result
) )
8973 /****************************************************************************
8974 enumprintmonitors level 2.
8975 ****************************************************************************/
8977 static WERROR
enumprintmonitors_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8979 PRINTMONITOR_2
*info_2
;
8980 WERROR result
= WERR_OK
;
8983 if((info_2
= SMB_MALLOC_ARRAY(PRINTMONITOR_2
, 2)) == NULL
)
8988 init_unistr( &(info_2
[0].name
), SPL_LOCAL_PORT
);
8989 init_unistr( &(info_2
[0].environment
), "Windows NT X86" );
8990 init_unistr( &(info_2
[0].dll_name
), "localmon.dll" );
8992 init_unistr( &(info_2
[1].name
), SPL_TCPIP_PORT
);
8993 init_unistr( &(info_2
[1].environment
), "Windows NT X86" );
8994 init_unistr( &(info_2
[1].dll_name
), "tcpmon.dll" );
8996 for ( i
=0; i
<*returned
; i
++ ) {
8997 *needed
+= spoolss_size_printmonitor_info_2(&info_2
[i
]);
9000 if (*needed
> offered
) {
9001 result
= WERR_INSUFFICIENT_BUFFER
;
9005 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9006 result
= WERR_NOMEM
;
9010 for ( i
=0; i
<*returned
; i
++ ) {
9011 smb_io_printmonitor_info_2("", buffer
, &info_2
[i
], 0);
9017 if ( !W_ERROR_IS_OK(result
) )
9023 /****************************************************************************
9024 ****************************************************************************/
9026 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
9028 uint32 level
= q_u
->level
;
9029 RPC_BUFFER
*buffer
= NULL
;
9030 uint32 offered
= q_u
->offered
;
9031 uint32
*needed
= &r_u
->needed
;
9032 uint32
*returned
= &r_u
->returned
;
9034 /* that's an [in out] buffer */
9036 if (!q_u
->buffer
&& (offered
!=0)) {
9037 return WERR_INVALID_PARAM
;
9040 if (offered
> MAX_RPC_DATA_SIZE
) {
9041 return WERR_INVALID_PARAM
;
9044 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9045 buffer
= r_u
->buffer
;
9047 DEBUG(5,("spoolss_enumprintmonitors\n"));
9050 * Enumerate the print monitors ...
9052 * Just reply with "Local Port", to keep NT happy
9053 * and I can use my nice printer checker.
9061 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
9063 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
9065 return WERR_UNKNOWN_LEVEL
;
9069 /****************************************************************************
9070 ****************************************************************************/
9072 static WERROR
getjob_level_1(print_queue_struct
**queue
, int count
, int snum
,
9073 NT_PRINTER_INFO_LEVEL
*ntprinter
,
9074 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
9079 JOB_INFO_1
*info_1
=NULL
;
9080 WERROR result
= WERR_OK
;
9082 info_1
=SMB_MALLOC_P(JOB_INFO_1
);
9084 if (info_1
== NULL
) {
9088 for (i
=0; i
<count
&& found
==False
; i
++) {
9089 if ((*queue
)[i
].job
==(int)jobid
)
9095 /* NT treats not found as bad param... yet another bad choice */
9096 return WERR_INVALID_PARAM
;
9099 fill_job_info_1( info_1
, &((*queue
)[i
-1]), i
, snum
, ntprinter
);
9101 *needed
+= spoolss_size_job_info_1(info_1
);
9103 if (*needed
> offered
) {
9104 result
= WERR_INSUFFICIENT_BUFFER
;
9108 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9109 result
= WERR_NOMEM
;
9113 smb_io_job_info_1("", buffer
, info_1
, 0);
9121 /****************************************************************************
9122 ****************************************************************************/
9124 static WERROR
getjob_level_2(print_queue_struct
**queue
, int count
, int snum
,
9125 NT_PRINTER_INFO_LEVEL
*ntprinter
,
9126 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
9133 DEVICEMODE
*devmode
= NULL
;
9134 NT_DEVICEMODE
*nt_devmode
= NULL
;
9136 if ( !(info_2
=SMB_MALLOC_P(JOB_INFO_2
)) )
9139 ZERO_STRUCTP(info_2
);
9141 for ( i
=0; i
<count
&& found
==False
; i
++ )
9143 if ((*queue
)[i
].job
== (int)jobid
)
9148 /* NT treats not found as bad param... yet another bad
9150 result
= WERR_INVALID_PARAM
;
9155 * if the print job does not have a DEVMODE associated with it,
9156 * just use the one for the printer. A NULL devicemode is not
9157 * a failure condition
9160 if ( !(nt_devmode
=print_job_devmode( lp_const_servicename(snum
), jobid
)) )
9161 devmode
= construct_dev_mode(lp_const_servicename(snum
));
9163 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) != NULL
) {
9164 ZERO_STRUCTP( devmode
);
9165 convert_nt_devicemode( devmode
, nt_devmode
);
9169 fill_job_info_2(info_2
, &((*queue
)[i
-1]), i
, snum
, ntprinter
, devmode
);
9171 *needed
+= spoolss_size_job_info_2(info_2
);
9173 if (*needed
> offered
) {
9174 result
= WERR_INSUFFICIENT_BUFFER
;
9178 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9179 result
= WERR_NOMEM
;
9183 smb_io_job_info_2("", buffer
, info_2
, 0);
9188 /* Cleanup allocated memory */
9190 free_job_info_2(info_2
); /* Also frees devmode */
9196 /****************************************************************************
9197 ****************************************************************************/
9199 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
9201 POLICY_HND
*handle
= &q_u
->handle
;
9202 uint32 jobid
= q_u
->jobid
;
9203 uint32 level
= q_u
->level
;
9204 RPC_BUFFER
*buffer
= NULL
;
9205 uint32 offered
= q_u
->offered
;
9206 uint32
*needed
= &r_u
->needed
;
9207 WERROR wstatus
= WERR_OK
;
9208 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9211 print_queue_struct
*queue
= NULL
;
9212 print_status_struct prt_status
;
9214 /* that's an [in out] buffer */
9216 if (!q_u
->buffer
&& (offered
!=0)) {
9217 return WERR_INVALID_PARAM
;
9220 if (offered
> MAX_RPC_DATA_SIZE
) {
9221 return WERR_INVALID_PARAM
;
9224 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9225 buffer
= r_u
->buffer
;
9227 DEBUG(5,("spoolss_getjob\n"));
9231 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9234 wstatus
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9235 if ( !W_ERROR_IS_OK(wstatus
) )
9238 count
= print_queue_status(snum
, &queue
, &prt_status
);
9240 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9241 count
, prt_status
.status
, prt_status
.message
));
9245 wstatus
= getjob_level_1(&queue
, count
, snum
, ntprinter
, jobid
,
9246 buffer
, offered
, needed
);
9249 wstatus
= getjob_level_2(&queue
, count
, snum
, ntprinter
, jobid
,
9250 buffer
, offered
, needed
);
9253 wstatus
= WERR_UNKNOWN_LEVEL
;
9258 free_a_printer( &ntprinter
, 2 );
9263 /****************************************************************
9264 _spoolss_GetPrinterDataEx
9266 From MSDN documentation of GetPrinterDataEx: pass request
9267 to GetPrinterData if key is "PrinterDriverData".
9268 ****************************************************************/
9270 WERROR
_spoolss_GetPrinterDataEx(pipes_struct
*p
,
9271 struct spoolss_GetPrinterDataEx
*r
)
9273 POLICY_HND
*handle
= r
->in
.handle
;
9275 const char *keyname
= r
->in
.key_name
;
9276 const char *valuename
= r
->in
.value_name
;
9278 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9280 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9282 WERROR status
= WERR_OK
;
9284 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9286 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9287 keyname
, valuename
));
9289 /* in case of problem, return some default values */
9295 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9296 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9297 status
= WERR_BADFID
;
9301 /* Is the handle to a printer or to the server? */
9303 if (Printer
->printer_type
== SPLHND_SERVER
) {
9304 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9305 "Not implemented for server handles yet\n"));
9306 status
= WERR_INVALID_PARAM
;
9310 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9313 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9314 if ( !W_ERROR_IS_OK(status
) )
9317 /* check to see if the keyname is valid */
9318 if ( !strlen(keyname
) ) {
9319 status
= WERR_INVALID_PARAM
;
9323 if ( lookup_printerkey( printer
->info_2
->data
, keyname
) == -1 ) {
9324 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9325 "Invalid keyname [%s]\n", keyname
));
9326 free_a_printer( &printer
, 2 );
9327 status
= WERR_BADFILE
;
9331 /* When given a new keyname, we should just create it */
9333 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
,
9334 r
->out
.type
, &data
, r
->out
.needed
,
9337 if (*r
->out
.needed
> r
->in
.offered
) {
9338 status
= WERR_MORE_DATA
;
9341 if (W_ERROR_IS_OK(status
)) {
9342 memcpy(r
->out
.buffer
, data
, r
->in
.offered
);
9347 free_a_printer( &printer
, 2 );
9352 /****************************************************************
9353 _spoolss_SetPrinterDataEx
9354 ****************************************************************/
9356 WERROR
_spoolss_SetPrinterDataEx(pipes_struct
*p
,
9357 struct spoolss_SetPrinterDataEx
*r
)
9359 POLICY_HND
*handle
= r
->in
.handle
;
9360 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9362 WERROR status
= WERR_OK
;
9363 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9366 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9368 /* From MSDN documentation of SetPrinterDataEx: pass request to
9369 SetPrinterData if key is "PrinterDriverData" */
9372 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9373 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9377 if ( Printer
->printer_type
== SPLHND_SERVER
) {
9378 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9379 "Not implemented for server handles yet\n"));
9380 return WERR_INVALID_PARAM
;
9383 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9387 * Access check : NT returns "access denied" if you make a
9388 * SetPrinterData call without the necessary privildge.
9389 * we were originally returning OK if nothing changed
9390 * which made Win2k issue **a lot** of SetPrinterData
9391 * when connecting to a printer --jerry
9394 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
9396 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9397 "change denied by handle access permissions\n"));
9398 return WERR_ACCESS_DENIED
;
9401 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9402 if (!W_ERROR_IS_OK(status
))
9405 /* check for OID in valuename */
9407 if ( (oid_string
= strchr( r
->in
.value_name
, ',' )) != NULL
)
9413 /* save the registry data */
9415 status
= set_printer_dataex( printer
, r
->in
.key_name
, r
->in
.value_name
,
9416 r
->in
.type
, r
->in
.buffer
, r
->in
.offered
);
9418 if ( W_ERROR_IS_OK(status
) )
9420 /* save the OID if one was specified */
9422 char *str
= talloc_asprintf(p
->mem_ctx
, "%s\\%s",
9423 r
->in
.key_name
, SPOOL_OID_KEY
);
9429 * I'm not checking the status here on purpose. Don't know
9430 * if this is right, but I'm returning the status from the
9431 * previous set_printer_dataex() call. I have no idea if
9432 * this is right. --jerry
9435 set_printer_dataex( printer
, str
, r
->in
.value_name
,
9436 REG_SZ
, (uint8
*)oid_string
,
9437 strlen(oid_string
)+1 );
9440 status
= mod_a_printer(printer
, 2);
9443 free_a_printer(&printer
, 2);
9448 /****************************************************************
9449 _spoolss_DeletePrinterDataEx
9450 ****************************************************************/
9452 WERROR
_spoolss_DeletePrinterDataEx(pipes_struct
*p
,
9453 struct spoolss_DeletePrinterDataEx
*r
)
9455 POLICY_HND
*handle
= r
->in
.handle
;
9456 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9458 WERROR status
= WERR_OK
;
9459 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
9461 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9464 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9465 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9469 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9472 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9473 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9474 "printer properties change denied by handle\n"));
9475 return WERR_ACCESS_DENIED
;
9478 if (!r
->in
.value_name
|| !r
->in
.key_name
) {
9482 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9483 if (!W_ERROR_IS_OK(status
))
9486 status
= delete_printer_dataex( printer
, r
->in
.key_name
, r
->in
.value_name
);
9488 if ( W_ERROR_IS_OK(status
) )
9489 mod_a_printer( printer
, 2 );
9491 free_a_printer(&printer
, 2);
9496 /********************************************************************
9497 * spoolss_enumprinterkey
9498 ********************************************************************/
9501 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
9504 fstring
*keynames
= NULL
;
9505 uint16
*enumkeys
= NULL
;
9508 POLICY_HND
*handle
= &q_u
->handle
;
9509 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9510 NT_PRINTER_DATA
*data
;
9511 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9513 WERROR status
= WERR_BADFILE
;
9516 DEBUG(4,("_spoolss_enumprinterkey\n"));
9519 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9523 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9526 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9527 if (!W_ERROR_IS_OK(status
))
9530 /* get the list of subkey names */
9532 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9533 data
= printer
->info_2
->data
;
9535 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
9537 if ( num_keys
== -1 ) {
9538 status
= WERR_BADFILE
;
9542 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
9544 r_u
->needed
= printerkey_len
*2;
9546 if ( q_u
->size
< r_u
->needed
) {
9547 status
= WERR_MORE_DATA
;
9551 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
9552 status
= WERR_NOMEM
;
9558 if ( q_u
->size
< r_u
->needed
)
9559 status
= WERR_MORE_DATA
;
9562 free_a_printer( &printer
, 2 );
9563 SAFE_FREE( keynames
);
9568 /****************************************************************
9569 _spoolss_DeletePrinterKey
9570 ****************************************************************/
9572 WERROR
_spoolss_DeletePrinterKey(pipes_struct
*p
,
9573 struct spoolss_DeletePrinterKey
*r
)
9575 POLICY_HND
*handle
= r
->in
.handle
;
9576 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9577 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9581 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9584 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9585 OUR_HANDLE(handle
)));
9589 /* if keyname == NULL, return error */
9591 if ( !r
->in
.key_name
)
9592 return WERR_INVALID_PARAM
;
9594 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9597 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9598 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9599 "printer properties change denied by handle\n"));
9600 return WERR_ACCESS_DENIED
;
9603 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9604 if (!W_ERROR_IS_OK(status
))
9607 /* delete the key and all subneys */
9609 status
= delete_all_printer_data( printer
->info_2
, r
->in
.key_name
);
9611 if ( W_ERROR_IS_OK(status
) )
9612 status
= mod_a_printer(printer
, 2);
9614 free_a_printer( &printer
, 2 );
9620 /********************************************************************
9621 * spoolss_enumprinterdataex
9622 ********************************************************************/
9624 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
9626 POLICY_HND
*handle
= &q_u
->handle
;
9627 uint32 in_size
= q_u
->size
;
9630 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9631 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
9632 NT_PRINTER_DATA
*p_data
;
9634 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9639 REGISTRY_VALUE
*val
;
9644 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9647 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
9652 * first check for a keyname of NULL or "". Win2k seems to send
9653 * this a lot and we should send back WERR_INVALID_PARAM
9654 * no need to spend time looking up the printer in this case.
9658 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9659 if ( !strlen(key
) ) {
9660 result
= WERR_INVALID_PARAM
;
9664 /* get the printer off of disk */
9666 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
9669 ZERO_STRUCT(printer
);
9670 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9671 if (!W_ERROR_IS_OK(result
))
9674 /* now look for a match on the key name */
9676 p_data
= printer
->info_2
->data
;
9678 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9679 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
9681 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
9682 result
= WERR_INVALID_PARAM
;
9689 /* allocate the memory for the array of pointers -- if necessary */
9691 num_entries
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
9694 if ( (enum_values
=TALLOC_ARRAY(p
->mem_ctx
, PRINTER_ENUM_VALUES
, num_entries
)) == NULL
)
9696 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9697 (unsigned long)num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
9698 result
= WERR_NOMEM
;
9702 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
9706 * loop through all params and build the array to pass
9707 * back to the client
9710 for ( i
=0; i
<num_entries
; i
++ )
9712 /* lookup the registry value */
9714 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
9715 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
9719 value_name
= regval_name( val
);
9720 init_unistr( &enum_values
[i
].valuename
, value_name
);
9721 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
9722 enum_values
[i
].type
= regval_type( val
);
9724 data_len
= regval_size( val
);
9726 if ( !(enum_values
[i
].data
= (uint8
*)TALLOC_MEMDUP(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
9728 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9730 result
= WERR_NOMEM
;
9734 enum_values
[i
].data_len
= data_len
;
9736 /* keep track of the size of the array in bytes */
9738 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
9741 /* housekeeping information in the reply */
9743 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9744 * the hand marshalled container size is a multiple
9745 * of 4 bytes for RPC alignment.
9749 needed
+= 4-(needed
% 4);
9752 r_u
->needed
= needed
;
9753 r_u
->returned
= num_entries
;
9755 if (needed
> in_size
) {
9756 result
= WERR_MORE_DATA
;
9760 /* copy data into the reply */
9762 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9763 response buffer size is != the offered buffer size
9765 r_u->ctr.size = r_u->needed;
9767 r_u
->ctr
.size
= in_size
;
9769 r_u
->ctr
.size_of_array
= r_u
->returned
;
9770 r_u
->ctr
.values
= enum_values
;
9774 free_a_printer(&printer
, 2);
9779 /****************************************************************************
9780 ****************************************************************************/
9782 static WERROR
getprintprocessordirectory_level_1(TALLOC_CTX
*mem_ctx
,
9783 const char *servername
,
9784 const char *environment
,
9785 struct spoolss_PrintProcessorDirectoryInfo1
*r
,
9792 werr
= compose_spoolss_server_path(mem_ctx
,
9795 SPOOLSS_PRTPROCS_PATH
,
9797 if (!W_ERROR_IS_OK(werr
)) {
9801 DEBUG(4,("print processor directory: [%s]\n", path
));
9803 r
->directory_name
= path
;
9805 *needed
+= ndr_size_spoolss_PrintProcessorDirectoryInfo1(r
, NULL
, 0);
9807 if (*needed
> offered
) {
9809 return WERR_INSUFFICIENT_BUFFER
;
9815 /****************************************************************
9816 _spoolss_GetPrintProcessorDirectory
9817 ****************************************************************/
9819 WERROR
_spoolss_GetPrintProcessorDirectory(pipes_struct
*p
,
9820 struct spoolss_GetPrintProcessorDirectory
*r
)
9824 /* that's an [in out] buffer */
9826 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
9827 return WERR_INVALID_PARAM
;
9830 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9835 /* r->in.level is ignored */
9837 result
= getprintprocessordirectory_level_1(p
->mem_ctx
,
9840 &r
->out
.info
->info1
,
9843 if (!W_ERROR_IS_OK(result
)) {
9844 TALLOC_FREE(r
->out
.info
);
9850 /*******************************************************************
9851 ********************************************************************/
9853 static bool push_monitorui_buf(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*buf
,
9854 const char *dllname
)
9856 enum ndr_err_code ndr_err
;
9857 struct spoolss_MonitorUi ui
;
9859 ui
.dll_name
= dllname
;
9861 ndr_err
= ndr_push_struct_blob(buf
, mem_ctx
, NULL
, &ui
,
9862 (ndr_push_flags_fn_t
)ndr_push_spoolss_MonitorUi
);
9863 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9864 NDR_PRINT_DEBUG(spoolss_MonitorUi
, &ui
);
9866 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9869 /*******************************************************************
9870 Streams the monitor UI DLL name in UNICODE
9871 *******************************************************************/
9873 static WERROR
xcvtcp_monitorui(TALLOC_CTX
*mem_ctx
,
9874 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9875 DATA_BLOB
*out
, uint32_t *needed
)
9877 const char *dllname
= "tcpmonui.dll";
9879 *needed
= (strlen(dllname
)+1) * 2;
9881 if (out
->length
< *needed
) {
9882 return WERR_INSUFFICIENT_BUFFER
;
9885 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
9892 /*******************************************************************
9893 ********************************************************************/
9895 static bool pull_port_data_1(TALLOC_CTX
*mem_ctx
,
9896 struct spoolss_PortData1
*port1
,
9897 const DATA_BLOB
*buf
)
9899 enum ndr_err_code ndr_err
;
9900 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, NULL
, port1
,
9901 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData1
);
9902 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9903 NDR_PRINT_DEBUG(spoolss_PortData1
, port1
);
9905 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9908 /*******************************************************************
9909 ********************************************************************/
9911 static bool pull_port_data_2(TALLOC_CTX
*mem_ctx
,
9912 struct spoolss_PortData2
*port2
,
9913 const DATA_BLOB
*buf
)
9915 enum ndr_err_code ndr_err
;
9916 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, NULL
, port2
,
9917 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData2
);
9918 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9919 NDR_PRINT_DEBUG(spoolss_PortData2
, port2
);
9921 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9924 /*******************************************************************
9925 Create a new TCP/IP port
9926 *******************************************************************/
9928 static WERROR
xcvtcp_addport(TALLOC_CTX
*mem_ctx
,
9929 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9930 DATA_BLOB
*out
, uint32_t *needed
)
9932 struct spoolss_PortData1 port1
;
9933 struct spoolss_PortData2 port2
;
9934 char *device_uri
= NULL
;
9937 const char *portname
;
9938 const char *hostaddress
;
9940 uint32_t port_number
;
9943 /* peek for spoolss_PortData version */
9945 if (!in
|| (in
->length
< (128 + 4))) {
9946 return WERR_GENERAL_FAILURE
;
9949 version
= IVAL(in
->data
, 128);
9955 if (!pull_port_data_1(mem_ctx
, &port1
, in
)) {
9959 portname
= port1
.portname
;
9960 hostaddress
= port1
.hostaddress
;
9961 queue
= port1
.queue
;
9962 protocol
= port1
.protocol
;
9963 port_number
= port1
.port_number
;
9969 if (!pull_port_data_2(mem_ctx
, &port2
, in
)) {
9973 portname
= port2
.portname
;
9974 hostaddress
= port2
.hostaddress
;
9975 queue
= port2
.queue
;
9976 protocol
= port2
.protocol
;
9977 port_number
= port2
.port_number
;
9981 DEBUG(1,("xcvtcp_addport: "
9982 "unknown version of port_data: %d\n", version
));
9983 return WERR_UNKNOWN_PORT
;
9986 /* create the device URI and call the add_port_hook() */
9989 case PROTOCOL_RAWTCP_TYPE
:
9990 device_uri
= talloc_asprintf(mem_ctx
,
9991 "socket://%s:%d/", hostaddress
,
9995 case PROTOCOL_LPR_TYPE
:
9996 device_uri
= talloc_asprintf(mem_ctx
,
9997 "lpr://%s/%s", hostaddress
, queue
);
10001 return WERR_UNKNOWN_PORT
;
10008 return add_port_hook(mem_ctx
, token
, portname
, device_uri
);
10011 /*******************************************************************
10012 *******************************************************************/
10014 struct xcv_api_table xcvtcp_cmds
[] = {
10015 { "MonitorUI", xcvtcp_monitorui
},
10016 { "AddPort", xcvtcp_addport
},
10020 static WERROR
process_xcvtcp_command(TALLOC_CTX
*mem_ctx
,
10021 NT_USER_TOKEN
*token
, const char *command
,
10028 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
10030 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
10031 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
10032 return xcvtcp_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
10035 return WERR_BADFUNC
;
10038 /*******************************************************************
10039 *******************************************************************/
10040 #if 0 /* don't support management using the "Local Port" monitor */
10042 static WERROR
xcvlocal_monitorui(TALLOC_CTX
*mem_ctx
,
10043 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
10044 DATA_BLOB
*out
, uint32_t *needed
)
10046 const char *dllname
= "localui.dll";
10048 *needed
= (strlen(dllname
)+1) * 2;
10050 if (out
->length
< *needed
) {
10051 return WERR_INSUFFICIENT_BUFFER
;
10054 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
10061 /*******************************************************************
10062 *******************************************************************/
10064 struct xcv_api_table xcvlocal_cmds
[] = {
10065 { "MonitorUI", xcvlocal_monitorui
},
10069 struct xcv_api_table xcvlocal_cmds
[] = {
10076 /*******************************************************************
10077 *******************************************************************/
10079 static WERROR
process_xcvlocal_command(TALLOC_CTX
*mem_ctx
,
10080 NT_USER_TOKEN
*token
, const char *command
,
10081 DATA_BLOB
*inbuf
, DATA_BLOB
*outbuf
,
10086 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
10088 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
10089 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
10090 return xcvlocal_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
10092 return WERR_BADFUNC
;
10095 /****************************************************************
10097 ****************************************************************/
10099 WERROR
_spoolss_XcvData(pipes_struct
*p
,
10100 struct spoolss_XcvData
*r
)
10102 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
10103 DATA_BLOB out_data
;
10107 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10108 OUR_HANDLE(r
->in
.handle
)));
10109 return WERR_BADFID
;
10112 /* Has to be a handle to the TCP/IP port monitor */
10114 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
10115 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10116 return WERR_BADFID
;
10119 /* requires administrative access to the server */
10121 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
10122 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10123 return WERR_ACCESS_DENIED
;
10126 /* Allocate the outgoing buffer */
10128 if (r
->in
.out_data_size
) {
10129 out_data
= data_blob_talloc_zero(p
->mem_ctx
, r
->in
.out_data_size
);
10130 if (out_data
.data
== NULL
) {
10135 switch ( Printer
->printer_type
) {
10136 case SPLHND_PORTMON_TCP
:
10137 werror
= process_xcvtcp_command(p
->mem_ctx
,
10138 p
->server_info
->ptok
,
10139 r
->in
.function_name
,
10140 &r
->in
.in_data
, &out_data
,
10143 case SPLHND_PORTMON_LOCAL
:
10144 werror
= process_xcvlocal_command(p
->mem_ctx
,
10145 p
->server_info
->ptok
,
10146 r
->in
.function_name
,
10147 &r
->in
.in_data
, &out_data
,
10151 werror
= WERR_INVALID_PRINT_MONITOR
;
10154 if (!W_ERROR_IS_OK(werror
)) {
10158 *r
->out
.status_code
= 0;
10160 memcpy(r
->out
.out_data
, out_data
.data
, out_data
.length
);
10165 /****************************************************************
10166 _spoolss_AddPrintProcessor
10167 ****************************************************************/
10169 WERROR
_spoolss_AddPrintProcessor(pipes_struct
*p
,
10170 struct spoolss_AddPrintProcessor
*r
)
10172 /* for now, just indicate success and ignore the add. We'll
10173 automatically set the winprint processor for printer
10174 entries later. Used to debug the LexMark Optra S 1855 PCL
10180 /****************************************************************
10181 _spoolss_EnumPrinters
10182 ****************************************************************/
10184 WERROR
_spoolss_EnumPrinters(pipes_struct
*p
,
10185 struct spoolss_EnumPrinters
*r
)
10187 p
->rng_fault_state
= true;
10188 return WERR_NOT_SUPPORTED
;
10191 /****************************************************************
10193 ****************************************************************/
10195 WERROR
_spoolss_GetJob(pipes_struct
*p
,
10196 struct spoolss_GetJob
*r
)
10198 p
->rng_fault_state
= true;
10199 return WERR_NOT_SUPPORTED
;
10202 /****************************************************************
10204 ****************************************************************/
10206 WERROR
_spoolss_EnumJobs(pipes_struct
*p
,
10207 struct spoolss_EnumJobs
*r
)
10209 p
->rng_fault_state
= true;
10210 return WERR_NOT_SUPPORTED
;
10213 /****************************************************************
10214 _spoolss_AddPrinter
10215 ****************************************************************/
10217 WERROR
_spoolss_AddPrinter(pipes_struct
*p
,
10218 struct spoolss_AddPrinter
*r
)
10220 p
->rng_fault_state
= true;
10221 return WERR_NOT_SUPPORTED
;
10224 /****************************************************************
10225 _spoolss_GetPrinter
10226 ****************************************************************/
10228 WERROR
_spoolss_GetPrinter(pipes_struct
*p
,
10229 struct spoolss_GetPrinter
*r
)
10231 p
->rng_fault_state
= true;
10232 return WERR_NOT_SUPPORTED
;
10235 /****************************************************************
10236 _spoolss_EnumPrinterDrivers
10237 ****************************************************************/
10239 WERROR
_spoolss_EnumPrinterDrivers(pipes_struct
*p
,
10240 struct spoolss_EnumPrinterDrivers
*r
)
10242 p
->rng_fault_state
= true;
10243 return WERR_NOT_SUPPORTED
;
10246 /****************************************************************
10247 _spoolss_GetPrinterDriver
10248 ****************************************************************/
10250 WERROR
_spoolss_GetPrinterDriver(pipes_struct
*p
,
10251 struct spoolss_GetPrinterDriver
*r
)
10253 p
->rng_fault_state
= true;
10254 return WERR_NOT_SUPPORTED
;
10257 /****************************************************************
10258 _spoolss_EnumPrintProcessors
10259 ****************************************************************/
10261 WERROR
_spoolss_EnumPrintProcessors(pipes_struct
*p
,
10262 struct spoolss_EnumPrintProcessors
*r
)
10264 p
->rng_fault_state
= true;
10265 return WERR_NOT_SUPPORTED
;
10268 /****************************************************************
10269 _spoolss_ReadPrinter
10270 ****************************************************************/
10272 WERROR
_spoolss_ReadPrinter(pipes_struct
*p
,
10273 struct spoolss_ReadPrinter
*r
)
10275 p
->rng_fault_state
= true;
10276 return WERR_NOT_SUPPORTED
;
10279 /****************************************************************
10280 _spoolss_GetPrinterData
10281 ****************************************************************/
10283 WERROR
_spoolss_GetPrinterData(pipes_struct
*p
,
10284 struct spoolss_GetPrinterData
*r
)
10286 p
->rng_fault_state
= true;
10287 return WERR_NOT_SUPPORTED
;
10290 /****************************************************************
10291 _spoolss_SetPrinterData
10292 ****************************************************************/
10294 WERROR
_spoolss_SetPrinterData(pipes_struct
*p
,
10295 struct spoolss_SetPrinterData
*r
)
10297 p
->rng_fault_state
= true;
10298 return WERR_NOT_SUPPORTED
;
10301 /****************************************************************
10302 _spoolss_WaitForPrinterChange
10303 ****************************************************************/
10305 WERROR
_spoolss_WaitForPrinterChange(pipes_struct
*p
,
10306 struct spoolss_WaitForPrinterChange
*r
)
10308 p
->rng_fault_state
= true;
10309 return WERR_NOT_SUPPORTED
;
10312 /****************************************************************
10314 ****************************************************************/
10316 WERROR
_spoolss_EnumForms(pipes_struct
*p
,
10317 struct spoolss_EnumForms
*r
)
10319 p
->rng_fault_state
= true;
10320 return WERR_NOT_SUPPORTED
;
10323 /****************************************************************
10325 ****************************************************************/
10327 WERROR
_spoolss_EnumPorts(pipes_struct
*p
,
10328 struct spoolss_EnumPorts
*r
)
10330 p
->rng_fault_state
= true;
10331 return WERR_NOT_SUPPORTED
;
10334 /****************************************************************
10335 _spoolss_EnumMonitors
10336 ****************************************************************/
10338 WERROR
_spoolss_EnumMonitors(pipes_struct
*p
,
10339 struct spoolss_EnumMonitors
*r
)
10341 p
->rng_fault_state
= true;
10342 return WERR_NOT_SUPPORTED
;
10345 /****************************************************************
10347 ****************************************************************/
10349 WERROR
_spoolss_AddPort(pipes_struct
*p
,
10350 struct spoolss_AddPort
*r
)
10352 p
->rng_fault_state
= true;
10353 return WERR_NOT_SUPPORTED
;
10356 /****************************************************************
10357 _spoolss_ConfigurePort
10358 ****************************************************************/
10360 WERROR
_spoolss_ConfigurePort(pipes_struct
*p
,
10361 struct spoolss_ConfigurePort
*r
)
10363 p
->rng_fault_state
= true;
10364 return WERR_NOT_SUPPORTED
;
10367 /****************************************************************
10368 _spoolss_DeletePort
10369 ****************************************************************/
10371 WERROR
_spoolss_DeletePort(pipes_struct
*p
,
10372 struct spoolss_DeletePort
*r
)
10374 p
->rng_fault_state
= true;
10375 return WERR_NOT_SUPPORTED
;
10378 /****************************************************************
10379 _spoolss_CreatePrinterIC
10380 ****************************************************************/
10382 WERROR
_spoolss_CreatePrinterIC(pipes_struct
*p
,
10383 struct spoolss_CreatePrinterIC
*r
)
10385 p
->rng_fault_state
= true;
10386 return WERR_NOT_SUPPORTED
;
10389 /****************************************************************
10390 _spoolss_PlayGDIScriptOnPrinterIC
10391 ****************************************************************/
10393 WERROR
_spoolss_PlayGDIScriptOnPrinterIC(pipes_struct
*p
,
10394 struct spoolss_PlayGDIScriptOnPrinterIC
*r
)
10396 p
->rng_fault_state
= true;
10397 return WERR_NOT_SUPPORTED
;
10400 /****************************************************************
10401 _spoolss_DeletePrinterIC
10402 ****************************************************************/
10404 WERROR
_spoolss_DeletePrinterIC(pipes_struct
*p
,
10405 struct spoolss_DeletePrinterIC
*r
)
10407 p
->rng_fault_state
= true;
10408 return WERR_NOT_SUPPORTED
;
10411 /****************************************************************
10412 _spoolss_AddPrinterConnection
10413 ****************************************************************/
10415 WERROR
_spoolss_AddPrinterConnection(pipes_struct
*p
,
10416 struct spoolss_AddPrinterConnection
*r
)
10418 p
->rng_fault_state
= true;
10419 return WERR_NOT_SUPPORTED
;
10422 /****************************************************************
10423 _spoolss_DeletePrinterConnection
10424 ****************************************************************/
10426 WERROR
_spoolss_DeletePrinterConnection(pipes_struct
*p
,
10427 struct spoolss_DeletePrinterConnection
*r
)
10429 p
->rng_fault_state
= true;
10430 return WERR_NOT_SUPPORTED
;
10433 /****************************************************************
10434 _spoolss_PrinterMessageBox
10435 ****************************************************************/
10437 WERROR
_spoolss_PrinterMessageBox(pipes_struct
*p
,
10438 struct spoolss_PrinterMessageBox
*r
)
10440 p
->rng_fault_state
= true;
10441 return WERR_NOT_SUPPORTED
;
10444 /****************************************************************
10445 _spoolss_AddMonitor
10446 ****************************************************************/
10448 WERROR
_spoolss_AddMonitor(pipes_struct
*p
,
10449 struct spoolss_AddMonitor
*r
)
10451 p
->rng_fault_state
= true;
10452 return WERR_NOT_SUPPORTED
;
10455 /****************************************************************
10456 _spoolss_DeleteMonitor
10457 ****************************************************************/
10459 WERROR
_spoolss_DeleteMonitor(pipes_struct
*p
,
10460 struct spoolss_DeleteMonitor
*r
)
10462 p
->rng_fault_state
= true;
10463 return WERR_NOT_SUPPORTED
;
10466 /****************************************************************
10467 _spoolss_DeletePrintProcessor
10468 ****************************************************************/
10470 WERROR
_spoolss_DeletePrintProcessor(pipes_struct
*p
,
10471 struct spoolss_DeletePrintProcessor
*r
)
10473 p
->rng_fault_state
= true;
10474 return WERR_NOT_SUPPORTED
;
10477 /****************************************************************
10478 _spoolss_AddPrintProvidor
10479 ****************************************************************/
10481 WERROR
_spoolss_AddPrintProvidor(pipes_struct
*p
,
10482 struct spoolss_AddPrintProvidor
*r
)
10484 p
->rng_fault_state
= true;
10485 return WERR_NOT_SUPPORTED
;
10488 /****************************************************************
10489 _spoolss_DeletePrintProvidor
10490 ****************************************************************/
10492 WERROR
_spoolss_DeletePrintProvidor(pipes_struct
*p
,
10493 struct spoolss_DeletePrintProvidor
*r
)
10495 p
->rng_fault_state
= true;
10496 return WERR_NOT_SUPPORTED
;
10499 /****************************************************************
10500 _spoolss_EnumPrintProcDataTypes
10501 ****************************************************************/
10503 WERROR
_spoolss_EnumPrintProcDataTypes(pipes_struct
*p
,
10504 struct spoolss_EnumPrintProcDataTypes
*r
)
10506 p
->rng_fault_state
= true;
10507 return WERR_NOT_SUPPORTED
;
10510 /****************************************************************
10511 _spoolss_GetPrinterDriver2
10512 ****************************************************************/
10514 WERROR
_spoolss_GetPrinterDriver2(pipes_struct
*p
,
10515 struct spoolss_GetPrinterDriver2
*r
)
10517 p
->rng_fault_state
= true;
10518 return WERR_NOT_SUPPORTED
;
10521 /****************************************************************
10522 _spoolss_FindFirstPrinterChangeNotification
10523 ****************************************************************/
10525 WERROR
_spoolss_FindFirstPrinterChangeNotification(pipes_struct
*p
,
10526 struct spoolss_FindFirstPrinterChangeNotification
*r
)
10528 p
->rng_fault_state
= true;
10529 return WERR_NOT_SUPPORTED
;
10532 /****************************************************************
10533 _spoolss_FindNextPrinterChangeNotification
10534 ****************************************************************/
10536 WERROR
_spoolss_FindNextPrinterChangeNotification(pipes_struct
*p
,
10537 struct spoolss_FindNextPrinterChangeNotification
*r
)
10539 p
->rng_fault_state
= true;
10540 return WERR_NOT_SUPPORTED
;
10543 /****************************************************************
10544 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10545 ****************************************************************/
10547 WERROR
_spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct
*p
,
10548 struct spoolss_RouterFindFirstPrinterChangeNotificationOld
*r
)
10550 p
->rng_fault_state
= true;
10551 return WERR_NOT_SUPPORTED
;
10554 /****************************************************************
10555 _spoolss_ReplyOpenPrinter
10556 ****************************************************************/
10558 WERROR
_spoolss_ReplyOpenPrinter(pipes_struct
*p
,
10559 struct spoolss_ReplyOpenPrinter
*r
)
10561 p
->rng_fault_state
= true;
10562 return WERR_NOT_SUPPORTED
;
10565 /****************************************************************
10566 _spoolss_RouterReplyPrinter
10567 ****************************************************************/
10569 WERROR
_spoolss_RouterReplyPrinter(pipes_struct
*p
,
10570 struct spoolss_RouterReplyPrinter
*r
)
10572 p
->rng_fault_state
= true;
10573 return WERR_NOT_SUPPORTED
;
10576 /****************************************************************
10577 _spoolss_ReplyClosePrinter
10578 ****************************************************************/
10580 WERROR
_spoolss_ReplyClosePrinter(pipes_struct
*p
,
10581 struct spoolss_ReplyClosePrinter
*r
)
10583 p
->rng_fault_state
= true;
10584 return WERR_NOT_SUPPORTED
;
10587 /****************************************************************
10589 ****************************************************************/
10591 WERROR
_spoolss_AddPortEx(pipes_struct
*p
,
10592 struct spoolss_AddPortEx
*r
)
10594 p
->rng_fault_state
= true;
10595 return WERR_NOT_SUPPORTED
;
10598 /****************************************************************
10599 _spoolss_RouterFindFirstPrinterChangeNotification
10600 ****************************************************************/
10602 WERROR
_spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct
*p
,
10603 struct spoolss_RouterFindFirstPrinterChangeNotification
*r
)
10605 p
->rng_fault_state
= true;
10606 return WERR_NOT_SUPPORTED
;
10609 /****************************************************************
10610 _spoolss_SpoolerInit
10611 ****************************************************************/
10613 WERROR
_spoolss_SpoolerInit(pipes_struct
*p
,
10614 struct spoolss_SpoolerInit
*r
)
10616 p
->rng_fault_state
= true;
10617 return WERR_NOT_SUPPORTED
;
10620 /****************************************************************
10621 _spoolss_ResetPrinterEx
10622 ****************************************************************/
10624 WERROR
_spoolss_ResetPrinterEx(pipes_struct
*p
,
10625 struct spoolss_ResetPrinterEx
*r
)
10627 p
->rng_fault_state
= true;
10628 return WERR_NOT_SUPPORTED
;
10631 /****************************************************************
10632 _spoolss_RouterReplyPrinterEx
10633 ****************************************************************/
10635 WERROR
_spoolss_RouterReplyPrinterEx(pipes_struct
*p
,
10636 struct spoolss_RouterReplyPrinterEx
*r
)
10638 p
->rng_fault_state
= true;
10639 return WERR_NOT_SUPPORTED
;
10642 /****************************************************************
10644 ****************************************************************/
10646 WERROR
_spoolss_44(pipes_struct
*p
,
10647 struct spoolss_44
*r
)
10649 p
->rng_fault_state
= true;
10650 return WERR_NOT_SUPPORTED
;
10653 /****************************************************************
10655 ****************************************************************/
10657 WERROR
_spoolss_47(pipes_struct
*p
,
10658 struct spoolss_47
*r
)
10660 p
->rng_fault_state
= true;
10661 return WERR_NOT_SUPPORTED
;
10664 /****************************************************************
10665 _spoolss_EnumPrinterData
10666 ****************************************************************/
10668 WERROR
_spoolss_EnumPrinterData(pipes_struct
*p
,
10669 struct spoolss_EnumPrinterData
*r
)
10671 p
->rng_fault_state
= true;
10672 return WERR_NOT_SUPPORTED
;
10675 /****************************************************************
10677 ****************************************************************/
10679 WERROR
_spoolss_4a(pipes_struct
*p
,
10680 struct spoolss_4a
*r
)
10682 p
->rng_fault_state
= true;
10683 return WERR_NOT_SUPPORTED
;
10686 /****************************************************************
10688 ****************************************************************/
10690 WERROR
_spoolss_4b(pipes_struct
*p
,
10691 struct spoolss_4b
*r
)
10693 p
->rng_fault_state
= true;
10694 return WERR_NOT_SUPPORTED
;
10697 /****************************************************************
10699 ****************************************************************/
10701 WERROR
_spoolss_4c(pipes_struct
*p
,
10702 struct spoolss_4c
*r
)
10704 p
->rng_fault_state
= true;
10705 return WERR_NOT_SUPPORTED
;
10708 /****************************************************************
10709 _spoolss_EnumPrinterDataEx
10710 ****************************************************************/
10712 WERROR
_spoolss_EnumPrinterDataEx(pipes_struct
*p
,
10713 struct spoolss_EnumPrinterDataEx
*r
)
10715 p
->rng_fault_state
= true;
10716 return WERR_NOT_SUPPORTED
;
10719 /****************************************************************
10720 _spoolss_EnumPrinterKey
10721 ****************************************************************/
10723 WERROR
_spoolss_EnumPrinterKey(pipes_struct
*p
,
10724 struct spoolss_EnumPrinterKey
*r
)
10726 p
->rng_fault_state
= true;
10727 return WERR_NOT_SUPPORTED
;
10730 /****************************************************************
10732 ****************************************************************/
10734 WERROR
_spoolss_53(pipes_struct
*p
,
10735 struct spoolss_53
*r
)
10737 p
->rng_fault_state
= true;
10738 return WERR_NOT_SUPPORTED
;
10741 /****************************************************************
10743 ****************************************************************/
10745 WERROR
_spoolss_55(pipes_struct
*p
,
10746 struct spoolss_55
*r
)
10748 p
->rng_fault_state
= true;
10749 return WERR_NOT_SUPPORTED
;
10752 /****************************************************************
10754 ****************************************************************/
10756 WERROR
_spoolss_56(pipes_struct
*p
,
10757 struct spoolss_56
*r
)
10759 p
->rng_fault_state
= true;
10760 return WERR_NOT_SUPPORTED
;
10763 /****************************************************************
10765 ****************************************************************/
10767 WERROR
_spoolss_57(pipes_struct
*p
,
10768 struct spoolss_57
*r
)
10770 p
->rng_fault_state
= true;
10771 return WERR_NOT_SUPPORTED
;
10774 /****************************************************************
10776 ****************************************************************/
10778 WERROR
_spoolss_5a(pipes_struct
*p
,
10779 struct spoolss_5a
*r
)
10781 p
->rng_fault_state
= true;
10782 return WERR_NOT_SUPPORTED
;
10785 /****************************************************************
10787 ****************************************************************/
10789 WERROR
_spoolss_5b(pipes_struct
*p
,
10790 struct spoolss_5b
*r
)
10792 p
->rng_fault_state
= true;
10793 return WERR_NOT_SUPPORTED
;
10796 /****************************************************************
10798 ****************************************************************/
10800 WERROR
_spoolss_5c(pipes_struct
*p
,
10801 struct spoolss_5c
*r
)
10803 p
->rng_fault_state
= true;
10804 return WERR_NOT_SUPPORTED
;
10807 /****************************************************************
10809 ****************************************************************/
10811 WERROR
_spoolss_5d(pipes_struct
*p
,
10812 struct spoolss_5d
*r
)
10814 p
->rng_fault_state
= true;
10815 return WERR_NOT_SUPPORTED
;
10818 /****************************************************************
10820 ****************************************************************/
10822 WERROR
_spoolss_5e(pipes_struct
*p
,
10823 struct spoolss_5e
*r
)
10825 p
->rng_fault_state
= true;
10826 return WERR_NOT_SUPPORTED
;
10829 /****************************************************************
10831 ****************************************************************/
10833 WERROR
_spoolss_5f(pipes_struct
*p
,
10834 struct spoolss_5f
*r
)
10836 p
->rng_fault_state
= true;
10837 return WERR_NOT_SUPPORTED
;