2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27 up, all the errors returned are DOS errors, not NT status codes. */
31 /* macros stolen from s4 spoolss server */
32 #define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
33 ((info)?ndr_size_##fn(info, level, ic, 0):0)
35 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
36 ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
38 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \
39 ((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0)
41 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
44 extern userdom_struct current_user_info
;
47 #define DBGC_CLASS DBGC_RPC_SRV
49 #ifndef MAX_OPEN_PRINTER_EXS
50 #define MAX_OPEN_PRINTER_EXS 50
53 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
54 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
56 static Printer_entry
*printers_list
;
58 typedef struct _counter_printer_0
{
59 struct _counter_printer_0
*next
;
60 struct _counter_printer_0
*prev
;
66 static counter_printer_0
*counter_list
;
68 static struct rpc_pipe_client
*notify_cli_pipe
; /* print notify back-channel pipe handle*/
69 static uint32_t smb_connections
= 0;
72 /* in printing/nt_printing.c */
74 extern struct standard_mapping printer_std_mapping
, printserver_std_mapping
;
76 /* API table for Xcv Monitor functions */
78 struct xcv_api_table
{
80 WERROR(*fn
) (TALLOC_CTX
*mem_ctx
, NT_USER_TOKEN
*token
, DATA_BLOB
*in
, DATA_BLOB
*out
, uint32_t *needed
);
83 /********************************************************************
84 * Canonicalize servername.
85 ********************************************************************/
87 static const char *canon_servername(const char *servername
)
89 const char *pservername
= servername
;
90 while (*pservername
== '\\') {
96 /* translate between internal status numbers and NT status numbers */
97 static int nt_printj_status(int v
)
103 return JOB_STATUS_PAUSED
;
105 return JOB_STATUS_SPOOLING
;
107 return JOB_STATUS_PRINTING
;
109 return JOB_STATUS_ERROR
;
111 return JOB_STATUS_DELETING
;
113 return JOB_STATUS_OFFLINE
;
115 return JOB_STATUS_PAPEROUT
;
117 return JOB_STATUS_PRINTED
;
119 return JOB_STATUS_DELETED
;
121 return JOB_STATUS_BLOCKED_DEVQ
;
122 case LPQ_USER_INTERVENTION
:
123 return JOB_STATUS_USER_INTERVENTION
;
128 static int nt_printq_status(int v
)
132 return PRINTER_STATUS_PAUSED
;
141 /***************************************************************************
142 Disconnect from the client
143 ****************************************************************************/
145 static void srv_spoolss_replycloseprinter(int snum
, struct policy_handle
*handle
)
151 * Tell the specific printing tdb we no longer want messages for this printer
152 * by deregistering our PID.
155 if (!print_notify_deregister_pid(snum
))
156 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum
) ));
158 /* weird if the test succeds !!! */
159 if (smb_connections
==0) {
160 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
164 status
= rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe
, talloc_tos(),
167 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
168 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
169 win_errstr(result
)));
171 /* if it's the last connection, deconnect the IPC$ share */
172 if (smb_connections
==1) {
174 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe
) );
175 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
177 messaging_deregister(smbd_messaging_context(),
178 MSG_PRINTER_NOTIFY2
, NULL
);
180 /* Tell the connections db we're no longer interested in
181 * printer notify messages. */
183 register_message_flags(false, FLAG_MSG_PRINT_NOTIFY
);
189 /****************************************************************************
190 Functions to free a printer entry datastruct.
191 ****************************************************************************/
193 static int printer_entry_destructor(Printer_entry
*Printer
)
195 if (Printer
->notify
.client_connected
== true) {
198 if ( Printer
->printer_type
== SPLHND_SERVER
) {
200 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
201 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
202 snum
= print_queue_snum(Printer
->sharename
);
204 srv_spoolss_replycloseprinter(snum
,
205 &Printer
->notify
.client_hnd
);
209 Printer
->notify
.flags
=0;
210 Printer
->notify
.options
=0;
211 Printer
->notify
.localmachine
[0]='\0';
212 Printer
->notify
.printerlocal
=0;
213 TALLOC_FREE(Printer
->notify
.option
);
214 Printer
->notify
.client_connected
= false;
216 free_nt_devicemode( &Printer
->nt_devmode
);
217 free_a_printer( &Printer
->printer_info
, 2 );
219 /* Remove from the internal list. */
220 DLIST_REMOVE(printers_list
, Printer
);
224 /****************************************************************************
225 find printer index by handle
226 ****************************************************************************/
228 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
,
229 struct policy_handle
*hnd
)
231 Printer_entry
*find_printer
= NULL
;
233 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
234 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
241 /****************************************************************************
242 Close printer index by handle.
243 ****************************************************************************/
245 static bool close_printer_handle(pipes_struct
*p
, struct policy_handle
*hnd
)
247 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
250 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
255 close_policy_hnd(p
, hnd
);
260 /****************************************************************************
261 Delete a printer given a handle.
262 ****************************************************************************/
264 static WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
266 char *cmd
= lp_deleteprinter_cmd();
267 char *command
= NULL
;
269 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
270 bool is_print_op
= false;
272 /* can't fail if we don't try */
277 command
= talloc_asprintf(ctx
,
284 is_print_op
= user_has_privileges( token
, &se_printop
);
286 DEBUG(10,("Running [%s]\n", command
));
288 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
293 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
294 /* Tell everyone we updated smb.conf. */
295 message_send_all(smbd_messaging_context(),
296 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
302 /********** END SePrintOperatorPrivlege BLOCK **********/
304 DEBUGADD(10,("returned [%d]\n", ret
));
306 TALLOC_FREE(command
);
309 return WERR_BADFID
; /* What to return here? */
311 /* go ahead and re-read the services immediately */
313 reload_services(false);
316 if ( lp_servicenumber( sharename
) < 0 )
317 return WERR_ACCESS_DENIED
;
322 /****************************************************************************
323 Delete a printer given a handle.
324 ****************************************************************************/
326 static WERROR
delete_printer_handle(pipes_struct
*p
, struct policy_handle
*hnd
)
328 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
331 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
337 * It turns out that Windows allows delete printer on a handle
338 * opened by an admin user, then used on a pipe handle created
339 * by an anonymous user..... but they're working on security.... riiight !
343 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
344 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
345 return WERR_ACCESS_DENIED
;
348 /* this does not need a become root since the access check has been
349 done on the handle already */
351 if (del_a_printer( Printer
->sharename
) != 0) {
352 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
356 return delete_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
357 Printer
->sharename
);
360 /****************************************************************************
361 Return the snum of a printer corresponding to an handle.
362 ****************************************************************************/
364 static bool get_printer_snum(pipes_struct
*p
, struct policy_handle
*hnd
,
365 int *number
, struct share_params
**params
)
367 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
370 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
375 switch (Printer
->printer_type
) {
377 DEBUG(4,("short name:%s\n", Printer
->sharename
));
378 *number
= print_queue_snum(Printer
->sharename
);
379 return (*number
!= -1);
387 /****************************************************************************
388 Set printer handle type.
389 Check if it's \\server or \\server\printer
390 ****************************************************************************/
392 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, const char *handlename
)
394 DEBUG(3,("Setting printer type=%s\n", handlename
));
396 if ( strlen(handlename
) < 3 ) {
397 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
401 /* it's a print server */
402 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
403 DEBUGADD(4,("Printer is a print server\n"));
404 Printer
->printer_type
= SPLHND_SERVER
;
406 /* it's a printer (set_printer_hnd_name() will handle port monitors */
408 DEBUGADD(4,("Printer is a printer\n"));
409 Printer
->printer_type
= SPLHND_PRINTER
;
415 /****************************************************************************
416 Set printer handle name.. Accept names like \\server, \\server\printer,
417 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
418 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
419 XcvDataPort() interface.
420 ****************************************************************************/
422 static bool set_printer_hnd_name(Printer_entry
*Printer
, const char *handlename
)
425 int n_services
=lp_numservices();
426 char *aprinter
, *printername
;
427 const char *servername
;
430 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
433 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
,
434 (unsigned long)strlen(handlename
)));
436 aprinter
= CONST_DISCARD(char *, handlename
);
437 if ( *handlename
== '\\' ) {
438 servername
= canon_servername(handlename
);
439 if ( (aprinter
= strchr_m( servername
, '\\' )) != NULL
) {
444 servername
= global_myname();
447 /* save the servername to fill in replies on this handle */
449 if ( !is_myname_or_ipaddr( servername
) )
452 fstrcpy( Printer
->servername
, servername
);
454 if ( Printer
->printer_type
== SPLHND_SERVER
)
457 if ( Printer
->printer_type
!= SPLHND_PRINTER
)
460 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
462 /* check for the Port Monitor Interface */
464 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
465 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
466 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
469 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
470 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
471 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
475 /* Search all sharenames first as this is easier than pulling
476 the printer_info_2 off of disk. Don't use find_service() since
477 that calls out to map_username() */
479 /* do another loop to look for printernames */
481 for (snum
=0; !found
&& snum
<n_services
; snum
++) {
483 /* no point going on if this is not a printer */
485 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
)) )
488 fstrcpy(sname
, lp_servicename(snum
));
489 if ( strequal( aprinter
, sname
) ) {
494 /* no point looking up the printer object if
495 we aren't allowing printername != sharename */
497 if ( lp_force_printername(snum
) )
500 fstrcpy(sname
, lp_servicename(snum
));
504 /* This call doesn't fill in the location or comment from
505 * a CUPS server for efficiency with large numbers of printers.
509 result
= get_a_printer_search( NULL
, &printer
, 2, sname
);
510 if ( !W_ERROR_IS_OK(result
) ) {
511 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
512 sname
, win_errstr(result
)));
516 /* printername is always returned as \\server\printername */
517 if ( !(printername
= strchr_m(&printer
->info_2
->printername
[2], '\\')) ) {
518 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
519 printer
->info_2
->printername
));
520 free_a_printer( &printer
, 2);
526 if ( strequal(printername
, aprinter
) ) {
527 free_a_printer( &printer
, 2);
532 DEBUGADD(10, ("printername: %s\n", printername
));
534 free_a_printer( &printer
, 2);
537 free_a_printer( &printer
, 2);
540 DEBUGADD(4,("Printer not found\n"));
544 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
546 fstrcpy(Printer
->sharename
, sname
);
551 /****************************************************************************
552 Find first available printer slot. creates a printer handle for you.
553 ****************************************************************************/
555 static bool open_printer_hnd(pipes_struct
*p
, struct policy_handle
*hnd
,
556 const char *name
, uint32_t access_granted
)
558 Printer_entry
*new_printer
;
560 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
562 new_printer
= TALLOC_ZERO_P(NULL
, Printer_entry
);
563 if (new_printer
== NULL
) {
566 talloc_set_destructor(new_printer
, printer_entry_destructor
);
568 if (!create_policy_hnd(p
, hnd
, new_printer
)) {
569 TALLOC_FREE(new_printer
);
573 /* Add to the internal list. */
574 DLIST_ADD(printers_list
, new_printer
);
576 new_printer
->notify
.option
=NULL
;
578 if (!set_printer_hnd_printertype(new_printer
, name
)) {
579 close_printer_handle(p
, hnd
);
583 if (!set_printer_hnd_name(new_printer
, name
)) {
584 close_printer_handle(p
, hnd
);
588 new_printer
->access_granted
= access_granted
;
590 DEBUG(5, ("%d printer handles active\n",
591 (int)num_pipe_handles(p
->pipe_handles
)));
596 /***************************************************************************
597 check to see if the client motify handle is monitoring the notification
598 given by (notify_type, notify_field).
599 **************************************************************************/
601 static bool is_monitoring_event_flags(uint32_t flags
, uint16_t notify_type
,
602 uint16_t notify_field
)
607 static bool is_monitoring_event(Printer_entry
*p
, uint16_t notify_type
,
608 uint16_t notify_field
)
610 struct spoolss_NotifyOption
*option
= p
->notify
.option
;
614 * Flags should always be zero when the change notify
615 * is registered by the client's spooler. A user Win32 app
616 * might use the flags though instead of the NOTIFY_OPTION_INFO
625 return is_monitoring_event_flags(
626 p
->notify
.flags
, notify_type
, notify_field
);
628 for (i
= 0; i
< option
->count
; i
++) {
630 /* Check match for notify_type */
632 if (option
->types
[i
].type
!= notify_type
)
635 /* Check match for field */
637 for (j
= 0; j
< option
->types
[i
].count
; j
++) {
638 if (option
->types
[i
].fields
[j
].field
== notify_field
) {
644 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
645 p
->servername
, p
->sharename
, notify_type
, notify_field
));
650 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
651 _data->data.integer[0] = _integer; \
652 _data->data.integer[1] = 0;
655 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
656 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
657 if (!_data->data.string.string) {\
658 _data->data.string.size = 0; \
660 _data->data.string.size = strlen_m_term(_p) * 2;
662 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
663 _data->data.devmode.devmode = _devmode;
665 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
666 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
667 if (!_data->data.sd.sd) { \
668 _data->data.sd.sd_size = 0; \
670 _data->data.sd.sd_size = _size;
672 static void init_systemtime_buffer(TALLOC_CTX
*mem_ctx
,
677 struct spoolss_Time st
;
681 if (!init_systemtime(&st
, t
)) {
685 p
= talloc_array(mem_ctx
, char, len
);
691 * Systemtime must be linearized as a set of UINT16's.
692 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
695 SSVAL(p
, 0, st
.year
);
696 SSVAL(p
, 2, st
.month
);
697 SSVAL(p
, 4, st
.day_of_week
);
699 SSVAL(p
, 8, st
.hour
);
700 SSVAL(p
, 10, st
.minute
);
701 SSVAL(p
, 12, st
.second
);
702 SSVAL(p
, 14, st
.millisecond
);
708 /* Convert a notification message to a struct spoolss_Notify */
710 static void notify_one_value(struct spoolss_notify_msg
*msg
,
711 struct spoolss_Notify
*data
,
714 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, msg
->notify
.value
[0]);
717 static void notify_string(struct spoolss_notify_msg
*msg
,
718 struct spoolss_Notify
*data
,
721 /* The length of the message includes the trailing \0 */
723 data
->data
.string
.size
= msg
->len
* 2;
724 data
->data
.string
.string
= talloc_strdup(mem_ctx
, msg
->notify
.data
);
725 if (!data
->data
.string
.string
) {
726 data
->data
.string
.size
= 0;
731 static void notify_system_time(struct spoolss_notify_msg
*msg
,
732 struct spoolss_Notify
*data
,
735 data
->data
.string
.string
= NULL
;
736 data
->data
.string
.size
= 0;
738 if (msg
->len
!= sizeof(time_t)) {
739 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
744 init_systemtime_buffer(mem_ctx
, gmtime((time_t *)msg
->notify
.data
),
745 &data
->data
.string
.string
,
746 &data
->data
.string
.size
);
749 struct notify2_message_table
{
751 void (*fn
)(struct spoolss_notify_msg
*msg
,
752 struct spoolss_Notify
*data
, TALLOC_CTX
*mem_ctx
);
755 static struct notify2_message_table printer_notify_table
[] = {
756 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string
},
757 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string
},
758 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string
},
759 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string
},
760 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string
},
761 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string
},
762 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string
},
763 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL
},
764 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string
},
765 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string
},
766 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL
},
767 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string
},
768 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL
},
769 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value
},
770 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value
},
771 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL
},
772 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL
},
773 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL
},
774 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value
},
777 static struct notify2_message_table job_notify_table
[] = {
778 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL
},
779 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL
},
780 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL
},
781 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string
},
782 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL
},
783 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL
},
784 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL
},
785 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL
},
786 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL
},
787 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL
},
788 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value
},
789 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL
},
790 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL
},
791 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string
},
792 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL
},
793 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL
},
794 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time
},
795 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL
},
796 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL
},
797 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL
},
798 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value
},
799 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL
},
800 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value
},
801 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL
},
805 /***********************************************************************
806 Allocate talloc context for container object
807 **********************************************************************/
809 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
814 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
819 /***********************************************************************
820 release all allocated memory and zero out structure
821 **********************************************************************/
823 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
829 talloc_destroy(ctr
->ctx
);
836 /***********************************************************************
837 **********************************************************************/
839 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
847 /***********************************************************************
848 **********************************************************************/
850 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32_t idx
)
852 if ( !ctr
|| !ctr
->msg_groups
)
855 if ( idx
>= ctr
->num_groups
)
858 return &ctr
->msg_groups
[idx
];
862 /***********************************************************************
863 How many groups of change messages do we have ?
864 **********************************************************************/
866 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
871 return ctr
->num_groups
;
874 /***********************************************************************
875 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
876 **********************************************************************/
878 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
880 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
881 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
882 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
888 /* loop over all groups looking for a matching printer name */
890 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
891 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
895 /* add a new group? */
897 if ( i
== ctr
->num_groups
) {
900 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
901 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
904 ctr
->msg_groups
= groups
;
906 /* clear the new entry and set the printer name */
908 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
909 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
912 /* add the change messages; 'i' is the correct index now regardless */
914 msg_grp
= &ctr
->msg_groups
[i
];
918 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
919 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
922 msg_grp
->msgs
= msg_list
;
924 new_slot
= msg_grp
->num_msgs
-1;
925 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
927 /* need to allocate own copy of data */
930 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
931 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
933 return ctr
->num_groups
;
936 /***********************************************************************
937 Send a change notication message on all handles which have a call
939 **********************************************************************/
941 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32_t idx
)
944 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
945 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
946 SPOOLSS_NOTIFY_MSG
*messages
;
947 int sending_msg_count
;
950 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
954 messages
= msg_group
->msgs
;
957 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
961 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
963 /* loop over all printers */
965 for (p
= printers_list
; p
; p
= p
->next
) {
966 struct spoolss_Notify
*notifies
;
971 /* Is there notification on this handle? */
973 if ( !p
->notify
.client_connected
)
976 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
978 /* For this printer? Print servers always receive
981 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
982 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
985 DEBUG(10,("Our printer\n"));
987 /* allocate the max entries possible */
989 notifies
= TALLOC_ZERO_ARRAY(mem_ctx
, struct spoolss_Notify
, msg_group
->num_msgs
);
994 /* build the array of change notifications */
996 sending_msg_count
= 0;
998 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
999 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
1001 /* Are we monitoring this event? */
1003 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1006 sending_msg_count
++;
1009 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1010 msg
->type
, msg
->field
, p
->sharename
));
1013 * if the is a printer notification handle and not a job notification
1014 * type, then set the id to 0. Other wise just use what was specified
1017 * When registering change notification on a print server handle
1018 * we always need to send back the id (snum) matching the printer
1019 * for which the change took place. For change notify registered
1020 * on a printer handle, this does not matter and the id should be 0.
1025 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1031 /* Convert unix jobid to smb jobid */
1033 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1034 id
= sysjob_to_jobid(msg
->id
);
1037 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1042 construct_info_data( ¬ifies
[count
], msg
->type
, msg
->field
, id
);
1045 case PRINTER_NOTIFY_TYPE
:
1046 if ( printer_notify_table
[msg
->field
].fn
)
1047 printer_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1050 case JOB_NOTIFY_TYPE
:
1051 if ( job_notify_table
[msg
->field
].fn
)
1052 job_notify_table
[msg
->field
].fn(msg
, ¬ifies
[count
], mem_ctx
);
1056 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1063 if ( sending_msg_count
) {
1066 union spoolss_ReplyPrinterInfo info
;
1067 struct spoolss_NotifyInfo info0
;
1068 uint32_t reply_result
;
1070 info0
.version
= 0x2;
1071 info0
.flags
= count
? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED
;
1072 info0
.count
= count
;
1073 info0
.notifies
= notifies
;
1075 info
.info0
= &info0
;
1077 status
= rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe
, mem_ctx
,
1078 &p
->notify
.client_hnd
,
1079 p
->notify
.change
, /* color */
1082 0, /* reply_type, must be 0 */
1085 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(werr
)) {
1086 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1087 notify_cli_pipe
->srv_name_slash
,
1090 switch (reply_result
) {
1093 case PRINTER_NOTIFY_INFO_DISCARDED
:
1094 case PRINTER_NOTIFY_INFO_DISCARDNOTED
:
1095 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH
:
1104 DEBUG(8,("send_notify2_changes: Exit...\n"));
1108 /***********************************************************************
1109 **********************************************************************/
1111 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1114 uint32_t tv_sec
, tv_usec
;
1117 /* Unpack message */
1119 offset
+= tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "f",
1122 offset
+= tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "ddddddd",
1124 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1127 tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "dd",
1128 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1130 tdb_unpack((uint8_t *)buf
+ offset
, len
- offset
, "B",
1131 &msg
->len
, &msg
->notify
.data
);
1133 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1134 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1136 tv
->tv_sec
= tv_sec
;
1137 tv
->tv_usec
= tv_usec
;
1140 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1141 msg
->notify
.value
[1]));
1143 dump_data(3, (uint8_t *)msg
->notify
.data
, msg
->len
);
1148 /********************************************************************
1149 Receive a notify2 message list
1150 ********************************************************************/
1152 static void receive_notify2_message_list(struct messaging_context
*msg
,
1155 struct server_id server_id
,
1158 size_t msg_count
, i
;
1159 char *buf
= (char *)data
->data
;
1162 SPOOLSS_NOTIFY_MSG notify
;
1163 SPOOLSS_NOTIFY_MSG_CTR messages
;
1166 if (data
->length
< 4) {
1167 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1171 msg_count
= IVAL(buf
, 0);
1174 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1176 if (msg_count
== 0) {
1177 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1181 /* initialize the container */
1183 ZERO_STRUCT( messages
);
1184 notify_msg_ctr_init( &messages
);
1187 * build message groups for each printer identified
1188 * in a change_notify msg. Remember that a PCN message
1189 * includes the handle returned for the srv_spoolss_replyopenprinter()
1190 * call. Therefore messages are grouped according to printer handle.
1193 for ( i
=0; i
<msg_count
; i
++ ) {
1194 struct timeval msg_tv
;
1196 if (msg_ptr
+ 4 - buf
> data
->length
) {
1197 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1201 msg_len
= IVAL(msg_ptr
,0);
1204 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1205 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1209 /* unpack messages */
1211 ZERO_STRUCT( notify
);
1212 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1215 /* add to correct list in container */
1217 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1219 /* free memory that might have been allocated by notify2_unpack_msg() */
1221 if ( notify
.len
!= 0 )
1222 SAFE_FREE( notify
.notify
.data
);
1225 /* process each group of messages */
1227 num_groups
= notify_msg_ctr_numgroups( &messages
);
1228 for ( i
=0; i
<num_groups
; i
++ )
1229 send_notify2_changes( &messages
, i
);
1234 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1235 (uint32_t)msg_count
));
1237 notify_msg_ctr_destroy( &messages
);
1242 /********************************************************************
1243 Send a message to ourself about new driver being installed
1244 so we can upgrade the information for each printer bound to this
1246 ********************************************************************/
1248 static bool srv_spoolss_drv_upgrade_printer(const char *drivername
)
1250 int len
= strlen(drivername
);
1255 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1258 messaging_send_buf(smbd_messaging_context(), procid_self(),
1259 MSG_PRINTER_DRVUPGRADE
,
1260 (uint8_t *)drivername
, len
+1);
1265 /**********************************************************************
1266 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1267 over all printers, upgrading ones as necessary
1268 **********************************************************************/
1270 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1273 struct server_id server_id
,
1278 int n_services
= lp_numservices();
1281 len
= MIN(data
->length
,sizeof(drivername
)-1);
1282 strncpy(drivername
, (const char *)data
->data
, len
);
1284 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1286 /* Iterate the printer list */
1288 for (snum
=0; snum
<n_services
; snum
++)
1290 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1293 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1295 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1296 if (!W_ERROR_IS_OK(result
))
1299 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1301 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1303 /* all we care about currently is the change_id */
1305 result
= mod_a_printer(printer
, 2);
1306 if (!W_ERROR_IS_OK(result
)) {
1307 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1308 win_errstr(result
)));
1312 free_a_printer(&printer
, 2);
1319 /********************************************************************
1320 Update the cache for all printq's with a registered client
1322 ********************************************************************/
1324 void update_monitored_printq_cache( void )
1326 Printer_entry
*printer
= printers_list
;
1329 /* loop through all printers and update the cache where
1330 client_connected == true */
1333 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1334 && printer
->notify
.client_connected
)
1336 snum
= print_queue_snum(printer
->sharename
);
1337 print_queue_status( snum
, NULL
, NULL
);
1340 printer
= printer
->next
;
1345 /********************************************************************
1346 Send a message to ourself about new driver being installed
1347 so we can upgrade the information for each printer bound to this
1349 ********************************************************************/
1351 static bool srv_spoolss_reset_printerdata(char* drivername
)
1353 int len
= strlen(drivername
);
1358 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1361 messaging_send_buf(smbd_messaging_context(), procid_self(),
1362 MSG_PRINTERDATA_INIT_RESET
,
1363 (uint8_t *)drivername
, len
+1);
1368 /**********************************************************************
1369 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1370 over all printers, resetting printer data as neessary
1371 **********************************************************************/
1373 void reset_all_printerdata(struct messaging_context
*msg
,
1376 struct server_id server_id
,
1381 int n_services
= lp_numservices();
1384 len
= MIN( data
->length
, sizeof(drivername
)-1 );
1385 strncpy( drivername
, (const char *)data
->data
, len
);
1387 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1389 /* Iterate the printer list */
1391 for ( snum
=0; snum
<n_services
; snum
++ )
1393 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1396 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1398 result
= get_a_printer( NULL
, &printer
, 2, lp_const_servicename(snum
) );
1399 if ( !W_ERROR_IS_OK(result
) )
1403 * if the printer is bound to the driver,
1404 * then reset to the new driver initdata
1407 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1409 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1411 if ( !set_driver_init(printer
, 2) ) {
1412 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1413 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1416 result
= mod_a_printer( printer
, 2 );
1417 if ( !W_ERROR_IS_OK(result
) ) {
1418 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1419 get_dos_error_msg(result
)));
1423 free_a_printer( &printer
, 2 );
1432 /****************************************************************
1433 _spoolss_OpenPrinter
1434 ****************************************************************/
1436 WERROR
_spoolss_OpenPrinter(pipes_struct
*p
,
1437 struct spoolss_OpenPrinter
*r
)
1439 struct spoolss_OpenPrinterEx e
;
1442 ZERO_STRUCT(e
.in
.userlevel
);
1444 e
.in
.printername
= r
->in
.printername
;
1445 e
.in
.datatype
= r
->in
.datatype
;
1446 e
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
1447 e
.in
.access_mask
= r
->in
.access_mask
;
1450 e
.out
.handle
= r
->out
.handle
;
1452 werr
= _spoolss_OpenPrinterEx(p
, &e
);
1454 if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
1455 /* OpenPrinterEx returns this for a bad
1456 * printer name. We must return WERR_INVALID_PRINTER_NAME
1459 werr
= WERR_INVALID_PRINTER_NAME
;
1465 /********************************************************************
1466 ********************************************************************/
1468 bool convert_devicemode(const char *printername
,
1469 const struct spoolss_DeviceMode
*devmode
,
1470 NT_DEVICEMODE
**pp_nt_devmode
)
1472 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1475 * Ensure nt_devmode is a valid pointer
1476 * as we will be overwriting it.
1479 if (nt_devmode
== NULL
) {
1480 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1481 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1485 rpcstr_push(nt_devmode
->devicename
, devmode
->devicename
, 31, 0);
1486 rpcstr_push(nt_devmode
->formname
, devmode
->formname
, 31, 0);
1488 nt_devmode
->specversion
= devmode
->specversion
;
1489 nt_devmode
->driverversion
= devmode
->driverversion
;
1490 nt_devmode
->size
= devmode
->size
;
1491 nt_devmode
->fields
= devmode
->fields
;
1492 nt_devmode
->orientation
= devmode
->orientation
;
1493 nt_devmode
->papersize
= devmode
->papersize
;
1494 nt_devmode
->paperlength
= devmode
->paperlength
;
1495 nt_devmode
->paperwidth
= devmode
->paperwidth
;
1496 nt_devmode
->scale
= devmode
->scale
;
1497 nt_devmode
->copies
= devmode
->copies
;
1498 nt_devmode
->defaultsource
= devmode
->defaultsource
;
1499 nt_devmode
->printquality
= devmode
->printquality
;
1500 nt_devmode
->color
= devmode
->color
;
1501 nt_devmode
->duplex
= devmode
->duplex
;
1502 nt_devmode
->yresolution
= devmode
->yresolution
;
1503 nt_devmode
->ttoption
= devmode
->ttoption
;
1504 nt_devmode
->collate
= devmode
->collate
;
1506 nt_devmode
->logpixels
= devmode
->logpixels
;
1507 nt_devmode
->bitsperpel
= devmode
->bitsperpel
;
1508 nt_devmode
->pelswidth
= devmode
->pelswidth
;
1509 nt_devmode
->pelsheight
= devmode
->pelsheight
;
1510 nt_devmode
->displayflags
= devmode
->displayflags
;
1511 nt_devmode
->displayfrequency
= devmode
->displayfrequency
;
1512 nt_devmode
->icmmethod
= devmode
->icmmethod
;
1513 nt_devmode
->icmintent
= devmode
->icmintent
;
1514 nt_devmode
->mediatype
= devmode
->mediatype
;
1515 nt_devmode
->dithertype
= devmode
->dithertype
;
1516 nt_devmode
->reserved1
= devmode
->reserved1
;
1517 nt_devmode
->reserved2
= devmode
->reserved2
;
1518 nt_devmode
->panningwidth
= devmode
->panningwidth
;
1519 nt_devmode
->panningheight
= devmode
->panningheight
;
1522 * Only change private and driverextra if the incoming devmode
1523 * has a new one. JRA.
1526 if ((devmode
->__driverextra_length
!= 0) && (devmode
->driverextra_data
.data
!= NULL
)) {
1527 SAFE_FREE(nt_devmode
->nt_dev_private
);
1528 nt_devmode
->driverextra
= devmode
->__driverextra_length
;
1529 if((nt_devmode
->nt_dev_private
= SMB_MALLOC_ARRAY(uint8_t, nt_devmode
->driverextra
)) == NULL
)
1531 memcpy(nt_devmode
->nt_dev_private
, devmode
->driverextra_data
.data
, nt_devmode
->driverextra
);
1534 *pp_nt_devmode
= nt_devmode
;
1539 /****************************************************************
1540 _spoolss_OpenPrinterEx
1541 ****************************************************************/
1543 WERROR
_spoolss_OpenPrinterEx(pipes_struct
*p
,
1544 struct spoolss_OpenPrinterEx
*r
)
1547 Printer_entry
*Printer
=NULL
;
1549 if (!r
->in
.printername
) {
1550 return WERR_INVALID_PARAM
;
1553 /* some sanity check because you can open a printer or a print server */
1554 /* aka: \\server\printer or \\server */
1556 DEBUGADD(3,("checking name: %s\n", r
->in
.printername
));
1558 if (!open_printer_hnd(p
, r
->out
.handle
, r
->in
.printername
, 0)) {
1559 ZERO_STRUCTP(r
->out
.handle
);
1560 return WERR_INVALID_PARAM
;
1563 Printer
= find_printer_index_by_hnd(p
, r
->out
.handle
);
1565 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1566 "handle we created for printer %s\n", r
->in
.printername
));
1567 close_printer_handle(p
, r
->out
.handle
);
1568 ZERO_STRUCTP(r
->out
.handle
);
1569 return WERR_INVALID_PARAM
;
1573 * First case: the user is opening the print server:
1575 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1576 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1578 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1579 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1580 * or if the user is listed in the smb.conf printer admin parameter.
1582 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1583 * client view printer folder, but does not show the MSAPW.
1585 * Note: this test needs code to check access rights here too. Jeremy
1586 * could you look at this?
1588 * Second case: the user is opening a printer:
1589 * NT doesn't let us connect to a printer if the connecting user
1590 * doesn't have print permission.
1592 * Third case: user is opening a Port Monitor
1593 * access checks same as opening a handle to the print server.
1596 switch (Printer
->printer_type
)
1599 case SPLHND_PORTMON_TCP
:
1600 case SPLHND_PORTMON_LOCAL
:
1601 /* Printserver handles use global struct... */
1605 /* Map standard access rights to object specific access rights */
1607 se_map_standard(&r
->in
.access_mask
,
1608 &printserver_std_mapping
);
1610 /* Deny any object specific bits that don't apply to print
1611 servers (i.e printer and job specific bits) */
1613 r
->in
.access_mask
&= SPECIFIC_RIGHTS_MASK
;
1615 if (r
->in
.access_mask
&
1616 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1617 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1618 close_printer_handle(p
, r
->out
.handle
);
1619 ZERO_STRUCTP(r
->out
.handle
);
1620 return WERR_ACCESS_DENIED
;
1623 /* Allow admin access */
1625 if ( r
->in
.access_mask
& SERVER_ACCESS_ADMINISTER
)
1627 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1629 if (!lp_ms_add_printer_wizard()) {
1630 close_printer_handle(p
, r
->out
.handle
);
1631 ZERO_STRUCTP(r
->out
.handle
);
1632 return WERR_ACCESS_DENIED
;
1635 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1636 and not a printer admin, then fail */
1638 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
1639 !user_has_privileges(p
->server_info
->ptok
,
1641 !token_contains_name_in_list(
1642 uidtoname(p
->server_info
->utok
.uid
),
1644 p
->server_info
->ptok
,
1645 lp_printer_admin(snum
))) {
1646 close_printer_handle(p
, r
->out
.handle
);
1647 ZERO_STRUCTP(r
->out
.handle
);
1648 return WERR_ACCESS_DENIED
;
1651 r
->in
.access_mask
= SERVER_ACCESS_ADMINISTER
;
1655 r
->in
.access_mask
= SERVER_ACCESS_ENUMERATE
;
1658 DEBUG(4,("Setting print server access = %s\n", (r
->in
.access_mask
== SERVER_ACCESS_ADMINISTER
)
1659 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1661 /* We fall through to return WERR_OK */
1664 case SPLHND_PRINTER
:
1665 /* NT doesn't let us connect to a printer if the connecting user
1666 doesn't have print permission. */
1668 if (!get_printer_snum(p
, r
->out
.handle
, &snum
, NULL
)) {
1669 close_printer_handle(p
, r
->out
.handle
);
1670 ZERO_STRUCTP(r
->out
.handle
);
1674 se_map_standard(&r
->in
.access_mask
, &printer_std_mapping
);
1676 /* map an empty access mask to the minimum access mask */
1677 if (r
->in
.access_mask
== 0x0)
1678 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1681 * If we are not serving the printer driver for this printer,
1682 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1683 * will keep NT clients happy --jerry
1686 if (lp_use_client_driver(snum
)
1687 && (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
))
1689 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1692 /* check smb.conf parameters and the the sec_desc */
1694 if ( !check_access(get_client_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1695 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1696 ZERO_STRUCTP(r
->out
.handle
);
1697 return WERR_ACCESS_DENIED
;
1700 if (!user_ok_token(uidtoname(p
->server_info
->utok
.uid
), NULL
,
1701 p
->server_info
->ptok
, snum
) ||
1702 !print_access_check(p
->server_info
, snum
,
1703 r
->in
.access_mask
)) {
1704 DEBUG(3, ("access DENIED for printer open\n"));
1705 close_printer_handle(p
, r
->out
.handle
);
1706 ZERO_STRUCTP(r
->out
.handle
);
1707 return WERR_ACCESS_DENIED
;
1710 if ((r
->in
.access_mask
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1711 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1712 close_printer_handle(p
, r
->out
.handle
);
1713 ZERO_STRUCTP(r
->out
.handle
);
1714 return WERR_ACCESS_DENIED
;
1717 if (r
->in
.access_mask
& PRINTER_ACCESS_ADMINISTER
)
1718 r
->in
.access_mask
= PRINTER_ACCESS_ADMINISTER
;
1720 r
->in
.access_mask
= PRINTER_ACCESS_USE
;
1722 DEBUG(4,("Setting printer access = %s\n", (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1723 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1728 /* sanity check to prevent programmer error */
1729 ZERO_STRUCTP(r
->out
.handle
);
1733 Printer
->access_granted
= r
->in
.access_mask
;
1736 * If the client sent a devmode in the OpenPrinter() call, then
1737 * save it here in case we get a job submission on this handle
1740 if ((Printer
->printer_type
!= SPLHND_SERVER
) &&
1741 r
->in
.devmode_ctr
.devmode
) {
1742 convert_devicemode(Printer
->sharename
,
1743 r
->in
.devmode_ctr
.devmode
,
1744 &Printer
->nt_devmode
);
1747 #if 0 /* JERRY -- I'm doubtful this is really effective */
1748 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1749 optimization in Windows 2000 clients --jerry */
1751 if ( (r
->in
.access_mask
== PRINTER_ACCESS_ADMINISTER
)
1752 && (RA_WIN2K
== get_remote_arch()) )
1754 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1755 sys_usleep( 500000 );
1762 /****************************************************************************
1763 ****************************************************************************/
1765 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2
*r
,
1766 NT_PRINTER_INFO_LEVEL_2
*d
)
1768 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1774 d
->attributes
= r
->attributes
;
1775 d
->priority
= r
->priority
;
1776 d
->default_priority
= r
->defaultpriority
;
1777 d
->starttime
= r
->starttime
;
1778 d
->untiltime
= r
->untiltime
;
1779 d
->status
= r
->status
;
1780 d
->cjobs
= r
->cjobs
;
1782 fstrcpy(d
->servername
, r
->servername
);
1783 fstrcpy(d
->printername
, r
->printername
);
1784 fstrcpy(d
->sharename
, r
->sharename
);
1785 fstrcpy(d
->portname
, r
->portname
);
1786 fstrcpy(d
->drivername
, r
->drivername
);
1787 slprintf(d
->comment
, sizeof(d
->comment
)-1, "%s", r
->comment
);
1788 fstrcpy(d
->location
, r
->location
);
1789 fstrcpy(d
->sepfile
, r
->sepfile
);
1790 fstrcpy(d
->printprocessor
, r
->printprocessor
);
1791 fstrcpy(d
->datatype
, r
->datatype
);
1792 fstrcpy(d
->parameters
, r
->parameters
);
1797 /****************************************************************************
1798 ****************************************************************************/
1800 static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr
*info_ctr
,
1801 NT_PRINTER_INFO_LEVEL
*printer
)
1805 switch (info_ctr
->level
) {
1807 /* allocate memory if needed. Messy because
1808 convert_printer_info is used to update an existing
1809 printer or build a new one */
1811 if (!printer
->info_2
) {
1812 printer
->info_2
= TALLOC_ZERO_P(printer
, NT_PRINTER_INFO_LEVEL_2
);
1813 if (!printer
->info_2
) {
1814 DEBUG(0,("convert_printer_info: "
1815 "talloc() failed!\n"));
1820 ret
= printer_info2_to_nt_printer_info2(info_ctr
->info
.info2
,
1822 printer
->info_2
->setuptime
= time(NULL
);
1829 /*******************************************************************
1830 ********************************************************************/
1832 static bool string_array_to_fstring_array(const char **sarray
, fstring
**farray
)
1841 *farray
= SMB_MALLOC_ARRAY(fstring
, 1);
1846 for (i
=0; sarray
[i
] != NULL
; i
++) {
1847 *farray
= SMB_REALLOC_ARRAY(*farray
, fstring
, i
+2);
1851 fstrcpy((*farray
)[i
], sarray
[i
]);
1854 fstrcpy((*farray
)[i
], "");
1859 /*******************************************************************
1860 ********************************************************************/
1862 static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3
*r
,
1863 NT_PRINTER_DRIVER_INFO_LEVEL_3
**p
)
1865 NT_PRINTER_DRIVER_INFO_LEVEL_3
*d
;
1867 DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
1870 *p
= SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3
);
1879 d
->cversion
= r
->version
;
1881 fstrcpy(d
->name
, r
->driver_name
);
1882 fstrcpy(d
->environment
, r
->architecture
);
1883 fstrcpy(d
->driverpath
, r
->driver_path
);
1884 fstrcpy(d
->datafile
, r
->data_file
);
1885 fstrcpy(d
->configfile
, r
->config_file
);
1886 fstrcpy(d
->helpfile
, r
->help_file
);
1887 fstrcpy(d
->monitorname
, r
->monitor_name
);
1888 fstrcpy(d
->defaultdatatype
, r
->default_datatype
);
1890 DEBUGADD(8,( "version: %d\n", d
->cversion
));
1891 DEBUGADD(8,( "name: %s\n", d
->name
));
1892 DEBUGADD(8,( "environment: %s\n", d
->environment
));
1893 DEBUGADD(8,( "driverpath: %s\n", d
->driverpath
));
1894 DEBUGADD(8,( "datafile: %s\n", d
->datafile
));
1895 DEBUGADD(8,( "configfile: %s\n", d
->configfile
));
1896 DEBUGADD(8,( "helpfile: %s\n", d
->helpfile
));
1897 DEBUGADD(8,( "monitorname: %s\n", d
->monitorname
));
1898 DEBUGADD(8,( "defaultdatatype: %s\n", d
->defaultdatatype
));
1900 if (r
->dependent_files
) {
1901 if (!string_array_to_fstring_array(r
->dependent_files
->string
,
1902 &d
->dependentfiles
)) {
1911 /*******************************************************************
1912 ********************************************************************/
1914 static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6
*r
,
1915 NT_PRINTER_DRIVER_INFO_LEVEL_6
**p
)
1917 NT_PRINTER_DRIVER_INFO_LEVEL_6
*d
;
1919 DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
1922 *p
= SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6
);
1931 d
->version
= r
->version
;
1933 fstrcpy(d
->name
, r
->driver_name
);
1934 fstrcpy(d
->environment
, r
->architecture
);
1935 fstrcpy(d
->driverpath
, r
->driver_path
);
1936 fstrcpy(d
->datafile
, r
->data_file
);
1937 fstrcpy(d
->configfile
, r
->config_file
);
1938 fstrcpy(d
->helpfile
, r
->help_file
);
1939 fstrcpy(d
->monitorname
, r
->monitor_name
);
1940 fstrcpy(d
->defaultdatatype
, r
->default_datatype
);
1942 DEBUGADD(8,( "version: %d\n", d
->version
));
1943 DEBUGADD(8,( "name: %s\n", d
->name
));
1944 DEBUGADD(8,( "environment: %s\n", d
->environment
));
1945 DEBUGADD(8,( "driverpath: %s\n", d
->driverpath
));
1946 DEBUGADD(8,( "datafile: %s\n", d
->datafile
));
1947 DEBUGADD(8,( "configfile: %s\n", d
->configfile
));
1948 DEBUGADD(8,( "helpfile: %s\n", d
->helpfile
));
1949 DEBUGADD(8,( "monitorname: %s\n", d
->monitorname
));
1950 DEBUGADD(8,( "defaultdatatype: %s\n", d
->defaultdatatype
));
1952 if (r
->dependent_files
) {
1953 if (!string_array_to_fstring_array(r
->dependent_files
->string
,
1954 &d
->dependentfiles
)) {
1959 if (r
->previous_names
) {
1960 if (!string_array_to_fstring_array(r
->previous_names
->string
,
1961 &d
->previousnames
)) {
1973 /********************************************************************
1974 ********************************************************************/
1976 static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr
*r
,
1977 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
,
1982 printer
->info_3
= NULL
;
1983 if (!driver_info3_to_nt_driver_info3(r
->info
.info3
, &printer
->info_3
)) {
1988 printer
->info_6
= NULL
;
1989 if (!driver_info6_to_nt_driver_info6(r
->info
.info6
, &printer
->info_6
)) {
2000 /****************************************************************
2001 _spoolss_ClosePrinter
2002 ****************************************************************/
2004 WERROR
_spoolss_ClosePrinter(pipes_struct
*p
,
2005 struct spoolss_ClosePrinter
*r
)
2007 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
2009 if (Printer
&& Printer
->document_started
) {
2010 struct spoolss_EndDocPrinter e
;
2012 e
.in
.handle
= r
->in
.handle
;
2014 _spoolss_EndDocPrinter(p
, &e
);
2017 if (!close_printer_handle(p
, r
->in
.handle
))
2020 /* clear the returned printer handle. Observed behavior
2021 from Win2k server. Don't think this really matters.
2022 Previous code just copied the value of the closed
2025 ZERO_STRUCTP(r
->out
.handle
);
2030 /****************************************************************
2031 _spoolss_DeletePrinter
2032 ****************************************************************/
2034 WERROR
_spoolss_DeletePrinter(pipes_struct
*p
,
2035 struct spoolss_DeletePrinter
*r
)
2037 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
2040 if (Printer
&& Printer
->document_started
) {
2041 struct spoolss_EndDocPrinter e
;
2043 e
.in
.handle
= r
->in
.handle
;
2045 _spoolss_EndDocPrinter(p
, &e
);
2048 result
= delete_printer_handle(p
, r
->in
.handle
);
2050 update_c_setprinter(false);
2055 /*******************************************************************
2056 * static function to lookup the version id corresponding to an
2057 * long architecture string
2058 ******************************************************************/
2060 static const struct print_architecture_table_node archi_table
[]= {
2062 {"Windows 4.0", SPL_ARCH_WIN40
, 0 },
2063 {"Windows NT x86", SPL_ARCH_W32X86
, 2 },
2064 {"Windows NT R4000", SPL_ARCH_W32MIPS
, 2 },
2065 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA
, 2 },
2066 {"Windows NT PowerPC", SPL_ARCH_W32PPC
, 2 },
2067 {"Windows IA64", SPL_ARCH_IA64
, 3 },
2068 {"Windows x64", SPL_ARCH_X64
, 3 },
2072 static int get_version_id(const char *arch
)
2076 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
2078 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
2079 return (archi_table
[i
].version
);
2085 /****************************************************************
2086 _spoolss_DeletePrinterDriver
2087 ****************************************************************/
2089 WERROR
_spoolss_DeletePrinterDriver(pipes_struct
*p
,
2090 struct spoolss_DeletePrinterDriver
*r
)
2092 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2093 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2096 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2097 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2099 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2100 and not a printer admin, then fail */
2102 if ( (p
->server_info
->utok
.uid
!= sec_initial_uid())
2103 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
2104 && !token_contains_name_in_list(
2105 uidtoname(p
->server_info
->utok
.uid
), NULL
,
2106 NULL
, p
->server_info
->ptok
,
2107 lp_printer_admin(-1)) )
2109 return WERR_ACCESS_DENIED
;
2112 /* check that we have a valid driver name first */
2114 if ((version
= get_version_id(r
->in
.architecture
)) == -1)
2115 return WERR_INVALID_ENVIRONMENT
;
2118 ZERO_STRUCT(info_win2k
);
2120 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, r
->in
.driver
,
2124 /* try for Win2k driver if "Windows NT x86" */
2126 if ( version
== 2 ) {
2128 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3,
2132 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2136 /* otherwise it was a failure */
2138 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2144 if (printer_driver_in_use(info
.info_3
)) {
2145 status
= WERR_PRINTER_DRIVER_IN_USE
;
2151 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3,
2153 r
->in
.architecture
, 3)))
2155 /* if we get to here, we now have 2 driver info structures to remove */
2156 /* remove the Win2k driver first*/
2158 status_win2k
= delete_printer_driver(
2159 p
, info_win2k
.info_3
, 3, false);
2160 free_a_printer_driver( info_win2k
, 3 );
2162 /* this should not have failed---if it did, report to client */
2163 if ( !W_ERROR_IS_OK(status_win2k
) )
2165 status
= status_win2k
;
2171 status
= delete_printer_driver(p
, info
.info_3
, version
, false);
2173 /* if at least one of the deletes succeeded return OK */
2175 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2179 free_a_printer_driver( info
, 3 );
2184 /****************************************************************
2185 _spoolss_DeletePrinterDriverEx
2186 ****************************************************************/
2188 WERROR
_spoolss_DeletePrinterDriverEx(pipes_struct
*p
,
2189 struct spoolss_DeletePrinterDriverEx
*r
)
2191 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2192 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2196 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2197 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2199 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2200 and not a printer admin, then fail */
2202 if ( (p
->server_info
->utok
.uid
!= sec_initial_uid())
2203 && !user_has_privileges(p
->server_info
->ptok
, &se_printop
)
2204 && !token_contains_name_in_list(
2205 uidtoname(p
->server_info
->utok
.uid
), NULL
, NULL
,
2206 p
->server_info
->ptok
, lp_printer_admin(-1)) )
2208 return WERR_ACCESS_DENIED
;
2211 /* check that we have a valid driver name first */
2212 if ((version
= get_version_id(r
->in
.architecture
)) == -1) {
2213 /* this is what NT returns */
2214 return WERR_INVALID_ENVIRONMENT
;
2217 if (r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
)
2218 version
= r
->in
.version
;
2221 ZERO_STRUCT(info_win2k
);
2223 status
= get_a_printer_driver(&info
, 3, r
->in
.driver
,
2224 r
->in
.architecture
, version
);
2226 if ( !W_ERROR_IS_OK(status
) )
2229 * if the client asked for a specific version,
2230 * or this is something other than Windows NT x86,
2234 if ( (r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2237 /* try for Win2k driver if "Windows NT x86" */
2240 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, r
->in
.driver
,
2243 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2248 if ( printer_driver_in_use(info
.info_3
) ) {
2249 status
= WERR_PRINTER_DRIVER_IN_USE
;
2254 * we have a couple of cases to consider.
2255 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2256 * then the delete should fail if **any** files overlap with
2258 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2259 * non-overlapping files
2260 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2261 * is set, the do not delete any files
2262 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2265 delete_files
= r
->in
.delete_flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2267 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2269 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (r
->in
.delete_flags
& DPD_DELETE_ALL_FILES
) ) {
2270 /* no idea of the correct error here */
2271 status
= WERR_ACCESS_DENIED
;
2276 /* also check for W32X86/3 if necessary; maybe we already have? */
2278 if ( (version
== 2) && ((r
->in
.delete_flags
& DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2279 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3,
2281 r
->in
.architecture
, 3)))
2284 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (r
->in
.delete_flags
& DPD_DELETE_ALL_FILES
) ) {
2285 /* no idea of the correct error here */
2286 free_a_printer_driver( info_win2k
, 3 );
2287 status
= WERR_ACCESS_DENIED
;
2291 /* if we get to here, we now have 2 driver info structures to remove */
2292 /* remove the Win2k driver first*/
2294 status_win2k
= delete_printer_driver(
2295 p
, info_win2k
.info_3
, 3, delete_files
);
2296 free_a_printer_driver( info_win2k
, 3 );
2298 /* this should not have failed---if it did, report to client */
2300 if ( !W_ERROR_IS_OK(status_win2k
) )
2305 status
= delete_printer_driver(p
, info
.info_3
, version
, delete_files
);
2307 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2310 free_a_printer_driver( info
, 3 );
2316 /****************************************************************************
2317 Internal routine for removing printerdata
2318 ***************************************************************************/
2320 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2322 return delete_printer_data( printer
->info_2
, key
, value
);
2325 /****************************************************************************
2326 Internal routine for storing printerdata
2327 ***************************************************************************/
2329 WERROR
set_printer_dataex(NT_PRINTER_INFO_LEVEL
*printer
,
2330 const char *key
, const char *value
,
2331 uint32_t type
, uint8_t *data
, int real_len
)
2333 /* the registry objects enforce uniqueness based on value name */
2335 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2338 /********************************************************************
2339 GetPrinterData on a printer server Handle.
2340 ********************************************************************/
2342 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*mem_ctx
,
2344 enum winreg_Type
*type
,
2345 union spoolss_PrinterData
*data
)
2347 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2349 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2355 if (!StrCaseCmp(value
, "BeepEnabled")) {
2361 if (!StrCaseCmp(value
, "EventLog")) {
2363 /* formally was 0x1b */
2368 if (!StrCaseCmp(value
, "NetPopup")) {
2374 if (!StrCaseCmp(value
, "MajorVersion")) {
2377 /* Windows NT 4.0 seems to not allow uploading of drivers
2378 to a server that reports 0x3 as the MajorVersion.
2379 need to investigate more how Win2k gets around this .
2382 if (RA_WINNT
== get_remote_arch()) {
2391 if (!StrCaseCmp(value
, "MinorVersion")) {
2398 * uint32_t size = 0x114
2399 * uint32_t major = 5
2400 * uint32_t minor = [0|1]
2401 * uint32_t build = [2195|2600]
2402 * extra unicode string = e.g. "Service Pack 3"
2404 if (!StrCaseCmp(value
, "OSVersion")) {
2406 enum ndr_err_code ndr_err
;
2407 struct spoolss_OSVersion os
;
2409 os
.major
= 5; /* Windows 2000 == 5.0 */
2411 os
.build
= 2195; /* build */
2412 os
.extra_string
= ""; /* leave extra string empty */
2414 ndr_err
= ndr_push_struct_blob(&blob
, mem_ctx
, NULL
, &os
,
2415 (ndr_push_flags_fn_t
)ndr_push_spoolss_OSVersion
);
2416 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2417 return WERR_GENERAL_FAILURE
;
2421 data
->binary
= blob
;
2427 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2430 data
->string
= talloc_strdup(mem_ctx
, "C:\\PRINTERS");
2431 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2436 if (!StrCaseCmp(value
, "Architecture")) {
2439 data
->string
= talloc_strdup(mem_ctx
, "Windows NT x86");
2440 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2445 if (!StrCaseCmp(value
, "DsPresent")) {
2448 /* only show the publish check box if we are a
2449 member of a AD domain */
2451 if (lp_security() == SEC_ADS
) {
2459 if (!StrCaseCmp(value
, "DNSMachineName")) {
2460 const char *hostname
= get_mydnsfullname();
2463 return WERR_BADFILE
;
2467 data
->string
= talloc_strdup(mem_ctx
, hostname
);
2468 W_ERROR_HAVE_NO_MEMORY(data
->string
);
2473 return WERR_INVALID_PARAM
;
2476 /****************************************************************
2477 _spoolss_GetPrinterData
2478 ****************************************************************/
2480 WERROR
_spoolss_GetPrinterData(pipes_struct
*p
,
2481 struct spoolss_GetPrinterData
*r
)
2484 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
2485 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2489 * Reminder: when it's a string, the length is in BYTES
2490 * even if UNICODE is negociated.
2495 /* in case of problem, return some default values */
2500 DEBUG(4,("_spoolss_GetPrinterData\n"));
2503 DEBUG(2,("_spoolss_GetPrinterData: Invalid handle (%s:%u:%u).\n",
2504 OUR_HANDLE(r
->in
.handle
)));
2505 result
= WERR_BADFID
;
2509 if (Printer
->printer_type
== SPLHND_SERVER
) {
2510 result
= getprinterdata_printer_server(p
->mem_ctx
,
2515 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
2516 result
= WERR_BADFID
;
2520 result
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2521 if (!W_ERROR_IS_OK(result
)) {
2525 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2527 if (strequal(r
->in
.value_name
, "ChangeId")) {
2528 *r
->out
.type
= REG_DWORD
;
2529 r
->out
.data
->value
= printer
->info_2
->changeid
;
2532 struct regval_blob
*v
;
2535 v
= get_printer_data(printer
->info_2
,
2536 SPOOL_PRINTERDATA_KEY
,
2539 result
= WERR_BADFILE
;
2543 *r
->out
.type
= v
->type
;
2545 blob
= data_blob_const(v
->data_p
, v
->size
);
2547 result
= pull_spoolss_PrinterData(p
->mem_ctx
, &blob
,
2554 /* cleanup & exit */
2557 free_a_printer(&printer
, 2);
2560 if (!W_ERROR_IS_OK(result
)) {
2564 *r
->out
.needed
= ndr_size_spoolss_PrinterData(r
->out
.data
, *r
->out
.type
, NULL
, 0);
2565 *r
->out
.type
= SPOOLSS_BUFFER_OK(*r
->out
.type
, REG_NONE
);
2566 r
->out
.data
= SPOOLSS_BUFFER_OK(r
->out
.data
, r
->out
.data
);
2568 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
2571 /*********************************************************
2572 Connect to the client machine.
2573 **********************************************************/
2575 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2576 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2579 struct cli_state
*the_cli
;
2580 struct sockaddr_storage rm_addr
;
2582 if ( is_zero_addr((struct sockaddr
*)client_ss
) ) {
2583 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20, false) ) {
2584 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2588 if (ismyaddr((struct sockaddr
*)&rm_addr
)) {
2589 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2593 char addr
[INET6_ADDRSTRLEN
];
2594 rm_addr
= *client_ss
;
2595 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2596 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2600 /* setup the connection */
2602 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2603 &rm_addr
, 0, "IPC$", "IPC",
2607 0, lp_client_signing(), NULL
);
2609 if ( !NT_STATUS_IS_OK( ret
) ) {
2610 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2615 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2616 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2617 cli_shutdown(the_cli
);
2622 * Ok - we have an anonymous connection to the IPC$ share.
2623 * Now start the NT Domain stuff :-).
2626 ret
= cli_rpc_pipe_open_noauth(the_cli
, &ndr_table_spoolss
.syntax_id
, pp_pipe
);
2627 if (!NT_STATUS_IS_OK(ret
)) {
2628 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2629 remote_machine
, nt_errstr(ret
)));
2630 cli_shutdown(the_cli
);
2637 /***************************************************************************
2638 Connect to the client.
2639 ****************************************************************************/
2641 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2642 uint32_t localprinter
, uint32_t type
,
2643 struct policy_handle
*handle
,
2644 struct sockaddr_storage
*client_ss
)
2650 * If it's the first connection, contact the client
2651 * and connect to the IPC$ share anonymously
2653 if (smb_connections
==0) {
2654 fstring unix_printer
;
2656 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2658 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2661 messaging_register(smbd_messaging_context(), NULL
,
2662 MSG_PRINTER_NOTIFY2
,
2663 receive_notify2_message_list
);
2664 /* Tell the connections db we're now interested in printer
2665 * notify messages. */
2666 register_message_flags(true, FLAG_MSG_PRINT_NOTIFY
);
2670 * Tell the specific printing tdb we want messages for this printer
2671 * by registering our PID.
2674 if (!print_notify_register_pid(snum
))
2675 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2679 status
= rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe
, talloc_tos(),
2687 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
2688 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2689 win_errstr(result
)));
2691 return (W_ERROR_IS_OK(result
));
2694 /****************************************************************
2695 ****************************************************************/
2697 static struct spoolss_NotifyOption
*dup_spoolss_NotifyOption(TALLOC_CTX
*mem_ctx
,
2698 const struct spoolss_NotifyOption
*r
)
2700 struct spoolss_NotifyOption
*option
;
2707 option
= talloc_zero(mem_ctx
, struct spoolss_NotifyOption
);
2714 if (!option
->count
) {
2718 option
->types
= talloc_zero_array(option
,
2719 struct spoolss_NotifyOptionType
, option
->count
);
2720 if (!option
->types
) {
2721 talloc_free(option
);
2725 for (i
=0; i
< option
->count
; i
++) {
2726 option
->types
[i
] = r
->types
[i
];
2728 if (option
->types
[i
].count
) {
2729 option
->types
[i
].fields
= talloc_zero_array(option
,
2730 union spoolss_Field
, option
->types
[i
].count
);
2731 if (!option
->types
[i
].fields
) {
2732 talloc_free(option
);
2735 for (k
=0; k
<option
->types
[i
].count
; k
++) {
2736 option
->types
[i
].fields
[k
] =
2737 r
->types
[i
].fields
[k
];
2745 /****************************************************************
2746 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2748 * before replying OK: status=0 a rpc call is made to the workstation
2749 * asking ReplyOpenPrinter
2751 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2752 * called from api_spoolss_rffpcnex
2753 ****************************************************************/
2755 WERROR
_spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct
*p
,
2756 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx
*r
)
2759 struct spoolss_NotifyOption
*option
= r
->in
.notify_options
;
2760 struct sockaddr_storage client_ss
;
2762 /* store the notify value in the printer struct */
2764 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
2767 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2768 "Invalid handle (%s:%u:%u).\n",
2769 OUR_HANDLE(r
->in
.handle
)));
2773 Printer
->notify
.flags
= r
->in
.flags
;
2774 Printer
->notify
.options
= r
->in
.options
;
2775 Printer
->notify
.printerlocal
= r
->in
.printer_local
;
2777 TALLOC_FREE(Printer
->notify
.option
);
2778 Printer
->notify
.option
= dup_spoolss_NotifyOption(Printer
, option
);
2780 fstrcpy(Printer
->notify
.localmachine
, r
->in
.local_machine
);
2782 /* Connect to the client machine and send a ReplyOpenPrinter */
2784 if ( Printer
->printer_type
== SPLHND_SERVER
)
2786 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2787 !get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
) )
2790 if (!interpret_string_addr(&client_ss
, p
->client_address
,
2792 return WERR_SERVER_UNAVAILABLE
;
2795 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2796 Printer
->notify
.printerlocal
, 1,
2797 &Printer
->notify
.client_hnd
, &client_ss
))
2798 return WERR_SERVER_UNAVAILABLE
;
2800 Printer
->notify
.client_connected
= true;
2805 /*******************************************************************
2806 * fill a notify_info_data with the servername
2807 ********************************************************************/
2809 void spoolss_notify_server_name(int snum
,
2810 struct spoolss_Notify
*data
,
2811 print_queue_struct
*queue
,
2812 NT_PRINTER_INFO_LEVEL
*printer
,
2813 TALLOC_CTX
*mem_ctx
)
2815 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->servername
);
2818 /*******************************************************************
2819 * fill a notify_info_data with the printername (not including the servername).
2820 ********************************************************************/
2822 void spoolss_notify_printer_name(int snum
,
2823 struct spoolss_Notify
*data
,
2824 print_queue_struct
*queue
,
2825 NT_PRINTER_INFO_LEVEL
*printer
,
2826 TALLOC_CTX
*mem_ctx
)
2828 /* the notify name should not contain the \\server\ part */
2829 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2832 p
= printer
->info_2
->printername
;
2837 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
2840 /*******************************************************************
2841 * fill a notify_info_data with the servicename
2842 ********************************************************************/
2844 void spoolss_notify_share_name(int snum
,
2845 struct spoolss_Notify
*data
,
2846 print_queue_struct
*queue
,
2847 NT_PRINTER_INFO_LEVEL
*printer
,
2848 TALLOC_CTX
*mem_ctx
)
2850 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, lp_servicename(snum
));
2853 /*******************************************************************
2854 * fill a notify_info_data with the port name
2855 ********************************************************************/
2857 void spoolss_notify_port_name(int snum
,
2858 struct spoolss_Notify
*data
,
2859 print_queue_struct
*queue
,
2860 NT_PRINTER_INFO_LEVEL
*printer
,
2861 TALLOC_CTX
*mem_ctx
)
2863 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->portname
);
2866 /*******************************************************************
2867 * fill a notify_info_data with the printername
2868 * but it doesn't exist, have to see what to do
2869 ********************************************************************/
2871 void spoolss_notify_driver_name(int snum
,
2872 struct spoolss_Notify
*data
,
2873 print_queue_struct
*queue
,
2874 NT_PRINTER_INFO_LEVEL
*printer
,
2875 TALLOC_CTX
*mem_ctx
)
2877 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->drivername
);
2880 /*******************************************************************
2881 * fill a notify_info_data with the comment
2882 ********************************************************************/
2884 void spoolss_notify_comment(int snum
,
2885 struct spoolss_Notify
*data
,
2886 print_queue_struct
*queue
,
2887 NT_PRINTER_INFO_LEVEL
*printer
,
2888 TALLOC_CTX
*mem_ctx
)
2892 if (*printer
->info_2
->comment
== '\0') {
2893 p
= lp_comment(snum
);
2895 p
= printer
->info_2
->comment
;
2898 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->comment
);
2901 /*******************************************************************
2902 * fill a notify_info_data with the comment
2903 * location = "Room 1, floor 2, building 3"
2904 ********************************************************************/
2906 void spoolss_notify_location(int snum
,
2907 struct spoolss_Notify
*data
,
2908 print_queue_struct
*queue
,
2909 NT_PRINTER_INFO_LEVEL
*printer
,
2910 TALLOC_CTX
*mem_ctx
)
2912 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->location
);
2915 /*******************************************************************
2916 * fill a notify_info_data with the device mode
2917 * jfm:xxxx don't to it for know but that's a real problem !!!
2918 ********************************************************************/
2920 static void spoolss_notify_devmode(int snum
,
2921 struct spoolss_Notify
*data
,
2922 print_queue_struct
*queue
,
2923 NT_PRINTER_INFO_LEVEL
*printer
,
2924 TALLOC_CTX
*mem_ctx
)
2926 /* for a dummy implementation we have to zero the fields */
2927 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data
, NULL
);
2930 /*******************************************************************
2931 * fill a notify_info_data with the separator file name
2932 ********************************************************************/
2934 void spoolss_notify_sepfile(int snum
,
2935 struct spoolss_Notify
*data
,
2936 print_queue_struct
*queue
,
2937 NT_PRINTER_INFO_LEVEL
*printer
,
2938 TALLOC_CTX
*mem_ctx
)
2940 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->sepfile
);
2943 /*******************************************************************
2944 * fill a notify_info_data with the print processor
2945 * jfm:xxxx return always winprint to indicate we don't do anything to it
2946 ********************************************************************/
2948 void spoolss_notify_print_processor(int snum
,
2949 struct spoolss_Notify
*data
,
2950 print_queue_struct
*queue
,
2951 NT_PRINTER_INFO_LEVEL
*printer
,
2952 TALLOC_CTX
*mem_ctx
)
2954 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->printprocessor
);
2957 /*******************************************************************
2958 * fill a notify_info_data with the print processor options
2959 * jfm:xxxx send an empty string
2960 ********************************************************************/
2962 void spoolss_notify_parameters(int snum
,
2963 struct spoolss_Notify
*data
,
2964 print_queue_struct
*queue
,
2965 NT_PRINTER_INFO_LEVEL
*printer
,
2966 TALLOC_CTX
*mem_ctx
)
2968 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->parameters
);
2971 /*******************************************************************
2972 * fill a notify_info_data with the data type
2973 * jfm:xxxx always send RAW as data type
2974 ********************************************************************/
2976 void spoolss_notify_datatype(int snum
,
2977 struct spoolss_Notify
*data
,
2978 print_queue_struct
*queue
,
2979 NT_PRINTER_INFO_LEVEL
*printer
,
2980 TALLOC_CTX
*mem_ctx
)
2982 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, printer
->info_2
->datatype
);
2985 /*******************************************************************
2986 * fill a notify_info_data with the security descriptor
2987 * jfm:xxxx send an null pointer to say no security desc
2988 * have to implement security before !
2989 ********************************************************************/
2991 static void spoolss_notify_security_desc(int snum
,
2992 struct spoolss_Notify
*data
,
2993 print_queue_struct
*queue
,
2994 NT_PRINTER_INFO_LEVEL
*printer
,
2995 TALLOC_CTX
*mem_ctx
)
2997 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data
,
2998 printer
->info_2
->secdesc_buf
->sd_size
,
2999 printer
->info_2
->secdesc_buf
->sd
);
3002 /*******************************************************************
3003 * fill a notify_info_data with the attributes
3004 * jfm:xxxx a samba printer is always shared
3005 ********************************************************************/
3007 void spoolss_notify_attributes(int snum
,
3008 struct spoolss_Notify
*data
,
3009 print_queue_struct
*queue
,
3010 NT_PRINTER_INFO_LEVEL
*printer
,
3011 TALLOC_CTX
*mem_ctx
)
3013 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->attributes
);
3016 /*******************************************************************
3017 * fill a notify_info_data with the priority
3018 ********************************************************************/
3020 static void spoolss_notify_priority(int snum
,
3021 struct spoolss_Notify
*data
,
3022 print_queue_struct
*queue
,
3023 NT_PRINTER_INFO_LEVEL
*printer
,
3024 TALLOC_CTX
*mem_ctx
)
3026 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->priority
);
3029 /*******************************************************************
3030 * fill a notify_info_data with the default priority
3031 ********************************************************************/
3033 static void spoolss_notify_default_priority(int snum
,
3034 struct spoolss_Notify
*data
,
3035 print_queue_struct
*queue
,
3036 NT_PRINTER_INFO_LEVEL
*printer
,
3037 TALLOC_CTX
*mem_ctx
)
3039 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->default_priority
);
3042 /*******************************************************************
3043 * fill a notify_info_data with the start time
3044 ********************************************************************/
3046 static void spoolss_notify_start_time(int snum
,
3047 struct spoolss_Notify
*data
,
3048 print_queue_struct
*queue
,
3049 NT_PRINTER_INFO_LEVEL
*printer
,
3050 TALLOC_CTX
*mem_ctx
)
3052 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->starttime
);
3055 /*******************************************************************
3056 * fill a notify_info_data with the until time
3057 ********************************************************************/
3059 static void spoolss_notify_until_time(int snum
,
3060 struct spoolss_Notify
*data
,
3061 print_queue_struct
*queue
,
3062 NT_PRINTER_INFO_LEVEL
*printer
,
3063 TALLOC_CTX
*mem_ctx
)
3065 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->untiltime
);
3068 /*******************************************************************
3069 * fill a notify_info_data with the status
3070 ********************************************************************/
3072 static void spoolss_notify_status(int snum
,
3073 struct spoolss_Notify
*data
,
3074 print_queue_struct
*queue
,
3075 NT_PRINTER_INFO_LEVEL
*printer
,
3076 TALLOC_CTX
*mem_ctx
)
3078 print_status_struct status
;
3080 print_queue_length(snum
, &status
);
3081 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, status
.status
);
3084 /*******************************************************************
3085 * fill a notify_info_data with the number of jobs queued
3086 ********************************************************************/
3088 void spoolss_notify_cjobs(int snum
,
3089 struct spoolss_Notify
*data
,
3090 print_queue_struct
*queue
,
3091 NT_PRINTER_INFO_LEVEL
*printer
,
3092 TALLOC_CTX
*mem_ctx
)
3094 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, print_queue_length(snum
, NULL
));
3097 /*******************************************************************
3098 * fill a notify_info_data with the average ppm
3099 ********************************************************************/
3101 static void spoolss_notify_average_ppm(int snum
,
3102 struct spoolss_Notify
*data
,
3103 print_queue_struct
*queue
,
3104 NT_PRINTER_INFO_LEVEL
*printer
,
3105 TALLOC_CTX
*mem_ctx
)
3107 /* always respond 8 pages per minutes */
3108 /* a little hard ! */
3109 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, printer
->info_2
->averageppm
);
3112 /*******************************************************************
3113 * fill a notify_info_data with username
3114 ********************************************************************/
3116 static void spoolss_notify_username(int snum
,
3117 struct spoolss_Notify
*data
,
3118 print_queue_struct
*queue
,
3119 NT_PRINTER_INFO_LEVEL
*printer
,
3120 TALLOC_CTX
*mem_ctx
)
3122 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, queue
->fs_user
);
3125 /*******************************************************************
3126 * fill a notify_info_data with job status
3127 ********************************************************************/
3129 static void spoolss_notify_job_status(int snum
,
3130 struct spoolss_Notify
*data
,
3131 print_queue_struct
*queue
,
3132 NT_PRINTER_INFO_LEVEL
*printer
,
3133 TALLOC_CTX
*mem_ctx
)
3135 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, nt_printj_status(queue
->status
));
3138 /*******************************************************************
3139 * fill a notify_info_data with job name
3140 ********************************************************************/
3142 static void spoolss_notify_job_name(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_STRING(data
, queue
->fs_file
);
3151 /*******************************************************************
3152 * fill a notify_info_data with job status
3153 ********************************************************************/
3155 static void spoolss_notify_job_status_string(int snum
,
3156 struct spoolss_Notify
*data
,
3157 print_queue_struct
*queue
,
3158 NT_PRINTER_INFO_LEVEL
*printer
,
3159 TALLOC_CTX
*mem_ctx
)
3162 * Now we're returning job status codes we just return a "" here. JRA.
3167 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3170 switch (queue
->status
) {
3175 p
= ""; /* NT provides the paused string */
3184 #endif /* NO LONGER NEEDED. */
3186 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data
, p
);
3189 /*******************************************************************
3190 * fill a notify_info_data with job time
3191 ********************************************************************/
3193 static void spoolss_notify_job_time(int snum
,
3194 struct spoolss_Notify
*data
,
3195 print_queue_struct
*queue
,
3196 NT_PRINTER_INFO_LEVEL
*printer
,
3197 TALLOC_CTX
*mem_ctx
)
3199 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
3202 /*******************************************************************
3203 * fill a notify_info_data with job size
3204 ********************************************************************/
3206 static void spoolss_notify_job_size(int snum
,
3207 struct spoolss_Notify
*data
,
3208 print_queue_struct
*queue
,
3209 NT_PRINTER_INFO_LEVEL
*printer
,
3210 TALLOC_CTX
*mem_ctx
)
3212 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->size
);
3215 /*******************************************************************
3216 * fill a notify_info_data with page info
3217 ********************************************************************/
3218 static void spoolss_notify_total_pages(int snum
,
3219 struct spoolss_Notify
*data
,
3220 print_queue_struct
*queue
,
3221 NT_PRINTER_INFO_LEVEL
*printer
,
3222 TALLOC_CTX
*mem_ctx
)
3224 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->page_count
);
3227 /*******************************************************************
3228 * fill a notify_info_data with pages printed info.
3229 ********************************************************************/
3230 static void spoolss_notify_pages_printed(int snum
,
3231 struct spoolss_Notify
*data
,
3232 print_queue_struct
*queue
,
3233 NT_PRINTER_INFO_LEVEL
*printer
,
3234 TALLOC_CTX
*mem_ctx
)
3236 /* Add code when back-end tracks this */
3237 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, 0);
3240 /*******************************************************************
3241 Fill a notify_info_data with job position.
3242 ********************************************************************/
3244 static void spoolss_notify_job_position(int snum
,
3245 struct spoolss_Notify
*data
,
3246 print_queue_struct
*queue
,
3247 NT_PRINTER_INFO_LEVEL
*printer
,
3248 TALLOC_CTX
*mem_ctx
)
3250 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data
, queue
->job
);
3253 /*******************************************************************
3254 Fill a notify_info_data with submitted time.
3255 ********************************************************************/
3257 static void spoolss_notify_submitted_time(int snum
,
3258 struct spoolss_Notify
*data
,
3259 print_queue_struct
*queue
,
3260 NT_PRINTER_INFO_LEVEL
*printer
,
3261 TALLOC_CTX
*mem_ctx
)
3263 data
->data
.string
.string
= NULL
;
3264 data
->data
.string
.size
= 0;
3266 init_systemtime_buffer(mem_ctx
, gmtime(&queue
->time
),
3267 &data
->data
.string
.string
,
3268 &data
->data
.string
.size
);
3272 struct s_notify_info_data_table
3274 enum spoolss_NotifyType type
;
3277 enum spoolss_NotifyTable variable_type
;
3278 void (*fn
) (int snum
, struct spoolss_Notify
*data
,
3279 print_queue_struct
*queue
,
3280 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3283 /* A table describing the various print notification constants and
3284 whether the notification data is a pointer to a variable sized
3285 buffer, a one value uint32_t or a two value uint32_t. */
3287 static const struct s_notify_info_data_table notify_info_data_table
[] =
3289 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SERVER_NAME
, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
3290 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRINTER_NAME
, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
3291 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SHARE_NAME
, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_share_name
},
3292 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PORT_NAME
, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
3293 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DRIVER_NAME
, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
3294 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_COMMENT
, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING
, spoolss_notify_comment
},
3295 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_LOCATION
, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING
, spoolss_notify_location
},
3296 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DEVMODE
, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
3297 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SEPFILE
, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING
, spoolss_notify_sepfile
},
3298 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR
, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
3299 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PARAMETERS
, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
3300 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DATATYPE
, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
3301 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, spoolss_notify_security_desc
},
3302 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_ATTRIBUTES
, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD
, spoolss_notify_attributes
},
3303 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PRIORITY
, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
3304 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_default_priority
},
3305 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_START_TIME
, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
3306 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_UNTIL_TIME
, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
3307 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_STATUS
, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_status
},
3308 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_STATUS_STRING
, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING
, NULL
},
3309 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_CJOBS
, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD
, spoolss_notify_cjobs
},
3310 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_AVERAGE_PPM
, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD
, spoolss_notify_average_ppm
},
3311 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_TOTAL_PAGES
, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, NULL
},
3312 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_PAGES_PRINTED
, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
3313 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_TOTAL_BYTES
, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, NULL
},
3314 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_FIELD_BYTES_PRINTED
, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD
, NULL
},
3315 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRINTER_NAME
, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_printer_name
},
3316 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_MACHINE_NAME
, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_server_name
},
3317 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PORT_NAME
, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_port_name
},
3318 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_USER_NAME
, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
3319 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_NOTIFY_NAME
, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_username
},
3320 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DATATYPE
, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING
, spoolss_notify_datatype
},
3321 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRINT_PROCESSOR
, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING
, spoolss_notify_print_processor
},
3322 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PARAMETERS
, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING
, spoolss_notify_parameters
},
3323 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DRIVER_NAME
, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING
, spoolss_notify_driver_name
},
3324 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DEVMODE
, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE
, spoolss_notify_devmode
},
3325 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_STATUS
, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD
, spoolss_notify_job_status
},
3326 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_STATUS_STRING
, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING
, spoolss_notify_job_status_string
},
3327 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR
, NULL
},
3328 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_DOCUMENT
, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING
, spoolss_notify_job_name
},
3329 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PRIORITY
, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD
, spoolss_notify_priority
},
3330 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_POSITION
, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD
, spoolss_notify_job_position
},
3331 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_SUBMITTED
, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME
, spoolss_notify_submitted_time
},
3332 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_START_TIME
, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_start_time
},
3333 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_UNTIL_TIME
, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_until_time
},
3334 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TIME
, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD
, spoolss_notify_job_time
},
3335 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TOTAL_PAGES
, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD
, spoolss_notify_total_pages
},
3336 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_PAGES_PRINTED
, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD
, spoolss_notify_pages_printed
},
3337 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_FIELD_TOTAL_BYTES
, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD
, spoolss_notify_job_size
},
3340 /*******************************************************************
3341 Return the variable_type of info_data structure.
3342 ********************************************************************/
3344 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type
,
3349 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
3350 if ( (notify_info_data_table
[i
].type
== type
) &&
3351 (notify_info_data_table
[i
].field
== field
) ) {
3352 return notify_info_data_table
[i
].variable_type
;
3356 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3361 /****************************************************************************
3362 ****************************************************************************/
3364 static bool search_notify(enum spoolss_NotifyType type
,
3370 for (i
= 0; i
< ARRAY_SIZE(notify_info_data_table
); i
++) {
3371 if (notify_info_data_table
[i
].type
== type
&&
3372 notify_info_data_table
[i
].field
== field
&&
3373 notify_info_data_table
[i
].fn
!= NULL
) {
3382 /****************************************************************************
3383 ****************************************************************************/
3385 void construct_info_data(struct spoolss_Notify
*info_data
,
3386 enum spoolss_NotifyType type
,
3390 info_data
->type
= type
;
3391 info_data
->field
.field
= field
;
3392 info_data
->variable_type
= variable_type_of_notify_info_data(type
, field
);
3393 info_data
->job_id
= id
;
3396 /*******************************************************************
3398 * fill a notify_info struct with info asked
3400 ********************************************************************/
3402 static bool construct_notify_printer_info(Printer_entry
*print_hnd
,
3403 struct spoolss_NotifyInfo
*info
,
3405 const struct spoolss_NotifyOptionType
*option_type
,
3407 TALLOC_CTX
*mem_ctx
)
3410 enum spoolss_NotifyType type
;
3413 struct spoolss_Notify
*current_data
;
3414 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3415 print_queue_struct
*queue
=NULL
;
3417 type
= option_type
->type
;
3419 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3420 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3421 option_type
->count
, lp_servicename(snum
)));
3423 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3426 for(field_num
=0; field_num
< option_type
->count
; field_num
++) {
3427 field
= option_type
->fields
[field_num
].field
;
3429 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3431 if (!search_notify(type
, field
, &j
) )
3434 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3435 struct spoolss_Notify
,
3437 if (info
->notifies
== NULL
) {
3438 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3439 free_a_printer(&printer
, 2);
3443 current_data
= &info
->notifies
[info
->count
];
3445 construct_info_data(current_data
, type
, field
, id
);
3447 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3448 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3450 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3456 free_a_printer(&printer
, 2);
3460 /*******************************************************************
3462 * fill a notify_info struct with info asked
3464 ********************************************************************/
3466 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3467 struct spoolss_NotifyInfo
*info
,
3468 NT_PRINTER_INFO_LEVEL
*printer
,
3470 const struct spoolss_NotifyOptionType
*option_type
,
3472 TALLOC_CTX
*mem_ctx
)
3475 enum spoolss_NotifyType type
;
3477 struct spoolss_Notify
*current_data
;
3479 DEBUG(4,("construct_notify_jobs_info\n"));
3481 type
= option_type
->type
;
3483 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3484 (type
== PRINTER_NOTIFY_TYPE
? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3485 option_type
->count
));
3487 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3488 field
= option_type
->fields
[field_num
].field
;
3490 if (!search_notify(type
, field
, &j
) )
3493 info
->notifies
= TALLOC_REALLOC_ARRAY(info
, info
->notifies
,
3494 struct spoolss_Notify
,
3496 if (info
->notifies
== NULL
) {
3497 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3501 current_data
=&(info
->notifies
[info
->count
]);
3503 construct_info_data(current_data
, type
, field
, id
);
3504 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3513 * JFM: The enumeration is not that simple, it's even non obvious.
3515 * let's take an example: I want to monitor the PRINTER SERVER for
3516 * the printer's name and the number of jobs currently queued.
3517 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3518 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3520 * I have 3 printers on the back of my server.
3522 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3525 * 1 printer 1 name 1
3526 * 2 printer 1 cjob 1
3527 * 3 printer 2 name 2
3528 * 4 printer 2 cjob 2
3529 * 5 printer 3 name 3
3530 * 6 printer 3 name 3
3532 * that's the print server case, the printer case is even worse.
3535 /*******************************************************************
3537 * enumerate all printers on the printserver
3538 * fill a notify_info struct with info asked
3540 ********************************************************************/
3542 static WERROR
printserver_notify_info(pipes_struct
*p
,
3543 struct policy_handle
*hnd
,
3544 struct spoolss_NotifyInfo
*info
,
3545 TALLOC_CTX
*mem_ctx
)
3548 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
3549 int n_services
=lp_numservices();
3551 struct spoolss_NotifyOption
*option
;
3552 struct spoolss_NotifyOptionType option_type
;
3554 DEBUG(4,("printserver_notify_info\n"));
3559 option
= Printer
->notify
.option
;
3562 info
->notifies
= NULL
;
3565 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3566 sending a ffpcn() request first */
3571 for (i
=0; i
<option
->count
; i
++) {
3572 option_type
= option
->types
[i
];
3574 if (option_type
.type
!= PRINTER_NOTIFY_TYPE
)
3577 for (snum
=0; snum
<n_services
; snum
++)
3579 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3580 construct_notify_printer_info ( Printer
, info
, snum
, &option_type
, snum
, mem_ctx
);
3586 * Debugging information, don't delete.
3589 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3590 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3591 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3593 for (i
=0; i
<info
->count
; i
++) {
3594 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3595 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3596 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3603 /*******************************************************************
3605 * fill a notify_info struct with info asked
3607 ********************************************************************/
3609 static WERROR
printer_notify_info(pipes_struct
*p
, struct policy_handle
*hnd
,
3610 struct spoolss_NotifyInfo
*info
,
3611 TALLOC_CTX
*mem_ctx
)
3614 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
3617 struct spoolss_NotifyOption
*option
;
3618 struct spoolss_NotifyOptionType option_type
;
3620 print_queue_struct
*queue
=NULL
;
3621 print_status_struct status
;
3623 DEBUG(4,("printer_notify_info\n"));
3628 option
= Printer
->notify
.option
;
3632 info
->notifies
= NULL
;
3635 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3636 sending a ffpcn() request first */
3641 get_printer_snum(p
, hnd
, &snum
, NULL
);
3643 for (i
=0; i
<option
->count
; i
++) {
3644 option_type
= option
->types
[i
];
3646 switch (option_type
.type
) {
3647 case PRINTER_NOTIFY_TYPE
:
3648 if(construct_notify_printer_info(Printer
, info
, snum
,
3654 case JOB_NOTIFY_TYPE
: {
3655 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3657 count
= print_queue_status(snum
, &queue
, &status
);
3659 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3662 for (j
=0; j
<count
; j
++) {
3663 construct_notify_jobs_info(&queue
[j
], info
,
3670 free_a_printer(&printer
, 2);
3680 * Debugging information, don't delete.
3683 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3684 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3685 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3687 for (i=0; i<info->count; i++) {
3688 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3689 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3690 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3696 /****************************************************************
3697 _spoolss_RouterRefreshPrinterChangeNotify
3698 ****************************************************************/
3700 WERROR
_spoolss_RouterRefreshPrinterChangeNotify(pipes_struct
*p
,
3701 struct spoolss_RouterRefreshPrinterChangeNotify
*r
)
3703 struct spoolss_NotifyInfo
*info
;
3705 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
3706 WERROR result
= WERR_BADFID
;
3708 /* we always have a spoolss_NotifyInfo struct */
3709 info
= talloc_zero(p
->mem_ctx
, struct spoolss_NotifyInfo
);
3711 result
= WERR_NOMEM
;
3715 *r
->out
.info
= info
;
3718 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3719 "Invalid handle (%s:%u:%u).\n",
3720 OUR_HANDLE(r
->in
.handle
)));
3724 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3727 * We are now using the change value, and
3728 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3729 * I don't have a global notification system, I'm sending back all the
3730 * informations even when _NOTHING_ has changed.
3733 /* We need to keep track of the change value to send back in
3734 RRPCN replies otherwise our updates are ignored. */
3736 Printer
->notify
.fnpcn
= true;
3738 if (Printer
->notify
.client_connected
) {
3739 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3740 "Saving change value in request [%x]\n",
3742 Printer
->notify
.change
= r
->in
.change_low
;
3745 /* just ignore the spoolss_NotifyOption */
3747 switch (Printer
->printer_type
) {
3749 result
= printserver_notify_info(p
, r
->in
.handle
,
3753 case SPLHND_PRINTER
:
3754 result
= printer_notify_info(p
, r
->in
.handle
,
3759 Printer
->notify
.fnpcn
= false;
3765 /********************************************************************
3766 * construct_printer_info_0
3767 * fill a printer_info_0 struct
3768 ********************************************************************/
3770 static WERROR
construct_printer_info0(TALLOC_CTX
*mem_ctx
,
3771 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
3772 struct spoolss_PrinterInfo0
*r
,
3776 counter_printer_0
*session_counter
;
3778 print_status_struct status
;
3780 r
->printername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->printername
);
3781 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3783 r
->servername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
3784 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3786 count
= print_queue_length(snum
, &status
);
3788 /* check if we already have a counter for this printer */
3789 for (session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3790 if (session_counter
->snum
== snum
)
3794 /* it's the first time, add it to the list */
3795 if (session_counter
== NULL
) {
3796 session_counter
= SMB_MALLOC_P(counter_printer_0
);
3797 W_ERROR_HAVE_NO_MEMORY(session_counter
);
3798 ZERO_STRUCTP(session_counter
);
3799 session_counter
->snum
= snum
;
3800 session_counter
->counter
= 0;
3801 DLIST_ADD(counter_list
, session_counter
);
3805 session_counter
->counter
++;
3811 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
3813 init_systemtime(&r
->time
, gmtime(&setuptime
));
3816 * the global_counter should be stored in a TDB as it's common to all the clients
3817 * and should be zeroed on samba startup
3819 r
->global_counter
= session_counter
->counter
;
3821 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3822 r
->version
= 0x0005; /* NT 5 */
3823 r
->free_build
= 0x0893; /* build 2195 */
3825 r
->max_spooling
= 0;
3826 r
->session_counter
= session_counter
->counter
;
3827 r
->num_error_out_of_paper
= 0x0;
3828 r
->num_error_not_ready
= 0x0; /* number of print failure */
3830 r
->number_of_processors
= 0x1;
3831 r
->processor_type
= PROCESSOR_INTEL_PENTIUM
; /* 586 Pentium ? */
3832 r
->high_part_total_bytes
= 0x0;
3833 r
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
3834 r
->last_error
= WERR_OK
;
3835 r
->status
= nt_printq_status(status
.status
);
3836 r
->enumerate_network_printers
= 0x0;
3837 r
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3838 r
->processor_architecture
= 0x0;
3839 r
->processor_level
= 0x6; /* 6 ???*/
3847 /****************************************************************************
3848 Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers
3849 should be valid upon entry
3850 ****************************************************************************/
3852 static WERROR
convert_nt_devicemode(TALLOC_CTX
*mem_ctx
,
3853 struct spoolss_DeviceMode
*r
,
3854 const NT_DEVICEMODE
*ntdevmode
)
3856 if (!r
|| !ntdevmode
) {
3857 return WERR_INVALID_PARAM
;
3860 r
->devicename
= talloc_strdup(mem_ctx
, ntdevmode
->devicename
);
3861 W_ERROR_HAVE_NO_MEMORY(r
->devicename
);
3863 r
->specversion
= ntdevmode
->specversion
;
3864 r
->driverversion
= ntdevmode
->driverversion
;
3865 r
->size
= ntdevmode
->size
;
3866 r
->__driverextra_length
= ntdevmode
->driverextra
;
3867 r
->fields
= ntdevmode
->fields
;
3869 r
->orientation
= ntdevmode
->orientation
;
3870 r
->papersize
= ntdevmode
->papersize
;
3871 r
->paperlength
= ntdevmode
->paperlength
;
3872 r
->paperwidth
= ntdevmode
->paperwidth
;
3873 r
->scale
= ntdevmode
->scale
;
3874 r
->copies
= ntdevmode
->copies
;
3875 r
->defaultsource
= ntdevmode
->defaultsource
;
3876 r
->printquality
= ntdevmode
->printquality
;
3877 r
->color
= ntdevmode
->color
;
3878 r
->duplex
= ntdevmode
->duplex
;
3879 r
->yresolution
= ntdevmode
->yresolution
;
3880 r
->ttoption
= ntdevmode
->ttoption
;
3881 r
->collate
= ntdevmode
->collate
;
3883 r
->formname
= talloc_strdup(mem_ctx
, ntdevmode
->formname
);
3884 W_ERROR_HAVE_NO_MEMORY(r
->formname
);
3886 /* all 0 below are values that have not been set in the old parsing/copy
3887 * function, maybe they should... - gd */
3893 r
->displayflags
= 0;
3894 r
->displayfrequency
= 0;
3895 r
->icmmethod
= ntdevmode
->icmmethod
;
3896 r
->icmintent
= ntdevmode
->icmintent
;
3897 r
->mediatype
= ntdevmode
->mediatype
;
3898 r
->dithertype
= ntdevmode
->dithertype
;
3901 r
->panningwidth
= 0;
3902 r
->panningheight
= 0;
3904 if (ntdevmode
->nt_dev_private
!= NULL
) {
3905 r
->driverextra_data
= data_blob_talloc(mem_ctx
,
3906 ntdevmode
->nt_dev_private
,
3907 ntdevmode
->driverextra
);
3908 W_ERROR_HAVE_NO_MEMORY(r
->driverextra_data
.data
);
3915 /****************************************************************************
3916 Create a spoolss_DeviceMode struct. Returns talloced memory.
3917 ****************************************************************************/
3919 struct spoolss_DeviceMode
*construct_dev_mode(TALLOC_CTX
*mem_ctx
,
3920 const char *servicename
)
3923 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3924 struct spoolss_DeviceMode
*devmode
= NULL
;
3926 DEBUG(7,("construct_dev_mode\n"));
3928 DEBUGADD(8,("getting printer characteristics\n"));
3930 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
3933 if (!printer
->info_2
->devmode
) {
3934 DEBUG(5, ("BONG! There was no device mode!\n"));
3938 devmode
= TALLOC_ZERO_P(mem_ctx
, struct spoolss_DeviceMode
);
3940 DEBUG(2,("construct_dev_mode: talloc fail.\n"));
3944 DEBUGADD(8,("loading DEVICEMODE\n"));
3946 result
= convert_nt_devicemode(mem_ctx
, devmode
, printer
->info_2
->devmode
);
3947 if (!W_ERROR_IS_OK(result
)) {
3948 TALLOC_FREE(devmode
);
3952 free_a_printer(&printer
,2);
3957 /********************************************************************
3958 * construct_printer_info3
3959 * fill a spoolss_PrinterInfo3 struct
3960 ********************************************************************/
3962 static WERROR
construct_printer_info3(TALLOC_CTX
*mem_ctx
,
3963 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
3964 struct spoolss_PrinterInfo3
*r
,
3967 /* These are the components of the SD we are returning. */
3969 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
3970 /* don't use talloc_steal() here unless you do a deep steal of all
3971 the SEC_DESC members */
3973 r
->secdesc
= dup_sec_desc(mem_ctx
,
3974 ntprinter
->info_2
->secdesc_buf
->sd
);
3975 W_ERROR_HAVE_NO_MEMORY(r
->secdesc
);
3981 /********************************************************************
3982 * construct_printer_info4
3983 * fill a spoolss_PrinterInfo4 struct
3984 ********************************************************************/
3986 static WERROR
construct_printer_info4(TALLOC_CTX
*mem_ctx
,
3987 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
3988 struct spoolss_PrinterInfo4
*r
,
3991 r
->printername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->printername
);
3992 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
3993 r
->servername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
3994 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
3996 r
->attributes
= ntprinter
->info_2
->attributes
;
4001 /********************************************************************
4002 * construct_printer_info5
4003 * fill a spoolss_PrinterInfo5 struct
4004 ********************************************************************/
4006 static WERROR
construct_printer_info5(TALLOC_CTX
*mem_ctx
,
4007 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
4008 struct spoolss_PrinterInfo5
*r
,
4011 r
->printername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->printername
);
4012 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
4013 r
->portname
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->portname
);
4014 W_ERROR_HAVE_NO_MEMORY(r
->portname
);
4016 r
->attributes
= ntprinter
->info_2
->attributes
;
4018 /* these two are not used by NT+ according to MSDN */
4020 r
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
4021 r
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
4026 /********************************************************************
4027 * construct_printer_info_6
4028 * fill a spoolss_PrinterInfo6 struct
4029 ********************************************************************/
4031 static WERROR
construct_printer_info6(TALLOC_CTX
*mem_ctx
,
4032 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
4033 struct spoolss_PrinterInfo6
*r
,
4037 print_status_struct status
;
4039 count
= print_queue_length(snum
, &status
);
4041 r
->status
= nt_printq_status(status
.status
);
4046 /********************************************************************
4047 * construct_printer_info7
4048 * fill a spoolss_PrinterInfo7 struct
4049 ********************************************************************/
4051 static WERROR
construct_printer_info7(TALLOC_CTX
*mem_ctx
,
4052 Printer_entry
*print_hnd
,
4053 struct spoolss_PrinterInfo7
*r
,
4058 if (is_printer_published(print_hnd
, snum
, &guid
)) {
4059 r
->guid
= talloc_strdup_upper(mem_ctx
, GUID_string2(mem_ctx
, &guid
));
4060 r
->action
= DSPRINT_PUBLISH
;
4062 r
->guid
= talloc_strdup(mem_ctx
, "");
4063 r
->action
= DSPRINT_UNPUBLISH
;
4065 W_ERROR_HAVE_NO_MEMORY(r
->guid
);
4070 /********************************************************************
4071 * construct_printer_info8
4072 * fill a spoolss_PrinterInfo8 struct
4073 ********************************************************************/
4075 static WERROR
construct_printer_info8(TALLOC_CTX
*mem_ctx
,
4076 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
4077 struct spoolss_DeviceModeInfo
*r
,
4080 struct spoolss_DeviceMode
*devmode
;
4083 if (!ntprinter
->info_2
->devmode
) {
4088 devmode
= TALLOC_ZERO_P(mem_ctx
, struct spoolss_DeviceMode
);
4089 W_ERROR_HAVE_NO_MEMORY(devmode
);
4091 result
= convert_nt_devicemode(mem_ctx
, devmode
, ntprinter
->info_2
->devmode
);
4092 if (!W_ERROR_IS_OK(result
)) {
4093 TALLOC_FREE(devmode
);
4097 r
->devmode
= devmode
;
4103 /********************************************************************
4104 * construct_printer_info1
4105 * fill a spoolss_PrinterInfo1 struct
4106 ********************************************************************/
4108 static WERROR
construct_printer_info1(TALLOC_CTX
*mem_ctx
,
4109 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
4111 struct spoolss_PrinterInfo1
*r
,
4116 r
->description
= talloc_asprintf(mem_ctx
, "%s,%s,%s",
4117 ntprinter
->info_2
->printername
,
4118 ntprinter
->info_2
->drivername
,
4119 ntprinter
->info_2
->location
);
4120 W_ERROR_HAVE_NO_MEMORY(r
->description
);
4122 if (*ntprinter
->info_2
->comment
== '\0') {
4123 r
->comment
= talloc_strdup(mem_ctx
, lp_comment(snum
));
4125 r
->comment
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->comment
); /* saved comment */
4127 W_ERROR_HAVE_NO_MEMORY(r
->comment
);
4129 r
->name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->printername
);
4130 W_ERROR_HAVE_NO_MEMORY(r
->name
);
4135 /********************************************************************
4136 * construct_printer_info2
4137 * fill a spoolss_PrinterInfo2 struct
4138 ********************************************************************/
4140 static WERROR
construct_printer_info2(TALLOC_CTX
*mem_ctx
,
4141 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
4142 struct spoolss_PrinterInfo2
*r
,
4147 print_status_struct status
;
4149 count
= print_queue_length(snum
, &status
);
4151 r
->servername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
4152 W_ERROR_HAVE_NO_MEMORY(r
->servername
);
4153 r
->printername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->printername
);
4154 W_ERROR_HAVE_NO_MEMORY(r
->printername
);
4155 r
->sharename
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
4156 W_ERROR_HAVE_NO_MEMORY(r
->sharename
);
4157 r
->portname
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->portname
);
4158 W_ERROR_HAVE_NO_MEMORY(r
->portname
);
4159 r
->drivername
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->drivername
);
4160 W_ERROR_HAVE_NO_MEMORY(r
->drivername
);
4162 if (*ntprinter
->info_2
->comment
== '\0') {
4163 r
->comment
= talloc_strdup(mem_ctx
, lp_comment(snum
));
4165 r
->comment
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->comment
);
4167 W_ERROR_HAVE_NO_MEMORY(r
->comment
);
4169 r
->location
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->location
);
4170 W_ERROR_HAVE_NO_MEMORY(r
->location
);
4171 r
->sepfile
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->sepfile
);
4172 W_ERROR_HAVE_NO_MEMORY(r
->sepfile
);
4173 r
->printprocessor
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->printprocessor
);
4174 W_ERROR_HAVE_NO_MEMORY(r
->printprocessor
);
4175 r
->datatype
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->datatype
);
4176 W_ERROR_HAVE_NO_MEMORY(r
->datatype
);
4177 r
->parameters
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->parameters
);
4178 W_ERROR_HAVE_NO_MEMORY(r
->parameters
);
4180 r
->attributes
= ntprinter
->info_2
->attributes
;
4182 r
->priority
= ntprinter
->info_2
->priority
;
4183 r
->defaultpriority
= ntprinter
->info_2
->default_priority
;
4184 r
->starttime
= ntprinter
->info_2
->starttime
;
4185 r
->untiltime
= ntprinter
->info_2
->untiltime
;
4186 r
->status
= nt_printq_status(status
.status
);
4188 r
->averageppm
= ntprinter
->info_2
->averageppm
;
4190 r
->devmode
= construct_dev_mode(mem_ctx
, lp_const_servicename(snum
));
4192 DEBUG(8,("Returning NULL Devicemode!\n"));
4197 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
4198 /* don't use talloc_steal() here unless you do a deep steal of all
4199 the SEC_DESC members */
4201 r
->secdesc
= dup_sec_desc(mem_ctx
, ntprinter
->info_2
->secdesc_buf
->sd
);
4207 /********************************************************************
4208 ********************************************************************/
4210 static bool snum_is_shared_printer(int snum
)
4212 return (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
));
4215 /********************************************************************
4216 Spoolss_enumprinters.
4217 ********************************************************************/
4219 static WERROR
enum_all_printers_info_level(TALLOC_CTX
*mem_ctx
,
4222 union spoolss_PrinterInfo
**info_p
,
4226 int n_services
= lp_numservices();
4227 union spoolss_PrinterInfo
*info
= NULL
;
4229 WERROR result
= WERR_OK
;
4234 for (snum
= 0; snum
< n_services
; snum
++) {
4236 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4238 if (!snum_is_shared_printer(snum
)) {
4242 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4243 lp_servicename(snum
), snum
));
4245 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
4246 union spoolss_PrinterInfo
,
4249 result
= WERR_NOMEM
;
4253 result
= get_a_printer(NULL
, &ntprinter
, 2,
4254 lp_const_servicename(snum
));
4255 if (!W_ERROR_IS_OK(result
)) {
4261 result
= construct_printer_info0(info
, ntprinter
,
4262 &info
[count
].info0
, snum
);
4265 result
= construct_printer_info1(info
, ntprinter
, flags
,
4266 &info
[count
].info1
, snum
);
4269 result
= construct_printer_info2(info
, ntprinter
,
4270 &info
[count
].info2
, snum
);
4273 result
= construct_printer_info4(info
, ntprinter
,
4274 &info
[count
].info4
, snum
);
4277 result
= construct_printer_info5(info
, ntprinter
,
4278 &info
[count
].info5
, snum
);
4282 result
= WERR_UNKNOWN_LEVEL
;
4283 free_a_printer(&ntprinter
, 2);
4287 free_a_printer(&ntprinter
, 2);
4288 if (!W_ERROR_IS_OK(result
)) {
4299 if (!W_ERROR_IS_OK(result
)) {
4309 /********************************************************************
4310 * handle enumeration of printers at level 0
4311 ********************************************************************/
4313 static WERROR
enumprinters_level0(TALLOC_CTX
*mem_ctx
,
4315 const char *servername
,
4316 union spoolss_PrinterInfo
**info
,
4319 DEBUG(4,("enum_all_printers_info_0\n"));
4321 return enum_all_printers_info_level(mem_ctx
, 0, flags
, info
, count
);
4325 /********************************************************************
4326 ********************************************************************/
4328 static WERROR
enum_all_printers_info_1(TALLOC_CTX
*mem_ctx
,
4330 union spoolss_PrinterInfo
**info
,
4333 DEBUG(4,("enum_all_printers_info_1\n"));
4335 return enum_all_printers_info_level(mem_ctx
, 1, flags
, info
, count
);
4338 /********************************************************************
4339 enum_all_printers_info_1_local.
4340 *********************************************************************/
4342 static WERROR
enum_all_printers_info_1_local(TALLOC_CTX
*mem_ctx
,
4343 union spoolss_PrinterInfo
**info
,
4346 DEBUG(4,("enum_all_printers_info_1_local\n"));
4348 return enum_all_printers_info_1(mem_ctx
, PRINTER_ENUM_ICON8
, info
, count
);
4351 /********************************************************************
4352 enum_all_printers_info_1_name.
4353 *********************************************************************/
4355 static WERROR
enum_all_printers_info_1_name(TALLOC_CTX
*mem_ctx
,
4357 union spoolss_PrinterInfo
**info
,
4360 const char *s
= name
;
4362 DEBUG(4,("enum_all_printers_info_1_name\n"));
4364 if ((name
[0] == '\\') && (name
[1] == '\\')) {
4368 if (!is_myname_or_ipaddr(s
)) {
4369 return WERR_INVALID_NAME
;
4372 return enum_all_printers_info_1(mem_ctx
, PRINTER_ENUM_ICON8
, info
, count
);
4375 /********************************************************************
4376 enum_all_printers_info_1_network.
4377 *********************************************************************/
4379 static WERROR
enum_all_printers_info_1_network(TALLOC_CTX
*mem_ctx
,
4381 union spoolss_PrinterInfo
**info
,
4384 const char *s
= name
;
4386 DEBUG(4,("enum_all_printers_info_1_network\n"));
4388 /* If we respond to a enum_printers level 1 on our name with flags
4389 set to PRINTER_ENUM_REMOTE with a list of printers then these
4390 printers incorrectly appear in the APW browse list.
4391 Specifically the printers for the server appear at the workgroup
4392 level where all the other servers in the domain are
4393 listed. Windows responds to this call with a
4394 WERR_CAN_NOT_COMPLETE so we should do the same. */
4396 if (name
[0] == '\\' && name
[1] == '\\') {
4400 if (is_myname_or_ipaddr(s
)) {
4401 return WERR_CAN_NOT_COMPLETE
;
4404 return enum_all_printers_info_1(mem_ctx
, PRINTER_ENUM_NAME
, info
, count
);
4407 /********************************************************************
4408 * api_spoolss_enumprinters
4410 * called from api_spoolss_enumprinters (see this to understand)
4411 ********************************************************************/
4413 static WERROR
enum_all_printers_info_2(TALLOC_CTX
*mem_ctx
,
4414 union spoolss_PrinterInfo
**info
,
4417 DEBUG(4,("enum_all_printers_info_2\n"));
4419 return enum_all_printers_info_level(mem_ctx
, 2, 0, info
, count
);
4422 /********************************************************************
4423 * handle enumeration of printers at level 1
4424 ********************************************************************/
4426 static WERROR
enumprinters_level1(TALLOC_CTX
*mem_ctx
,
4429 union spoolss_PrinterInfo
**info
,
4432 /* Not all the flags are equals */
4434 if (flags
& PRINTER_ENUM_LOCAL
) {
4435 return enum_all_printers_info_1_local(mem_ctx
, info
, count
);
4438 if (flags
& PRINTER_ENUM_NAME
) {
4439 return enum_all_printers_info_1_name(mem_ctx
, name
, info
, count
);
4442 if (flags
& PRINTER_ENUM_NETWORK
) {
4443 return enum_all_printers_info_1_network(mem_ctx
, name
, info
, count
);
4446 return WERR_OK
; /* NT4sp5 does that */
4449 /********************************************************************
4450 * handle enumeration of printers at level 2
4451 ********************************************************************/
4453 static WERROR
enumprinters_level2(TALLOC_CTX
*mem_ctx
,
4455 const char *servername
,
4456 union spoolss_PrinterInfo
**info
,
4459 if (flags
& PRINTER_ENUM_LOCAL
) {
4460 return enum_all_printers_info_2(mem_ctx
, info
, count
);
4463 if (flags
& PRINTER_ENUM_NAME
) {
4464 if (!is_myname_or_ipaddr(canon_servername(servername
))) {
4465 return WERR_INVALID_NAME
;
4468 return enum_all_printers_info_2(mem_ctx
, info
, count
);
4471 if (flags
& PRINTER_ENUM_REMOTE
) {
4472 return WERR_UNKNOWN_LEVEL
;
4478 /********************************************************************
4479 * handle enumeration of printers at level 4
4480 ********************************************************************/
4482 static WERROR
enumprinters_level4(TALLOC_CTX
*mem_ctx
,
4484 const char *servername
,
4485 union spoolss_PrinterInfo
**info
,
4488 DEBUG(4,("enum_all_printers_info_4\n"));
4490 return enum_all_printers_info_level(mem_ctx
, 4, flags
, info
, count
);
4494 /********************************************************************
4495 * handle enumeration of printers at level 5
4496 ********************************************************************/
4498 static WERROR
enumprinters_level5(TALLOC_CTX
*mem_ctx
,
4500 const char *servername
,
4501 union spoolss_PrinterInfo
**info
,
4504 DEBUG(4,("enum_all_printers_info_5\n"));
4506 return enum_all_printers_info_level(mem_ctx
, 5, flags
, info
, count
);
4509 /****************************************************************
4510 _spoolss_EnumPrinters
4511 ****************************************************************/
4513 WERROR
_spoolss_EnumPrinters(pipes_struct
*p
,
4514 struct spoolss_EnumPrinters
*r
)
4519 /* that's an [in out] buffer */
4521 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4522 return WERR_INVALID_PARAM
;
4525 DEBUG(4,("_spoolss_EnumPrinters\n"));
4529 *r
->out
.info
= NULL
;
4533 * flags==PRINTER_ENUM_NAME
4534 * if name=="" then enumerates all printers
4535 * if name!="" then enumerate the printer
4536 * flags==PRINTER_ENUM_REMOTE
4537 * name is NULL, enumerate printers
4538 * Level 2: name!="" enumerates printers, name can't be NULL
4539 * Level 3: doesn't exist
4540 * Level 4: does a local registry lookup
4541 * Level 5: same as Level 2
4544 name
= talloc_strdup_upper(p
->mem_ctx
, r
->in
.server
);
4545 W_ERROR_HAVE_NO_MEMORY(name
);
4547 switch (r
->in
.level
) {
4549 result
= enumprinters_level0(p
->mem_ctx
, r
->in
.flags
, name
,
4550 r
->out
.info
, r
->out
.count
);
4553 result
= enumprinters_level1(p
->mem_ctx
, r
->in
.flags
, name
,
4554 r
->out
.info
, r
->out
.count
);
4557 result
= enumprinters_level2(p
->mem_ctx
, r
->in
.flags
, name
,
4558 r
->out
.info
, r
->out
.count
);
4561 result
= enumprinters_level4(p
->mem_ctx
, r
->in
.flags
, name
,
4562 r
->out
.info
, r
->out
.count
);
4565 result
= enumprinters_level5(p
->mem_ctx
, r
->in
.flags
, name
,
4566 r
->out
.info
, r
->out
.count
);
4569 return WERR_UNKNOWN_LEVEL
;
4572 if (!W_ERROR_IS_OK(result
)) {
4576 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
4577 spoolss_EnumPrinters
, NULL
,
4578 *r
->out
.info
, r
->in
.level
,
4580 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
4581 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
4583 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4586 /****************************************************************
4588 ****************************************************************/
4590 WERROR
_spoolss_GetPrinter(pipes_struct
*p
,
4591 struct spoolss_GetPrinter
*r
)
4593 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
4594 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4595 WERROR result
= WERR_OK
;
4599 /* that's an [in out] buffer */
4601 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
4602 return WERR_INVALID_PARAM
;
4607 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
4611 result
= get_a_printer(Printer
, &ntprinter
, 2,
4612 lp_const_servicename(snum
));
4613 if (!W_ERROR_IS_OK(result
)) {
4617 switch (r
->in
.level
) {
4619 result
= construct_printer_info0(p
->mem_ctx
, ntprinter
,
4620 &r
->out
.info
->info0
, snum
);
4623 result
= construct_printer_info1(p
->mem_ctx
, ntprinter
,
4625 &r
->out
.info
->info1
, snum
);
4628 result
= construct_printer_info2(p
->mem_ctx
, ntprinter
,
4629 &r
->out
.info
->info2
, snum
);
4632 result
= construct_printer_info3(p
->mem_ctx
, ntprinter
,
4633 &r
->out
.info
->info3
, snum
);
4636 result
= construct_printer_info4(p
->mem_ctx
, ntprinter
,
4637 &r
->out
.info
->info4
, snum
);
4640 result
= construct_printer_info5(p
->mem_ctx
, ntprinter
,
4641 &r
->out
.info
->info5
, snum
);
4644 result
= construct_printer_info6(p
->mem_ctx
, ntprinter
,
4645 &r
->out
.info
->info6
, snum
);
4648 result
= construct_printer_info7(p
->mem_ctx
, Printer
,
4649 &r
->out
.info
->info7
, snum
);
4652 result
= construct_printer_info8(p
->mem_ctx
, ntprinter
,
4653 &r
->out
.info
->info8
, snum
);
4656 result
= WERR_UNKNOWN_LEVEL
;
4660 free_a_printer(&ntprinter
, 2);
4662 if (!W_ERROR_IS_OK(result
)) {
4663 TALLOC_FREE(r
->out
.info
);
4667 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo
, NULL
,
4668 r
->out
.info
, r
->in
.level
);
4669 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
4671 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
4674 /********************************************************************
4675 ********************************************************************/
4677 static const char **string_array_from_driver_info(TALLOC_CTX
*mem_ctx
,
4678 fstring
*fstring_array
,
4679 const char *cservername
)
4681 int i
, num_strings
= 0;
4682 const char **array
= NULL
;
4684 for (i
=0; fstring_array
&& fstring_array
[i
][0] != '\0'; i
++) {
4686 const char *str
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4687 cservername
, fstring_array
[i
]);
4694 if (!add_string_to_array(mem_ctx
, str
, &array
, &num_strings
)) {
4701 ADD_TO_ARRAY(mem_ctx
, const char *, NULL
,
4702 &array
, &num_strings
);
4708 /********************************************************************
4709 * fill a spoolss_DriverInfo1 struct
4710 ********************************************************************/
4712 static WERROR
fill_printer_driver_info1(TALLOC_CTX
*mem_ctx
,
4713 struct spoolss_DriverInfo1
*r
,
4714 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
4715 const char *servername
,
4716 const char *architecture
)
4718 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
4719 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4724 /********************************************************************
4725 * fill a spoolss_DriverInfo2 struct
4726 ********************************************************************/
4728 static WERROR
fill_printer_driver_info2(TALLOC_CTX
*mem_ctx
,
4729 struct spoolss_DriverInfo2
*r
,
4730 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
4731 const char *servername
)
4734 const char *cservername
= canon_servername(servername
);
4736 r
->version
= driver
->info_3
->cversion
;
4738 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
4739 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4740 r
->architecture
= talloc_strdup(mem_ctx
, driver
->info_3
->environment
);
4741 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4743 if (strlen(driver
->info_3
->driverpath
)) {
4744 r
->driver_path
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4745 cservername
, driver
->info_3
->driverpath
);
4747 r
->driver_path
= talloc_strdup(mem_ctx
, "");
4749 W_ERROR_HAVE_NO_MEMORY(r
->driver_path
);
4751 if (strlen(driver
->info_3
->datafile
)) {
4752 r
->data_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4753 cservername
, driver
->info_3
->datafile
);
4755 r
->data_file
= talloc_strdup(mem_ctx
, "");
4757 W_ERROR_HAVE_NO_MEMORY(r
->data_file
);
4759 if (strlen(driver
->info_3
->configfile
)) {
4760 r
->config_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4761 cservername
, driver
->info_3
->configfile
);
4763 r
->config_file
= talloc_strdup(mem_ctx
, "");
4765 W_ERROR_HAVE_NO_MEMORY(r
->config_file
);
4770 /********************************************************************
4771 * fill a spoolss_DriverInfo3 struct
4772 ********************************************************************/
4774 static WERROR
fill_printer_driver_info3(TALLOC_CTX
*mem_ctx
,
4775 struct spoolss_DriverInfo3
*r
,
4776 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
4777 const char *servername
)
4779 const char *cservername
= canon_servername(servername
);
4781 r
->version
= driver
->info_3
->cversion
;
4783 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
4784 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4785 r
->architecture
= talloc_strdup(mem_ctx
, driver
->info_3
->environment
);
4786 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4788 if (strlen(driver
->info_3
->driverpath
)) {
4789 r
->driver_path
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4790 cservername
, driver
->info_3
->driverpath
);
4792 r
->driver_path
= talloc_strdup(mem_ctx
, "");
4794 W_ERROR_HAVE_NO_MEMORY(r
->driver_path
);
4796 if (strlen(driver
->info_3
->datafile
)) {
4797 r
->data_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4798 cservername
, driver
->info_3
->datafile
);
4800 r
->data_file
= talloc_strdup(mem_ctx
, "");
4802 W_ERROR_HAVE_NO_MEMORY(r
->data_file
);
4804 if (strlen(driver
->info_3
->configfile
)) {
4805 r
->config_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4806 cservername
, driver
->info_3
->configfile
);
4808 r
->config_file
= talloc_strdup(mem_ctx
, "");
4810 W_ERROR_HAVE_NO_MEMORY(r
->config_file
);
4812 if (strlen(driver
->info_3
->helpfile
)) {
4813 r
->help_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4814 cservername
, driver
->info_3
->helpfile
);
4816 r
->help_file
= talloc_strdup(mem_ctx
, "");
4818 W_ERROR_HAVE_NO_MEMORY(r
->help_file
);
4820 r
->monitor_name
= talloc_strdup(mem_ctx
, driver
->info_3
->monitorname
);
4821 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
4822 r
->default_datatype
= talloc_strdup(mem_ctx
, driver
->info_3
->defaultdatatype
);
4823 W_ERROR_HAVE_NO_MEMORY(r
->default_datatype
);
4825 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
4826 driver
->info_3
->dependentfiles
,
4831 /********************************************************************
4832 * fill a spoolss_DriverInfo4 struct
4833 ********************************************************************/
4835 static WERROR
fill_printer_driver_info4(TALLOC_CTX
*mem_ctx
,
4836 struct spoolss_DriverInfo4
*r
,
4837 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
4838 const char *servername
)
4840 const char *cservername
= canon_servername(servername
);
4842 r
->version
= driver
->info_3
->cversion
;
4844 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
4845 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4846 r
->architecture
= talloc_strdup(mem_ctx
, driver
->info_3
->environment
);
4847 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4849 if (strlen(driver
->info_3
->driverpath
)) {
4850 r
->driver_path
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4851 cservername
, driver
->info_3
->driverpath
);
4853 r
->driver_path
= talloc_strdup(mem_ctx
, "");
4855 W_ERROR_HAVE_NO_MEMORY(r
->driver_path
);
4857 if (strlen(driver
->info_3
->datafile
)) {
4858 r
->data_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4859 cservername
, driver
->info_3
->datafile
);
4861 r
->data_file
= talloc_strdup(mem_ctx
, "");
4863 W_ERROR_HAVE_NO_MEMORY(r
->data_file
);
4865 if (strlen(driver
->info_3
->configfile
)) {
4866 r
->config_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4867 cservername
, driver
->info_3
->configfile
);
4869 r
->config_file
= talloc_strdup(mem_ctx
, "");
4871 W_ERROR_HAVE_NO_MEMORY(r
->config_file
);
4873 if (strlen(driver
->info_3
->helpfile
)) {
4874 r
->help_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4875 cservername
, driver
->info_3
->helpfile
);
4877 r
->help_file
= talloc_strdup(mem_ctx
, "");
4879 W_ERROR_HAVE_NO_MEMORY(r
->help_file
);
4881 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
4882 driver
->info_3
->dependentfiles
,
4886 r
->monitor_name
= talloc_strdup(mem_ctx
, driver
->info_3
->monitorname
);
4887 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
4888 r
->default_datatype
= talloc_strdup(mem_ctx
, driver
->info_3
->defaultdatatype
);
4889 W_ERROR_HAVE_NO_MEMORY(r
->default_datatype
);
4891 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
4898 /********************************************************************
4899 * fill a spoolss_DriverInfo5 struct
4900 ********************************************************************/
4902 static WERROR
fill_printer_driver_info5(TALLOC_CTX
*mem_ctx
,
4903 struct spoolss_DriverInfo5
*r
,
4904 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
4905 const char *servername
)
4907 const char *cservername
= canon_servername(servername
);
4909 r
->version
= driver
->info_3
->cversion
;
4911 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
4912 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4913 r
->architecture
= talloc_strdup(mem_ctx
, driver
->info_3
->environment
);
4914 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4916 if (strlen(driver
->info_3
->driverpath
)) {
4917 r
->driver_path
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4918 cservername
, driver
->info_3
->driverpath
);
4920 r
->driver_path
= talloc_strdup(mem_ctx
, "");
4922 W_ERROR_HAVE_NO_MEMORY(r
->driver_path
);
4924 if (strlen(driver
->info_3
->datafile
)) {
4925 r
->data_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4926 cservername
, driver
->info_3
->datafile
);
4928 r
->data_file
= talloc_strdup(mem_ctx
, "");
4930 W_ERROR_HAVE_NO_MEMORY(r
->data_file
);
4932 if (strlen(driver
->info_3
->configfile
)) {
4933 r
->config_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4934 cservername
, driver
->info_3
->configfile
);
4936 r
->config_file
= talloc_strdup(mem_ctx
, "");
4938 W_ERROR_HAVE_NO_MEMORY(r
->config_file
);
4940 r
->driver_attributes
= 0;
4941 r
->config_version
= 0;
4942 r
->driver_version
= 0;
4946 /********************************************************************
4947 * fill a spoolss_DriverInfo6 struct
4948 ********************************************************************/
4950 static WERROR
fill_printer_driver_info6(TALLOC_CTX
*mem_ctx
,
4951 struct spoolss_DriverInfo6
*r
,
4952 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
4953 const char *servername
)
4955 const char *cservername
= canon_servername(servername
);
4957 r
->version
= driver
->info_3
->cversion
;
4959 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
4960 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
4961 r
->architecture
= talloc_strdup(mem_ctx
, driver
->info_3
->environment
);
4962 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
4964 if (strlen(driver
->info_3
->driverpath
)) {
4965 r
->driver_path
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4966 cservername
, driver
->info_3
->driverpath
);
4968 r
->driver_path
= talloc_strdup(mem_ctx
, "");
4970 W_ERROR_HAVE_NO_MEMORY(r
->driver_path
);
4972 if (strlen(driver
->info_3
->datafile
)) {
4973 r
->data_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4974 cservername
, driver
->info_3
->datafile
);
4976 r
->data_file
= talloc_strdup(mem_ctx
, "");
4978 W_ERROR_HAVE_NO_MEMORY(r
->data_file
);
4980 if (strlen(driver
->info_3
->configfile
)) {
4981 r
->config_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4982 cservername
, driver
->info_3
->configfile
);
4984 r
->config_file
= talloc_strdup(mem_ctx
, "");
4986 W_ERROR_HAVE_NO_MEMORY(r
->config_file
);
4988 if (strlen(driver
->info_3
->helpfile
)) {
4989 r
->help_file
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
4990 cservername
, driver
->info_3
->helpfile
);
4992 r
->help_file
= talloc_strdup(mem_ctx
, "");
4994 W_ERROR_HAVE_NO_MEMORY(r
->help_file
);
4996 r
->monitor_name
= talloc_strdup(mem_ctx
, driver
->info_3
->monitorname
);
4997 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
4998 r
->default_datatype
= talloc_strdup(mem_ctx
, driver
->info_3
->defaultdatatype
);
4999 W_ERROR_HAVE_NO_MEMORY(r
->default_datatype
);
5001 r
->dependent_files
= string_array_from_driver_info(mem_ctx
,
5002 driver
->info_3
->dependentfiles
,
5004 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
5009 r
->driver_version
= 0;
5011 r
->manufacturer_name
= talloc_strdup(mem_ctx
, "");
5012 W_ERROR_HAVE_NO_MEMORY(r
->manufacturer_name
);
5013 r
->manufacturer_url
= talloc_strdup(mem_ctx
, "");
5014 W_ERROR_HAVE_NO_MEMORY(r
->manufacturer_url
);
5015 r
->hardware_id
= talloc_strdup(mem_ctx
, "");
5016 W_ERROR_HAVE_NO_MEMORY(r
->hardware_id
);
5017 r
->provider
= talloc_strdup(mem_ctx
, "");
5018 W_ERROR_HAVE_NO_MEMORY(r
->provider
);
5023 /********************************************************************
5024 ********************************************************************/
5026 static WERROR
fill_spoolss_DriverFileInfo(TALLOC_CTX
*mem_ctx
,
5027 struct spoolss_DriverFileInfo
*r
,
5028 const char *cservername
,
5029 const char *file_name
,
5030 enum spoolss_DriverFileType file_type
,
5031 uint32_t file_version
)
5033 r
->file_name
= talloc_asprintf(mem_ctx
, "\\\\%s%s",
5034 cservername
, file_name
);
5035 W_ERROR_HAVE_NO_MEMORY(r
->file_name
);
5036 r
->file_type
= file_type
;
5037 r
->file_version
= file_version
;
5042 /********************************************************************
5043 ********************************************************************/
5045 static WERROR
spoolss_DriverFileInfo_from_driver(TALLOC_CTX
*mem_ctx
,
5046 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
5047 const char *cservername
,
5048 struct spoolss_DriverFileInfo
**info_p
,
5051 struct spoolss_DriverFileInfo
*info
= NULL
;
5059 if (strlen(driver
->info_3
->driverpath
)) {
5060 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
5061 struct spoolss_DriverFileInfo
,
5063 W_ERROR_HAVE_NO_MEMORY(info
);
5064 result
= fill_spoolss_DriverFileInfo(info
,
5067 driver
->info_3
->driverpath
,
5068 SPOOLSS_DRIVER_FILE_TYPE_RENDERING
,
5070 W_ERROR_NOT_OK_RETURN(result
);
5074 if (strlen(driver
->info_3
->configfile
)) {
5075 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
5076 struct spoolss_DriverFileInfo
,
5078 W_ERROR_HAVE_NO_MEMORY(info
);
5079 result
= fill_spoolss_DriverFileInfo(info
,
5082 driver
->info_3
->configfile
,
5083 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION
,
5085 W_ERROR_NOT_OK_RETURN(result
);
5089 if (strlen(driver
->info_3
->datafile
)) {
5090 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
5091 struct spoolss_DriverFileInfo
,
5093 W_ERROR_HAVE_NO_MEMORY(info
);
5094 result
= fill_spoolss_DriverFileInfo(info
,
5097 driver
->info_3
->datafile
,
5098 SPOOLSS_DRIVER_FILE_TYPE_DATA
,
5100 W_ERROR_NOT_OK_RETURN(result
);
5104 if (strlen(driver
->info_3
->helpfile
)) {
5105 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
5106 struct spoolss_DriverFileInfo
,
5108 W_ERROR_HAVE_NO_MEMORY(info
);
5109 result
= fill_spoolss_DriverFileInfo(info
,
5112 driver
->info_3
->helpfile
,
5113 SPOOLSS_DRIVER_FILE_TYPE_HELP
,
5115 W_ERROR_NOT_OK_RETURN(result
);
5119 for (i
=0; driver
->info_3
->dependentfiles
[i
][0] != '\0'; i
++) {
5120 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
5121 struct spoolss_DriverFileInfo
,
5123 W_ERROR_HAVE_NO_MEMORY(info
);
5124 result
= fill_spoolss_DriverFileInfo(info
,
5127 driver
->info_3
->dependentfiles
[i
],
5128 SPOOLSS_DRIVER_FILE_TYPE_OTHER
,
5130 W_ERROR_NOT_OK_RETURN(result
);
5140 /********************************************************************
5141 * fill a spoolss_DriverInfo101 sttruct
5142 ********************************************************************/
5144 static WERROR
fill_printer_driver_info101(TALLOC_CTX
*mem_ctx
,
5145 struct spoolss_DriverInfo101
*r
,
5146 const NT_PRINTER_DRIVER_INFO_LEVEL
*driver
,
5147 const char *servername
)
5149 const char *cservername
= canon_servername(servername
);
5152 r
->version
= driver
->info_3
->cversion
;
5154 r
->driver_name
= talloc_strdup(mem_ctx
, driver
->info_3
->name
);
5155 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
5156 r
->architecture
= talloc_strdup(mem_ctx
, driver
->info_3
->environment
);
5157 W_ERROR_HAVE_NO_MEMORY(r
->architecture
);
5159 result
= spoolss_DriverFileInfo_from_driver(mem_ctx
, driver
,
5163 if (!W_ERROR_IS_OK(result
)) {
5167 r
->monitor_name
= talloc_strdup(mem_ctx
, driver
->info_3
->monitorname
);
5168 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
5170 r
->default_datatype
= talloc_strdup(mem_ctx
, driver
->info_3
->defaultdatatype
);
5171 W_ERROR_HAVE_NO_MEMORY(r
->default_datatype
);
5173 r
->previous_names
= string_array_from_driver_info(mem_ctx
,
5177 r
->driver_version
= 0;
5179 r
->manufacturer_name
= talloc_strdup(mem_ctx
, "");
5180 W_ERROR_HAVE_NO_MEMORY(r
->manufacturer_name
);
5181 r
->manufacturer_url
= talloc_strdup(mem_ctx
, "");
5182 W_ERROR_HAVE_NO_MEMORY(r
->manufacturer_url
);
5183 r
->hardware_id
= talloc_strdup(mem_ctx
, "");
5184 W_ERROR_HAVE_NO_MEMORY(r
->hardware_id
);
5185 r
->provider
= talloc_strdup(mem_ctx
, "");
5186 W_ERROR_HAVE_NO_MEMORY(r
->provider
);
5191 /********************************************************************
5192 * construct_printer_driver_info_1
5193 ********************************************************************/
5195 static WERROR
construct_printer_driver_info_1(TALLOC_CTX
*mem_ctx
,
5196 struct spoolss_DriverInfo1
*r
,
5198 const char *servername
,
5199 const char *architecture
,
5202 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5203 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5206 ZERO_STRUCT(driver
);
5208 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5209 return WERR_INVALID_PRINTER_NAME
;
5211 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5212 free_a_printer(&printer
, 2);
5213 return WERR_UNKNOWN_PRINTER_DRIVER
;
5216 result
= fill_printer_driver_info1(mem_ctx
, r
, &driver
, servername
, architecture
);
5218 free_a_printer(&printer
,2);
5223 /********************************************************************
5224 * construct_printer_driver_info_2
5225 * fill a printer_info_2 struct
5226 ********************************************************************/
5228 static WERROR
construct_printer_driver_info_2(TALLOC_CTX
*mem_ctx
,
5229 struct spoolss_DriverInfo2
*r
,
5231 const char *servername
,
5232 const char *architecture
,
5235 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5236 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5239 ZERO_STRUCT(printer
);
5240 ZERO_STRUCT(driver
);
5242 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5243 return WERR_INVALID_PRINTER_NAME
;
5245 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5246 free_a_printer(&printer
, 2);
5247 return WERR_UNKNOWN_PRINTER_DRIVER
;
5250 result
= fill_printer_driver_info2(mem_ctx
, r
, &driver
, servername
);
5252 free_a_printer(&printer
,2);
5257 /********************************************************************
5258 * construct_printer_info_3
5259 * fill a printer_info_3 struct
5260 ********************************************************************/
5262 static WERROR
construct_printer_driver_info_3(TALLOC_CTX
*mem_ctx
,
5263 struct spoolss_DriverInfo3
*r
,
5265 const char *servername
,
5266 const char *architecture
,
5269 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5270 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5272 ZERO_STRUCT(driver
);
5274 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5275 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5276 if (!W_ERROR_IS_OK(status
))
5277 return WERR_INVALID_PRINTER_NAME
;
5279 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5280 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5285 * I put this code in during testing. Helpful when commenting out the
5286 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5287 * as win2k always queries the driver using an infor level of 6.
5288 * I've left it in (but ifdef'd out) because I'll probably
5289 * use it in experimentation again in the future. --jerry 22/01/2002
5292 if (!W_ERROR_IS_OK(status
)) {
5294 * Is this a W2k client ?
5297 /* Yes - try again with a WinNT driver. */
5299 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5300 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status
)));
5304 if (!W_ERROR_IS_OK(status
)) {
5305 free_a_printer(&printer
,2);
5306 return WERR_UNKNOWN_PRINTER_DRIVER
;
5314 status
= fill_printer_driver_info3(mem_ctx
, r
, &driver
, servername
);
5316 free_a_printer(&printer
,2);
5321 /********************************************************************
5322 * construct_printer_info_6
5323 * fill a printer_info_6 struct
5324 ********************************************************************/
5326 static WERROR
construct_printer_driver_info_6(TALLOC_CTX
*mem_ctx
,
5327 struct spoolss_DriverInfo6
*r
,
5329 const char *servername
,
5330 const char *architecture
,
5333 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5334 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5337 ZERO_STRUCT(driver
);
5339 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5341 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5343 if (!W_ERROR_IS_OK(status
))
5344 return WERR_INVALID_PRINTER_NAME
;
5346 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5348 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5350 if (!W_ERROR_IS_OK(status
))
5353 * Is this a W2k client ?
5357 free_a_printer(&printer
,2);
5358 return WERR_UNKNOWN_PRINTER_DRIVER
;
5361 /* Yes - try again with a WinNT driver. */
5363 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5364 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status
)));
5365 if (!W_ERROR_IS_OK(status
)) {
5366 free_a_printer(&printer
,2);
5367 return WERR_UNKNOWN_PRINTER_DRIVER
;
5371 status
= fill_printer_driver_info6(mem_ctx
, r
, &driver
, servername
);
5373 free_a_printer(&printer
,2);
5374 free_a_printer_driver(driver
, 3);
5379 /********************************************************************
5380 * construct_printer_info_101
5381 * fill a printer_info_101 struct
5382 ********************************************************************/
5384 static WERROR
construct_printer_driver_info_101(TALLOC_CTX
*mem_ctx
,
5385 struct spoolss_DriverInfo101
*r
,
5387 const char *servername
,
5388 const char *architecture
,
5391 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5392 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5395 ZERO_STRUCT(driver
);
5397 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
5399 DEBUG(8,("construct_printer_driver_info_101: status: %s\n",
5400 win_errstr(result
)));
5402 if (!W_ERROR_IS_OK(result
)) {
5403 return WERR_INVALID_PRINTER_NAME
;
5406 result
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
,
5407 architecture
, version
);
5409 DEBUG(8,("construct_printer_driver_info_101: status: %s\n",
5410 win_errstr(result
)));
5412 if (!W_ERROR_IS_OK(result
)) {
5414 * Is this a W2k client ?
5418 free_a_printer(&printer
, 2);
5419 return WERR_UNKNOWN_PRINTER_DRIVER
;
5422 /* Yes - try again with a WinNT driver. */
5424 result
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
,
5425 architecture
, version
);
5426 DEBUG(8,("construct_printer_driver_info_6: status: %s\n",
5427 win_errstr(result
)));
5428 if (!W_ERROR_IS_OK(result
)) {
5429 free_a_printer(&printer
, 2);
5430 return WERR_UNKNOWN_PRINTER_DRIVER
;
5434 result
= fill_printer_driver_info101(mem_ctx
, r
, &driver
, servername
);
5436 free_a_printer(&printer
, 2);
5437 free_a_printer_driver(driver
, 3);
5442 /****************************************************************
5443 _spoolss_GetPrinterDriver2
5444 ****************************************************************/
5446 WERROR
_spoolss_GetPrinterDriver2(pipes_struct
*p
,
5447 struct spoolss_GetPrinterDriver2
*r
)
5449 Printer_entry
*printer
;
5452 const char *servername
;
5455 /* that's an [in out] buffer */
5457 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
5458 return WERR_INVALID_PARAM
;
5461 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5463 if (!(printer
= find_printer_index_by_hnd(p
, r
->in
.handle
))) {
5464 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5465 return WERR_INVALID_PRINTER_NAME
;
5469 *r
->out
.server_major_version
= 0;
5470 *r
->out
.server_minor_version
= 0;
5472 servername
= get_server_name(printer
);
5474 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5478 switch (r
->in
.level
) {
5480 result
= construct_printer_driver_info_1(p
->mem_ctx
,
5481 &r
->out
.info
->info1
,
5485 r
->in
.client_major_version
);
5488 result
= construct_printer_driver_info_2(p
->mem_ctx
,
5489 &r
->out
.info
->info2
,
5493 r
->in
.client_major_version
);
5496 result
= construct_printer_driver_info_3(p
->mem_ctx
,
5497 &r
->out
.info
->info3
,
5501 r
->in
.client_major_version
);
5504 result
= construct_printer_driver_info_6(p
->mem_ctx
,
5505 &r
->out
.info
->info6
,
5509 r
->in
.client_major_version
);
5512 result
= construct_printer_driver_info_101(p
->mem_ctx
,
5513 &r
->out
.info
->info101
,
5517 r
->in
.client_major_version
);
5520 result
= WERR_UNKNOWN_LEVEL
;
5524 if (!W_ERROR_IS_OK(result
)) {
5525 TALLOC_FREE(r
->out
.info
);
5529 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_DriverInfo
, NULL
,
5530 r
->out
.info
, r
->in
.level
);
5531 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
5533 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
5537 /****************************************************************
5538 _spoolss_StartPagePrinter
5539 ****************************************************************/
5541 WERROR
_spoolss_StartPagePrinter(pipes_struct
*p
,
5542 struct spoolss_StartPagePrinter
*r
)
5544 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5547 DEBUG(3,("_spoolss_StartPagePrinter: "
5548 "Error in startpageprinter printer handle\n"));
5552 Printer
->page_started
= true;
5556 /****************************************************************
5557 _spoolss_EndPagePrinter
5558 ****************************************************************/
5560 WERROR
_spoolss_EndPagePrinter(pipes_struct
*p
,
5561 struct spoolss_EndPagePrinter
*r
)
5565 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5568 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5569 OUR_HANDLE(r
->in
.handle
)));
5573 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5576 Printer
->page_started
= false;
5577 print_job_endpage(snum
, Printer
->jobid
);
5582 /****************************************************************
5583 _spoolss_StartDocPrinter
5584 ****************************************************************/
5586 WERROR
_spoolss_StartDocPrinter(pipes_struct
*p
,
5587 struct spoolss_StartDocPrinter
*r
)
5589 struct spoolss_DocumentInfo1
*info_1
;
5591 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5594 DEBUG(2,("_spoolss_StartDocPrinter: "
5595 "Invalid handle (%s:%u:%u)\n",
5596 OUR_HANDLE(r
->in
.handle
)));
5600 if (r
->in
.level
!= 1) {
5601 return WERR_UNKNOWN_LEVEL
;
5604 info_1
= r
->in
.info
.info1
;
5607 * a nice thing with NT is it doesn't listen to what you tell it.
5608 * when asked to send _only_ RAW datas, it tries to send datas
5611 * So I add checks like in NT Server ...
5614 if (info_1
->datatype
) {
5615 if (strcmp(info_1
->datatype
, "RAW") != 0) {
5617 return WERR_INVALID_DATATYPE
;
5621 /* get the share number of the printer */
5622 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5626 Printer
->jobid
= print_job_start(p
->server_info
, snum
,
5627 info_1
->document_name
,
5628 Printer
->nt_devmode
);
5630 /* An error occured in print_job_start() so return an appropriate
5633 if (Printer
->jobid
== -1) {
5634 return map_werror_from_unix(errno
);
5637 Printer
->document_started
= true;
5638 *r
->out
.job_id
= Printer
->jobid
;
5643 /****************************************************************
5644 _spoolss_EndDocPrinter
5645 ****************************************************************/
5647 WERROR
_spoolss_EndDocPrinter(pipes_struct
*p
,
5648 struct spoolss_EndDocPrinter
*r
)
5650 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5654 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5655 OUR_HANDLE(r
->in
.handle
)));
5659 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
5663 Printer
->document_started
= false;
5664 print_job_end(snum
, Printer
->jobid
, NORMAL_CLOSE
);
5665 /* error codes unhandled so far ... */
5670 /****************************************************************
5671 _spoolss_WritePrinter
5672 ****************************************************************/
5674 WERROR
_spoolss_WritePrinter(pipes_struct
*p
,
5675 struct spoolss_WritePrinter
*r
)
5677 uint32_t buffer_written
;
5679 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5682 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5683 OUR_HANDLE(r
->in
.handle
)));
5684 *r
->out
.num_written
= r
->in
._data_size
;
5688 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5691 buffer_written
= (uint32_t)print_job_write(snum
, Printer
->jobid
,
5692 (const char *)r
->in
.data
.data
,
5694 (size_t)r
->in
._data_size
);
5695 if (buffer_written
== (uint32_t)-1) {
5696 *r
->out
.num_written
= 0;
5697 if (errno
== ENOSPC
)
5698 return WERR_NO_SPOOL_SPACE
;
5700 return WERR_ACCESS_DENIED
;
5703 *r
->out
.num_written
= r
->in
._data_size
;
5708 /********************************************************************
5709 * api_spoolss_getprinter
5710 * called from the spoolss dispatcher
5712 ********************************************************************/
5714 static WERROR
control_printer(struct policy_handle
*handle
, uint32_t command
,
5718 WERROR errcode
= WERR_BADFUNC
;
5719 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5722 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5723 OUR_HANDLE(handle
)));
5727 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5731 case SPOOLSS_PRINTER_CONTROL_PAUSE
:
5732 errcode
= print_queue_pause(p
->server_info
, snum
);
5734 case SPOOLSS_PRINTER_CONTROL_RESUME
:
5735 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
:
5736 errcode
= print_queue_resume(p
->server_info
, snum
);
5738 case SPOOLSS_PRINTER_CONTROL_PURGE
:
5739 errcode
= print_queue_purge(p
->server_info
, snum
);
5742 return WERR_UNKNOWN_LEVEL
;
5749 /****************************************************************
5750 _spoolss_AbortPrinter
5751 * From MSDN: "Deletes printer's spool file if printer is configured
5753 ****************************************************************/
5755 WERROR
_spoolss_AbortPrinter(pipes_struct
*p
,
5756 struct spoolss_AbortPrinter
*r
)
5758 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
5760 WERROR errcode
= WERR_OK
;
5763 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5764 OUR_HANDLE(r
->in
.handle
)));
5768 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
5771 print_job_delete(p
->server_info
, snum
, Printer
->jobid
, &errcode
);
5776 /********************************************************************
5777 * called by spoolss_api_setprinter
5778 * when updating a printer description
5779 ********************************************************************/
5781 static WERROR
update_printer_sec(struct policy_handle
*handle
,
5782 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
5784 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
5788 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5790 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
5791 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5792 OUR_HANDLE(handle
)));
5794 result
= WERR_BADFID
;
5799 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5800 result
= WERR_INVALID_PARAM
;
5804 /* Check the user has permissions to change the security
5805 descriptor. By experimentation with two NT machines, the user
5806 requires Full Access to the printer to change security
5809 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
5810 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5811 result
= WERR_ACCESS_DENIED
;
5815 /* NT seems to like setting the security descriptor even though
5816 nothing may have actually changed. */
5818 if ( !nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
)) {
5819 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5820 result
= WERR_BADFID
;
5824 if (DEBUGLEVEL
>= 10) {
5828 the_acl
= old_secdesc_ctr
->sd
->dacl
;
5829 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5830 PRINTERNAME(snum
), the_acl
->num_aces
));
5832 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5833 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5834 &the_acl
->aces
[i
].trustee
),
5835 the_acl
->aces
[i
].access_mask
));
5838 the_acl
= secdesc_ctr
->sd
->dacl
;
5841 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5842 PRINTERNAME(snum
), the_acl
->num_aces
));
5844 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5845 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5846 &the_acl
->aces
[i
].trustee
),
5847 the_acl
->aces
[i
].access_mask
));
5850 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5854 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
5855 if (!new_secdesc_ctr
) {
5856 result
= WERR_NOMEM
;
5860 if (security_descriptor_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
5865 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
5872 /********************************************************************
5873 Canonicalize printer info from a client
5875 ATTN: It does not matter what we set the servername to hear
5876 since we do the necessary work in get_a_printer() to set it to
5877 the correct value based on what the client sent in the
5878 _spoolss_open_printer_ex().
5879 ********************************************************************/
5881 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
5883 fstring printername
;
5886 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5887 "portname=%s drivername=%s comment=%s location=%s\n",
5888 info
->servername
, info
->printername
, info
->sharename
,
5889 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
5891 /* we force some elements to "correct" values */
5892 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
5893 fstrcpy(info
->sharename
, lp_servicename(snum
));
5895 /* check to see if we allow printername != sharename */
5897 if ( lp_force_printername(snum
) ) {
5898 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
5899 global_myname(), info
->sharename
);
5902 /* make sure printername is in \\server\printername format */
5904 fstrcpy( printername
, info
->printername
);
5906 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
5907 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
5911 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
5912 global_myname(), p
);
5915 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
5916 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
5923 /****************************************************************************
5924 ****************************************************************************/
5926 static WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
5928 char *cmd
= lp_addport_cmd();
5929 char *command
= NULL
;
5931 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
5932 bool is_print_op
= false;
5935 return WERR_ACCESS_DENIED
;
5938 command
= talloc_asprintf(ctx
,
5939 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
5945 is_print_op
= user_has_privileges( token
, &se_printop
);
5947 DEBUG(10,("Running [%s]\n", command
));
5949 /********* BEGIN SePrintOperatorPrivilege **********/
5954 ret
= smbrun(command
, NULL
);
5959 /********* END SePrintOperatorPrivilege **********/
5961 DEBUGADD(10,("returned [%d]\n", ret
));
5963 TALLOC_FREE(command
);
5966 return WERR_ACCESS_DENIED
;
5972 /****************************************************************************
5973 ****************************************************************************/
5975 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
5977 char *cmd
= lp_addprinter_cmd();
5979 char *command
= NULL
;
5983 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
5984 bool is_print_op
= false;
5985 char *remote_machine
= talloc_strdup(ctx
, "%m");
5987 if (!remote_machine
) {
5990 remote_machine
= talloc_sub_basic(ctx
,
5991 current_user_info
.smb_name
,
5992 current_user_info
.domain
,
5994 if (!remote_machine
) {
5998 command
= talloc_asprintf(ctx
,
5999 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6000 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6001 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6002 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6008 is_print_op
= user_has_privileges( token
, &se_printop
);
6010 DEBUG(10,("Running [%s]\n", command
));
6012 /********* BEGIN SePrintOperatorPrivilege **********/
6017 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6018 /* Tell everyone we updated smb.conf. */
6019 message_send_all(smbd_messaging_context(),
6020 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6026 /********* END SePrintOperatorPrivilege **********/
6028 DEBUGADD(10,("returned [%d]\n", ret
));
6030 TALLOC_FREE(command
);
6031 TALLOC_FREE(remote_machine
);
6039 /* reload our services immediately */
6041 reload_services(false);
6045 /* Get lines and convert them back to dos-codepage */
6046 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
6047 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6050 /* Set the portname to what the script says the portname should be. */
6051 /* but don't require anything to be return from the script exit a good error code */
6054 /* Set the portname to what the script says the portname should be. */
6055 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6056 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6059 TALLOC_FREE(qlines
);
6064 /********************************************************************
6065 * Called by spoolss_api_setprinter
6066 * when updating a printer description.
6067 ********************************************************************/
6069 static WERROR
update_printer(pipes_struct
*p
, struct policy_handle
*handle
,
6070 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
6071 struct spoolss_DeviceMode
*devmode
)
6074 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6075 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6080 DEBUG(8,("update_printer\n"));
6085 result
= WERR_BADFID
;
6089 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6090 result
= WERR_BADFID
;
6094 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6095 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6096 result
= WERR_BADFID
;
6100 DEBUGADD(8,("Converting info_2 struct\n"));
6103 * convert_printer_info converts the incoming
6104 * info from the client and overwrites the info
6105 * just read from the tdb in the pointer 'printer'.
6108 if (!convert_printer_info(info_ctr
, printer
)) {
6109 result
= WERR_NOMEM
;
6114 /* we have a valid devmode
6115 convert it and link it*/
6117 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6118 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6119 &printer
->info_2
->devmode
)) {
6120 result
= WERR_NOMEM
;
6125 /* Do sanity check on the requested changes for Samba */
6127 if (!check_printer_ok(printer
->info_2
, snum
)) {
6128 result
= WERR_INVALID_PARAM
;
6132 /* FIXME!!! If the driver has changed we really should verify that
6133 it is installed before doing much else --jerry */
6135 /* Check calling user has permission to update printer description */
6137 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6138 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6139 result
= WERR_ACCESS_DENIED
;
6143 /* Call addprinter hook */
6144 /* Check changes to see if this is really needed */
6146 if ( *lp_addprinter_cmd()
6147 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6148 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6149 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6150 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6152 /* add_printer_hook() will call reload_services() */
6154 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
6156 result
= WERR_ACCESS_DENIED
;
6162 * When a *new* driver is bound to a printer, the drivername is used to
6163 * lookup previously saved driver initialization info, which is then
6164 * bound to the printer, simulating what happens in the Windows arch.
6166 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6168 if (!set_driver_init(printer
, 2))
6170 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6171 printer
->info_2
->drivername
));
6174 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6175 printer
->info_2
->drivername
));
6177 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6181 * flag which changes actually occured. This is a small subset of
6182 * all the possible changes. We also have to update things in the
6186 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6187 push_reg_sz(talloc_tos(), &buffer
, printer
->info_2
->comment
);
6188 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6189 REG_SZ
, buffer
.data
, buffer
.length
);
6191 notify_printer_comment(snum
, printer
->info_2
->comment
);
6194 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6195 push_reg_sz(talloc_tos(), &buffer
, printer
->info_2
->sharename
);
6196 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6197 REG_SZ
, buffer
.data
, buffer
.length
);
6199 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6202 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6205 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6208 pname
= printer
->info_2
->printername
;
6211 push_reg_sz(talloc_tos(), &buffer
, pname
);
6212 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6213 REG_SZ
, buffer
.data
, buffer
.length
);
6215 notify_printer_printername( snum
, pname
);
6218 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6219 push_reg_sz(talloc_tos(), &buffer
, printer
->info_2
->portname
);
6220 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6221 REG_SZ
, buffer
.data
, buffer
.length
);
6223 notify_printer_port(snum
, printer
->info_2
->portname
);
6226 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6227 push_reg_sz(talloc_tos(), &buffer
, printer
->info_2
->location
);
6228 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6229 REG_SZ
, buffer
.data
, buffer
.length
);
6231 notify_printer_location(snum
, printer
->info_2
->location
);
6234 /* here we need to update some more DsSpooler keys */
6235 /* uNCName, serverName, shortServerName */
6237 push_reg_sz(talloc_tos(), &buffer
, global_myname());
6238 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6239 REG_SZ
, buffer
.data
, buffer
.length
);
6240 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6241 REG_SZ
, buffer
.data
, buffer
.length
);
6243 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6244 global_myname(), printer
->info_2
->sharename
);
6245 push_reg_sz(talloc_tos(), &buffer
, asc_buffer
);
6246 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6247 REG_SZ
, buffer
.data
, buffer
.length
);
6249 /* Update printer info */
6250 result
= mod_a_printer(printer
, 2);
6253 free_a_printer(&printer
, 2);
6254 free_a_printer(&old_printer
, 2);
6260 /****************************************************************************
6261 ****************************************************************************/
6262 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
,
6263 struct policy_handle
*handle
,
6264 struct spoolss_SetPrinterInfo7
*info7
)
6268 Printer_entry
*Printer
;
6270 if ( lp_security() != SEC_ADS
) {
6271 return WERR_UNKNOWN_LEVEL
;
6274 Printer
= find_printer_index_by_hnd(p
, handle
);
6276 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6281 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6284 nt_printer_publish(Printer
, snum
, info7
->action
);
6288 return WERR_UNKNOWN_LEVEL
;
6292 /****************************************************************
6294 ****************************************************************/
6296 WERROR
_spoolss_SetPrinter(pipes_struct
*p
,
6297 struct spoolss_SetPrinter
*r
)
6301 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
6304 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6305 OUR_HANDLE(r
->in
.handle
)));
6309 /* check the level */
6310 switch (r
->in
.info_ctr
->level
) {
6312 return control_printer(r
->in
.handle
, r
->in
.command
, p
);
6314 result
= update_printer(p
, r
->in
.handle
,
6316 r
->in
.devmode_ctr
->devmode
);
6317 if (!W_ERROR_IS_OK(result
))
6319 if (r
->in
.secdesc_ctr
->sd
)
6320 result
= update_printer_sec(r
->in
.handle
, p
,
6324 return update_printer_sec(r
->in
.handle
, p
,
6327 return publish_or_unpublish_printer(p
, r
->in
.handle
,
6328 r
->in
.info_ctr
->info
.info7
);
6330 return WERR_UNKNOWN_LEVEL
;
6334 /****************************************************************
6335 _spoolss_FindClosePrinterNotify
6336 ****************************************************************/
6338 WERROR
_spoolss_FindClosePrinterNotify(pipes_struct
*p
,
6339 struct spoolss_FindClosePrinterNotify
*r
)
6341 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
6344 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6345 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r
->in
.handle
)));
6349 if (Printer
->notify
.client_connected
== true) {
6352 if ( Printer
->printer_type
== SPLHND_SERVER
)
6354 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6355 !get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
) )
6358 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6361 Printer
->notify
.flags
=0;
6362 Printer
->notify
.options
=0;
6363 Printer
->notify
.localmachine
[0]='\0';
6364 Printer
->notify
.printerlocal
=0;
6365 TALLOC_FREE(Printer
->notify
.option
);
6366 Printer
->notify
.client_connected
= false;
6371 /****************************************************************
6373 ****************************************************************/
6375 WERROR
_spoolss_AddJob(pipes_struct
*p
,
6376 struct spoolss_AddJob
*r
)
6378 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6379 return WERR_INVALID_PARAM
;
6382 /* this is what a NT server returns for AddJob. AddJob must fail on
6383 * non-local printers */
6385 if (r
->in
.level
!= 1) {
6386 return WERR_UNKNOWN_LEVEL
;
6389 return WERR_INVALID_PARAM
;
6392 /****************************************************************************
6394 ****************************************************************************/
6396 static WERROR
fill_job_info1(TALLOC_CTX
*mem_ctx
,
6397 struct spoolss_JobInfo1
*r
,
6398 const print_queue_struct
*queue
,
6399 int position
, int snum
,
6400 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6404 t
= gmtime(&queue
->time
);
6406 r
->job_id
= queue
->job
;
6408 r
->printer_name
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
6409 W_ERROR_HAVE_NO_MEMORY(r
->printer_name
);
6410 r
->server_name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
6411 W_ERROR_HAVE_NO_MEMORY(r
->server_name
);
6412 r
->user_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
6413 W_ERROR_HAVE_NO_MEMORY(r
->user_name
);
6414 r
->document_name
= talloc_strdup(mem_ctx
, queue
->fs_file
);
6415 W_ERROR_HAVE_NO_MEMORY(r
->document_name
);
6416 r
->data_type
= talloc_strdup(mem_ctx
, "RAW");
6417 W_ERROR_HAVE_NO_MEMORY(r
->data_type
);
6418 r
->text_status
= talloc_strdup(mem_ctx
, "");
6419 W_ERROR_HAVE_NO_MEMORY(r
->text_status
);
6421 r
->status
= nt_printj_status(queue
->status
);
6422 r
->priority
= queue
->priority
;
6423 r
->position
= position
;
6424 r
->total_pages
= queue
->page_count
;
6425 r
->pages_printed
= 0; /* ??? */
6427 init_systemtime(&r
->submitted
, t
);
6432 /****************************************************************************
6434 ****************************************************************************/
6436 static WERROR
fill_job_info2(TALLOC_CTX
*mem_ctx
,
6437 struct spoolss_JobInfo2
*r
,
6438 const print_queue_struct
*queue
,
6439 int position
, int snum
,
6440 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6441 struct spoolss_DeviceMode
*devmode
)
6445 t
= gmtime(&queue
->time
);
6447 r
->job_id
= queue
->job
;
6449 r
->printer_name
= talloc_strdup(mem_ctx
, lp_servicename(snum
));
6450 W_ERROR_HAVE_NO_MEMORY(r
->printer_name
);
6451 r
->server_name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->servername
);
6452 W_ERROR_HAVE_NO_MEMORY(r
->server_name
);
6453 r
->user_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
6454 W_ERROR_HAVE_NO_MEMORY(r
->user_name
);
6455 r
->document_name
= talloc_strdup(mem_ctx
, queue
->fs_file
);
6456 W_ERROR_HAVE_NO_MEMORY(r
->document_name
);
6457 r
->notify_name
= talloc_strdup(mem_ctx
, queue
->fs_user
);
6458 W_ERROR_HAVE_NO_MEMORY(r
->notify_name
);
6459 r
->data_type
= talloc_strdup(mem_ctx
, "RAW");
6460 W_ERROR_HAVE_NO_MEMORY(r
->data_type
);
6461 r
->print_processor
= talloc_strdup(mem_ctx
, "winprint");
6462 W_ERROR_HAVE_NO_MEMORY(r
->print_processor
);
6463 r
->parameters
= talloc_strdup(mem_ctx
, "");
6464 W_ERROR_HAVE_NO_MEMORY(r
->parameters
);
6465 r
->driver_name
= talloc_strdup(mem_ctx
, ntprinter
->info_2
->drivername
);
6466 W_ERROR_HAVE_NO_MEMORY(r
->driver_name
);
6468 r
->devmode
= devmode
;
6470 r
->text_status
= talloc_strdup(mem_ctx
, "");
6471 W_ERROR_HAVE_NO_MEMORY(r
->text_status
);
6475 r
->status
= nt_printj_status(queue
->status
);
6476 r
->priority
= queue
->priority
;
6477 r
->position
= position
;
6480 r
->total_pages
= queue
->page_count
;
6481 r
->size
= queue
->size
;
6482 init_systemtime(&r
->submitted
, t
);
6484 r
->pages_printed
= 0; /* ??? */
6489 /****************************************************************************
6490 Enumjobs at level 1.
6491 ****************************************************************************/
6493 static WERROR
enumjobs_level1(TALLOC_CTX
*mem_ctx
,
6494 const print_queue_struct
*queue
,
6495 uint32_t num_queues
, int snum
,
6496 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6497 union spoolss_JobInfo
**info_p
,
6500 union spoolss_JobInfo
*info
;
6502 WERROR result
= WERR_OK
;
6504 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6505 W_ERROR_HAVE_NO_MEMORY(info
);
6507 *count
= num_queues
;
6509 for (i
=0; i
<*count
; i
++) {
6510 result
= fill_job_info1(info
,
6516 if (!W_ERROR_IS_OK(result
)) {
6522 if (!W_ERROR_IS_OK(result
)) {
6533 /****************************************************************************
6534 Enumjobs at level 2.
6535 ****************************************************************************/
6537 static WERROR
enumjobs_level2(TALLOC_CTX
*mem_ctx
,
6538 const print_queue_struct
*queue
,
6539 uint32_t num_queues
, int snum
,
6540 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6541 union spoolss_JobInfo
**info_p
,
6544 union spoolss_JobInfo
*info
;
6546 WERROR result
= WERR_OK
;
6548 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_JobInfo
, num_queues
);
6549 W_ERROR_HAVE_NO_MEMORY(info
);
6551 *count
= num_queues
;
6553 for (i
=0; i
<*count
; i
++) {
6555 struct spoolss_DeviceMode
*devmode
;
6557 devmode
= construct_dev_mode(info
, lp_const_servicename(snum
));
6559 result
= WERR_NOMEM
;
6563 result
= fill_job_info2(info
,
6570 if (!W_ERROR_IS_OK(result
)) {
6576 if (!W_ERROR_IS_OK(result
)) {
6587 /****************************************************************
6589 ****************************************************************/
6591 WERROR
_spoolss_EnumJobs(pipes_struct
*p
,
6592 struct spoolss_EnumJobs
*r
)
6595 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6597 print_status_struct prt_status
;
6598 print_queue_struct
*queue
= NULL
;
6601 /* that's an [in out] buffer */
6603 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6604 return WERR_INVALID_PARAM
;
6607 DEBUG(4,("_spoolss_EnumJobs\n"));
6611 *r
->out
.info
= NULL
;
6613 /* lookup the printer snum and tdb entry */
6615 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
6619 result
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6620 if (!W_ERROR_IS_OK(result
)) {
6624 count
= print_queue_status(snum
, &queue
, &prt_status
);
6625 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6626 count
, prt_status
.status
, prt_status
.message
));
6630 free_a_printer(&ntprinter
, 2);
6634 switch (r
->in
.level
) {
6636 result
= enumjobs_level1(p
->mem_ctx
, queue
, count
, snum
,
6637 ntprinter
, r
->out
.info
, r
->out
.count
);
6640 result
= enumjobs_level2(p
->mem_ctx
, queue
, count
, snum
,
6641 ntprinter
, r
->out
.info
, r
->out
.count
);
6644 result
= WERR_UNKNOWN_LEVEL
;
6649 free_a_printer(&ntprinter
, 2);
6651 if (!W_ERROR_IS_OK(result
)) {
6655 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
6656 spoolss_EnumJobs
, NULL
,
6657 *r
->out
.info
, r
->in
.level
,
6659 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
6660 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
6662 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
6665 /****************************************************************
6666 _spoolss_ScheduleJob
6667 ****************************************************************/
6669 WERROR
_spoolss_ScheduleJob(pipes_struct
*p
,
6670 struct spoolss_ScheduleJob
*r
)
6675 /****************************************************************
6677 ****************************************************************/
6679 WERROR
_spoolss_SetJob(pipes_struct
*p
,
6680 struct spoolss_SetJob
*r
)
6683 WERROR errcode
= WERR_BADFUNC
;
6685 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
6689 if (!print_job_exists(lp_const_servicename(snum
), r
->in
.job_id
)) {
6690 return WERR_INVALID_PRINTER_NAME
;
6693 switch (r
->in
.command
) {
6694 case SPOOLSS_JOB_CONTROL_CANCEL
:
6695 case SPOOLSS_JOB_CONTROL_DELETE
:
6696 if (print_job_delete(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6700 case SPOOLSS_JOB_CONTROL_PAUSE
:
6701 if (print_job_pause(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6705 case SPOOLSS_JOB_CONTROL_RESTART
:
6706 case SPOOLSS_JOB_CONTROL_RESUME
:
6707 if (print_job_resume(p
->server_info
, snum
, r
->in
.job_id
, &errcode
)) {
6712 return WERR_UNKNOWN_LEVEL
;
6718 /****************************************************************************
6719 Enumerates all printer drivers by level and architecture.
6720 ****************************************************************************/
6722 static WERROR
enumprinterdrivers_level_by_architecture(TALLOC_CTX
*mem_ctx
,
6723 const char *servername
,
6724 const char *architecture
,
6726 union spoolss_DriverInfo
**info_p
,
6732 fstring
*list
= NULL
;
6733 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6734 union spoolss_DriverInfo
*info
= NULL
;
6736 WERROR result
= WERR_OK
;
6741 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6743 ndrivers
= get_ntdrivers(&list
, architecture
, version
);
6744 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6745 ndrivers
, architecture
, version
));
6747 if (ndrivers
== -1) {
6748 result
= WERR_NOMEM
;
6752 if (ndrivers
!= 0) {
6753 info
= TALLOC_REALLOC_ARRAY(mem_ctx
, info
,
6754 union spoolss_DriverInfo
,
6757 DEBUG(0,("enumprinterdrivers_level1: "
6758 "failed to enlarge driver info buffer!\n"));
6759 result
= WERR_NOMEM
;
6764 for (i
=0; i
<ndrivers
; i
++) {
6765 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6766 ZERO_STRUCT(driver
);
6767 result
= get_a_printer_driver(&driver
, 3, list
[i
],
6768 architecture
, version
);
6769 if (!W_ERROR_IS_OK(result
)) {
6775 result
= fill_printer_driver_info1(info
, &info
[count
+i
].info1
,
6776 &driver
, servername
,
6780 result
= fill_printer_driver_info2(info
, &info
[count
+i
].info2
,
6781 &driver
, servername
);
6784 result
= fill_printer_driver_info3(info
, &info
[count
+i
].info3
,
6785 &driver
, servername
);
6788 result
= fill_printer_driver_info4(info
, &info
[count
+i
].info4
,
6789 &driver
, servername
);
6792 result
= fill_printer_driver_info5(info
, &info
[count
+i
].info5
,
6793 &driver
, servername
);
6796 result
= fill_printer_driver_info6(info
, &info
[count
+i
].info6
,
6797 &driver
, servername
);
6800 result
= WERR_UNKNOWN_LEVEL
;
6804 if (!W_ERROR_IS_OK(result
)) {
6805 free_a_printer_driver(driver
, 3);
6808 free_a_printer_driver(driver
, 3);
6818 if (!W_ERROR_IS_OK(result
)) {
6829 /****************************************************************************
6830 Enumerates all printer drivers by level.
6831 ****************************************************************************/
6833 static WERROR
enumprinterdrivers_level(TALLOC_CTX
*mem_ctx
,
6834 const char *servername
,
6835 const char *architecture
,
6837 union spoolss_DriverInfo
**info_p
,
6841 WERROR result
= WERR_OK
;
6843 if (strequal(architecture
, "all")) {
6845 for (a
=0; archi_table
[a
].long_archi
!= NULL
; a
++) {
6847 union spoolss_DriverInfo
*info
= NULL
;
6850 result
= enumprinterdrivers_level_by_architecture(mem_ctx
,
6852 archi_table
[a
].long_archi
,
6856 if (!W_ERROR_IS_OK(result
)) {
6860 for (i
=0; i
< count
; i
++) {
6861 ADD_TO_ARRAY(mem_ctx
, union spoolss_DriverInfo
,
6862 info
[i
], info_p
, count_p
);
6869 return enumprinterdrivers_level_by_architecture(mem_ctx
,
6877 /****************************************************************************
6878 Enumerates all printer drivers at level 1.
6879 ****************************************************************************/
6881 static WERROR
enumprinterdrivers_level1(TALLOC_CTX
*mem_ctx
,
6882 const char *servername
,
6883 const char *architecture
,
6884 union spoolss_DriverInfo
**info_p
,
6887 return enumprinterdrivers_level(mem_ctx
, servername
, architecture
, 1,
6891 /****************************************************************************
6892 Enumerates all printer drivers at level 2.
6893 ****************************************************************************/
6895 static WERROR
enumprinterdrivers_level2(TALLOC_CTX
*mem_ctx
,
6896 const char *servername
,
6897 const char *architecture
,
6898 union spoolss_DriverInfo
**info_p
,
6901 return enumprinterdrivers_level(mem_ctx
, servername
, architecture
, 2,
6905 /****************************************************************************
6906 Enumerates all printer drivers at level 3.
6907 ****************************************************************************/
6909 static WERROR
enumprinterdrivers_level3(TALLOC_CTX
*mem_ctx
,
6910 const char *servername
,
6911 const char *architecture
,
6912 union spoolss_DriverInfo
**info_p
,
6915 return enumprinterdrivers_level(mem_ctx
, servername
, architecture
, 3,
6919 /****************************************************************************
6920 Enumerates all printer drivers at level 4.
6921 ****************************************************************************/
6923 static WERROR
enumprinterdrivers_level4(TALLOC_CTX
*mem_ctx
,
6924 const char *servername
,
6925 const char *architecture
,
6926 union spoolss_DriverInfo
**info_p
,
6929 return enumprinterdrivers_level(mem_ctx
, servername
, architecture
, 4,
6933 /****************************************************************************
6934 Enumerates all printer drivers at level 5.
6935 ****************************************************************************/
6937 static WERROR
enumprinterdrivers_level5(TALLOC_CTX
*mem_ctx
,
6938 const char *servername
,
6939 const char *architecture
,
6940 union spoolss_DriverInfo
**info_p
,
6943 return enumprinterdrivers_level(mem_ctx
, servername
, architecture
, 5,
6947 /****************************************************************************
6948 Enumerates all printer drivers at level 6.
6949 ****************************************************************************/
6951 static WERROR
enumprinterdrivers_level6(TALLOC_CTX
*mem_ctx
,
6952 const char *servername
,
6953 const char *architecture
,
6954 union spoolss_DriverInfo
**info_p
,
6957 return enumprinterdrivers_level(mem_ctx
, servername
, architecture
, 6,
6962 /****************************************************************
6963 _spoolss_EnumPrinterDrivers
6964 ****************************************************************/
6966 WERROR
_spoolss_EnumPrinterDrivers(pipes_struct
*p
,
6967 struct spoolss_EnumPrinterDrivers
*r
)
6969 const char *cservername
;
6972 /* that's an [in out] buffer */
6974 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
6975 return WERR_INVALID_PARAM
;
6978 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6982 *r
->out
.info
= NULL
;
6984 cservername
= canon_servername(r
->in
.server
);
6986 if (!is_myname_or_ipaddr(cservername
)) {
6987 return WERR_UNKNOWN_PRINTER_DRIVER
;
6990 switch (r
->in
.level
) {
6992 result
= enumprinterdrivers_level1(p
->mem_ctx
, cservername
,
6994 r
->out
.info
, r
->out
.count
);
6997 result
= enumprinterdrivers_level2(p
->mem_ctx
, cservername
,
6999 r
->out
.info
, r
->out
.count
);
7002 result
= enumprinterdrivers_level3(p
->mem_ctx
, cservername
,
7004 r
->out
.info
, r
->out
.count
);
7007 result
= enumprinterdrivers_level4(p
->mem_ctx
, cservername
,
7009 r
->out
.info
, r
->out
.count
);
7012 result
= enumprinterdrivers_level5(p
->mem_ctx
, cservername
,
7014 r
->out
.info
, r
->out
.count
);
7017 result
= enumprinterdrivers_level6(p
->mem_ctx
, cservername
,
7019 r
->out
.info
, r
->out
.count
);
7022 return WERR_UNKNOWN_LEVEL
;
7025 if (!W_ERROR_IS_OK(result
)) {
7029 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
7030 spoolss_EnumPrinterDrivers
, NULL
,
7031 *r
->out
.info
, r
->in
.level
,
7033 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
7034 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
7036 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7039 /****************************************************************************
7040 ****************************************************************************/
7042 static WERROR
fill_form_info_1(TALLOC_CTX
*mem_ctx
,
7043 struct spoolss_FormInfo1
*r
,
7044 const nt_forms_struct
*form
)
7046 r
->form_name
= talloc_strdup(mem_ctx
, form
->name
);
7047 W_ERROR_HAVE_NO_MEMORY(r
->form_name
);
7049 r
->flags
= form
->flag
;
7050 r
->size
.width
= form
->width
;
7051 r
->size
.height
= form
->length
;
7052 r
->area
.left
= form
->left
;
7053 r
->area
.top
= form
->top
;
7054 r
->area
.right
= form
->right
;
7055 r
->area
.bottom
= form
->bottom
;
7060 /****************************************************************
7061 spoolss_enumforms_level1
7062 ****************************************************************/
7064 static WERROR
spoolss_enumforms_level1(TALLOC_CTX
*mem_ctx
,
7065 const nt_forms_struct
*builtin_forms
,
7066 uint32_t num_builtin_forms
,
7067 const nt_forms_struct
*user_forms
,
7068 uint32_t num_user_forms
,
7069 union spoolss_FormInfo
**info_p
,
7072 union spoolss_FormInfo
*info
;
7073 WERROR result
= WERR_OK
;
7076 *count
= num_builtin_forms
+ num_user_forms
;
7078 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_FormInfo
, *count
);
7079 W_ERROR_HAVE_NO_MEMORY(info
);
7081 /* construct the list of form structures */
7082 for (i
=0; i
<num_builtin_forms
; i
++) {
7083 DEBUGADD(6,("Filling builtin form number [%d]\n",i
));
7084 result
= fill_form_info_1(info
, &info
[i
].info1
,
7086 if (!W_ERROR_IS_OK(result
)) {
7091 for (i
=0; i
<num_user_forms
; i
++) {
7092 DEBUGADD(6,("Filling user form number [%d]\n",i
));
7093 result
= fill_form_info_1(info
, &info
[i
+num_builtin_forms
].info1
,
7095 if (!W_ERROR_IS_OK(result
)) {
7101 if (!W_ERROR_IS_OK(result
)) {
7112 /****************************************************************
7114 ****************************************************************/
7116 WERROR
_spoolss_EnumForms(pipes_struct
*p
,
7117 struct spoolss_EnumForms
*r
)
7120 nt_forms_struct
*user_forms
= NULL
;
7121 nt_forms_struct
*builtin_forms
= NULL
;
7122 uint32_t num_user_forms
;
7123 uint32_t num_builtin_forms
;
7127 *r
->out
.info
= NULL
;
7129 /* that's an [in out] buffer */
7131 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0) ) {
7132 return WERR_INVALID_PARAM
;
7135 DEBUG(4,("_spoolss_EnumForms\n"));
7136 DEBUGADD(5,("Offered buffer size [%d]\n", r
->in
.offered
));
7137 DEBUGADD(5,("Info level [%d]\n", r
->in
.level
));
7139 num_builtin_forms
= get_builtin_ntforms(&builtin_forms
);
7140 DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms
));
7141 num_user_forms
= get_ntforms(&user_forms
);
7142 DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms
));
7144 if (num_user_forms
+ num_builtin_forms
== 0) {
7145 SAFE_FREE(builtin_forms
);
7146 SAFE_FREE(user_forms
);
7147 return WERR_NO_MORE_ITEMS
;
7150 switch (r
->in
.level
) {
7152 result
= spoolss_enumforms_level1(p
->mem_ctx
,
7161 result
= WERR_UNKNOWN_LEVEL
;
7165 SAFE_FREE(user_forms
);
7166 SAFE_FREE(builtin_forms
);
7168 if (!W_ERROR_IS_OK(result
)) {
7172 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
7173 spoolss_EnumForms
, NULL
,
7174 *r
->out
.info
, r
->in
.level
,
7176 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
7177 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
7179 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7182 /****************************************************************
7183 ****************************************************************/
7185 static WERROR
find_form_byname(const char *name
,
7186 nt_forms_struct
*form
)
7188 nt_forms_struct
*list
= NULL
;
7189 int num_forms
= 0, i
= 0;
7191 if (get_a_builtin_ntform_by_string(name
, form
)) {
7195 num_forms
= get_ntforms(&list
);
7196 DEBUGADD(5,("Number of forms [%d]\n", num_forms
));
7198 if (num_forms
== 0) {
7202 /* Check if the requested name is in the list of form structures */
7203 for (i
= 0; i
< num_forms
; i
++) {
7205 DEBUG(4,("checking form %s (want %s)\n", list
[i
].name
, name
));
7207 if (strequal(name
, list
[i
].name
)) {
7208 DEBUGADD(6,("Found form %s number [%d]\n", name
, i
));
7220 /****************************************************************
7222 ****************************************************************/
7224 WERROR
_spoolss_GetForm(pipes_struct
*p
,
7225 struct spoolss_GetForm
*r
)
7228 nt_forms_struct form
;
7230 /* that's an [in out] buffer */
7232 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7233 return WERR_INVALID_PARAM
;
7236 DEBUG(4,("_spoolss_GetForm\n"));
7237 DEBUGADD(5,("Offered buffer size [%d]\n", r
->in
.offered
));
7238 DEBUGADD(5,("Info level [%d]\n", r
->in
.level
));
7240 result
= find_form_byname(r
->in
.form_name
, &form
);
7241 if (!W_ERROR_IS_OK(result
)) {
7242 TALLOC_FREE(r
->out
.info
);
7246 switch (r
->in
.level
) {
7248 result
= fill_form_info_1(p
->mem_ctx
,
7249 &r
->out
.info
->info1
,
7254 result
= WERR_UNKNOWN_LEVEL
;
7258 if (!W_ERROR_IS_OK(result
)) {
7259 TALLOC_FREE(r
->out
.info
);
7263 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_FormInfo
, NULL
,
7264 r
->out
.info
, r
->in
.level
);
7265 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
7267 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7270 /****************************************************************************
7271 ****************************************************************************/
7273 static WERROR
fill_port_1(TALLOC_CTX
*mem_ctx
,
7274 struct spoolss_PortInfo1
*r
,
7277 r
->port_name
= talloc_strdup(mem_ctx
, name
);
7278 W_ERROR_HAVE_NO_MEMORY(r
->port_name
);
7283 /****************************************************************************
7284 TODO: This probably needs distinguish between TCP/IP and Local ports
7286 ****************************************************************************/
7288 static WERROR
fill_port_2(TALLOC_CTX
*mem_ctx
,
7289 struct spoolss_PortInfo2
*r
,
7292 r
->port_name
= talloc_strdup(mem_ctx
, name
);
7293 W_ERROR_HAVE_NO_MEMORY(r
->port_name
);
7295 r
->monitor_name
= talloc_strdup(mem_ctx
, "Local Monitor");
7296 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
7298 r
->description
= talloc_strdup(mem_ctx
, SPL_LOCAL_PORT
);
7299 W_ERROR_HAVE_NO_MEMORY(r
->description
);
7301 r
->port_type
= SPOOLSS_PORT_TYPE_WRITE
;
7308 /****************************************************************************
7309 wrapper around the enumer ports command
7310 ****************************************************************************/
7312 static WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7314 char *cmd
= lp_enumports_cmd();
7315 char **qlines
= NULL
;
7316 char *command
= NULL
;
7324 /* if no hook then just fill in the default port */
7327 if (!(qlines
= TALLOC_ARRAY( NULL
, char*, 2 ))) {
7330 if (!(qlines
[0] = talloc_strdup(qlines
, SAMBA_PRINTER_PORT_NAME
))) {
7331 TALLOC_FREE(qlines
);
7338 /* we have a valid enumport command */
7340 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7345 DEBUG(10,("Running [%s]\n", command
));
7346 ret
= smbrun(command
, &fd
);
7347 DEBUG(10,("Returned [%d]\n", ret
));
7348 TALLOC_FREE(command
);
7353 return WERR_ACCESS_DENIED
;
7357 qlines
= fd_lines_load(fd
, &numlines
, 0, NULL
);
7358 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7368 /****************************************************************************
7370 ****************************************************************************/
7372 static WERROR
enumports_level_1(TALLOC_CTX
*mem_ctx
,
7373 union spoolss_PortInfo
**info_p
,
7376 union spoolss_PortInfo
*info
= NULL
;
7378 WERROR result
= WERR_OK
;
7379 char **qlines
= NULL
;
7382 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7383 if (!W_ERROR_IS_OK(result
)) {
7388 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PortInfo
, numlines
);
7390 DEBUG(10,("Returning WERR_NOMEM\n"));
7391 result
= WERR_NOMEM
;
7395 for (i
=0; i
<numlines
; i
++) {
7396 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7397 result
= fill_port_1(info
, &info
[i
].info1
, qlines
[i
]);
7398 if (!W_ERROR_IS_OK(result
)) {
7403 TALLOC_FREE(qlines
);
7406 if (!W_ERROR_IS_OK(result
)) {
7408 TALLOC_FREE(qlines
);
7420 /****************************************************************************
7422 ****************************************************************************/
7424 static WERROR
enumports_level_2(TALLOC_CTX
*mem_ctx
,
7425 union spoolss_PortInfo
**info_p
,
7428 union spoolss_PortInfo
*info
= NULL
;
7430 WERROR result
= WERR_OK
;
7431 char **qlines
= NULL
;
7434 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7435 if (!W_ERROR_IS_OK(result
)) {
7440 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PortInfo
, numlines
);
7442 DEBUG(10,("Returning WERR_NOMEM\n"));
7443 result
= WERR_NOMEM
;
7447 for (i
=0; i
<numlines
; i
++) {
7448 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7449 result
= fill_port_2(info
, &info
[i
].info2
, qlines
[i
]);
7450 if (!W_ERROR_IS_OK(result
)) {
7455 TALLOC_FREE(qlines
);
7458 if (!W_ERROR_IS_OK(result
)) {
7460 TALLOC_FREE(qlines
);
7472 /****************************************************************
7474 ****************************************************************/
7476 WERROR
_spoolss_EnumPorts(pipes_struct
*p
,
7477 struct spoolss_EnumPorts
*r
)
7481 /* that's an [in out] buffer */
7483 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7484 return WERR_INVALID_PARAM
;
7487 DEBUG(4,("_spoolss_EnumPorts\n"));
7491 *r
->out
.info
= NULL
;
7493 switch (r
->in
.level
) {
7495 result
= enumports_level_1(p
->mem_ctx
, r
->out
.info
,
7499 result
= enumports_level_2(p
->mem_ctx
, r
->out
.info
,
7503 return WERR_UNKNOWN_LEVEL
;
7506 if (!W_ERROR_IS_OK(result
)) {
7510 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
7511 spoolss_EnumPorts
, NULL
,
7512 *r
->out
.info
, r
->in
.level
,
7514 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
7515 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
7517 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
7520 /****************************************************************************
7521 ****************************************************************************/
7523 static WERROR
spoolss_addprinterex_level_2(pipes_struct
*p
,
7525 struct spoolss_SetPrinterInfoCtr
*info_ctr
,
7526 struct spoolss_DeviceMode
*devmode
,
7527 struct security_descriptor
*sec_desc
,
7528 struct spoolss_UserLevelCtr
*user_ctr
,
7529 struct policy_handle
*handle
)
7531 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7534 WERROR err
= WERR_OK
;
7536 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7537 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7541 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7542 if (!convert_printer_info(info_ctr
, printer
)) {
7543 free_a_printer(&printer
, 2);
7547 /* check to see if the printer already exists */
7549 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7550 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7551 printer
->info_2
->sharename
));
7552 free_a_printer(&printer
, 2);
7553 return WERR_PRINTER_ALREADY_EXISTS
;
7556 /* FIXME!!! smbd should check to see if the driver is installed before
7557 trying to add a printer like this --jerry */
7559 if (*lp_addprinter_cmd() ) {
7560 if ( !add_printer_hook(p
->mem_ctx
, p
->server_info
->ptok
,
7562 free_a_printer(&printer
,2);
7563 return WERR_ACCESS_DENIED
;
7566 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7567 "smb.conf parameter \"addprinter command\" is defined. This"
7568 "parameter must exist for this call to succeed\n",
7569 printer
->info_2
->sharename
));
7572 /* use our primary netbios name since get_a_printer() will convert
7573 it to what the client expects on a case by case basis */
7575 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7576 printer
->info_2
->sharename
);
7579 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7580 free_a_printer(&printer
,2);
7581 return WERR_ACCESS_DENIED
;
7584 /* you must be a printer admin to add a new printer */
7585 if (!print_access_check(p
->server_info
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7586 free_a_printer(&printer
,2);
7587 return WERR_ACCESS_DENIED
;
7591 * Do sanity check on the requested changes for Samba.
7594 if (!check_printer_ok(printer
->info_2
, snum
)) {
7595 free_a_printer(&printer
,2);
7596 return WERR_INVALID_PARAM
;
7600 * When a printer is created, the drivername bound to the printer is used
7601 * to lookup previously saved driver initialization info, which is then
7602 * bound to the new printer, simulating what happens in the Windows arch.
7607 set_driver_init(printer
, 2);
7611 /* A valid devmode was included, convert and link it
7613 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7615 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
7616 &printer
->info_2
->devmode
)) {
7621 /* write the ASCII on disk */
7622 err
= mod_a_printer(printer
, 2);
7623 if (!W_ERROR_IS_OK(err
)) {
7624 free_a_printer(&printer
,2);
7628 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7629 /* Handle open failed - remove addition. */
7630 del_a_printer(printer
->info_2
->sharename
);
7631 free_a_printer(&printer
,2);
7632 ZERO_STRUCTP(handle
);
7633 return WERR_ACCESS_DENIED
;
7636 update_c_setprinter(false);
7637 free_a_printer(&printer
,2);
7642 /****************************************************************
7643 _spoolss_AddPrinterEx
7644 ****************************************************************/
7646 WERROR
_spoolss_AddPrinterEx(pipes_struct
*p
,
7647 struct spoolss_AddPrinterEx
*r
)
7649 switch (r
->in
.info_ctr
->level
) {
7651 /* we don't handle yet */
7652 /* but I know what to do ... */
7653 return WERR_UNKNOWN_LEVEL
;
7655 return spoolss_addprinterex_level_2(p
, r
->in
.server
,
7657 r
->in
.devmode_ctr
->devmode
,
7658 r
->in
.secdesc_ctr
->sd
,
7659 r
->in
.userlevel_ctr
,
7662 return WERR_UNKNOWN_LEVEL
;
7666 /****************************************************************
7668 ****************************************************************/
7670 WERROR
_spoolss_AddPrinter(pipes_struct
*p
,
7671 struct spoolss_AddPrinter
*r
)
7673 struct spoolss_AddPrinterEx a
;
7674 struct spoolss_UserLevelCtr userlevel_ctr
;
7676 ZERO_STRUCT(userlevel_ctr
);
7678 userlevel_ctr
.level
= 1;
7680 a
.in
.server
= r
->in
.server
;
7681 a
.in
.info_ctr
= r
->in
.info_ctr
;
7682 a
.in
.devmode_ctr
= r
->in
.devmode_ctr
;
7683 a
.in
.secdesc_ctr
= r
->in
.secdesc_ctr
;
7684 a
.in
.userlevel_ctr
= &userlevel_ctr
;
7685 a
.out
.handle
= r
->out
.handle
;
7687 return _spoolss_AddPrinterEx(p
, &a
);
7690 /****************************************************************
7691 _spoolss_AddPrinterDriver
7692 ****************************************************************/
7694 WERROR
_spoolss_AddPrinterDriver(pipes_struct
*p
,
7695 struct spoolss_AddPrinterDriver
*r
)
7697 uint32_t level
= r
->in
.info_ctr
->level
;
7698 struct spoolss_AddDriverInfoCtr
*info
= r
->in
.info_ctr
;
7699 WERROR err
= WERR_OK
;
7700 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7701 const char *driver_name
= NULL
;
7705 switch (p
->hdr_req
.opnum
) {
7706 case NDR_SPOOLSS_ADDPRINTERDRIVER
:
7707 fn
= "_spoolss_AddPrinterDriver";
7709 case NDR_SPOOLSS_ADDPRINTERDRIVEREX
:
7710 fn
= "_spoolss_AddPrinterDriverEx";
7713 return WERR_INVALID_PARAM
;
7718 if (level
!= 3 && level
!= 6) {
7719 /* Clever hack from Martin Zielinski <mz@seh.de>
7720 * to allow downgrade from level 8 (Vista).
7722 DEBUG(0,("%s: level %d not yet implemented\n", fn
, level
));
7723 return WERR_UNKNOWN_LEVEL
;
7726 ZERO_STRUCT(driver
);
7728 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7733 DEBUG(5,("Cleaning driver's information\n"));
7734 err
= clean_up_driver_struct(p
, driver
, level
);
7735 if (!W_ERROR_IS_OK(err
))
7738 DEBUG(5,("Moving driver to final destination\n"));
7739 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(p
, driver
, level
,
7744 if (add_a_printer_driver(driver
, level
)!=0) {
7745 err
= WERR_ACCESS_DENIED
;
7751 driver_name
= driver
.info_3
->name
? driver
.info_3
->name
: "";
7754 driver_name
= driver
.info_6
->name
? driver
.info_6
->name
: "";
7759 * I think this is where he DrvUpgradePrinter() hook would be
7760 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7761 * server. Right now, we just need to send ourselves a message
7762 * to update each printer bound to this driver. --jerry
7765 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7766 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7771 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7772 * decide if the driver init data should be deleted. The rules are:
7773 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7774 * 2) delete init data only if there is no 2k/Xp driver
7775 * 3) always delete init data
7776 * The generalized rule is always use init data from the highest order driver.
7777 * It is necessary to follow the driver install by an initialization step to
7778 * finish off this process.
7781 version
= driver
.info_3
->cversion
;
7782 else if (level
== 6)
7783 version
= driver
.info_6
->version
;
7788 * 9x printer driver - never delete init data
7791 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7796 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7797 * there is no 2k/Xp driver init data for this driver name.
7801 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7803 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7805 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7807 if (!del_driver_init(driver_name
))
7808 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7812 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7814 free_a_printer_driver(driver1
,3);
7815 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7822 * 2k or Xp printer driver - always delete init data
7825 if (!del_driver_init(driver_name
))
7826 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7831 DEBUG(0,("%s: invalid level=%d\n", fn
, level
));
7837 free_a_printer_driver(driver
, level
);
7841 /****************************************************************
7842 _spoolss_AddPrinterDriverEx
7843 ****************************************************************/
7845 WERROR
_spoolss_AddPrinterDriverEx(pipes_struct
*p
,
7846 struct spoolss_AddPrinterDriverEx
*r
)
7848 struct spoolss_AddPrinterDriver a
;
7851 * we only support the semantics of AddPrinterDriver()
7852 * i.e. only copy files that are newer than existing ones
7855 if (r
->in
.flags
!= APD_COPY_NEW_FILES
) {
7856 return WERR_ACCESS_DENIED
;
7859 a
.in
.servername
= r
->in
.servername
;
7860 a
.in
.info_ctr
= r
->in
.info_ctr
;
7862 return _spoolss_AddPrinterDriver(p
, &a
);
7865 /****************************************************************************
7866 ****************************************************************************/
7868 struct _spoolss_paths
{
7874 enum { SPOOLSS_DRIVER_PATH
, SPOOLSS_PRTPROCS_PATH
};
7876 static const struct _spoolss_paths spoolss_paths
[]= {
7877 { SPOOLSS_DRIVER_PATH
, "print$", "DRIVERS" },
7878 { SPOOLSS_PRTPROCS_PATH
, "prnproc$", "PRTPROCS" }
7881 static WERROR
compose_spoolss_server_path(TALLOC_CTX
*mem_ctx
,
7882 const char *servername
,
7883 const char *environment
,
7887 const char *pservername
= NULL
;
7888 const char *long_archi
= SPOOLSS_ARCHITECTURE_NT_X86
;
7889 const char *short_archi
;
7893 /* environment may be empty */
7894 if (environment
&& strlen(environment
)) {
7895 long_archi
= environment
;
7898 /* servername may be empty */
7899 if (servername
&& strlen(servername
)) {
7900 pservername
= canon_servername(servername
);
7902 if (!is_myname_or_ipaddr(pservername
)) {
7903 return WERR_INVALID_PARAM
;
7907 if (!(short_archi
= get_short_archi(long_archi
))) {
7908 return WERR_INVALID_ENVIRONMENT
;
7911 switch (component
) {
7912 case SPOOLSS_PRTPROCS_PATH
:
7913 case SPOOLSS_DRIVER_PATH
:
7915 *path
= talloc_asprintf(mem_ctx
,
7918 spoolss_paths
[component
].share
,
7921 *path
= talloc_asprintf(mem_ctx
, "%s\\%s\\%s",
7922 SPOOLSS_DEFAULT_SERVER_PATH
,
7923 spoolss_paths
[component
].dir
,
7928 return WERR_INVALID_PARAM
;
7938 /****************************************************************************
7939 ****************************************************************************/
7941 static WERROR
getprinterdriverdir_level_1(TALLOC_CTX
*mem_ctx
,
7942 const char *servername
,
7943 const char *environment
,
7944 struct spoolss_DriverDirectoryInfo1
*r
)
7949 werr
= compose_spoolss_server_path(mem_ctx
,
7952 SPOOLSS_DRIVER_PATH
,
7954 if (!W_ERROR_IS_OK(werr
)) {
7958 DEBUG(4,("printer driver directory: [%s]\n", path
));
7960 r
->directory_name
= path
;
7965 /****************************************************************
7966 _spoolss_GetPrinterDriverDirectory
7967 ****************************************************************/
7969 WERROR
_spoolss_GetPrinterDriverDirectory(pipes_struct
*p
,
7970 struct spoolss_GetPrinterDriverDirectory
*r
)
7974 /* that's an [in out] buffer */
7976 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
7977 return WERR_INVALID_PARAM
;
7980 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7985 /* r->in.level is ignored */
7987 werror
= getprinterdriverdir_level_1(p
->mem_ctx
,
7990 &r
->out
.info
->info1
);
7991 if (!W_ERROR_IS_OK(werror
)) {
7992 TALLOC_FREE(r
->out
.info
);
7996 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo
, NULL
,
7997 r
->out
.info
, r
->in
.level
);
7998 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
8000 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8003 /****************************************************************
8004 _spoolss_EnumPrinterData
8005 ****************************************************************/
8007 WERROR
_spoolss_EnumPrinterData(pipes_struct
*p
,
8008 struct spoolss_EnumPrinterData
*r
)
8010 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8011 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8014 struct regval_blob
*val
= NULL
;
8015 NT_PRINTER_DATA
*p_data
;
8016 int i
, key_index
, num_values
;
8019 *r
->out
.value_needed
= 0;
8020 *r
->out
.type
= REG_NONE
;
8021 *r
->out
.data_needed
= 0;
8023 DEBUG(5,("_spoolss_EnumPrinterData\n"));
8026 DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
8027 OUR_HANDLE(r
->in
.handle
)));
8031 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8035 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8036 if (!W_ERROR_IS_OK(result
)) {
8040 p_data
= printer
->info_2
->data
;
8041 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8046 * The NT machine wants to know the biggest size of value and data
8048 * cf: MSDN EnumPrinterData remark section
8051 if (!r
->in
.value_offered
&& !r
->in
.data_offered
&& (key_index
!= -1)) {
8053 uint32_t biggest_valuesize
= 0;
8054 uint32_t biggest_datasize
= 0;
8056 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8058 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8060 for ( i
=0; i
<num_values
; i
++ )
8062 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8064 name_length
= strlen(val
->valuename
);
8065 if ( strlen(val
->valuename
) > biggest_valuesize
)
8066 biggest_valuesize
= name_length
;
8068 if ( val
->size
> biggest_datasize
)
8069 biggest_datasize
= val
->size
;
8071 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8075 /* the value is an UNICODE string but real_value_size is the length
8076 in bytes including the trailing 0 */
8078 *r
->out
.value_needed
= 2 * (1 + biggest_valuesize
);
8079 *r
->out
.data_needed
= biggest_datasize
;
8081 DEBUG(6,("final values: [%d], [%d]\n",
8082 *r
->out
.value_needed
, *r
->out
.data_needed
));
8088 * the value len is wrong in NT sp3
8089 * that's the number of bytes not the number of unicode chars
8092 if (key_index
!= -1) {
8093 val
= regval_ctr_specific_value(p_data
->keys
[key_index
].values
,
8099 /* out_value should default to "" or else NT4 has
8100 problems unmarshalling the response */
8102 if (r
->in
.value_offered
) {
8103 *r
->out
.value_needed
= 1;
8104 r
->out
.value_name
= talloc_strdup(r
, "");
8105 if (!r
->out
.value_name
) {
8106 result
= WERR_NOMEM
;
8110 r
->out
.value_name
= NULL
;
8111 *r
->out
.value_needed
= 0;
8114 /* the data is counted in bytes */
8116 *r
->out
.data_needed
= r
->in
.data_offered
;
8118 result
= WERR_NO_MORE_ITEMS
;
8122 * - counted in bytes in the request
8123 * - counted in UNICODE chars in the max reply
8124 * - counted in bytes in the real size
8126 * take a pause *before* coding not *during* coding
8130 if (r
->in
.value_offered
) {
8131 r
->out
.value_name
= talloc_strdup(r
, regval_name(val
));
8132 if (!r
->out
.value_name
) {
8133 result
= WERR_NOMEM
;
8136 *r
->out
.value_needed
= strlen_m(regval_name(val
));
8138 r
->out
.value_name
= NULL
;
8139 *r
->out
.value_needed
= 0;
8144 *r
->out
.type
= regval_type(val
);
8146 /* data - counted in bytes */
8148 if (r
->out
.data
&& regval_size(val
)) {
8149 memcpy(r
->out
.data
, regval_data_p(val
), regval_size(val
));
8152 *r
->out
.data_needed
= regval_size(val
);
8156 free_a_printer(&printer
, 2);
8160 /****************************************************************
8161 _spoolss_SetPrinterData
8162 ****************************************************************/
8164 WERROR
_spoolss_SetPrinterData(pipes_struct
*p
,
8165 struct spoolss_SetPrinterData
*r
)
8167 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8169 WERROR result
= WERR_OK
;
8170 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8173 DEBUG(5,("_spoolss_SetPrinterData\n"));
8176 DEBUG(2,("_spoolss_SetPrinterData: Invalid handle (%s:%u:%u).\n",
8177 OUR_HANDLE(r
->in
.handle
)));
8181 if (Printer
->printer_type
== SPLHND_SERVER
) {
8182 DEBUG(10,("_spoolss_SetPrinterData: "
8183 "Not implemented for server handles yet\n"));
8184 return WERR_INVALID_PARAM
;
8187 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
8192 * Access check : NT returns "access denied" if you make a
8193 * SetPrinterData call without the necessary privildge.
8194 * we were originally returning OK if nothing changed
8195 * which made Win2k issue **a lot** of SetPrinterData
8196 * when connecting to a printer --jerry
8199 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8200 DEBUG(3,("_spoolss_SetPrinterData: "
8201 "change denied by handle access permissions\n"));
8202 result
= WERR_ACCESS_DENIED
;
8206 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8207 if (!W_ERROR_IS_OK(result
)) {
8211 result
= push_spoolss_PrinterData(p
->mem_ctx
, &blob
,
8212 r
->in
.type
, &r
->in
.data
);
8213 if (!W_ERROR_IS_OK(result
)) {
8218 * When client side code sets a magic printer data key, detect it and save
8219 * the current printer data and the magic key's data (its the DEVMODE) for
8220 * future printer/driver initializations.
8222 if ((r
->in
.type
== REG_BINARY
) && strequal(r
->in
.value_name
, PHANTOM_DEVMODE_KEY
)) {
8223 /* Set devmode and printer initialization info */
8224 result
= save_driver_init(printer
, 2, blob
.data
, blob
.length
);
8226 srv_spoolss_reset_printerdata(printer
->info_2
->drivername
);
8231 result
= set_printer_dataex(printer
, SPOOL_PRINTERDATA_KEY
,
8232 r
->in
.value_name
, r
->in
.type
,
8233 blob
.data
, blob
.length
);
8234 if (W_ERROR_IS_OK(result
)) {
8235 result
= mod_a_printer(printer
, 2);
8239 free_a_printer(&printer
, 2);
8244 /****************************************************************
8245 _spoolss_ResetPrinter
8246 ****************************************************************/
8248 WERROR
_spoolss_ResetPrinter(pipes_struct
*p
,
8249 struct spoolss_ResetPrinter
*r
)
8251 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8254 DEBUG(5,("_spoolss_ResetPrinter\n"));
8257 * All we do is to check to see if the handle and queue is valid.
8258 * This call really doesn't mean anything to us because we only
8259 * support RAW printing. --jerry
8263 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8264 OUR_HANDLE(r
->in
.handle
)));
8268 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
8272 /* blindly return success */
8276 /****************************************************************
8277 _spoolss_DeletePrinterData
8278 ****************************************************************/
8280 WERROR
_spoolss_DeletePrinterData(pipes_struct
*p
,
8281 struct spoolss_DeletePrinterData
*r
)
8283 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8285 WERROR status
= WERR_OK
;
8286 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8288 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8291 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8292 OUR_HANDLE(r
->in
.handle
)));
8296 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
8299 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8300 DEBUG(3, ("_spoolss_DeletePrinterData: "
8301 "printer properties change denied by handle\n"));
8302 return WERR_ACCESS_DENIED
;
8305 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8306 if (!W_ERROR_IS_OK(status
))
8309 if (!r
->in
.value_name
) {
8310 free_a_printer(&printer
, 2);
8314 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
,
8317 if ( W_ERROR_IS_OK(status
) )
8318 mod_a_printer( printer
, 2 );
8320 free_a_printer(&printer
, 2);
8325 /****************************************************************
8327 ****************************************************************/
8329 WERROR
_spoolss_AddForm(pipes_struct
*p
,
8330 struct spoolss_AddForm
*r
)
8332 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8333 nt_forms_struct tmpForm
;
8335 WERROR status
= WERR_OK
;
8336 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8337 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
8340 nt_forms_struct
*list
=NULL
;
8341 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8343 DEBUG(5,("_spoolss_AddForm\n"));
8346 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8347 OUR_HANDLE(r
->in
.handle
)));
8352 /* forms can be added on printer of on the print server handle */
8354 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8356 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
8359 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8360 if (!W_ERROR_IS_OK(status
))
8364 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8365 and not a printer admin, then fail */
8367 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
8368 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
8369 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
8371 p
->server_info
->ptok
,
8372 lp_printer_admin(snum
))) {
8373 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
8374 return WERR_ACCESS_DENIED
;
8377 /* can't add if builtin */
8379 if (get_a_builtin_ntform_by_string(form
->form_name
, &tmpForm
)) {
8380 status
= WERR_FILE_EXISTS
;
8384 count
= get_ntforms(&list
);
8386 if(!add_a_form(&list
, form
, &count
)) {
8387 status
= WERR_NOMEM
;
8392 write_ntforms(&list
, count
);
8396 * ChangeID must always be set if this is a printer
8399 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8400 status
= mod_a_printer(printer
, 2);
8404 free_a_printer(&printer
, 2);
8410 /****************************************************************
8412 ****************************************************************/
8414 WERROR
_spoolss_DeleteForm(pipes_struct
*p
,
8415 struct spoolss_DeleteForm
*r
)
8417 const char *form_name
= r
->in
.form_name
;
8418 nt_forms_struct tmpForm
;
8420 nt_forms_struct
*list
=NULL
;
8421 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8423 WERROR status
= WERR_OK
;
8424 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8425 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
8428 DEBUG(5,("_spoolss_DeleteForm\n"));
8431 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8432 OUR_HANDLE(r
->in
.handle
)));
8436 /* forms can be deleted on printer of on the print server handle */
8438 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8440 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
8443 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8444 if (!W_ERROR_IS_OK(status
))
8448 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
8449 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
8450 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
8452 p
->server_info
->ptok
,
8453 lp_printer_admin(snum
))) {
8454 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8455 return WERR_ACCESS_DENIED
;
8459 /* can't delete if builtin */
8461 if (get_a_builtin_ntform_by_string(form_name
,&tmpForm
)) {
8462 status
= WERR_INVALID_PARAM
;
8466 count
= get_ntforms(&list
);
8469 ret
= delete_a_form(&list
, form_name
, &count
, &status
);
8476 * ChangeID must always be set if this is a printer
8479 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8480 status
= mod_a_printer(printer
, 2);
8484 free_a_printer(&printer
, 2);
8490 /****************************************************************
8492 ****************************************************************/
8494 WERROR
_spoolss_SetForm(pipes_struct
*p
,
8495 struct spoolss_SetForm
*r
)
8497 struct spoolss_AddFormInfo1
*form
= r
->in
.info
.info1
;
8498 nt_forms_struct tmpForm
;
8500 WERROR status
= WERR_OK
;
8501 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8502 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
8505 nt_forms_struct
*list
=NULL
;
8506 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
8508 DEBUG(5,("_spoolss_SetForm\n"));
8511 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8512 OUR_HANDLE(r
->in
.handle
)));
8516 /* forms can be modified on printer of on the print server handle */
8518 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8520 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
8523 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8524 if (!W_ERROR_IS_OK(status
))
8528 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8529 and not a printer admin, then fail */
8531 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
8532 !user_has_privileges(p
->server_info
->ptok
, &se_printop
) &&
8533 !token_contains_name_in_list(uidtoname(p
->server_info
->utok
.uid
),
8535 p
->server_info
->ptok
,
8536 lp_printer_admin(snum
))) {
8537 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8538 return WERR_ACCESS_DENIED
;
8541 /* can't set if builtin */
8542 if (get_a_builtin_ntform_by_string(form
->form_name
, &tmpForm
)) {
8543 status
= WERR_INVALID_PARAM
;
8547 count
= get_ntforms(&list
);
8548 update_a_form(&list
, form
, count
);
8550 write_ntforms(&list
, count
);
8554 * ChangeID must always be set if this is a printer
8557 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8558 status
= mod_a_printer(printer
, 2);
8563 free_a_printer(&printer
, 2);
8569 /****************************************************************************
8570 fill_print_processor1
8571 ****************************************************************************/
8573 static WERROR
fill_print_processor1(TALLOC_CTX
*mem_ctx
,
8574 struct spoolss_PrintProcessorInfo1
*r
,
8575 const char *print_processor_name
)
8577 r
->print_processor_name
= talloc_strdup(mem_ctx
, print_processor_name
);
8578 W_ERROR_HAVE_NO_MEMORY(r
->print_processor_name
);
8583 /****************************************************************************
8584 enumprintprocessors level 1.
8585 ****************************************************************************/
8587 static WERROR
enumprintprocessors_level_1(TALLOC_CTX
*mem_ctx
,
8588 union spoolss_PrintProcessorInfo
**info_p
,
8591 union spoolss_PrintProcessorInfo
*info
;
8594 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PrintProcessorInfo
, 1);
8595 W_ERROR_HAVE_NO_MEMORY(info
);
8599 result
= fill_print_processor1(info
, &info
[0].info1
, "winprint");
8600 if (!W_ERROR_IS_OK(result
)) {
8605 if (!W_ERROR_IS_OK(result
)) {
8616 /****************************************************************
8617 _spoolss_EnumPrintProcessors
8618 ****************************************************************/
8620 WERROR
_spoolss_EnumPrintProcessors(pipes_struct
*p
,
8621 struct spoolss_EnumPrintProcessors
*r
)
8625 /* that's an [in out] buffer */
8627 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8628 return WERR_INVALID_PARAM
;
8631 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8634 * Enumerate the print processors ...
8636 * Just reply with "winprint", to keep NT happy
8637 * and I can use my nice printer checker.
8642 *r
->out
.info
= NULL
;
8644 switch (r
->in
.level
) {
8646 result
= enumprintprocessors_level_1(p
->mem_ctx
, r
->out
.info
,
8650 return WERR_UNKNOWN_LEVEL
;
8653 if (!W_ERROR_IS_OK(result
)) {
8657 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8658 spoolss_EnumPrintProcessors
, NULL
,
8659 *r
->out
.info
, r
->in
.level
,
8661 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8662 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8664 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8667 /****************************************************************************
8668 fill_printprocdatatype1
8669 ****************************************************************************/
8671 static WERROR
fill_printprocdatatype1(TALLOC_CTX
*mem_ctx
,
8672 struct spoolss_PrintProcDataTypesInfo1
*r
,
8673 const char *name_array
)
8675 r
->name_array
= talloc_strdup(mem_ctx
, name_array
);
8676 W_ERROR_HAVE_NO_MEMORY(r
->name_array
);
8681 /****************************************************************************
8682 enumprintprocdatatypes level 1.
8683 ****************************************************************************/
8685 static WERROR
enumprintprocdatatypes_level_1(TALLOC_CTX
*mem_ctx
,
8686 union spoolss_PrintProcDataTypesInfo
**info_p
,
8690 union spoolss_PrintProcDataTypesInfo
*info
;
8692 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_PrintProcDataTypesInfo
, 1);
8693 W_ERROR_HAVE_NO_MEMORY(info
);
8697 result
= fill_printprocdatatype1(info
, &info
[0].info1
, "RAW");
8698 if (!W_ERROR_IS_OK(result
)) {
8703 if (!W_ERROR_IS_OK(result
)) {
8714 /****************************************************************
8715 _spoolss_EnumPrintProcDataTypes
8716 ****************************************************************/
8718 WERROR
_spoolss_EnumPrintProcDataTypes(pipes_struct
*p
,
8719 struct spoolss_EnumPrintProcDataTypes
*r
)
8723 /* that's an [in out] buffer */
8725 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8726 return WERR_INVALID_PARAM
;
8729 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8733 *r
->out
.info
= NULL
;
8735 switch (r
->in
.level
) {
8737 result
= enumprintprocdatatypes_level_1(p
->mem_ctx
, r
->out
.info
,
8741 return WERR_UNKNOWN_LEVEL
;
8744 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8745 spoolss_EnumPrintProcDataTypes
, NULL
,
8746 *r
->out
.info
, r
->in
.level
,
8748 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8749 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8751 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8754 /****************************************************************************
8756 ****************************************************************************/
8758 static WERROR
fill_monitor_1(TALLOC_CTX
*mem_ctx
,
8759 struct spoolss_MonitorInfo1
*r
,
8760 const char *monitor_name
)
8762 r
->monitor_name
= talloc_strdup(mem_ctx
, monitor_name
);
8763 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
8768 /****************************************************************************
8770 ****************************************************************************/
8772 static WERROR
fill_monitor_2(TALLOC_CTX
*mem_ctx
,
8773 struct spoolss_MonitorInfo2
*r
,
8774 const char *monitor_name
,
8775 const char *environment
,
8776 const char *dll_name
)
8778 r
->monitor_name
= talloc_strdup(mem_ctx
, monitor_name
);
8779 W_ERROR_HAVE_NO_MEMORY(r
->monitor_name
);
8780 r
->environment
= talloc_strdup(mem_ctx
, environment
);
8781 W_ERROR_HAVE_NO_MEMORY(r
->environment
);
8782 r
->dll_name
= talloc_strdup(mem_ctx
, dll_name
);
8783 W_ERROR_HAVE_NO_MEMORY(r
->dll_name
);
8788 /****************************************************************************
8789 enumprintmonitors level 1.
8790 ****************************************************************************/
8792 static WERROR
enumprintmonitors_level_1(TALLOC_CTX
*mem_ctx
,
8793 union spoolss_MonitorInfo
**info_p
,
8796 union spoolss_MonitorInfo
*info
;
8797 WERROR result
= WERR_OK
;
8799 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_MonitorInfo
, 2);
8800 W_ERROR_HAVE_NO_MEMORY(info
);
8804 result
= fill_monitor_1(info
, &info
[0].info1
,
8806 if (!W_ERROR_IS_OK(result
)) {
8810 result
= fill_monitor_1(info
, &info
[1].info1
,
8812 if (!W_ERROR_IS_OK(result
)) {
8817 if (!W_ERROR_IS_OK(result
)) {
8828 /****************************************************************************
8829 enumprintmonitors level 2.
8830 ****************************************************************************/
8832 static WERROR
enumprintmonitors_level_2(TALLOC_CTX
*mem_ctx
,
8833 union spoolss_MonitorInfo
**info_p
,
8836 union spoolss_MonitorInfo
*info
;
8837 WERROR result
= WERR_OK
;
8839 info
= TALLOC_ARRAY(mem_ctx
, union spoolss_MonitorInfo
, 2);
8840 W_ERROR_HAVE_NO_MEMORY(info
);
8844 result
= fill_monitor_2(info
, &info
[0].info2
,
8846 "Windows NT X86", /* FIXME */
8848 if (!W_ERROR_IS_OK(result
)) {
8852 result
= fill_monitor_2(info
, &info
[1].info2
,
8854 "Windows NT X86", /* FIXME */
8856 if (!W_ERROR_IS_OK(result
)) {
8861 if (!W_ERROR_IS_OK(result
)) {
8872 /****************************************************************
8873 _spoolss_EnumMonitors
8874 ****************************************************************/
8876 WERROR
_spoolss_EnumMonitors(pipes_struct
*p
,
8877 struct spoolss_EnumMonitors
*r
)
8881 /* that's an [in out] buffer */
8883 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
8884 return WERR_INVALID_PARAM
;
8887 DEBUG(5,("_spoolss_EnumMonitors\n"));
8890 * Enumerate the print monitors ...
8892 * Just reply with "Local Port", to keep NT happy
8893 * and I can use my nice printer checker.
8898 *r
->out
.info
= NULL
;
8900 switch (r
->in
.level
) {
8902 result
= enumprintmonitors_level_1(p
->mem_ctx
, r
->out
.info
,
8906 result
= enumprintmonitors_level_2(p
->mem_ctx
, r
->out
.info
,
8910 return WERR_UNKNOWN_LEVEL
;
8913 if (!W_ERROR_IS_OK(result
)) {
8917 *r
->out
.needed
= SPOOLSS_BUFFER_UNION_ARRAY(p
->mem_ctx
,
8918 spoolss_EnumMonitors
, NULL
,
8919 *r
->out
.info
, r
->in
.level
,
8921 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
8922 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, 0);
8924 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
8927 /****************************************************************************
8928 ****************************************************************************/
8930 static WERROR
getjob_level_1(TALLOC_CTX
*mem_ctx
,
8931 const print_queue_struct
*queue
,
8932 int count
, int snum
,
8933 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
8935 struct spoolss_JobInfo1
*r
)
8940 for (i
=0; i
<count
&& found
== false; i
++) {
8941 if (queue
[i
].job
== (int)jobid
) {
8946 if (found
== false) {
8947 /* NT treats not found as bad param... yet another bad choice */
8948 return WERR_INVALID_PARAM
;
8951 return fill_job_info1(mem_ctx
,
8959 /****************************************************************************
8960 ****************************************************************************/
8962 static WERROR
getjob_level_2(TALLOC_CTX
*mem_ctx
,
8963 const print_queue_struct
*queue
,
8964 int count
, int snum
,
8965 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
8967 struct spoolss_JobInfo2
*r
)
8971 struct spoolss_DeviceMode
*devmode
;
8972 NT_DEVICEMODE
*nt_devmode
;
8975 for (i
=0; i
<count
&& found
== false; i
++) {
8976 if (queue
[i
].job
== (int)jobid
) {
8981 if (found
== false) {
8982 /* NT treats not found as bad param... yet another bad
8984 return WERR_INVALID_PARAM
;
8988 * if the print job does not have a DEVMODE associated with it,
8989 * just use the one for the printer. A NULL devicemode is not
8990 * a failure condition
8993 nt_devmode
= print_job_devmode(lp_const_servicename(snum
), jobid
);
8995 devmode
= TALLOC_ZERO_P(mem_ctx
, struct spoolss_DeviceMode
);
8996 W_ERROR_HAVE_NO_MEMORY(devmode
);
8997 result
= convert_nt_devicemode(devmode
, devmode
, nt_devmode
);
8998 if (!W_ERROR_IS_OK(result
)) {
9002 devmode
= construct_dev_mode(mem_ctx
, lp_const_servicename(snum
));
9003 W_ERROR_HAVE_NO_MEMORY(devmode
);
9006 return fill_job_info2(mem_ctx
,
9015 /****************************************************************
9017 ****************************************************************/
9019 WERROR
_spoolss_GetJob(pipes_struct
*p
,
9020 struct spoolss_GetJob
*r
)
9022 WERROR result
= WERR_OK
;
9023 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9026 print_queue_struct
*queue
= NULL
;
9027 print_status_struct prt_status
;
9029 /* that's an [in out] buffer */
9031 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
9032 return WERR_INVALID_PARAM
;
9035 DEBUG(5,("_spoolss_GetJob\n"));
9039 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
9043 result
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9044 if (!W_ERROR_IS_OK(result
)) {
9048 count
= print_queue_status(snum
, &queue
, &prt_status
);
9050 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9051 count
, prt_status
.status
, prt_status
.message
));
9053 switch (r
->in
.level
) {
9055 result
= getjob_level_1(p
->mem_ctx
,
9056 queue
, count
, snum
, ntprinter
,
9057 r
->in
.job_id
, &r
->out
.info
->info1
);
9060 result
= getjob_level_2(p
->mem_ctx
,
9061 queue
, count
, snum
, ntprinter
,
9062 r
->in
.job_id
, &r
->out
.info
->info2
);
9065 result
= WERR_UNKNOWN_LEVEL
;
9070 free_a_printer(&ntprinter
, 2);
9072 if (!W_ERROR_IS_OK(result
)) {
9073 TALLOC_FREE(r
->out
.info
);
9077 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_JobInfo
, NULL
,
9078 r
->out
.info
, r
->in
.level
);
9079 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
9081 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
9084 /****************************************************************
9085 _spoolss_GetPrinterDataEx
9087 From MSDN documentation of GetPrinterDataEx: pass request
9088 to GetPrinterData if key is "PrinterDriverData".
9089 ****************************************************************/
9091 WERROR
_spoolss_GetPrinterDataEx(pipes_struct
*p
,
9092 struct spoolss_GetPrinterDataEx
*r
)
9095 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9096 struct regval_blob
*val
= NULL
;
9097 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9099 WERROR result
= WERR_OK
;
9101 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9103 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9104 r
->in
.key_name
, r
->in
.value_name
));
9106 /* in case of problem, return some default values */
9109 *r
->out
.type
= REG_NONE
;
9112 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
9113 OUR_HANDLE(r
->in
.handle
)));
9114 result
= WERR_BADFID
;
9118 /* Is the handle to a printer or to the server? */
9120 if (Printer
->printer_type
== SPLHND_SERVER
) {
9121 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9122 "Not implemented for server handles yet\n"));
9123 result
= WERR_INVALID_PARAM
;
9127 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
9131 result
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9132 if (!W_ERROR_IS_OK(result
)) {
9136 /* check to see if the keyname is valid */
9137 if (!strlen(r
->in
.key_name
)) {
9138 result
= WERR_INVALID_PARAM
;
9142 if (lookup_printerkey(printer
->info_2
->data
, r
->in
.key_name
) == -1) {
9143 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9144 "Invalid keyname [%s]\n", r
->in
.key_name
));
9145 result
= WERR_BADFILE
;
9149 /* When given a new keyname, we should just create it */
9151 val
= get_printer_data(printer
->info_2
,
9152 r
->in
.key_name
, r
->in
.value_name
);
9154 result
= WERR_BADFILE
;
9158 *r
->out
.needed
= regval_size(val
);
9160 if (*r
->out
.needed
> r
->in
.offered
) {
9161 result
= WERR_MORE_DATA
;
9165 *r
->out
.type
= regval_type(val
);
9167 memcpy(r
->out
.buffer
, regval_data_p(val
), regval_size(val
));
9171 free_a_printer(&printer
, 2);
9177 /****************************************************************
9178 _spoolss_SetPrinterDataEx
9179 ****************************************************************/
9181 WERROR
_spoolss_SetPrinterDataEx(pipes_struct
*p
,
9182 struct spoolss_SetPrinterDataEx
*r
)
9184 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9186 WERROR result
= WERR_OK
;
9187 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9190 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9192 /* From MSDN documentation of SetPrinterDataEx: pass request to
9193 SetPrinterData if key is "PrinterDriverData" */
9196 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
9197 OUR_HANDLE(r
->in
.handle
)));
9201 if (Printer
->printer_type
== SPLHND_SERVER
) {
9202 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9203 "Not implemented for server handles yet\n"));
9204 return WERR_INVALID_PARAM
;
9207 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
9212 * Access check : NT returns "access denied" if you make a
9213 * SetPrinterData call without the necessary privildge.
9214 * we were originally returning OK if nothing changed
9215 * which made Win2k issue **a lot** of SetPrinterData
9216 * when connecting to a printer --jerry
9219 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9220 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9221 "change denied by handle access permissions\n"));
9222 return WERR_ACCESS_DENIED
;
9225 result
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9226 if (!W_ERROR_IS_OK(result
)) {
9230 /* check for OID in valuename */
9232 oid_string
= strchr(r
->in
.value_name
, ',');
9238 /* save the registry data */
9240 result
= set_printer_dataex(printer
, r
->in
.key_name
, r
->in
.value_name
,
9241 r
->in
.type
, r
->in
.buffer
, r
->in
.offered
);
9243 if (W_ERROR_IS_OK(result
)) {
9244 /* save the OID if one was specified */
9246 char *str
= talloc_asprintf(p
->mem_ctx
, "%s\\%s",
9247 r
->in
.key_name
, SPOOL_OID_KEY
);
9249 result
= WERR_NOMEM
;
9254 * I'm not checking the status here on purpose. Don't know
9255 * if this is right, but I'm returning the status from the
9256 * previous set_printer_dataex() call. I have no idea if
9257 * this is right. --jerry
9260 set_printer_dataex(printer
, str
, r
->in
.value_name
,
9261 REG_SZ
, (uint8_t *)oid_string
,
9262 strlen(oid_string
)+1);
9265 result
= mod_a_printer(printer
, 2);
9269 free_a_printer(&printer
, 2);
9274 /****************************************************************
9275 _spoolss_DeletePrinterDataEx
9276 ****************************************************************/
9278 WERROR
_spoolss_DeletePrinterDataEx(pipes_struct
*p
,
9279 struct spoolss_DeletePrinterDataEx
*r
)
9281 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9283 WERROR status
= WERR_OK
;
9284 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9286 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9289 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9290 "Invalid handle (%s:%u:%u).\n",
9291 OUR_HANDLE(r
->in
.handle
)));
9295 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
9298 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9299 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9300 "printer properties change denied by handle\n"));
9301 return WERR_ACCESS_DENIED
;
9304 if (!r
->in
.value_name
|| !r
->in
.key_name
) {
9308 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9309 if (!W_ERROR_IS_OK(status
))
9312 status
= delete_printer_dataex( printer
, r
->in
.key_name
, r
->in
.value_name
);
9314 if ( W_ERROR_IS_OK(status
) )
9315 mod_a_printer( printer
, 2 );
9317 free_a_printer(&printer
, 2);
9322 /****************************************************************
9323 _spoolss_EnumPrinterKey
9324 ****************************************************************/
9326 WERROR
_spoolss_EnumPrinterKey(pipes_struct
*p
,
9327 struct spoolss_EnumPrinterKey
*r
)
9329 fstring
*keynames
= NULL
;
9331 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9332 NT_PRINTER_DATA
*data
;
9333 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9335 WERROR result
= WERR_BADFILE
;
9337 const char **array
= NULL
;
9340 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9343 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9344 OUR_HANDLE(r
->in
.handle
)));
9348 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
9352 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9353 if (!W_ERROR_IS_OK(result
)) {
9357 /* get the list of subkey names */
9359 data
= printer
->info_2
->data
;
9361 num_keys
= get_printer_subkeys(data
, r
->in
.key_name
, &keynames
);
9362 if (num_keys
== -1) {
9363 result
= WERR_BADFILE
;
9369 array
= talloc_zero_array(r
->out
.key_buffer
, const char *, num_keys
+ 1);
9371 result
= WERR_NOMEM
;
9375 for (i
=0; i
< num_keys
; i
++) {
9376 array
[i
] = talloc_strdup(array
, keynames
[i
]);
9378 result
= WERR_NOMEM
;
9382 *r
->out
.needed
+= strlen_m_term(keynames
[i
]) * 2;
9385 if (r
->in
.offered
< *r
->out
.needed
) {
9386 result
= WERR_MORE_DATA
;
9392 *r
->out
.key_buffer
= array
;
9395 if (!W_ERROR_IS_OK(result
)) {
9397 ZERO_STRUCTP(r
->out
.key_buffer
);
9400 free_a_printer(&printer
, 2);
9401 SAFE_FREE(keynames
);
9406 /****************************************************************
9407 _spoolss_DeletePrinterKey
9408 ****************************************************************/
9410 WERROR
_spoolss_DeletePrinterKey(pipes_struct
*p
,
9411 struct spoolss_DeletePrinterKey
*r
)
9413 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9414 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9418 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9421 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9422 OUR_HANDLE(r
->in
.handle
)));
9426 /* if keyname == NULL, return error */
9428 if ( !r
->in
.key_name
)
9429 return WERR_INVALID_PARAM
;
9431 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
))
9434 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9435 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9436 "printer properties change denied by handle\n"));
9437 return WERR_ACCESS_DENIED
;
9440 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9441 if (!W_ERROR_IS_OK(status
))
9444 /* delete the key and all subneys */
9446 status
= delete_all_printer_data( printer
->info_2
, r
->in
.key_name
);
9448 if ( W_ERROR_IS_OK(status
) )
9449 status
= mod_a_printer(printer
, 2);
9451 free_a_printer( &printer
, 2 );
9456 /****************************************************************
9457 ****************************************************************/
9459 static WERROR
registry_value_to_printer_enum_value(TALLOC_CTX
*mem_ctx
,
9460 struct regval_blob
*v
,
9461 struct spoolss_PrinterEnumValues
*r
)
9465 r
->data
= TALLOC_ZERO_P(mem_ctx
, union spoolss_PrinterData
);
9466 W_ERROR_HAVE_NO_MEMORY(r
->data
);
9468 r
->value_name
= talloc_strdup(mem_ctx
, regval_name(v
));
9469 W_ERROR_HAVE_NO_MEMORY(r
->value_name
);
9471 r
->type
= regval_type(v
);
9472 r
->data_length
= regval_size(v
);
9474 if (r
->data_length
) {
9475 DATA_BLOB blob
= data_blob_const(regval_data_p(v
),
9477 result
= pull_spoolss_PrinterData(mem_ctx
, &blob
,
9480 if (!W_ERROR_IS_OK(result
)) {
9488 /****************************************************************
9489 _spoolss_EnumPrinterDataEx
9490 ****************************************************************/
9492 WERROR
_spoolss_EnumPrinterDataEx(pipes_struct
*p
,
9493 struct spoolss_EnumPrinterDataEx
*r
)
9496 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9497 struct spoolss_PrinterEnumValues
*info
= NULL
;
9498 NT_PRINTER_DATA
*p_data
;
9499 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9505 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9509 *r
->out
.info
= NULL
;
9512 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9513 OUR_HANDLE(r
->in
.handle
)));
9518 * first check for a keyname of NULL or "". Win2k seems to send
9519 * this a lot and we should send back WERR_INVALID_PARAM
9520 * no need to spend time looking up the printer in this case.
9524 if (!strlen(r
->in
.key_name
)) {
9525 result
= WERR_INVALID_PARAM
;
9529 /* get the printer off of disk */
9531 if (!get_printer_snum(p
, r
->in
.handle
, &snum
, NULL
)) {
9535 ZERO_STRUCT(printer
);
9536 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9537 if (!W_ERROR_IS_OK(result
)) {
9541 /* now look for a match on the key name */
9543 p_data
= printer
->info_2
->data
;
9545 key_index
= lookup_printerkey(p_data
, r
->in
.key_name
);
9546 if (key_index
== -1) {
9547 DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
9549 result
= WERR_INVALID_PARAM
;
9553 /* allocate the memory for the array of pointers -- if necessary */
9555 count
= regval_ctr_numvals(p_data
->keys
[key_index
].values
);
9557 result
= WERR_OK
; /* ??? */
9561 info
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,
9562 struct spoolss_PrinterEnumValues
,
9565 DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
9566 result
= WERR_NOMEM
;
9571 * loop through all params and build the array to pass
9572 * back to the client
9575 for (i
=0; i
< count
; i
++) {
9577 struct regval_blob
*val
;
9579 /* lookup the registry value */
9581 val
= regval_ctr_specific_value(p_data
->keys
[key_index
].values
, i
);
9583 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
)));
9587 result
= registry_value_to_printer_enum_value(info
, val
, &info
[i
]);
9588 if (!W_ERROR_IS_OK(result
)) {
9593 #if 0 /* FIXME - gd */
9594 /* housekeeping information in the reply */
9596 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9597 * the hand marshalled container size is a multiple
9598 * of 4 bytes for RPC alignment.
9602 needed
+= 4-(needed
% 4);
9605 *r
->out
.count
= count
;
9606 *r
->out
.info
= info
;
9611 free_a_printer(&printer
, 2);
9614 if (!W_ERROR_IS_OK(result
)) {
9618 *r
->out
.needed
= SPOOLSS_BUFFER_ARRAY(p
->mem_ctx
,
9619 spoolss_EnumPrinterDataEx
, NULL
,
9622 *r
->out
.info
= SPOOLSS_BUFFER_OK(*r
->out
.info
, NULL
);
9623 *r
->out
.count
= SPOOLSS_BUFFER_OK(*r
->out
.count
, *r
->out
.count
);
9625 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_MORE_DATA
);
9628 /****************************************************************************
9629 ****************************************************************************/
9631 static WERROR
getprintprocessordirectory_level_1(TALLOC_CTX
*mem_ctx
,
9632 const char *servername
,
9633 const char *environment
,
9634 struct spoolss_PrintProcessorDirectoryInfo1
*r
)
9639 werr
= compose_spoolss_server_path(mem_ctx
,
9642 SPOOLSS_PRTPROCS_PATH
,
9644 if (!W_ERROR_IS_OK(werr
)) {
9648 DEBUG(4,("print processor directory: [%s]\n", path
));
9650 r
->directory_name
= path
;
9655 /****************************************************************
9656 _spoolss_GetPrintProcessorDirectory
9657 ****************************************************************/
9659 WERROR
_spoolss_GetPrintProcessorDirectory(pipes_struct
*p
,
9660 struct spoolss_GetPrintProcessorDirectory
*r
)
9664 /* that's an [in out] buffer */
9666 if (!r
->in
.buffer
&& (r
->in
.offered
!= 0)) {
9667 return WERR_INVALID_PARAM
;
9670 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9675 /* r->in.level is ignored */
9677 /* We always should reply with a local print processor directory so that
9678 * users are not forced to have a [prnproc$] share on the Samba spoolss
9679 * server - Guenther */
9681 result
= getprintprocessordirectory_level_1(p
->mem_ctx
,
9682 NULL
, /* r->in.server */
9684 &r
->out
.info
->info1
);
9685 if (!W_ERROR_IS_OK(result
)) {
9686 TALLOC_FREE(r
->out
.info
);
9690 *r
->out
.needed
= SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo
, NULL
,
9691 r
->out
.info
, r
->in
.level
);
9692 r
->out
.info
= SPOOLSS_BUFFER_OK(r
->out
.info
, NULL
);
9694 return SPOOLSS_BUFFER_OK(WERR_OK
, WERR_INSUFFICIENT_BUFFER
);
9697 /*******************************************************************
9698 ********************************************************************/
9700 static bool push_monitorui_buf(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*buf
,
9701 const char *dllname
)
9703 enum ndr_err_code ndr_err
;
9704 struct spoolss_MonitorUi ui
;
9706 ui
.dll_name
= dllname
;
9708 ndr_err
= ndr_push_struct_blob(buf
, mem_ctx
, NULL
, &ui
,
9709 (ndr_push_flags_fn_t
)ndr_push_spoolss_MonitorUi
);
9710 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9711 NDR_PRINT_DEBUG(spoolss_MonitorUi
, &ui
);
9713 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9716 /*******************************************************************
9717 Streams the monitor UI DLL name in UNICODE
9718 *******************************************************************/
9720 static WERROR
xcvtcp_monitorui(TALLOC_CTX
*mem_ctx
,
9721 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9722 DATA_BLOB
*out
, uint32_t *needed
)
9724 const char *dllname
= "tcpmonui.dll";
9726 *needed
= (strlen(dllname
)+1) * 2;
9728 if (out
->length
< *needed
) {
9729 return WERR_INSUFFICIENT_BUFFER
;
9732 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
9739 /*******************************************************************
9740 ********************************************************************/
9742 static bool pull_port_data_1(TALLOC_CTX
*mem_ctx
,
9743 struct spoolss_PortData1
*port1
,
9744 const DATA_BLOB
*buf
)
9746 enum ndr_err_code ndr_err
;
9747 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, NULL
, port1
,
9748 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData1
);
9749 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9750 NDR_PRINT_DEBUG(spoolss_PortData1
, port1
);
9752 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9755 /*******************************************************************
9756 ********************************************************************/
9758 static bool pull_port_data_2(TALLOC_CTX
*mem_ctx
,
9759 struct spoolss_PortData2
*port2
,
9760 const DATA_BLOB
*buf
)
9762 enum ndr_err_code ndr_err
;
9763 ndr_err
= ndr_pull_struct_blob(buf
, mem_ctx
, NULL
, port2
,
9764 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_PortData2
);
9765 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
) && (DEBUGLEVEL
>= 10)) {
9766 NDR_PRINT_DEBUG(spoolss_PortData2
, port2
);
9768 return NDR_ERR_CODE_IS_SUCCESS(ndr_err
);
9771 /*******************************************************************
9772 Create a new TCP/IP port
9773 *******************************************************************/
9775 static WERROR
xcvtcp_addport(TALLOC_CTX
*mem_ctx
,
9776 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9777 DATA_BLOB
*out
, uint32_t *needed
)
9779 struct spoolss_PortData1 port1
;
9780 struct spoolss_PortData2 port2
;
9781 char *device_uri
= NULL
;
9784 const char *portname
;
9785 const char *hostaddress
;
9787 uint32_t port_number
;
9790 /* peek for spoolss_PortData version */
9792 if (!in
|| (in
->length
< (128 + 4))) {
9793 return WERR_GENERAL_FAILURE
;
9796 version
= IVAL(in
->data
, 128);
9802 if (!pull_port_data_1(mem_ctx
, &port1
, in
)) {
9806 portname
= port1
.portname
;
9807 hostaddress
= port1
.hostaddress
;
9808 queue
= port1
.queue
;
9809 protocol
= port1
.protocol
;
9810 port_number
= port1
.port_number
;
9816 if (!pull_port_data_2(mem_ctx
, &port2
, in
)) {
9820 portname
= port2
.portname
;
9821 hostaddress
= port2
.hostaddress
;
9822 queue
= port2
.queue
;
9823 protocol
= port2
.protocol
;
9824 port_number
= port2
.port_number
;
9828 DEBUG(1,("xcvtcp_addport: "
9829 "unknown version of port_data: %d\n", version
));
9830 return WERR_UNKNOWN_PORT
;
9833 /* create the device URI and call the add_port_hook() */
9836 case PROTOCOL_RAWTCP_TYPE
:
9837 device_uri
= talloc_asprintf(mem_ctx
,
9838 "socket://%s:%d/", hostaddress
,
9842 case PROTOCOL_LPR_TYPE
:
9843 device_uri
= talloc_asprintf(mem_ctx
,
9844 "lpr://%s/%s", hostaddress
, queue
);
9848 return WERR_UNKNOWN_PORT
;
9855 return add_port_hook(mem_ctx
, token
, portname
, device_uri
);
9858 /*******************************************************************
9859 *******************************************************************/
9861 struct xcv_api_table xcvtcp_cmds
[] = {
9862 { "MonitorUI", xcvtcp_monitorui
},
9863 { "AddPort", xcvtcp_addport
},
9867 static WERROR
process_xcvtcp_command(TALLOC_CTX
*mem_ctx
,
9868 NT_USER_TOKEN
*token
, const char *command
,
9875 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9877 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9878 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9879 return xcvtcp_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
9882 return WERR_BADFUNC
;
9885 /*******************************************************************
9886 *******************************************************************/
9887 #if 0 /* don't support management using the "Local Port" monitor */
9889 static WERROR
xcvlocal_monitorui(TALLOC_CTX
*mem_ctx
,
9890 NT_USER_TOKEN
*token
, DATA_BLOB
*in
,
9891 DATA_BLOB
*out
, uint32_t *needed
)
9893 const char *dllname
= "localui.dll";
9895 *needed
= (strlen(dllname
)+1) * 2;
9897 if (out
->length
< *needed
) {
9898 return WERR_INSUFFICIENT_BUFFER
;
9901 if (!push_monitorui_buf(mem_ctx
, out
, dllname
)) {
9908 /*******************************************************************
9909 *******************************************************************/
9911 struct xcv_api_table xcvlocal_cmds
[] = {
9912 { "MonitorUI", xcvlocal_monitorui
},
9916 struct xcv_api_table xcvlocal_cmds
[] = {
9923 /*******************************************************************
9924 *******************************************************************/
9926 static WERROR
process_xcvlocal_command(TALLOC_CTX
*mem_ctx
,
9927 NT_USER_TOKEN
*token
, const char *command
,
9928 DATA_BLOB
*inbuf
, DATA_BLOB
*outbuf
,
9933 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9935 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9936 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9937 return xcvlocal_cmds
[i
].fn(mem_ctx
, token
, inbuf
, outbuf
, needed
);
9939 return WERR_BADFUNC
;
9942 /****************************************************************
9944 ****************************************************************/
9946 WERROR
_spoolss_XcvData(pipes_struct
*p
,
9947 struct spoolss_XcvData
*r
)
9949 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, r
->in
.handle
);
9950 DATA_BLOB out_data
= data_blob_null
;
9954 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9955 OUR_HANDLE(r
->in
.handle
)));
9959 /* Has to be a handle to the TCP/IP port monitor */
9961 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9962 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9966 /* requires administrative access to the server */
9968 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9969 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9970 return WERR_ACCESS_DENIED
;
9973 /* Allocate the outgoing buffer */
9975 if (r
->in
.out_data_size
) {
9976 out_data
= data_blob_talloc_zero(p
->mem_ctx
, r
->in
.out_data_size
);
9977 if (out_data
.data
== NULL
) {
9982 switch ( Printer
->printer_type
) {
9983 case SPLHND_PORTMON_TCP
:
9984 werror
= process_xcvtcp_command(p
->mem_ctx
,
9985 p
->server_info
->ptok
,
9986 r
->in
.function_name
,
9987 &r
->in
.in_data
, &out_data
,
9990 case SPLHND_PORTMON_LOCAL
:
9991 werror
= process_xcvlocal_command(p
->mem_ctx
,
9992 p
->server_info
->ptok
,
9993 r
->in
.function_name
,
9994 &r
->in
.in_data
, &out_data
,
9998 werror
= WERR_INVALID_PRINT_MONITOR
;
10001 if (!W_ERROR_IS_OK(werror
)) {
10005 *r
->out
.status_code
= 0;
10007 memcpy(r
->out
.out_data
, out_data
.data
, out_data
.length
);
10012 /****************************************************************
10013 _spoolss_AddPrintProcessor
10014 ****************************************************************/
10016 WERROR
_spoolss_AddPrintProcessor(pipes_struct
*p
,
10017 struct spoolss_AddPrintProcessor
*r
)
10019 /* for now, just indicate success and ignore the add. We'll
10020 automatically set the winprint processor for printer
10021 entries later. Used to debug the LexMark Optra S 1855 PCL
10027 /****************************************************************
10029 ****************************************************************/
10031 WERROR
_spoolss_AddPort(pipes_struct
*p
,
10032 struct spoolss_AddPort
*r
)
10034 /* do what w2k3 does */
10036 return WERR_NOT_SUPPORTED
;
10039 /****************************************************************
10040 _spoolss_GetPrinterDriver
10041 ****************************************************************/
10043 WERROR
_spoolss_GetPrinterDriver(pipes_struct
*p
,
10044 struct spoolss_GetPrinterDriver
*r
)
10046 p
->rng_fault_state
= true;
10047 return WERR_NOT_SUPPORTED
;
10050 /****************************************************************
10051 _spoolss_ReadPrinter
10052 ****************************************************************/
10054 WERROR
_spoolss_ReadPrinter(pipes_struct
*p
,
10055 struct spoolss_ReadPrinter
*r
)
10057 p
->rng_fault_state
= true;
10058 return WERR_NOT_SUPPORTED
;
10061 /****************************************************************
10062 _spoolss_WaitForPrinterChange
10063 ****************************************************************/
10065 WERROR
_spoolss_WaitForPrinterChange(pipes_struct
*p
,
10066 struct spoolss_WaitForPrinterChange
*r
)
10068 p
->rng_fault_state
= true;
10069 return WERR_NOT_SUPPORTED
;
10072 /****************************************************************
10073 _spoolss_ConfigurePort
10074 ****************************************************************/
10076 WERROR
_spoolss_ConfigurePort(pipes_struct
*p
,
10077 struct spoolss_ConfigurePort
*r
)
10079 p
->rng_fault_state
= true;
10080 return WERR_NOT_SUPPORTED
;
10083 /****************************************************************
10084 _spoolss_DeletePort
10085 ****************************************************************/
10087 WERROR
_spoolss_DeletePort(pipes_struct
*p
,
10088 struct spoolss_DeletePort
*r
)
10090 p
->rng_fault_state
= true;
10091 return WERR_NOT_SUPPORTED
;
10094 /****************************************************************
10095 _spoolss_CreatePrinterIC
10096 ****************************************************************/
10098 WERROR
_spoolss_CreatePrinterIC(pipes_struct
*p
,
10099 struct spoolss_CreatePrinterIC
*r
)
10101 p
->rng_fault_state
= true;
10102 return WERR_NOT_SUPPORTED
;
10105 /****************************************************************
10106 _spoolss_PlayGDIScriptOnPrinterIC
10107 ****************************************************************/
10109 WERROR
_spoolss_PlayGDIScriptOnPrinterIC(pipes_struct
*p
,
10110 struct spoolss_PlayGDIScriptOnPrinterIC
*r
)
10112 p
->rng_fault_state
= true;
10113 return WERR_NOT_SUPPORTED
;
10116 /****************************************************************
10117 _spoolss_DeletePrinterIC
10118 ****************************************************************/
10120 WERROR
_spoolss_DeletePrinterIC(pipes_struct
*p
,
10121 struct spoolss_DeletePrinterIC
*r
)
10123 p
->rng_fault_state
= true;
10124 return WERR_NOT_SUPPORTED
;
10127 /****************************************************************
10128 _spoolss_AddPrinterConnection
10129 ****************************************************************/
10131 WERROR
_spoolss_AddPrinterConnection(pipes_struct
*p
,
10132 struct spoolss_AddPrinterConnection
*r
)
10134 p
->rng_fault_state
= true;
10135 return WERR_NOT_SUPPORTED
;
10138 /****************************************************************
10139 _spoolss_DeletePrinterConnection
10140 ****************************************************************/
10142 WERROR
_spoolss_DeletePrinterConnection(pipes_struct
*p
,
10143 struct spoolss_DeletePrinterConnection
*r
)
10145 p
->rng_fault_state
= true;
10146 return WERR_NOT_SUPPORTED
;
10149 /****************************************************************
10150 _spoolss_PrinterMessageBox
10151 ****************************************************************/
10153 WERROR
_spoolss_PrinterMessageBox(pipes_struct
*p
,
10154 struct spoolss_PrinterMessageBox
*r
)
10156 p
->rng_fault_state
= true;
10157 return WERR_NOT_SUPPORTED
;
10160 /****************************************************************
10161 _spoolss_AddMonitor
10162 ****************************************************************/
10164 WERROR
_spoolss_AddMonitor(pipes_struct
*p
,
10165 struct spoolss_AddMonitor
*r
)
10167 p
->rng_fault_state
= true;
10168 return WERR_NOT_SUPPORTED
;
10171 /****************************************************************
10172 _spoolss_DeleteMonitor
10173 ****************************************************************/
10175 WERROR
_spoolss_DeleteMonitor(pipes_struct
*p
,
10176 struct spoolss_DeleteMonitor
*r
)
10178 p
->rng_fault_state
= true;
10179 return WERR_NOT_SUPPORTED
;
10182 /****************************************************************
10183 _spoolss_DeletePrintProcessor
10184 ****************************************************************/
10186 WERROR
_spoolss_DeletePrintProcessor(pipes_struct
*p
,
10187 struct spoolss_DeletePrintProcessor
*r
)
10189 p
->rng_fault_state
= true;
10190 return WERR_NOT_SUPPORTED
;
10193 /****************************************************************
10194 _spoolss_AddPrintProvidor
10195 ****************************************************************/
10197 WERROR
_spoolss_AddPrintProvidor(pipes_struct
*p
,
10198 struct spoolss_AddPrintProvidor
*r
)
10200 p
->rng_fault_state
= true;
10201 return WERR_NOT_SUPPORTED
;
10204 /****************************************************************
10205 _spoolss_DeletePrintProvidor
10206 ****************************************************************/
10208 WERROR
_spoolss_DeletePrintProvidor(pipes_struct
*p
,
10209 struct spoolss_DeletePrintProvidor
*r
)
10211 p
->rng_fault_state
= true;
10212 return WERR_NOT_SUPPORTED
;
10215 /****************************************************************
10216 _spoolss_FindFirstPrinterChangeNotification
10217 ****************************************************************/
10219 WERROR
_spoolss_FindFirstPrinterChangeNotification(pipes_struct
*p
,
10220 struct spoolss_FindFirstPrinterChangeNotification
*r
)
10222 p
->rng_fault_state
= true;
10223 return WERR_NOT_SUPPORTED
;
10226 /****************************************************************
10227 _spoolss_FindNextPrinterChangeNotification
10228 ****************************************************************/
10230 WERROR
_spoolss_FindNextPrinterChangeNotification(pipes_struct
*p
,
10231 struct spoolss_FindNextPrinterChangeNotification
*r
)
10233 p
->rng_fault_state
= true;
10234 return WERR_NOT_SUPPORTED
;
10237 /****************************************************************
10238 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10239 ****************************************************************/
10241 WERROR
_spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct
*p
,
10242 struct spoolss_RouterFindFirstPrinterChangeNotificationOld
*r
)
10244 p
->rng_fault_state
= true;
10245 return WERR_NOT_SUPPORTED
;
10248 /****************************************************************
10249 _spoolss_ReplyOpenPrinter
10250 ****************************************************************/
10252 WERROR
_spoolss_ReplyOpenPrinter(pipes_struct
*p
,
10253 struct spoolss_ReplyOpenPrinter
*r
)
10255 p
->rng_fault_state
= true;
10256 return WERR_NOT_SUPPORTED
;
10259 /****************************************************************
10260 _spoolss_RouterReplyPrinter
10261 ****************************************************************/
10263 WERROR
_spoolss_RouterReplyPrinter(pipes_struct
*p
,
10264 struct spoolss_RouterReplyPrinter
*r
)
10266 p
->rng_fault_state
= true;
10267 return WERR_NOT_SUPPORTED
;
10270 /****************************************************************
10271 _spoolss_ReplyClosePrinter
10272 ****************************************************************/
10274 WERROR
_spoolss_ReplyClosePrinter(pipes_struct
*p
,
10275 struct spoolss_ReplyClosePrinter
*r
)
10277 p
->rng_fault_state
= true;
10278 return WERR_NOT_SUPPORTED
;
10281 /****************************************************************
10283 ****************************************************************/
10285 WERROR
_spoolss_AddPortEx(pipes_struct
*p
,
10286 struct spoolss_AddPortEx
*r
)
10288 p
->rng_fault_state
= true;
10289 return WERR_NOT_SUPPORTED
;
10292 /****************************************************************
10293 _spoolss_RouterFindFirstPrinterChangeNotification
10294 ****************************************************************/
10296 WERROR
_spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct
*p
,
10297 struct spoolss_RouterFindFirstPrinterChangeNotification
*r
)
10299 p
->rng_fault_state
= true;
10300 return WERR_NOT_SUPPORTED
;
10303 /****************************************************************
10304 _spoolss_SpoolerInit
10305 ****************************************************************/
10307 WERROR
_spoolss_SpoolerInit(pipes_struct
*p
,
10308 struct spoolss_SpoolerInit
*r
)
10310 p
->rng_fault_state
= true;
10311 return WERR_NOT_SUPPORTED
;
10314 /****************************************************************
10315 _spoolss_ResetPrinterEx
10316 ****************************************************************/
10318 WERROR
_spoolss_ResetPrinterEx(pipes_struct
*p
,
10319 struct spoolss_ResetPrinterEx
*r
)
10321 p
->rng_fault_state
= true;
10322 return WERR_NOT_SUPPORTED
;
10325 /****************************************************************
10326 _spoolss_RouterReplyPrinterEx
10327 ****************************************************************/
10329 WERROR
_spoolss_RouterReplyPrinterEx(pipes_struct
*p
,
10330 struct spoolss_RouterReplyPrinterEx
*r
)
10332 p
->rng_fault_state
= true;
10333 return WERR_NOT_SUPPORTED
;
10336 /****************************************************************
10338 ****************************************************************/
10340 WERROR
_spoolss_44(pipes_struct
*p
,
10341 struct spoolss_44
*r
)
10343 p
->rng_fault_state
= true;
10344 return WERR_NOT_SUPPORTED
;
10347 /****************************************************************
10349 ****************************************************************/
10351 WERROR
_spoolss_47(pipes_struct
*p
,
10352 struct spoolss_47
*r
)
10354 p
->rng_fault_state
= true;
10355 return WERR_NOT_SUPPORTED
;
10358 /****************************************************************
10360 ****************************************************************/
10362 WERROR
_spoolss_4a(pipes_struct
*p
,
10363 struct spoolss_4a
*r
)
10365 p
->rng_fault_state
= true;
10366 return WERR_NOT_SUPPORTED
;
10369 /****************************************************************
10371 ****************************************************************/
10373 WERROR
_spoolss_4b(pipes_struct
*p
,
10374 struct spoolss_4b
*r
)
10376 p
->rng_fault_state
= true;
10377 return WERR_NOT_SUPPORTED
;
10380 /****************************************************************
10382 ****************************************************************/
10384 WERROR
_spoolss_4c(pipes_struct
*p
,
10385 struct spoolss_4c
*r
)
10387 p
->rng_fault_state
= true;
10388 return WERR_NOT_SUPPORTED
;
10391 /****************************************************************
10393 ****************************************************************/
10395 WERROR
_spoolss_53(pipes_struct
*p
,
10396 struct spoolss_53
*r
)
10398 p
->rng_fault_state
= true;
10399 return WERR_NOT_SUPPORTED
;
10402 /****************************************************************
10404 ****************************************************************/
10406 WERROR
_spoolss_55(pipes_struct
*p
,
10407 struct spoolss_55
*r
)
10409 p
->rng_fault_state
= true;
10410 return WERR_NOT_SUPPORTED
;
10413 /****************************************************************
10415 ****************************************************************/
10417 WERROR
_spoolss_56(pipes_struct
*p
,
10418 struct spoolss_56
*r
)
10420 p
->rng_fault_state
= true;
10421 return WERR_NOT_SUPPORTED
;
10424 /****************************************************************
10426 ****************************************************************/
10428 WERROR
_spoolss_57(pipes_struct
*p
,
10429 struct spoolss_57
*r
)
10431 p
->rng_fault_state
= true;
10432 return WERR_NOT_SUPPORTED
;
10435 /****************************************************************
10437 ****************************************************************/
10439 WERROR
_spoolss_5a(pipes_struct
*p
,
10440 struct spoolss_5a
*r
)
10442 p
->rng_fault_state
= true;
10443 return WERR_NOT_SUPPORTED
;
10446 /****************************************************************
10448 ****************************************************************/
10450 WERROR
_spoolss_5b(pipes_struct
*p
,
10451 struct spoolss_5b
*r
)
10453 p
->rng_fault_state
= true;
10454 return WERR_NOT_SUPPORTED
;
10457 /****************************************************************
10459 ****************************************************************/
10461 WERROR
_spoolss_5c(pipes_struct
*p
,
10462 struct spoolss_5c
*r
)
10464 p
->rng_fault_state
= true;
10465 return WERR_NOT_SUPPORTED
;
10468 /****************************************************************
10470 ****************************************************************/
10472 WERROR
_spoolss_5d(pipes_struct
*p
,
10473 struct spoolss_5d
*r
)
10475 p
->rng_fault_state
= true;
10476 return WERR_NOT_SUPPORTED
;
10479 /****************************************************************
10481 ****************************************************************/
10483 WERROR
_spoolss_5e(pipes_struct
*p
,
10484 struct spoolss_5e
*r
)
10486 p
->rng_fault_state
= true;
10487 return WERR_NOT_SUPPORTED
;
10490 /****************************************************************
10492 ****************************************************************/
10494 WERROR
_spoolss_5f(pipes_struct
*p
,
10495 struct spoolss_5f
*r
)
10497 p
->rng_fault_state
= true;
10498 return WERR_NOT_SUPPORTED
;
10501 /****************************************************************
10503 ****************************************************************/
10505 WERROR
_spoolss_60(pipes_struct
*p
,
10506 struct spoolss_60
*r
)
10508 p
->rng_fault_state
= true;
10509 return WERR_NOT_SUPPORTED
;
10512 /****************************************************************
10514 ****************************************************************/
10516 WERROR
_spoolss_61(pipes_struct
*p
,
10517 struct spoolss_61
*r
)
10519 p
->rng_fault_state
= true;
10520 return WERR_NOT_SUPPORTED
;
10523 /****************************************************************
10525 ****************************************************************/
10527 WERROR
_spoolss_62(pipes_struct
*p
,
10528 struct spoolss_62
*r
)
10530 p
->rng_fault_state
= true;
10531 return WERR_NOT_SUPPORTED
;
10534 /****************************************************************
10536 ****************************************************************/
10538 WERROR
_spoolss_63(pipes_struct
*p
,
10539 struct spoolss_63
*r
)
10541 p
->rng_fault_state
= true;
10542 return WERR_NOT_SUPPORTED
;
10545 /****************************************************************
10547 ****************************************************************/
10549 WERROR
_spoolss_64(pipes_struct
*p
,
10550 struct spoolss_64
*r
)
10552 p
->rng_fault_state
= true;
10553 return WERR_NOT_SUPPORTED
;
10556 /****************************************************************
10558 ****************************************************************/
10560 WERROR
_spoolss_65(pipes_struct
*p
,
10561 struct spoolss_65
*r
)
10563 p
->rng_fault_state
= true;
10564 return WERR_NOT_SUPPORTED
;
10567 /****************************************************************
10568 _spoolss_GetCorePrinterDrivers
10569 ****************************************************************/
10571 WERROR
_spoolss_GetCorePrinterDrivers(pipes_struct
*p
,
10572 struct spoolss_GetCorePrinterDrivers
*r
)
10574 p
->rng_fault_state
= true;
10575 return WERR_NOT_SUPPORTED
;
10578 /****************************************************************
10580 ****************************************************************/
10582 WERROR
_spoolss_67(pipes_struct
*p
,
10583 struct spoolss_67
*r
)
10585 p
->rng_fault_state
= true;
10586 return WERR_NOT_SUPPORTED
;
10589 /****************************************************************
10590 _spoolss_GetPrinterDriverPackagePath
10591 ****************************************************************/
10593 WERROR
_spoolss_GetPrinterDriverPackagePath(pipes_struct
*p
,
10594 struct spoolss_GetPrinterDriverPackagePath
*r
)
10596 p
->rng_fault_state
= true;
10597 return WERR_NOT_SUPPORTED
;
10600 /****************************************************************
10602 ****************************************************************/
10604 WERROR
_spoolss_69(pipes_struct
*p
,
10605 struct spoolss_69
*r
)
10607 p
->rng_fault_state
= true;
10608 return WERR_NOT_SUPPORTED
;
10611 /****************************************************************
10613 ****************************************************************/
10615 WERROR
_spoolss_6a(pipes_struct
*p
,
10616 struct spoolss_6a
*r
)
10618 p
->rng_fault_state
= true;
10619 return WERR_NOT_SUPPORTED
;
10622 /****************************************************************
10624 ****************************************************************/
10626 WERROR
_spoolss_6b(pipes_struct
*p
,
10627 struct spoolss_6b
*r
)
10629 p
->rng_fault_state
= true;
10630 return WERR_NOT_SUPPORTED
;
10633 /****************************************************************
10635 ****************************************************************/
10637 WERROR
_spoolss_6c(pipes_struct
*p
,
10638 struct spoolss_6c
*r
)
10640 p
->rng_fault_state
= true;
10641 return WERR_NOT_SUPPORTED
;
10644 /****************************************************************
10646 ****************************************************************/
10648 WERROR
_spoolss_6d(pipes_struct
*p
,
10649 struct spoolss_6d
*r
)
10651 p
->rng_fault_state
= true;
10652 return WERR_NOT_SUPPORTED
;