2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009-2010.
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. */
30 #include "../librpc/gen_ndr/srv_spoolss.h"
31 #include "../librpc/gen_ndr/cli_spoolss.h"
32 #include "librpc/gen_ndr/messaging.h"
35 /* macros stolen from s4 spoolss server */
36 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
37 ((info)?ndr_size_##fn(info, level, 0):0)
39 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
40 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
42 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
43 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
45 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
48 extern userdom_struct current_user_info;
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #ifndef MAX_OPEN_PRINTER_EXS
54 #define MAX_OPEN_PRINTER_EXS 50
57 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
58 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
60 static Printer_entry *printers_list;
62 typedef struct _counter_printer_0 {
63 struct _counter_printer_0 *next;
64 struct _counter_printer_0 *prev;
70 static counter_printer_0 *counter_list;
72 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
73 static uint32_t smb_connections = 0;
76 /* in printing/nt_printing.c */
78 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
80 /* API table for Xcv Monitor functions */
82 struct xcv_api_table {
84 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
87 /********************************************************************
88 * Canonicalize servername.
89 ********************************************************************/
91 static const char *canon_servername(const char *servername)
93 const char *pservername = servername;
94 while (*pservername == '\\') {
100 /* translate between internal status numbers and NT status numbers */
101 static int nt_printj_status(int v)
107 return JOB_STATUS_PAUSED;
109 return JOB_STATUS_SPOOLING;
111 return JOB_STATUS_PRINTING;
113 return JOB_STATUS_ERROR;
115 return JOB_STATUS_DELETING;
117 return JOB_STATUS_OFFLINE;
119 return JOB_STATUS_PAPEROUT;
121 return JOB_STATUS_PRINTED;
123 return JOB_STATUS_DELETED;
125 return JOB_STATUS_BLOCKED_DEVQ;
126 case LPQ_USER_INTERVENTION:
127 return JOB_STATUS_USER_INTERVENTION;
132 static int nt_printq_status(int v)
136 return PRINTER_STATUS_PAUSED;
145 /***************************************************************************
146 Disconnect from the client
147 ****************************************************************************/
149 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
155 * Tell the specific printing tdb we no longer want messages for this printer
156 * by deregistering our PID.
159 if (!print_notify_deregister_pid(snum))
160 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
162 /* weird if the test succeds !!! */
163 if (smb_connections==0) {
164 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
168 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
171 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
172 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
173 win_errstr(result)));
175 /* if it's the last connection, deconnect the IPC$ share */
176 if (smb_connections==1) {
178 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
179 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
181 messaging_deregister(smbd_messaging_context(),
182 MSG_PRINTER_NOTIFY2, NULL);
184 /* Tell the connections db we're no longer interested in
185 * printer notify messages. */
187 register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
193 /****************************************************************************
194 Functions to free a printer entry datastruct.
195 ****************************************************************************/
197 static int printer_entry_destructor(Printer_entry *Printer)
199 if (Printer->notify.client_connected == true) {
202 if ( Printer->printer_type == SPLHND_SERVER) {
204 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
205 } else if (Printer->printer_type == SPLHND_PRINTER) {
206 snum = print_queue_snum(Printer->sharename);
208 srv_spoolss_replycloseprinter(snum,
209 &Printer->notify.client_hnd);
213 Printer->notify.flags=0;
214 Printer->notify.options=0;
215 Printer->notify.localmachine[0]='\0';
216 Printer->notify.printerlocal=0;
217 TALLOC_FREE(Printer->notify.option);
218 Printer->notify.client_connected = false;
220 free_nt_devicemode( &Printer->nt_devmode );
221 free_a_printer( &Printer->printer_info, 2 );
223 /* Remove from the internal list. */
224 DLIST_REMOVE(printers_list, Printer);
228 /****************************************************************************
229 find printer index by handle
230 ****************************************************************************/
232 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
233 struct policy_handle *hnd)
235 Printer_entry *find_printer = NULL;
237 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
238 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
245 /****************************************************************************
246 Close printer index by handle.
247 ****************************************************************************/
249 static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
251 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
254 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
259 close_policy_hnd(p, hnd);
264 /****************************************************************************
265 Delete a printer given a handle.
266 ****************************************************************************/
268 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
270 char *cmd = lp_deleteprinter_cmd();
271 char *command = NULL;
273 SE_PRIV se_printop = SE_PRINT_OPERATOR;
274 bool is_print_op = false;
276 /* can't fail if we don't try */
281 command = talloc_asprintf(ctx,
288 is_print_op = user_has_privileges( token, &se_printop );
290 DEBUG(10,("Running [%s]\n", command));
292 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
297 if ( (ret = smbrun(command, NULL)) == 0 ) {
298 /* Tell everyone we updated smb.conf. */
299 message_send_all(smbd_messaging_context(),
300 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
306 /********** END SePrintOperatorPrivlege BLOCK **********/
308 DEBUGADD(10,("returned [%d]\n", ret));
310 TALLOC_FREE(command);
313 return WERR_BADFID; /* What to return here? */
315 /* go ahead and re-read the services immediately */
317 reload_services(false);
320 if ( lp_servicenumber( sharename ) > 0 )
321 return WERR_ACCESS_DENIED;
326 /****************************************************************************
327 Delete a printer given a handle.
328 ****************************************************************************/
330 static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
332 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
335 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
341 * It turns out that Windows allows delete printer on a handle
342 * opened by an admin user, then used on a pipe handle created
343 * by an anonymous user..... but they're working on security.... riiight !
347 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
348 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
349 return WERR_ACCESS_DENIED;
352 /* this does not need a become root since the access check has been
353 done on the handle already */
355 if (del_a_printer( Printer->sharename ) != 0) {
356 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
360 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
361 Printer->sharename );
364 /****************************************************************************
365 Return the snum of a printer corresponding to an handle.
366 ****************************************************************************/
368 static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
369 int *number, struct share_params **params)
371 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
374 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
379 switch (Printer->printer_type) {
381 DEBUG(4,("short name:%s\n", Printer->sharename));
382 *number = print_queue_snum(Printer->sharename);
383 return (*number != -1);
391 /****************************************************************************
392 Set printer handle type.
393 Check if it's \\server or \\server\printer
394 ****************************************************************************/
396 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
398 DEBUG(3,("Setting printer type=%s\n", handlename));
400 if ( strlen(handlename) < 3 ) {
401 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
405 /* it's a print server */
406 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
407 DEBUGADD(4,("Printer is a print server\n"));
408 Printer->printer_type = SPLHND_SERVER;
410 /* it's a printer (set_printer_hnd_name() will handle port monitors */
412 DEBUGADD(4,("Printer is a printer\n"));
413 Printer->printer_type = SPLHND_PRINTER;
419 /****************************************************************************
420 Set printer handle name.. Accept names like \\server, \\server\printer,
421 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
422 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
423 XcvDataPort() interface.
424 ****************************************************************************/
426 static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
429 int n_services=lp_numservices();
430 char *aprinter, *printername;
431 const char *servername;
434 NT_PRINTER_INFO_LEVEL *printer = NULL;
437 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
438 (unsigned long)strlen(handlename)));
440 aprinter = CONST_DISCARD(char *, handlename);
441 if ( *handlename == '\\' ) {
442 servername = canon_servername(handlename);
443 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
448 servername = global_myname();
451 /* save the servername to fill in replies on this handle */
453 if ( !is_myname_or_ipaddr( servername ) )
456 fstrcpy( Printer->servername, servername );
458 if ( Printer->printer_type == SPLHND_SERVER )
461 if ( Printer->printer_type != SPLHND_PRINTER )
464 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
466 /* check for the Port Monitor Interface */
468 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
469 Printer->printer_type = SPLHND_PORTMON_TCP;
470 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
473 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
474 Printer->printer_type = SPLHND_PORTMON_LOCAL;
475 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
479 /* Search all sharenames first as this is easier than pulling
480 the printer_info_2 off of disk. Don't use find_service() since
481 that calls out to map_username() */
483 /* do another loop to look for printernames */
485 for (snum=0; !found && snum<n_services; snum++) {
487 /* no point going on if this is not a printer */
489 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
492 fstrcpy(sname, lp_servicename(snum));
493 if ( strequal( aprinter, sname ) ) {
498 /* no point looking up the printer object if
499 we aren't allowing printername != sharename */
501 if ( lp_force_printername(snum) )
504 fstrcpy(sname, lp_servicename(snum));
508 /* This call doesn't fill in the location or comment from
509 * a CUPS server for efficiency with large numbers of printers.
513 result = get_a_printer_search( NULL, &printer, 2, sname );
514 if ( !W_ERROR_IS_OK(result) ) {
515 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
516 sname, win_errstr(result)));
520 /* printername is always returned as \\server\printername */
521 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
522 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
523 printer->info_2->printername));
524 free_a_printer( &printer, 2);
530 if ( strequal(printername, aprinter) ) {
531 free_a_printer( &printer, 2);
536 DEBUGADD(10, ("printername: %s\n", printername));
538 free_a_printer( &printer, 2);
541 free_a_printer( &printer, 2);
544 DEBUGADD(4,("Printer not found\n"));
548 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
550 fstrcpy(Printer->sharename, sname);
555 /****************************************************************************
556 Find first available printer slot. creates a printer handle for you.
557 ****************************************************************************/
559 static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
560 const char *name, uint32_t access_granted)
562 Printer_entry *new_printer;
564 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
566 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
567 if (new_printer == NULL) {
570 talloc_set_destructor(new_printer, printer_entry_destructor);
572 if (!create_policy_hnd(p, hnd, new_printer)) {
573 TALLOC_FREE(new_printer);
577 /* Add to the internal list. */
578 DLIST_ADD(printers_list, new_printer);
580 new_printer->notify.option=NULL;
582 if (!set_printer_hnd_printertype(new_printer, name)) {
583 close_printer_handle(p, hnd);
587 if (!set_printer_hnd_name(new_printer, name)) {
588 close_printer_handle(p, hnd);
592 new_printer->access_granted = access_granted;
594 DEBUG(5, ("%d printer handles active\n",
595 (int)num_pipe_handles(p->pipe_handles)));
600 /***************************************************************************
601 check to see if the client motify handle is monitoring the notification
602 given by (notify_type, notify_field).
603 **************************************************************************/
605 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
606 uint16_t notify_field)
611 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
612 uint16_t notify_field)
614 struct spoolss_NotifyOption *option = p->notify.option;
618 * Flags should always be zero when the change notify
619 * is registered by the client's spooler. A user Win32 app
620 * might use the flags though instead of the NOTIFY_OPTION_INFO
629 return is_monitoring_event_flags(
630 p->notify.flags, notify_type, notify_field);
632 for (i = 0; i < option->count; i++) {
634 /* Check match for notify_type */
636 if (option->types[i].type != notify_type)
639 /* Check match for field */
641 for (j = 0; j < option->types[i].count; j++) {
642 if (option->types[i].fields[j].field == notify_field) {
648 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
649 p->servername, p->sharename, notify_type, notify_field));
654 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
655 _data->data.integer[0] = _integer; \
656 _data->data.integer[1] = 0;
659 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
660 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
661 if (!_data->data.string.string) {\
662 _data->data.string.size = 0; \
664 _data->data.string.size = strlen_m_term(_p) * 2;
666 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
667 _data->data.devmode.devmode = _devmode;
669 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
670 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
671 if (!_data->data.sd.sd) { \
672 _data->data.sd.sd_size = 0; \
674 _data->data.sd.sd_size = _size;
676 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
681 struct spoolss_Time st;
685 if (!init_systemtime(&st, t)) {
689 p = talloc_array(mem_ctx, char, len);
695 * Systemtime must be linearized as a set of UINT16's.
696 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
699 SSVAL(p, 0, st.year);
700 SSVAL(p, 2, st.month);
701 SSVAL(p, 4, st.day_of_week);
703 SSVAL(p, 8, st.hour);
704 SSVAL(p, 10, st.minute);
705 SSVAL(p, 12, st.second);
706 SSVAL(p, 14, st.millisecond);
712 /* Convert a notification message to a struct spoolss_Notify */
714 static void notify_one_value(struct spoolss_notify_msg *msg,
715 struct spoolss_Notify *data,
718 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
721 static void notify_string(struct spoolss_notify_msg *msg,
722 struct spoolss_Notify *data,
725 /* The length of the message includes the trailing \0 */
727 data->data.string.size = msg->len * 2;
728 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
729 if (!data->data.string.string) {
730 data->data.string.size = 0;
735 static void notify_system_time(struct spoolss_notify_msg *msg,
736 struct spoolss_Notify *data,
739 data->data.string.string = NULL;
740 data->data.string.size = 0;
742 if (msg->len != sizeof(time_t)) {
743 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
748 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
749 &data->data.string.string,
750 &data->data.string.size);
753 struct notify2_message_table {
755 void (*fn)(struct spoolss_notify_msg *msg,
756 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
759 static struct notify2_message_table printer_notify_table[] = {
760 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
761 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
762 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
763 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
764 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
765 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
766 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
767 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
768 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
769 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
770 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
771 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
772 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
773 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
774 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
775 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
776 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
777 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
778 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
781 static struct notify2_message_table job_notify_table[] = {
782 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
783 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
784 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
785 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
786 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
787 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
788 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
789 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
790 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
791 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
792 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
793 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
794 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
795 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
796 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
797 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
798 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
799 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
800 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
801 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
802 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
803 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
804 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
805 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
809 /***********************************************************************
810 Allocate talloc context for container object
811 **********************************************************************/
813 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
818 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
823 /***********************************************************************
824 release all allocated memory and zero out structure
825 **********************************************************************/
827 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
833 talloc_destroy(ctr->ctx);
840 /***********************************************************************
841 **********************************************************************/
843 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
851 /***********************************************************************
852 **********************************************************************/
854 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
856 if ( !ctr || !ctr->msg_groups )
859 if ( idx >= ctr->num_groups )
862 return &ctr->msg_groups[idx];
866 /***********************************************************************
867 How many groups of change messages do we have ?
868 **********************************************************************/
870 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
875 return ctr->num_groups;
878 /***********************************************************************
879 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
880 **********************************************************************/
882 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
884 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
885 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
886 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
892 /* loop over all groups looking for a matching printer name */
894 for ( i=0; i<ctr->num_groups; i++ ) {
895 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
899 /* add a new group? */
901 if ( i == ctr->num_groups ) {
904 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
905 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
908 ctr->msg_groups = groups;
910 /* clear the new entry and set the printer name */
912 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
913 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
916 /* add the change messages; 'i' is the correct index now regardless */
918 msg_grp = &ctr->msg_groups[i];
922 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
923 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
926 msg_grp->msgs = msg_list;
928 new_slot = msg_grp->num_msgs-1;
929 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
931 /* need to allocate own copy of data */
934 msg_grp->msgs[new_slot].notify.data = (char *)
935 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
937 return ctr->num_groups;
940 void construct_info_data(struct spoolss_Notify *info_data,
941 enum spoolss_NotifyType type,
945 /***********************************************************************
946 Send a change notication message on all handles which have a call
948 **********************************************************************/
950 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
953 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
954 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
955 SPOOLSS_NOTIFY_MSG *messages;
956 int sending_msg_count;
959 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
963 messages = msg_group->msgs;
966 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
970 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
972 /* loop over all printers */
974 for (p = printers_list; p; p = p->next) {
975 struct spoolss_Notify *notifies;
980 /* Is there notification on this handle? */
982 if ( !p->notify.client_connected )
985 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
987 /* For this printer? Print servers always receive
990 if ( ( p->printer_type == SPLHND_PRINTER ) &&
991 ( !strequal(msg_group->printername, p->sharename) ) )
994 DEBUG(10,("Our printer\n"));
996 /* allocate the max entries possible */
998 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1003 /* build the array of change notifications */
1005 sending_msg_count = 0;
1007 for ( i=0; i<msg_group->num_msgs; i++ ) {
1008 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1010 /* Are we monitoring this event? */
1012 if (!is_monitoring_event(p, msg->type, msg->field))
1015 sending_msg_count++;
1018 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1019 msg->type, msg->field, p->sharename));
1022 * if the is a printer notification handle and not a job notification
1023 * type, then set the id to 0. Other wise just use what was specified
1026 * When registering change notification on a print server handle
1027 * we always need to send back the id (snum) matching the printer
1028 * for which the change took place. For change notify registered
1029 * on a printer handle, this does not matter and the id should be 0.
1034 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1040 /* Convert unix jobid to smb jobid */
1042 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1043 id = sysjob_to_jobid(msg->id);
1046 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1051 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1054 case PRINTER_NOTIFY_TYPE:
1055 if ( printer_notify_table[msg->field].fn )
1056 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1059 case JOB_NOTIFY_TYPE:
1060 if ( job_notify_table[msg->field].fn )
1061 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1065 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1072 if ( sending_msg_count ) {
1075 union spoolss_ReplyPrinterInfo info;
1076 struct spoolss_NotifyInfo info0;
1077 uint32_t reply_result;
1079 info0.version = 0x2;
1080 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1081 info0.count = count;
1082 info0.notifies = notifies;
1084 info.info0 = &info0;
1086 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1087 &p->notify.client_hnd,
1088 p->notify.change, /* color */
1091 0, /* reply_type, must be 0 */
1094 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1095 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1096 notify_cli_pipe->srv_name_slash,
1099 switch (reply_result) {
1102 case PRINTER_NOTIFY_INFO_DISCARDED:
1103 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1104 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1113 DEBUG(8,("send_notify2_changes: Exit...\n"));
1117 /***********************************************************************
1118 **********************************************************************/
1120 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1123 uint32_t tv_sec, tv_usec;
1126 /* Unpack message */
1128 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1131 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1133 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1136 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1137 &msg->notify.value[0], &msg->notify.value[1]);
1139 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1140 &msg->len, &msg->notify.data);
1142 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1143 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1145 tv->tv_sec = tv_sec;
1146 tv->tv_usec = tv_usec;
1149 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1150 msg->notify.value[1]));
1152 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1157 /********************************************************************
1158 Receive a notify2 message list
1159 ********************************************************************/
1161 static void receive_notify2_message_list(struct messaging_context *msg,
1164 struct server_id server_id,
1167 size_t msg_count, i;
1168 char *buf = (char *)data->data;
1171 SPOOLSS_NOTIFY_MSG notify;
1172 SPOOLSS_NOTIFY_MSG_CTR messages;
1175 if (data->length < 4) {
1176 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1180 msg_count = IVAL(buf, 0);
1183 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1185 if (msg_count == 0) {
1186 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1190 /* initialize the container */
1192 ZERO_STRUCT( messages );
1193 notify_msg_ctr_init( &messages );
1196 * build message groups for each printer identified
1197 * in a change_notify msg. Remember that a PCN message
1198 * includes the handle returned for the srv_spoolss_replyopenprinter()
1199 * call. Therefore messages are grouped according to printer handle.
1202 for ( i=0; i<msg_count; i++ ) {
1203 struct timeval msg_tv;
1205 if (msg_ptr + 4 - buf > data->length) {
1206 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1210 msg_len = IVAL(msg_ptr,0);
1213 if (msg_ptr + msg_len - buf > data->length) {
1214 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1218 /* unpack messages */
1220 ZERO_STRUCT( notify );
1221 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1224 /* add to correct list in container */
1226 notify_msg_ctr_addmsg( &messages, ¬ify );
1228 /* free memory that might have been allocated by notify2_unpack_msg() */
1230 if ( notify.len != 0 )
1231 SAFE_FREE( notify.notify.data );
1234 /* process each group of messages */
1236 num_groups = notify_msg_ctr_numgroups( &messages );
1237 for ( i=0; i<num_groups; i++ )
1238 send_notify2_changes( &messages, i );
1243 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1244 (uint32_t)msg_count ));
1246 notify_msg_ctr_destroy( &messages );
1251 /********************************************************************
1252 Send a message to ourself about new driver being installed
1253 so we can upgrade the information for each printer bound to this
1255 ********************************************************************/
1257 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1259 int len = strlen(drivername);
1264 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1267 messaging_send_buf(smbd_messaging_context(), procid_self(),
1268 MSG_PRINTER_DRVUPGRADE,
1269 (uint8_t *)drivername, len+1);
1274 /**********************************************************************
1275 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1276 over all printers, upgrading ones as necessary
1277 **********************************************************************/
1279 void do_drv_upgrade_printer(struct messaging_context *msg,
1282 struct server_id server_id,
1287 int n_services = lp_numservices();
1290 len = MIN(data->length,sizeof(drivername)-1);
1291 strncpy(drivername, (const char *)data->data, len);
1293 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1295 /* Iterate the printer list */
1297 for (snum=0; snum<n_services; snum++)
1299 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1302 NT_PRINTER_INFO_LEVEL *printer = NULL;
1304 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1305 if (!W_ERROR_IS_OK(result))
1308 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1310 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1312 /* all we care about currently is the change_id */
1314 result = mod_a_printer(printer, 2);
1315 if (!W_ERROR_IS_OK(result)) {
1316 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1317 win_errstr(result)));
1321 free_a_printer(&printer, 2);
1328 /********************************************************************
1329 Update the cache for all printq's with a registered client
1331 ********************************************************************/
1333 void update_monitored_printq_cache( void )
1335 Printer_entry *printer = printers_list;
1338 /* loop through all printers and update the cache where
1339 client_connected == true */
1342 if ( (printer->printer_type == SPLHND_PRINTER)
1343 && printer->notify.client_connected )
1345 snum = print_queue_snum(printer->sharename);
1346 print_queue_status( snum, NULL, NULL );
1349 printer = printer->next;
1354 /********************************************************************
1355 Send a message to ourself about new driver being installed
1356 so we can upgrade the information for each printer bound to this
1358 ********************************************************************/
1360 static bool srv_spoolss_reset_printerdata(char* drivername)
1362 int len = strlen(drivername);
1367 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1370 messaging_send_buf(smbd_messaging_context(), procid_self(),
1371 MSG_PRINTERDATA_INIT_RESET,
1372 (uint8_t *)drivername, len+1);
1377 /**********************************************************************
1378 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1379 over all printers, resetting printer data as neessary
1380 **********************************************************************/
1382 void reset_all_printerdata(struct messaging_context *msg,
1385 struct server_id server_id,
1390 int n_services = lp_numservices();
1393 len = MIN( data->length, sizeof(drivername)-1 );
1394 strncpy( drivername, (const char *)data->data, len );
1396 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1398 /* Iterate the printer list */
1400 for ( snum=0; snum<n_services; snum++ )
1402 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1405 NT_PRINTER_INFO_LEVEL *printer = NULL;
1407 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1408 if ( !W_ERROR_IS_OK(result) )
1412 * if the printer is bound to the driver,
1413 * then reset to the new driver initdata
1416 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1418 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1420 if ( !set_driver_init(printer, 2) ) {
1421 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1422 printer->info_2->printername, printer->info_2->drivername));
1425 result = mod_a_printer( printer, 2 );
1426 if ( !W_ERROR_IS_OK(result) ) {
1427 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1428 get_dos_error_msg(result)));
1432 free_a_printer( &printer, 2 );
1441 /****************************************************************
1442 _spoolss_OpenPrinter
1443 ****************************************************************/
1445 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1446 struct spoolss_OpenPrinter *r)
1448 struct spoolss_OpenPrinterEx e;
1451 ZERO_STRUCT(e.in.userlevel);
1453 e.in.printername = r->in.printername;
1454 e.in.datatype = r->in.datatype;
1455 e.in.devmode_ctr = r->in.devmode_ctr;
1456 e.in.access_mask = r->in.access_mask;
1459 e.out.handle = r->out.handle;
1461 werr = _spoolss_OpenPrinterEx(p, &e);
1463 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1464 /* OpenPrinterEx returns this for a bad
1465 * printer name. We must return WERR_INVALID_PRINTER_NAME
1468 werr = WERR_INVALID_PRINTER_NAME;
1474 /********************************************************************
1475 ********************************************************************/
1477 bool convert_devicemode(const char *printername,
1478 const struct spoolss_DeviceMode *devmode,
1479 NT_DEVICEMODE **pp_nt_devmode)
1481 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1484 * Ensure nt_devmode is a valid pointer
1485 * as we will be overwriting it.
1488 if (nt_devmode == NULL) {
1489 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1490 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1494 fstrcpy(nt_devmode->devicename, devmode->devicename);
1495 fstrcpy(nt_devmode->formname, devmode->formname);
1497 nt_devmode->devicename[31] = '\0';
1498 nt_devmode->formname[31] = '\0';
1500 nt_devmode->specversion = devmode->specversion;
1501 nt_devmode->driverversion = devmode->driverversion;
1502 nt_devmode->size = devmode->size;
1503 nt_devmode->fields = devmode->fields;
1504 nt_devmode->orientation = devmode->orientation;
1505 nt_devmode->papersize = devmode->papersize;
1506 nt_devmode->paperlength = devmode->paperlength;
1507 nt_devmode->paperwidth = devmode->paperwidth;
1508 nt_devmode->scale = devmode->scale;
1509 nt_devmode->copies = devmode->copies;
1510 nt_devmode->defaultsource = devmode->defaultsource;
1511 nt_devmode->printquality = devmode->printquality;
1512 nt_devmode->color = devmode->color;
1513 nt_devmode->duplex = devmode->duplex;
1514 nt_devmode->yresolution = devmode->yresolution;
1515 nt_devmode->ttoption = devmode->ttoption;
1516 nt_devmode->collate = devmode->collate;
1518 nt_devmode->logpixels = devmode->logpixels;
1519 nt_devmode->bitsperpel = devmode->bitsperpel;
1520 nt_devmode->pelswidth = devmode->pelswidth;
1521 nt_devmode->pelsheight = devmode->pelsheight;
1522 nt_devmode->displayflags = devmode->displayflags;
1523 nt_devmode->displayfrequency = devmode->displayfrequency;
1524 nt_devmode->icmmethod = devmode->icmmethod;
1525 nt_devmode->icmintent = devmode->icmintent;
1526 nt_devmode->mediatype = devmode->mediatype;
1527 nt_devmode->dithertype = devmode->dithertype;
1528 nt_devmode->reserved1 = devmode->reserved1;
1529 nt_devmode->reserved2 = devmode->reserved2;
1530 nt_devmode->panningwidth = devmode->panningwidth;
1531 nt_devmode->panningheight = devmode->panningheight;
1534 * Only change private and driverextra if the incoming devmode
1535 * has a new one. JRA.
1538 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1539 SAFE_FREE(nt_devmode->nt_dev_private);
1540 nt_devmode->driverextra = devmode->__driverextra_length;
1541 if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
1543 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1546 *pp_nt_devmode = nt_devmode;
1551 /****************************************************************
1552 _spoolss_OpenPrinterEx
1553 ****************************************************************/
1555 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1556 struct spoolss_OpenPrinterEx *r)
1559 Printer_entry *Printer=NULL;
1561 if (!r->in.printername) {
1562 return WERR_INVALID_PARAM;
1565 /* some sanity check because you can open a printer or a print server */
1566 /* aka: \\server\printer or \\server */
1568 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1570 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1571 ZERO_STRUCTP(r->out.handle);
1572 return WERR_INVALID_PARAM;
1575 Printer = find_printer_index_by_hnd(p, r->out.handle);
1577 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1578 "handle we created for printer %s\n", r->in.printername));
1579 close_printer_handle(p, r->out.handle);
1580 ZERO_STRUCTP(r->out.handle);
1581 return WERR_INVALID_PARAM;
1585 * First case: the user is opening the print server:
1587 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1588 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1590 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1591 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1592 * or if the user is listed in the smb.conf printer admin parameter.
1594 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1595 * client view printer folder, but does not show the MSAPW.
1597 * Note: this test needs code to check access rights here too. Jeremy
1598 * could you look at this?
1600 * Second case: the user is opening a printer:
1601 * NT doesn't let us connect to a printer if the connecting user
1602 * doesn't have print permission.
1604 * Third case: user is opening a Port Monitor
1605 * access checks same as opening a handle to the print server.
1608 switch (Printer->printer_type )
1611 case SPLHND_PORTMON_TCP:
1612 case SPLHND_PORTMON_LOCAL:
1613 /* Printserver handles use global struct... */
1617 /* Map standard access rights to object specific access rights */
1619 se_map_standard(&r->in.access_mask,
1620 &printserver_std_mapping);
1622 /* Deny any object specific bits that don't apply to print
1623 servers (i.e printer and job specific bits) */
1625 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1627 if (r->in.access_mask &
1628 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1629 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1630 close_printer_handle(p, r->out.handle);
1631 ZERO_STRUCTP(r->out.handle);
1632 return WERR_ACCESS_DENIED;
1635 /* Allow admin access */
1637 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1639 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1641 if (!lp_ms_add_printer_wizard()) {
1642 close_printer_handle(p, r->out.handle);
1643 ZERO_STRUCTP(r->out.handle);
1644 return WERR_ACCESS_DENIED;
1647 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1648 and not a printer admin, then fail */
1650 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1651 !user_has_privileges(p->server_info->ptok,
1653 !token_contains_name_in_list(
1654 uidtoname(p->server_info->utok.uid),
1656 p->server_info->ptok,
1657 lp_printer_admin(snum))) {
1658 close_printer_handle(p, r->out.handle);
1659 ZERO_STRUCTP(r->out.handle);
1660 return WERR_ACCESS_DENIED;
1663 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1667 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1670 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1671 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1673 /* We fall through to return WERR_OK */
1676 case SPLHND_PRINTER:
1677 /* NT doesn't let us connect to a printer if the connecting user
1678 doesn't have print permission. */
1680 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1681 close_printer_handle(p, r->out.handle);
1682 ZERO_STRUCTP(r->out.handle);
1686 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1687 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1690 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1692 /* map an empty access mask to the minimum access mask */
1693 if (r->in.access_mask == 0x0)
1694 r->in.access_mask = PRINTER_ACCESS_USE;
1697 * If we are not serving the printer driver for this printer,
1698 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1699 * will keep NT clients happy --jerry
1702 if (lp_use_client_driver(snum)
1703 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1705 r->in.access_mask = PRINTER_ACCESS_USE;
1708 /* check smb.conf parameters and the the sec_desc */
1710 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1711 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1712 ZERO_STRUCTP(r->out.handle);
1713 return WERR_ACCESS_DENIED;
1716 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1717 p->server_info->ptok, snum) ||
1718 !print_access_check(p->server_info, snum,
1719 r->in.access_mask)) {
1720 DEBUG(3, ("access DENIED for printer open\n"));
1721 close_printer_handle(p, r->out.handle);
1722 ZERO_STRUCTP(r->out.handle);
1723 return WERR_ACCESS_DENIED;
1726 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1727 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1728 close_printer_handle(p, r->out.handle);
1729 ZERO_STRUCTP(r->out.handle);
1730 return WERR_ACCESS_DENIED;
1733 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1734 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1736 r->in.access_mask = PRINTER_ACCESS_USE;
1738 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1739 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1744 /* sanity check to prevent programmer error */
1745 ZERO_STRUCTP(r->out.handle);
1749 Printer->access_granted = r->in.access_mask;
1752 * If the client sent a devmode in the OpenPrinter() call, then
1753 * save it here in case we get a job submission on this handle
1756 if ((Printer->printer_type != SPLHND_SERVER) &&
1757 r->in.devmode_ctr.devmode) {
1758 convert_devicemode(Printer->sharename,
1759 r->in.devmode_ctr.devmode,
1760 &Printer->nt_devmode);
1763 #if 0 /* JERRY -- I'm doubtful this is really effective */
1764 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1765 optimization in Windows 2000 clients --jerry */
1767 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1768 && (RA_WIN2K == get_remote_arch()) )
1770 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1771 sys_usleep( 500000 );
1778 /****************************************************************************
1779 ****************************************************************************/
1781 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1782 NT_PRINTER_INFO_LEVEL_2 *d)
1784 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1790 d->attributes = r->attributes;
1791 d->priority = r->priority;
1792 d->default_priority = r->defaultpriority;
1793 d->starttime = r->starttime;
1794 d->untiltime = r->untiltime;
1795 d->status = r->status;
1796 d->cjobs = r->cjobs;
1798 fstrcpy(d->servername, r->servername);
1799 fstrcpy(d->printername, r->printername);
1800 fstrcpy(d->sharename, r->sharename);
1801 fstrcpy(d->portname, r->portname);
1802 fstrcpy(d->drivername, r->drivername);
1803 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1804 fstrcpy(d->location, r->location);
1805 fstrcpy(d->sepfile, r->sepfile);
1806 fstrcpy(d->printprocessor, r->printprocessor);
1807 fstrcpy(d->datatype, r->datatype);
1808 fstrcpy(d->parameters, r->parameters);
1813 /****************************************************************************
1814 ****************************************************************************/
1816 static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
1817 NT_PRINTER_INFO_LEVEL *printer)
1821 switch (info_ctr->level) {
1823 /* allocate memory if needed. Messy because
1824 convert_printer_info is used to update an existing
1825 printer or build a new one */
1827 if (!printer->info_2) {
1828 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1829 if (!printer->info_2) {
1830 DEBUG(0,("convert_printer_info: "
1831 "talloc() failed!\n"));
1836 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1838 printer->info_2->setuptime = time(NULL);
1845 /****************************************************************
1846 _spoolss_ClosePrinter
1847 ****************************************************************/
1849 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1850 struct spoolss_ClosePrinter *r)
1852 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1854 if (Printer && Printer->document_started) {
1855 struct spoolss_EndDocPrinter e;
1857 e.in.handle = r->in.handle;
1859 _spoolss_EndDocPrinter(p, &e);
1862 if (!close_printer_handle(p, r->in.handle))
1865 /* clear the returned printer handle. Observed behavior
1866 from Win2k server. Don't think this really matters.
1867 Previous code just copied the value of the closed
1870 ZERO_STRUCTP(r->out.handle);
1875 /****************************************************************
1876 _spoolss_DeletePrinter
1877 ****************************************************************/
1879 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1880 struct spoolss_DeletePrinter *r)
1882 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1885 if (Printer && Printer->document_started) {
1886 struct spoolss_EndDocPrinter e;
1888 e.in.handle = r->in.handle;
1890 _spoolss_EndDocPrinter(p, &e);
1893 result = delete_printer_handle(p, r->in.handle);
1895 update_c_setprinter(false);
1900 /*******************************************************************
1901 * static function to lookup the version id corresponding to an
1902 * long architecture string
1903 ******************************************************************/
1905 static const struct print_architecture_table_node archi_table[]= {
1907 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1908 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1909 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1910 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1911 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1912 {"Windows IA64", SPL_ARCH_IA64, 3 },
1913 {"Windows x64", SPL_ARCH_X64, 3 },
1917 static int get_version_id(const char *arch)
1921 for (i=0; archi_table[i].long_archi != NULL; i++)
1923 if (strcmp(arch, archi_table[i].long_archi) == 0)
1924 return (archi_table[i].version);
1930 /****************************************************************
1931 _spoolss_DeletePrinterDriver
1932 ****************************************************************/
1934 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1935 struct spoolss_DeletePrinterDriver *r)
1938 struct spoolss_DriverInfo8 *info = NULL;
1939 struct spoolss_DriverInfo8 *info_win2k = NULL;
1942 WERROR status_win2k = WERR_ACCESS_DENIED;
1943 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1945 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1946 and not a printer admin, then fail */
1948 if ( (p->server_info->utok.uid != sec_initial_uid())
1949 && !user_has_privileges(p->server_info->ptok, &se_printop )
1950 && !token_contains_name_in_list(
1951 uidtoname(p->server_info->utok.uid), NULL,
1952 NULL, p->server_info->ptok,
1953 lp_printer_admin(-1)) )
1955 return WERR_ACCESS_DENIED;
1958 /* check that we have a valid driver name first */
1960 if ((version = get_version_id(r->in.architecture)) == -1)
1961 return WERR_INVALID_ENVIRONMENT;
1963 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
1967 /* try for Win2k driver if "Windows NT x86" */
1969 if ( version == 2 ) {
1971 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1976 status = WERR_UNKNOWN_PRINTER_DRIVER;
1980 /* otherwise it was a failure */
1982 status = WERR_UNKNOWN_PRINTER_DRIVER;
1988 if (printer_driver_in_use(info)) {
1989 status = WERR_PRINTER_DRIVER_IN_USE;
1995 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1998 r->in.architecture, 3)))
2000 /* if we get to here, we now have 2 driver info structures to remove */
2001 /* remove the Win2k driver first*/
2003 status_win2k = delete_printer_driver(
2004 p, info_win2k, 3, false);
2005 free_a_printer_driver(info_win2k);
2007 /* this should not have failed---if it did, report to client */
2008 if ( !W_ERROR_IS_OK(status_win2k) )
2010 status = status_win2k;
2016 status = delete_printer_driver(p, info, version, false);
2018 /* if at least one of the deletes succeeded return OK */
2020 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2024 free_a_printer_driver(info);
2029 /****************************************************************
2030 _spoolss_DeletePrinterDriverEx
2031 ****************************************************************/
2033 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2034 struct spoolss_DeletePrinterDriverEx *r)
2036 struct spoolss_DriverInfo8 *info = NULL;
2037 struct spoolss_DriverInfo8 *info_win2k = NULL;
2041 WERROR status_win2k = WERR_ACCESS_DENIED;
2042 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2044 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2045 and not a printer admin, then fail */
2047 if ( (p->server_info->utok.uid != sec_initial_uid())
2048 && !user_has_privileges(p->server_info->ptok, &se_printop )
2049 && !token_contains_name_in_list(
2050 uidtoname(p->server_info->utok.uid), NULL, NULL,
2051 p->server_info->ptok, lp_printer_admin(-1)) )
2053 return WERR_ACCESS_DENIED;
2056 /* check that we have a valid driver name first */
2057 if ((version = get_version_id(r->in.architecture)) == -1) {
2058 /* this is what NT returns */
2059 return WERR_INVALID_ENVIRONMENT;
2062 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2063 version = r->in.version;
2065 status = get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2066 r->in.architecture, version);
2068 if ( !W_ERROR_IS_OK(status) )
2071 * if the client asked for a specific version,
2072 * or this is something other than Windows NT x86,
2076 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2079 /* try for Win2k driver if "Windows NT x86" */
2082 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2085 status = WERR_UNKNOWN_PRINTER_DRIVER;
2090 if (printer_driver_in_use(info)) {
2091 status = WERR_PRINTER_DRIVER_IN_USE;
2096 * we have a couple of cases to consider.
2097 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2098 * then the delete should fail if **any** files overlap with
2100 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2101 * non-overlapping files
2102 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2103 * is set, the do not delete any files
2104 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2107 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2109 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2111 if (delete_files && printer_driver_files_in_use(info, info) & (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
2112 /* no idea of the correct error here */
2113 status = WERR_ACCESS_DENIED;
2118 /* also check for W32X86/3 if necessary; maybe we already have? */
2120 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2121 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info_win2k,
2123 r->in.architecture, 3)))
2126 if (delete_files && printer_driver_files_in_use(info, info_win2k) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2127 /* no idea of the correct error here */
2128 free_a_printer_driver(info_win2k);
2129 status = WERR_ACCESS_DENIED;
2133 /* if we get to here, we now have 2 driver info structures to remove */
2134 /* remove the Win2k driver first*/
2136 status_win2k = delete_printer_driver(
2137 p, info_win2k, 3, delete_files);
2138 free_a_printer_driver(info_win2k);
2140 /* this should not have failed---if it did, report to client */
2142 if ( !W_ERROR_IS_OK(status_win2k) )
2147 status = delete_printer_driver(p, info, version, delete_files);
2149 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2152 free_a_printer_driver(info);
2158 /****************************************************************************
2159 Internal routine for removing printerdata
2160 ***************************************************************************/
2162 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2164 return delete_printer_data( printer->info_2, key, value );
2167 /****************************************************************************
2168 Internal routine for storing printerdata
2169 ***************************************************************************/
2171 WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2172 const char *key, const char *value,
2173 uint32_t type, uint8_t *data, int real_len)
2175 /* the registry objects enforce uniqueness based on value name */
2177 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2180 /********************************************************************
2181 GetPrinterData on a printer server Handle.
2182 ********************************************************************/
2184 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2186 enum winreg_Type *type,
2187 union spoolss_PrinterData *data)
2189 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2191 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2197 if (!StrCaseCmp(value, "BeepEnabled")) {
2203 if (!StrCaseCmp(value, "EventLog")) {
2205 /* formally was 0x1b */
2210 if (!StrCaseCmp(value, "NetPopup")) {
2216 if (!StrCaseCmp(value, "MajorVersion")) {
2219 /* Windows NT 4.0 seems to not allow uploading of drivers
2220 to a server that reports 0x3 as the MajorVersion.
2221 need to investigate more how Win2k gets around this .
2224 if (RA_WINNT == get_remote_arch()) {
2233 if (!StrCaseCmp(value, "MinorVersion")) {
2240 * uint32_t size = 0x114
2241 * uint32_t major = 5
2242 * uint32_t minor = [0|1]
2243 * uint32_t build = [2195|2600]
2244 * extra unicode string = e.g. "Service Pack 3"
2246 if (!StrCaseCmp(value, "OSVersion")) {
2248 enum ndr_err_code ndr_err;
2249 struct spoolss_OSVersion os;
2251 os.major = 5; /* Windows 2000 == 5.0 */
2253 os.build = 2195; /* build */
2254 os.extra_string = ""; /* leave extra string empty */
2256 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2257 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2258 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2259 return WERR_GENERAL_FAILURE;
2263 data->binary = blob;
2269 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2272 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2273 W_ERROR_HAVE_NO_MEMORY(data->string);
2278 if (!StrCaseCmp(value, "Architecture")) {
2280 data->string = talloc_strdup(mem_ctx,
2281 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2282 W_ERROR_HAVE_NO_MEMORY(data->string);
2287 if (!StrCaseCmp(value, "DsPresent")) {
2290 /* only show the publish check box if we are a
2291 member of a AD domain */
2293 if (lp_security() == SEC_ADS) {
2301 if (!StrCaseCmp(value, "DNSMachineName")) {
2302 const char *hostname = get_mydnsfullname();
2305 return WERR_BADFILE;
2309 data->string = talloc_strdup(mem_ctx, hostname);
2310 W_ERROR_HAVE_NO_MEMORY(data->string);
2317 return WERR_INVALID_PARAM;
2320 /****************************************************************
2321 _spoolss_GetPrinterData
2322 ****************************************************************/
2324 WERROR _spoolss_GetPrinterData(pipes_struct *p,
2325 struct spoolss_GetPrinterData *r)
2327 struct spoolss_GetPrinterDataEx r2;
2329 r2.in.handle = r->in.handle;
2330 r2.in.key_name = "PrinterDriverData";
2331 r2.in.value_name = r->in.value_name;
2332 r2.in.offered = r->in.offered;
2333 r2.out.type = r->out.type;
2334 r2.out.data = r->out.data;
2335 r2.out.needed = r->out.needed;
2337 return _spoolss_GetPrinterDataEx(p, &r2);
2340 /*********************************************************
2341 Connect to the client machine.
2342 **********************************************************/
2344 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2345 struct sockaddr_storage *client_ss, const char *remote_machine)
2348 struct cli_state *the_cli;
2349 struct sockaddr_storage rm_addr;
2350 char addr[INET6_ADDRSTRLEN];
2352 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2353 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2355 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2356 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2359 print_sockaddr(addr, sizeof(addr), &rm_addr);
2361 rm_addr = *client_ss;
2362 print_sockaddr(addr, sizeof(addr), &rm_addr);
2363 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2367 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2368 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2373 /* setup the connection */
2374 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2375 &rm_addr, 0, "IPC$", "IPC",
2379 0, lp_client_signing(), NULL );
2381 if ( !NT_STATUS_IS_OK( ret ) ) {
2382 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2387 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2388 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2389 cli_shutdown(the_cli);
2394 * Ok - we have an anonymous connection to the IPC$ share.
2395 * Now start the NT Domain stuff :-).
2398 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2399 if (!NT_STATUS_IS_OK(ret)) {
2400 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2401 remote_machine, nt_errstr(ret)));
2402 cli_shutdown(the_cli);
2409 /***************************************************************************
2410 Connect to the client.
2411 ****************************************************************************/
2413 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2414 uint32_t localprinter, uint32_t type,
2415 struct policy_handle *handle,
2416 struct sockaddr_storage *client_ss)
2422 * If it's the first connection, contact the client
2423 * and connect to the IPC$ share anonymously
2425 if (smb_connections==0) {
2426 fstring unix_printer;
2428 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2430 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2433 messaging_register(smbd_messaging_context(), NULL,
2434 MSG_PRINTER_NOTIFY2,
2435 receive_notify2_message_list);
2436 /* Tell the connections db we're now interested in printer
2437 * notify messages. */
2438 register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
2442 * Tell the specific printing tdb we want messages for this printer
2443 * by registering our PID.
2446 if (!print_notify_register_pid(snum))
2447 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2451 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2459 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2460 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2461 win_errstr(result)));
2463 return (W_ERROR_IS_OK(result));
2466 /****************************************************************
2467 ****************************************************************/
2469 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2470 const struct spoolss_NotifyOption *r)
2472 struct spoolss_NotifyOption *option;
2479 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2486 if (!option->count) {
2490 option->types = talloc_zero_array(option,
2491 struct spoolss_NotifyOptionType, option->count);
2492 if (!option->types) {
2493 talloc_free(option);
2497 for (i=0; i < option->count; i++) {
2498 option->types[i] = r->types[i];
2500 if (option->types[i].count) {
2501 option->types[i].fields = talloc_zero_array(option,
2502 union spoolss_Field, option->types[i].count);
2503 if (!option->types[i].fields) {
2504 talloc_free(option);
2507 for (k=0; k<option->types[i].count; k++) {
2508 option->types[i].fields[k] =
2509 r->types[i].fields[k];
2517 /****************************************************************
2518 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2520 * before replying OK: status=0 a rpc call is made to the workstation
2521 * asking ReplyOpenPrinter
2523 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2524 * called from api_spoolss_rffpcnex
2525 ****************************************************************/
2527 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2528 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2531 struct spoolss_NotifyOption *option = r->in.notify_options;
2532 struct sockaddr_storage client_ss;
2534 /* store the notify value in the printer struct */
2536 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2539 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2540 "Invalid handle (%s:%u:%u).\n",
2541 OUR_HANDLE(r->in.handle)));
2545 Printer->notify.flags = r->in.flags;
2546 Printer->notify.options = r->in.options;
2547 Printer->notify.printerlocal = r->in.printer_local;
2549 TALLOC_FREE(Printer->notify.option);
2550 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2552 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2554 /* Connect to the client machine and send a ReplyOpenPrinter */
2556 if ( Printer->printer_type == SPLHND_SERVER)
2558 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2559 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2562 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2563 "client_address is %s\n", p->client_address));
2565 if (!interpret_string_addr(&client_ss, p->client_address,
2567 return WERR_SERVER_UNAVAILABLE;
2570 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2571 Printer->notify.printerlocal, 1,
2572 &Printer->notify.client_hnd, &client_ss))
2573 return WERR_SERVER_UNAVAILABLE;
2575 Printer->notify.client_connected = true;
2580 /*******************************************************************
2581 * fill a notify_info_data with the servername
2582 ********************************************************************/
2584 static void spoolss_notify_server_name(int snum,
2585 struct spoolss_Notify *data,
2586 print_queue_struct *queue,
2587 NT_PRINTER_INFO_LEVEL *printer,
2588 TALLOC_CTX *mem_ctx)
2590 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2593 /*******************************************************************
2594 * fill a notify_info_data with the printername (not including the servername).
2595 ********************************************************************/
2597 static void spoolss_notify_printer_name(int snum,
2598 struct spoolss_Notify *data,
2599 print_queue_struct *queue,
2600 NT_PRINTER_INFO_LEVEL *printer,
2601 TALLOC_CTX *mem_ctx)
2603 /* the notify name should not contain the \\server\ part */
2604 char *p = strrchr(printer->info_2->printername, '\\');
2607 p = printer->info_2->printername;
2612 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2615 /*******************************************************************
2616 * fill a notify_info_data with the servicename
2617 ********************************************************************/
2619 static void spoolss_notify_share_name(int snum,
2620 struct spoolss_Notify *data,
2621 print_queue_struct *queue,
2622 NT_PRINTER_INFO_LEVEL *printer,
2623 TALLOC_CTX *mem_ctx)
2625 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2628 /*******************************************************************
2629 * fill a notify_info_data with the port name
2630 ********************************************************************/
2632 static void spoolss_notify_port_name(int snum,
2633 struct spoolss_Notify *data,
2634 print_queue_struct *queue,
2635 NT_PRINTER_INFO_LEVEL *printer,
2636 TALLOC_CTX *mem_ctx)
2638 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2641 /*******************************************************************
2642 * fill a notify_info_data with the printername
2643 * but it doesn't exist, have to see what to do
2644 ********************************************************************/
2646 static void spoolss_notify_driver_name(int snum,
2647 struct spoolss_Notify *data,
2648 print_queue_struct *queue,
2649 NT_PRINTER_INFO_LEVEL *printer,
2650 TALLOC_CTX *mem_ctx)
2652 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2655 /*******************************************************************
2656 * fill a notify_info_data with the comment
2657 ********************************************************************/
2659 static void spoolss_notify_comment(int snum,
2660 struct spoolss_Notify *data,
2661 print_queue_struct *queue,
2662 NT_PRINTER_INFO_LEVEL *printer,
2663 TALLOC_CTX *mem_ctx)
2667 if (*printer->info_2->comment == '\0') {
2668 p = lp_comment(snum);
2670 p = printer->info_2->comment;
2673 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
2676 /*******************************************************************
2677 * fill a notify_info_data with the comment
2678 * location = "Room 1, floor 2, building 3"
2679 ********************************************************************/
2681 static void spoolss_notify_location(int snum,
2682 struct spoolss_Notify *data,
2683 print_queue_struct *queue,
2684 NT_PRINTER_INFO_LEVEL *printer,
2685 TALLOC_CTX *mem_ctx)
2687 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
2690 /*******************************************************************
2691 * fill a notify_info_data with the device mode
2692 * jfm:xxxx don't to it for know but that's a real problem !!!
2693 ********************************************************************/
2695 static void spoolss_notify_devmode(int snum,
2696 struct spoolss_Notify *data,
2697 print_queue_struct *queue,
2698 NT_PRINTER_INFO_LEVEL *printer,
2699 TALLOC_CTX *mem_ctx)
2701 /* for a dummy implementation we have to zero the fields */
2702 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2705 /*******************************************************************
2706 * fill a notify_info_data with the separator file name
2707 ********************************************************************/
2709 static void spoolss_notify_sepfile(int snum,
2710 struct spoolss_Notify *data,
2711 print_queue_struct *queue,
2712 NT_PRINTER_INFO_LEVEL *printer,
2713 TALLOC_CTX *mem_ctx)
2715 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
2718 /*******************************************************************
2719 * fill a notify_info_data with the print processor
2720 * jfm:xxxx return always winprint to indicate we don't do anything to it
2721 ********************************************************************/
2723 static void spoolss_notify_print_processor(int snum,
2724 struct spoolss_Notify *data,
2725 print_queue_struct *queue,
2726 NT_PRINTER_INFO_LEVEL *printer,
2727 TALLOC_CTX *mem_ctx)
2729 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
2732 /*******************************************************************
2733 * fill a notify_info_data with the print processor options
2734 * jfm:xxxx send an empty string
2735 ********************************************************************/
2737 static void spoolss_notify_parameters(int snum,
2738 struct spoolss_Notify *data,
2739 print_queue_struct *queue,
2740 NT_PRINTER_INFO_LEVEL *printer,
2741 TALLOC_CTX *mem_ctx)
2743 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
2746 /*******************************************************************
2747 * fill a notify_info_data with the data type
2748 * jfm:xxxx always send RAW as data type
2749 ********************************************************************/
2751 static void spoolss_notify_datatype(int snum,
2752 struct spoolss_Notify *data,
2753 print_queue_struct *queue,
2754 NT_PRINTER_INFO_LEVEL *printer,
2755 TALLOC_CTX *mem_ctx)
2757 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
2760 /*******************************************************************
2761 * fill a notify_info_data with the security descriptor
2762 * jfm:xxxx send an null pointer to say no security desc
2763 * have to implement security before !
2764 ********************************************************************/
2766 static void spoolss_notify_security_desc(int snum,
2767 struct spoolss_Notify *data,
2768 print_queue_struct *queue,
2769 NT_PRINTER_INFO_LEVEL *printer,
2770 TALLOC_CTX *mem_ctx)
2772 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
2773 printer->info_2->secdesc_buf->sd_size,
2774 printer->info_2->secdesc_buf->sd);
2777 /*******************************************************************
2778 * fill a notify_info_data with the attributes
2779 * jfm:xxxx a samba printer is always shared
2780 ********************************************************************/
2782 static void spoolss_notify_attributes(int snum,
2783 struct spoolss_Notify *data,
2784 print_queue_struct *queue,
2785 NT_PRINTER_INFO_LEVEL *printer,
2786 TALLOC_CTX *mem_ctx)
2788 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
2791 /*******************************************************************
2792 * fill a notify_info_data with the priority
2793 ********************************************************************/
2795 static void spoolss_notify_priority(int snum,
2796 struct spoolss_Notify *data,
2797 print_queue_struct *queue,
2798 NT_PRINTER_INFO_LEVEL *printer,
2799 TALLOC_CTX *mem_ctx)
2801 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
2804 /*******************************************************************
2805 * fill a notify_info_data with the default priority
2806 ********************************************************************/
2808 static void spoolss_notify_default_priority(int snum,
2809 struct spoolss_Notify *data,
2810 print_queue_struct *queue,
2811 NT_PRINTER_INFO_LEVEL *printer,
2812 TALLOC_CTX *mem_ctx)
2814 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
2817 /*******************************************************************
2818 * fill a notify_info_data with the start time
2819 ********************************************************************/
2821 static void spoolss_notify_start_time(int snum,
2822 struct spoolss_Notify *data,
2823 print_queue_struct *queue,
2824 NT_PRINTER_INFO_LEVEL *printer,
2825 TALLOC_CTX *mem_ctx)
2827 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
2830 /*******************************************************************
2831 * fill a notify_info_data with the until time
2832 ********************************************************************/
2834 static void spoolss_notify_until_time(int snum,
2835 struct spoolss_Notify *data,
2836 print_queue_struct *queue,
2837 NT_PRINTER_INFO_LEVEL *printer,
2838 TALLOC_CTX *mem_ctx)
2840 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
2843 /*******************************************************************
2844 * fill a notify_info_data with the status
2845 ********************************************************************/
2847 static void spoolss_notify_status(int snum,
2848 struct spoolss_Notify *data,
2849 print_queue_struct *queue,
2850 NT_PRINTER_INFO_LEVEL *printer,
2851 TALLOC_CTX *mem_ctx)
2853 print_status_struct status;
2855 print_queue_length(snum, &status);
2856 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2859 /*******************************************************************
2860 * fill a notify_info_data with the number of jobs queued
2861 ********************************************************************/
2863 static void spoolss_notify_cjobs(int snum,
2864 struct spoolss_Notify *data,
2865 print_queue_struct *queue,
2866 NT_PRINTER_INFO_LEVEL *printer,
2867 TALLOC_CTX *mem_ctx)
2869 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2872 /*******************************************************************
2873 * fill a notify_info_data with the average ppm
2874 ********************************************************************/
2876 static void spoolss_notify_average_ppm(int snum,
2877 struct spoolss_Notify *data,
2878 print_queue_struct *queue,
2879 NT_PRINTER_INFO_LEVEL *printer,
2880 TALLOC_CTX *mem_ctx)
2882 /* always respond 8 pages per minutes */
2883 /* a little hard ! */
2884 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
2887 /*******************************************************************
2888 * fill a notify_info_data with username
2889 ********************************************************************/
2891 static void spoolss_notify_username(int snum,
2892 struct spoolss_Notify *data,
2893 print_queue_struct *queue,
2894 NT_PRINTER_INFO_LEVEL *printer,
2895 TALLOC_CTX *mem_ctx)
2897 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2900 /*******************************************************************
2901 * fill a notify_info_data with job status
2902 ********************************************************************/
2904 static void spoolss_notify_job_status(int snum,
2905 struct spoolss_Notify *data,
2906 print_queue_struct *queue,
2907 NT_PRINTER_INFO_LEVEL *printer,
2908 TALLOC_CTX *mem_ctx)
2910 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2913 /*******************************************************************
2914 * fill a notify_info_data with job name
2915 ********************************************************************/
2917 static void spoolss_notify_job_name(int snum,
2918 struct spoolss_Notify *data,
2919 print_queue_struct *queue,
2920 NT_PRINTER_INFO_LEVEL *printer,
2921 TALLOC_CTX *mem_ctx)
2923 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2926 /*******************************************************************
2927 * fill a notify_info_data with job status
2928 ********************************************************************/
2930 static void spoolss_notify_job_status_string(int snum,
2931 struct spoolss_Notify *data,
2932 print_queue_struct *queue,
2933 NT_PRINTER_INFO_LEVEL *printer,
2934 TALLOC_CTX *mem_ctx)
2937 * Now we're returning job status codes we just return a "" here. JRA.
2942 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2945 switch (queue->status) {
2950 p = ""; /* NT provides the paused string */
2959 #endif /* NO LONGER NEEDED. */
2961 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2964 /*******************************************************************
2965 * fill a notify_info_data with job time
2966 ********************************************************************/
2968 static void spoolss_notify_job_time(int snum,
2969 struct spoolss_Notify *data,
2970 print_queue_struct *queue,
2971 NT_PRINTER_INFO_LEVEL *printer,
2972 TALLOC_CTX *mem_ctx)
2974 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2977 /*******************************************************************
2978 * fill a notify_info_data with job size
2979 ********************************************************************/
2981 static void spoolss_notify_job_size(int snum,
2982 struct spoolss_Notify *data,
2983 print_queue_struct *queue,
2984 NT_PRINTER_INFO_LEVEL *printer,
2985 TALLOC_CTX *mem_ctx)
2987 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2990 /*******************************************************************
2991 * fill a notify_info_data with page info
2992 ********************************************************************/
2993 static void spoolss_notify_total_pages(int snum,
2994 struct spoolss_Notify *data,
2995 print_queue_struct *queue,
2996 NT_PRINTER_INFO_LEVEL *printer,
2997 TALLOC_CTX *mem_ctx)
2999 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3002 /*******************************************************************
3003 * fill a notify_info_data with pages printed info.
3004 ********************************************************************/
3005 static void spoolss_notify_pages_printed(int snum,
3006 struct spoolss_Notify *data,
3007 print_queue_struct *queue,
3008 NT_PRINTER_INFO_LEVEL *printer,
3009 TALLOC_CTX *mem_ctx)
3011 /* Add code when back-end tracks this */
3012 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3015 /*******************************************************************
3016 Fill a notify_info_data with job position.
3017 ********************************************************************/
3019 static void spoolss_notify_job_position(int snum,
3020 struct spoolss_Notify *data,
3021 print_queue_struct *queue,
3022 NT_PRINTER_INFO_LEVEL *printer,
3023 TALLOC_CTX *mem_ctx)
3025 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3028 /*******************************************************************
3029 Fill a notify_info_data with submitted time.
3030 ********************************************************************/
3032 static void spoolss_notify_submitted_time(int snum,
3033 struct spoolss_Notify *data,
3034 print_queue_struct *queue,
3035 NT_PRINTER_INFO_LEVEL *printer,
3036 TALLOC_CTX *mem_ctx)
3038 data->data.string.string = NULL;
3039 data->data.string.size = 0;
3041 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3042 &data->data.string.string,
3043 &data->data.string.size);
3047 struct s_notify_info_data_table
3049 enum spoolss_NotifyType type;
3052 enum spoolss_NotifyTable variable_type;
3053 void (*fn) (int snum, struct spoolss_Notify *data,
3054 print_queue_struct *queue,
3055 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3058 /* A table describing the various print notification constants and
3059 whether the notification data is a pointer to a variable sized
3060 buffer, a one value uint32_t or a two value uint32_t. */
3062 static const struct s_notify_info_data_table notify_info_data_table[] =
3064 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3065 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3066 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3067 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3068 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3069 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3070 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3071 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3081 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3082 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3083 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3084 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3085 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3086 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3087 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3088 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3089 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3090 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3091 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3092 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3093 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3094 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3095 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3096 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3097 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3098 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3099 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3100 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3101 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3102 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3103 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3104 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3105 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3106 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3107 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3108 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3109 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3110 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3111 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3112 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3115 /*******************************************************************
3116 Return the variable_type of info_data structure.
3117 ********************************************************************/
3119 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3124 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3125 if ( (notify_info_data_table[i].type == type) &&
3126 (notify_info_data_table[i].field == field) ) {
3127 return notify_info_data_table[i].variable_type;
3131 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3136 /****************************************************************************
3137 ****************************************************************************/
3139 static bool search_notify(enum spoolss_NotifyType type,
3145 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3146 if (notify_info_data_table[i].type == type &&
3147 notify_info_data_table[i].field == field &&
3148 notify_info_data_table[i].fn != NULL) {
3157 /****************************************************************************
3158 ****************************************************************************/
3160 void construct_info_data(struct spoolss_Notify *info_data,
3161 enum spoolss_NotifyType type,
3165 info_data->type = type;
3166 info_data->field.field = field;
3167 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3168 info_data->job_id = id;
3171 /*******************************************************************
3173 * fill a notify_info struct with info asked
3175 ********************************************************************/
3177 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3178 struct spoolss_NotifyInfo *info,
3180 const struct spoolss_NotifyOptionType *option_type,
3182 TALLOC_CTX *mem_ctx)
3185 enum spoolss_NotifyType type;
3188 struct spoolss_Notify *current_data;
3189 NT_PRINTER_INFO_LEVEL *printer = NULL;
3190 print_queue_struct *queue=NULL;
3192 type = option_type->type;
3194 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3195 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3196 option_type->count, lp_servicename(snum)));
3198 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3201 for(field_num=0; field_num < option_type->count; field_num++) {
3202 field = option_type->fields[field_num].field;
3204 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3206 if (!search_notify(type, field, &j) )
3209 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3210 struct spoolss_Notify,
3212 if (info->notifies == NULL) {
3213 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3214 free_a_printer(&printer, 2);
3218 current_data = &info->notifies[info->count];
3220 construct_info_data(current_data, type, field, id);
3222 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3223 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3225 notify_info_data_table[j].fn(snum, current_data, queue,
3231 free_a_printer(&printer, 2);
3235 /*******************************************************************
3237 * fill a notify_info struct with info asked
3239 ********************************************************************/
3241 static bool construct_notify_jobs_info(print_queue_struct *queue,
3242 struct spoolss_NotifyInfo *info,
3243 NT_PRINTER_INFO_LEVEL *printer,
3245 const struct spoolss_NotifyOptionType *option_type,
3247 TALLOC_CTX *mem_ctx)
3250 enum spoolss_NotifyType type;
3252 struct spoolss_Notify *current_data;
3254 DEBUG(4,("construct_notify_jobs_info\n"));
3256 type = option_type->type;
3258 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3259 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3260 option_type->count));
3262 for(field_num=0; field_num<option_type->count; field_num++) {
3263 field = option_type->fields[field_num].field;
3265 if (!search_notify(type, field, &j) )
3268 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3269 struct spoolss_Notify,
3271 if (info->notifies == NULL) {
3272 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3276 current_data=&(info->notifies[info->count]);
3278 construct_info_data(current_data, type, field, id);
3279 notify_info_data_table[j].fn(snum, current_data, queue,
3288 * JFM: The enumeration is not that simple, it's even non obvious.
3290 * let's take an example: I want to monitor the PRINTER SERVER for
3291 * the printer's name and the number of jobs currently queued.
3292 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3293 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3295 * I have 3 printers on the back of my server.
3297 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3300 * 1 printer 1 name 1
3301 * 2 printer 1 cjob 1
3302 * 3 printer 2 name 2
3303 * 4 printer 2 cjob 2
3304 * 5 printer 3 name 3
3305 * 6 printer 3 name 3
3307 * that's the print server case, the printer case is even worse.
3310 /*******************************************************************
3312 * enumerate all printers on the printserver
3313 * fill a notify_info struct with info asked
3315 ********************************************************************/
3317 static WERROR printserver_notify_info(pipes_struct *p,
3318 struct policy_handle *hnd,
3319 struct spoolss_NotifyInfo *info,
3320 TALLOC_CTX *mem_ctx)
3323 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3324 int n_services=lp_numservices();
3326 struct spoolss_NotifyOption *option;
3327 struct spoolss_NotifyOptionType option_type;
3329 DEBUG(4,("printserver_notify_info\n"));
3334 option = Printer->notify.option;
3337 info->notifies = NULL;
3340 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3341 sending a ffpcn() request first */
3346 for (i=0; i<option->count; i++) {
3347 option_type = option->types[i];
3349 if (option_type.type != PRINTER_NOTIFY_TYPE)
3352 for (snum=0; snum<n_services; snum++)
3354 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3355 construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3361 * Debugging information, don't delete.
3364 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3365 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3366 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3368 for (i=0; i<info->count; i++) {
3369 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3370 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3371 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3378 /*******************************************************************
3380 * fill a notify_info struct with info asked
3382 ********************************************************************/
3384 static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3385 struct spoolss_NotifyInfo *info,
3386 TALLOC_CTX *mem_ctx)
3389 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3392 struct spoolss_NotifyOption *option;
3393 struct spoolss_NotifyOptionType option_type;
3395 print_queue_struct *queue=NULL;
3396 print_status_struct status;
3398 DEBUG(4,("printer_notify_info\n"));
3403 option = Printer->notify.option;
3407 info->notifies = NULL;
3410 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3411 sending a ffpcn() request first */
3416 get_printer_snum(p, hnd, &snum, NULL);
3418 for (i=0; i<option->count; i++) {
3419 option_type = option->types[i];
3421 switch (option_type.type) {
3422 case PRINTER_NOTIFY_TYPE:
3423 if(construct_notify_printer_info(Printer, info, snum,
3429 case JOB_NOTIFY_TYPE: {
3430 NT_PRINTER_INFO_LEVEL *printer = NULL;
3432 count = print_queue_status(snum, &queue, &status);
3434 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3437 for (j=0; j<count; j++) {
3438 construct_notify_jobs_info(&queue[j], info,
3445 free_a_printer(&printer, 2);
3455 * Debugging information, don't delete.
3458 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3459 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3460 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3462 for (i=0; i<info->count; i++) {
3463 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3464 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3465 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3471 /****************************************************************
3472 _spoolss_RouterRefreshPrinterChangeNotify
3473 ****************************************************************/
3475 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3476 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3478 struct spoolss_NotifyInfo *info;
3480 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3481 WERROR result = WERR_BADFID;
3483 /* we always have a spoolss_NotifyInfo struct */
3484 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3486 result = WERR_NOMEM;
3490 *r->out.info = info;
3493 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3494 "Invalid handle (%s:%u:%u).\n",
3495 OUR_HANDLE(r->in.handle)));
3499 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3502 * We are now using the change value, and
3503 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3504 * I don't have a global notification system, I'm sending back all the
3505 * informations even when _NOTHING_ has changed.
3508 /* We need to keep track of the change value to send back in
3509 RRPCN replies otherwise our updates are ignored. */
3511 Printer->notify.fnpcn = true;
3513 if (Printer->notify.client_connected) {
3514 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3515 "Saving change value in request [%x]\n",
3517 Printer->notify.change = r->in.change_low;
3520 /* just ignore the spoolss_NotifyOption */
3522 switch (Printer->printer_type) {
3524 result = printserver_notify_info(p, r->in.handle,
3528 case SPLHND_PRINTER:
3529 result = printer_notify_info(p, r->in.handle,
3534 Printer->notify.fnpcn = false;
3540 /********************************************************************
3541 * construct_printer_info_0
3542 * fill a printer_info_0 struct
3543 ********************************************************************/
3545 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3546 const NT_PRINTER_INFO_LEVEL *ntprinter,
3547 struct spoolss_PrinterInfo0 *r,
3551 counter_printer_0 *session_counter;
3553 print_status_struct status;
3555 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3556 W_ERROR_HAVE_NO_MEMORY(r->printername);
3558 r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3559 W_ERROR_HAVE_NO_MEMORY(r->servername);
3561 count = print_queue_length(snum, &status);
3563 /* check if we already have a counter for this printer */
3564 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3565 if (session_counter->snum == snum)
3569 /* it's the first time, add it to the list */
3570 if (session_counter == NULL) {
3571 session_counter = SMB_MALLOC_P(counter_printer_0);
3572 W_ERROR_HAVE_NO_MEMORY(session_counter);
3573 ZERO_STRUCTP(session_counter);
3574 session_counter->snum = snum;
3575 session_counter->counter = 0;
3576 DLIST_ADD(counter_list, session_counter);
3580 session_counter->counter++;
3586 setuptime = (time_t)ntprinter->info_2->setuptime;
3588 init_systemtime(&r->time, gmtime(&setuptime));
3591 * the global_counter should be stored in a TDB as it's common to all the clients
3592 * and should be zeroed on samba startup
3594 r->global_counter = session_counter->counter;
3596 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3597 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3598 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3599 r->free_build = SPOOLSS_RELEASE_BUILD;
3601 r->max_spooling = 0;
3602 r->session_counter = session_counter->counter;
3603 r->num_error_out_of_paper = 0x0;
3604 r->num_error_not_ready = 0x0; /* number of print failure */
3606 r->number_of_processors = 0x1;
3607 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3608 r->high_part_total_bytes = 0x0;
3609 r->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3610 r->last_error = WERR_OK;
3611 r->status = nt_printq_status(status.status);
3612 r->enumerate_network_printers = 0x0;
3613 r->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3614 r->processor_architecture = 0x0;
3615 r->processor_level = 0x6; /* 6 ???*/
3623 /****************************************************************************
3624 Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers
3625 should be valid upon entry
3626 ****************************************************************************/
3628 static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
3629 struct spoolss_DeviceMode *r,
3630 const NT_DEVICEMODE *ntdevmode)
3632 if (!r || !ntdevmode) {
3633 return WERR_INVALID_PARAM;
3636 r->devicename = talloc_strdup(mem_ctx, ntdevmode->devicename);
3637 W_ERROR_HAVE_NO_MEMORY(r->devicename);
3639 r->specversion = ntdevmode->specversion;
3640 r->driverversion = ntdevmode->driverversion;
3641 r->size = ntdevmode->size;
3642 r->__driverextra_length = ntdevmode->driverextra;
3643 r->fields = ntdevmode->fields;
3645 r->orientation = ntdevmode->orientation;
3646 r->papersize = ntdevmode->papersize;
3647 r->paperlength = ntdevmode->paperlength;
3648 r->paperwidth = ntdevmode->paperwidth;
3649 r->scale = ntdevmode->scale;
3650 r->copies = ntdevmode->copies;
3651 r->defaultsource = ntdevmode->defaultsource;
3652 r->printquality = ntdevmode->printquality;
3653 r->color = ntdevmode->color;
3654 r->duplex = ntdevmode->duplex;
3655 r->yresolution = ntdevmode->yresolution;
3656 r->ttoption = ntdevmode->ttoption;
3657 r->collate = ntdevmode->collate;
3659 r->formname = talloc_strdup(mem_ctx, ntdevmode->formname);
3660 W_ERROR_HAVE_NO_MEMORY(r->formname);
3662 r->logpixels = ntdevmode->logpixels;
3663 r->bitsperpel = ntdevmode->bitsperpel;
3664 r->pelswidth = ntdevmode->pelswidth;
3665 r->pelsheight = ntdevmode->pelsheight;
3666 r->displayflags = ntdevmode->displayflags;
3667 r->displayfrequency = ntdevmode->displayfrequency;
3668 r->icmmethod = ntdevmode->icmmethod;
3669 r->icmintent = ntdevmode->icmintent;
3670 r->mediatype = ntdevmode->mediatype;
3671 r->dithertype = ntdevmode->dithertype;
3672 r->reserved1 = ntdevmode->reserved1;
3673 r->reserved2 = ntdevmode->reserved2;
3674 r->panningwidth = ntdevmode->panningwidth;
3675 r->panningheight = ntdevmode->panningheight;
3677 if (ntdevmode->nt_dev_private != NULL) {
3678 r->driverextra_data = data_blob_talloc(mem_ctx,
3679 ntdevmode->nt_dev_private,
3680 ntdevmode->driverextra);
3681 W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
3688 /****************************************************************************
3689 Create a spoolss_DeviceMode struct. Returns talloced memory.
3690 ****************************************************************************/
3692 struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
3693 const char *servicename)
3696 NT_PRINTER_INFO_LEVEL *printer = NULL;
3697 struct spoolss_DeviceMode *devmode = NULL;
3699 DEBUG(7,("construct_dev_mode\n"));
3701 DEBUGADD(8,("getting printer characteristics\n"));
3703 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
3706 if (!printer->info_2->devmode) {
3707 DEBUG(5, ("BONG! There was no device mode!\n"));
3711 devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
3713 DEBUG(2,("construct_dev_mode: talloc fail.\n"));
3717 DEBUGADD(8,("loading DEVICEMODE\n"));
3719 result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode);
3720 if (!W_ERROR_IS_OK(result)) {
3721 TALLOC_FREE(devmode);
3725 free_a_printer(&printer,2);
3730 /********************************************************************
3731 * construct_printer_info1
3732 * fill a spoolss_PrinterInfo1 struct
3733 ********************************************************************/
3735 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3736 const NT_PRINTER_INFO_LEVEL *ntprinter,
3738 struct spoolss_PrinterInfo1 *r,
3743 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3744 ntprinter->info_2->printername,
3745 ntprinter->info_2->drivername,
3746 ntprinter->info_2->location);
3747 W_ERROR_HAVE_NO_MEMORY(r->description);
3749 if (*ntprinter->info_2->comment == '\0') {
3750 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3752 r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
3754 W_ERROR_HAVE_NO_MEMORY(r->comment);
3756 r->name = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3757 W_ERROR_HAVE_NO_MEMORY(r->name);
3762 /********************************************************************
3763 * construct_printer_info2
3764 * fill a spoolss_PrinterInfo2 struct
3765 ********************************************************************/
3767 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3768 const NT_PRINTER_INFO_LEVEL *ntprinter,
3769 struct spoolss_PrinterInfo2 *r,
3774 print_status_struct status;
3776 count = print_queue_length(snum, &status);
3778 r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3779 W_ERROR_HAVE_NO_MEMORY(r->servername);
3780 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3781 W_ERROR_HAVE_NO_MEMORY(r->printername);
3782 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3783 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3784 r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3785 W_ERROR_HAVE_NO_MEMORY(r->portname);
3786 r->drivername = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
3787 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3789 if (*ntprinter->info_2->comment == '\0') {
3790 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3792 r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
3794 W_ERROR_HAVE_NO_MEMORY(r->comment);
3796 r->location = talloc_strdup(mem_ctx, ntprinter->info_2->location);
3797 W_ERROR_HAVE_NO_MEMORY(r->location);
3798 r->sepfile = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
3799 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3800 r->printprocessor = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
3801 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3802 r->datatype = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
3803 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3804 r->parameters = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
3805 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3807 r->attributes = ntprinter->info_2->attributes;
3809 r->priority = ntprinter->info_2->priority;
3810 r->defaultpriority = ntprinter->info_2->default_priority;
3811 r->starttime = ntprinter->info_2->starttime;
3812 r->untiltime = ntprinter->info_2->untiltime;
3813 r->status = nt_printq_status(status.status);
3815 r->averageppm = ntprinter->info_2->averageppm;
3817 r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3819 DEBUG(8,("Returning NULL Devicemode!\n"));
3824 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3825 /* don't use talloc_steal() here unless you do a deep steal of all
3826 the SEC_DESC members */
3828 r->secdesc = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
3834 /********************************************************************
3835 * construct_printer_info3
3836 * fill a spoolss_PrinterInfo3 struct
3837 ********************************************************************/
3839 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3840 const NT_PRINTER_INFO_LEVEL *ntprinter,
3841 struct spoolss_PrinterInfo3 *r,
3844 /* These are the components of the SD we are returning. */
3846 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3847 /* don't use talloc_steal() here unless you do a deep steal of all
3848 the SEC_DESC members */
3850 r->secdesc = dup_sec_desc(mem_ctx,
3851 ntprinter->info_2->secdesc_buf->sd);
3852 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3858 /********************************************************************
3859 * construct_printer_info4
3860 * fill a spoolss_PrinterInfo4 struct
3861 ********************************************************************/
3863 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3864 const NT_PRINTER_INFO_LEVEL *ntprinter,
3865 struct spoolss_PrinterInfo4 *r,
3868 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3869 W_ERROR_HAVE_NO_MEMORY(r->printername);
3870 r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3871 W_ERROR_HAVE_NO_MEMORY(r->servername);
3873 r->attributes = ntprinter->info_2->attributes;
3878 /********************************************************************
3879 * construct_printer_info5
3880 * fill a spoolss_PrinterInfo5 struct
3881 ********************************************************************/
3883 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3884 const NT_PRINTER_INFO_LEVEL *ntprinter,
3885 struct spoolss_PrinterInfo5 *r,
3888 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3889 W_ERROR_HAVE_NO_MEMORY(r->printername);
3890 r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3891 W_ERROR_HAVE_NO_MEMORY(r->portname);
3893 r->attributes = ntprinter->info_2->attributes;
3895 /* these two are not used by NT+ according to MSDN */
3897 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3898 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3903 /********************************************************************
3904 * construct_printer_info_6
3905 * fill a spoolss_PrinterInfo6 struct
3906 ********************************************************************/
3908 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3909 const NT_PRINTER_INFO_LEVEL *ntprinter,
3910 struct spoolss_PrinterInfo6 *r,
3914 print_status_struct status;
3916 count = print_queue_length(snum, &status);
3918 r->status = nt_printq_status(status.status);
3923 /********************************************************************
3924 * construct_printer_info7
3925 * fill a spoolss_PrinterInfo7 struct
3926 ********************************************************************/
3928 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3929 Printer_entry *print_hnd,
3930 struct spoolss_PrinterInfo7 *r,
3935 if (is_printer_published(print_hnd, snum, &guid)) {
3936 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3937 r->action = DSPRINT_PUBLISH;
3939 r->guid = talloc_strdup(mem_ctx, "");
3940 r->action = DSPRINT_UNPUBLISH;
3942 W_ERROR_HAVE_NO_MEMORY(r->guid);
3947 /********************************************************************
3948 * construct_printer_info8
3949 * fill a spoolss_PrinterInfo8 struct
3950 ********************************************************************/
3952 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3953 const NT_PRINTER_INFO_LEVEL *ntprinter,
3954 struct spoolss_DeviceModeInfo *r,
3957 r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3959 DEBUG(8,("Returning NULL Devicemode!\n"));
3966 /********************************************************************
3967 ********************************************************************/
3969 static bool snum_is_shared_printer(int snum)
3971 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3974 /********************************************************************
3975 Spoolss_enumprinters.
3976 ********************************************************************/
3978 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3981 union spoolss_PrinterInfo **info_p,
3985 int n_services = lp_numservices();
3986 union spoolss_PrinterInfo *info = NULL;
3988 WERROR result = WERR_OK;
3993 for (snum = 0; snum < n_services; snum++) {
3995 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3997 if (!snum_is_shared_printer(snum)) {
4001 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4002 lp_servicename(snum), snum));
4004 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4005 union spoolss_PrinterInfo,
4008 result = WERR_NOMEM;
4012 result = get_a_printer(NULL, &ntprinter, 2,
4013 lp_const_servicename(snum));
4014 if (!W_ERROR_IS_OK(result)) {
4020 result = construct_printer_info0(info, ntprinter,
4021 &info[count].info0, snum);
4024 result = construct_printer_info1(info, ntprinter, flags,
4025 &info[count].info1, snum);
4028 result = construct_printer_info2(info, ntprinter,
4029 &info[count].info2, snum);
4032 result = construct_printer_info4(info, ntprinter,
4033 &info[count].info4, snum);
4036 result = construct_printer_info5(info, ntprinter,
4037 &info[count].info5, snum);
4041 result = WERR_UNKNOWN_LEVEL;
4042 free_a_printer(&ntprinter, 2);
4046 free_a_printer(&ntprinter, 2);
4047 if (!W_ERROR_IS_OK(result)) {
4058 if (!W_ERROR_IS_OK(result)) {
4068 /********************************************************************
4069 * handle enumeration of printers at level 0
4070 ********************************************************************/
4072 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4074 const char *servername,
4075 union spoolss_PrinterInfo **info,
4078 DEBUG(4,("enum_all_printers_info_0\n"));
4080 return enum_all_printers_info_level(mem_ctx, 0, flags, info, count);
4084 /********************************************************************
4085 ********************************************************************/
4087 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4089 union spoolss_PrinterInfo **info,
4092 DEBUG(4,("enum_all_printers_info_1\n"));
4094 return enum_all_printers_info_level(mem_ctx, 1, flags, info, count);
4097 /********************************************************************
4098 enum_all_printers_info_1_local.
4099 *********************************************************************/
4101 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4102 union spoolss_PrinterInfo **info,
4105 DEBUG(4,("enum_all_printers_info_1_local\n"));
4107 return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4110 /********************************************************************
4111 enum_all_printers_info_1_name.
4112 *********************************************************************/
4114 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4116 union spoolss_PrinterInfo **info,
4119 const char *s = name;
4121 DEBUG(4,("enum_all_printers_info_1_name\n"));
4123 if ((name[0] == '\\') && (name[1] == '\\')) {
4127 if (!is_myname_or_ipaddr(s)) {
4128 return WERR_INVALID_NAME;
4131 return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4134 /********************************************************************
4135 enum_all_printers_info_1_network.
4136 *********************************************************************/
4138 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4140 union spoolss_PrinterInfo **info,
4143 const char *s = name;
4145 DEBUG(4,("enum_all_printers_info_1_network\n"));
4147 /* If we respond to a enum_printers level 1 on our name with flags
4148 set to PRINTER_ENUM_REMOTE with a list of printers then these
4149 printers incorrectly appear in the APW browse list.
4150 Specifically the printers for the server appear at the workgroup
4151 level where all the other servers in the domain are
4152 listed. Windows responds to this call with a
4153 WERR_CAN_NOT_COMPLETE so we should do the same. */
4155 if (name[0] == '\\' && name[1] == '\\') {
4159 if (is_myname_or_ipaddr(s)) {
4160 return WERR_CAN_NOT_COMPLETE;
4163 return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
4166 /********************************************************************
4167 * api_spoolss_enumprinters
4169 * called from api_spoolss_enumprinters (see this to understand)
4170 ********************************************************************/
4172 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4173 union spoolss_PrinterInfo **info,
4176 DEBUG(4,("enum_all_printers_info_2\n"));
4178 return enum_all_printers_info_level(mem_ctx, 2, 0, info, count);
4181 /********************************************************************
4182 * handle enumeration of printers at level 1
4183 ********************************************************************/
4185 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4188 union spoolss_PrinterInfo **info,
4191 /* Not all the flags are equals */
4193 if (flags & PRINTER_ENUM_LOCAL) {
4194 return enum_all_printers_info_1_local(mem_ctx, info, count);
4197 if (flags & PRINTER_ENUM_NAME) {
4198 return enum_all_printers_info_1_name(mem_ctx, name, info, count);
4201 if (flags & PRINTER_ENUM_NETWORK) {
4202 return enum_all_printers_info_1_network(mem_ctx, name, info, count);
4205 return WERR_OK; /* NT4sp5 does that */
4208 /********************************************************************
4209 * handle enumeration of printers at level 2
4210 ********************************************************************/
4212 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4214 const char *servername,
4215 union spoolss_PrinterInfo **info,
4218 if (flags & PRINTER_ENUM_LOCAL) {
4219 return enum_all_printers_info_2(mem_ctx, info, count);
4222 if (flags & PRINTER_ENUM_NAME) {
4223 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4224 return WERR_INVALID_NAME;
4227 return enum_all_printers_info_2(mem_ctx, info, count);
4230 if (flags & PRINTER_ENUM_REMOTE) {
4231 return WERR_UNKNOWN_LEVEL;
4237 /********************************************************************
4238 * handle enumeration of printers at level 4
4239 ********************************************************************/
4241 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4243 const char *servername,
4244 union spoolss_PrinterInfo **info,
4247 DEBUG(4,("enum_all_printers_info_4\n"));
4249 return enum_all_printers_info_level(mem_ctx, 4, flags, info, count);
4253 /********************************************************************
4254 * handle enumeration of printers at level 5
4255 ********************************************************************/
4257 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4259 const char *servername,
4260 union spoolss_PrinterInfo **info,
4263 DEBUG(4,("enum_all_printers_info_5\n"));
4265 return enum_all_printers_info_level(mem_ctx, 5, flags, info, count);
4268 /****************************************************************
4269 _spoolss_EnumPrinters
4270 ****************************************************************/
4272 WERROR _spoolss_EnumPrinters(pipes_struct *p,
4273 struct spoolss_EnumPrinters *r)
4275 const char *name = NULL;
4278 /* that's an [in out] buffer */
4280 if (!r->in.buffer && (r->in.offered != 0)) {
4281 return WERR_INVALID_PARAM;
4284 DEBUG(4,("_spoolss_EnumPrinters\n"));
4288 *r->out.info = NULL;
4292 * flags==PRINTER_ENUM_NAME
4293 * if name=="" then enumerates all printers
4294 * if name!="" then enumerate the printer
4295 * flags==PRINTER_ENUM_REMOTE
4296 * name is NULL, enumerate printers
4297 * Level 2: name!="" enumerates printers, name can't be NULL
4298 * Level 3: doesn't exist
4299 * Level 4: does a local registry lookup
4300 * Level 5: same as Level 2
4304 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4305 W_ERROR_HAVE_NO_MEMORY(name);
4308 switch (r->in.level) {
4310 result = enumprinters_level0(p->mem_ctx, r->in.flags, name,
4311 r->out.info, r->out.count);
4314 result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
4315 r->out.info, r->out.count);
4318 result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
4319 r->out.info, r->out.count);
4322 result = enumprinters_level4(p->mem_ctx, r->in.flags, name,
4323 r->out.info, r->out.count);
4326 result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
4327 r->out.info, r->out.count);
4330 return WERR_UNKNOWN_LEVEL;
4333 if (!W_ERROR_IS_OK(result)) {
4337 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4338 spoolss_EnumPrinters,
4339 *r->out.info, r->in.level,
4341 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4342 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4344 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4347 /****************************************************************
4349 ****************************************************************/
4351 WERROR _spoolss_GetPrinter(pipes_struct *p,
4352 struct spoolss_GetPrinter *r)
4354 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4355 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4356 WERROR result = WERR_OK;
4360 /* that's an [in out] buffer */
4362 if (!r->in.buffer && (r->in.offered != 0)) {
4363 return WERR_INVALID_PARAM;
4368 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4372 result = get_a_printer(Printer, &ntprinter, 2,
4373 lp_const_servicename(snum));
4374 if (!W_ERROR_IS_OK(result)) {
4378 switch (r->in.level) {
4380 result = construct_printer_info0(p->mem_ctx, ntprinter,
4381 &r->out.info->info0, snum);
4384 result = construct_printer_info1(p->mem_ctx, ntprinter,
4386 &r->out.info->info1, snum);
4389 result = construct_printer_info2(p->mem_ctx, ntprinter,
4390 &r->out.info->info2, snum);
4393 result = construct_printer_info3(p->mem_ctx, ntprinter,
4394 &r->out.info->info3, snum);
4397 result = construct_printer_info4(p->mem_ctx, ntprinter,
4398 &r->out.info->info4, snum);
4401 result = construct_printer_info5(p->mem_ctx, ntprinter,
4402 &r->out.info->info5, snum);
4405 result = construct_printer_info6(p->mem_ctx, ntprinter,
4406 &r->out.info->info6, snum);
4409 result = construct_printer_info7(p->mem_ctx, Printer,
4410 &r->out.info->info7, snum);
4413 result = construct_printer_info8(p->mem_ctx, ntprinter,
4414 &r->out.info->info8, snum);
4417 result = WERR_UNKNOWN_LEVEL;
4421 free_a_printer(&ntprinter, 2);
4423 if (!W_ERROR_IS_OK(result)) {
4424 TALLOC_FREE(r->out.info);
4428 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4429 r->out.info, r->in.level);
4430 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4432 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4435 /********************************************************************
4436 ********************************************************************/
4438 static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4439 const char **string_array,
4440 const char *cservername)
4442 int i, num_strings = 0;
4443 const char **array = NULL;
4445 if (!string_array) {
4449 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4451 const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
4452 cservername, string_array[i]);
4459 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4466 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4467 &array, &num_strings);
4473 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4475 if (in && strlen(in)) { \
4476 out = talloc_strdup(mem_ctx, in); \
4477 W_ERROR_HAVE_NO_MEMORY(out); \
4483 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
4485 if (in && strlen(in)) { \
4486 out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
4488 out = talloc_strdup(mem_ctx, ""); \
4490 W_ERROR_HAVE_NO_MEMORY(out); \
4493 /********************************************************************
4494 * fill a spoolss_DriverInfo1 struct
4495 ********************************************************************/
4497 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4498 struct spoolss_DriverInfo1 *r,
4499 const struct spoolss_DriverInfo8 *driver,
4500 const char *servername)
4502 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4503 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4508 /********************************************************************
4509 * fill a spoolss_DriverInfo2 struct
4510 ********************************************************************/
4512 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4513 struct spoolss_DriverInfo2 *r,
4514 const struct spoolss_DriverInfo8 *driver,
4515 const char *servername)
4518 const char *cservername = canon_servername(servername);
4520 r->version = driver->version;
4522 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4523 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4524 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4525 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4527 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4528 driver->driver_path,
4531 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4535 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4536 driver->config_file,
4542 /********************************************************************
4543 * fill a spoolss_DriverInfo3 struct
4544 ********************************************************************/
4546 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4547 struct spoolss_DriverInfo3 *r,
4548 const struct spoolss_DriverInfo8 *driver,
4549 const char *servername)
4551 const char *cservername = canon_servername(servername);
4553 r->version = driver->version;
4555 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4556 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4557 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4558 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4560 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4561 driver->driver_path,
4564 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4568 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4569 driver->config_file,
4572 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4576 FILL_DRIVER_STRING(mem_ctx,
4577 driver->monitor_name,
4580 FILL_DRIVER_STRING(mem_ctx,
4581 driver->default_datatype,
4582 r->default_datatype);
4584 r->dependent_files = string_array_from_driver_info(mem_ctx,
4585 driver->dependent_files,
4590 /********************************************************************
4591 * fill a spoolss_DriverInfo4 struct
4592 ********************************************************************/
4594 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4595 struct spoolss_DriverInfo4 *r,
4596 const struct spoolss_DriverInfo8 *driver,
4597 const char *servername)
4599 const char *cservername = canon_servername(servername);
4601 r->version = driver->version;
4603 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4604 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4605 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4606 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4608 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4609 driver->driver_path,
4612 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4616 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4617 driver->config_file,
4620 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4624 r->dependent_files = string_array_from_driver_info(mem_ctx,
4625 driver->dependent_files,
4628 FILL_DRIVER_STRING(mem_ctx,
4629 driver->monitor_name,
4632 FILL_DRIVER_STRING(mem_ctx,
4633 driver->default_datatype,
4634 r->default_datatype);
4636 r->previous_names = string_array_from_driver_info(mem_ctx,
4637 driver->previous_names,
4643 /********************************************************************
4644 * fill a spoolss_DriverInfo5 struct
4645 ********************************************************************/
4647 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4648 struct spoolss_DriverInfo5 *r,
4649 const struct spoolss_DriverInfo8 *driver,
4650 const char *servername)
4652 const char *cservername = canon_servername(servername);
4654 r->version = driver->version;
4656 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4657 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4658 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4659 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4661 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4662 driver->driver_path,
4665 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4669 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4670 driver->config_file,
4673 r->driver_attributes = 0;
4674 r->config_version = 0;
4675 r->driver_version = 0;
4679 /********************************************************************
4680 * fill a spoolss_DriverInfo6 struct
4681 ********************************************************************/
4683 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4684 struct spoolss_DriverInfo6 *r,
4685 const struct spoolss_DriverInfo8 *driver,
4686 const char *servername)
4688 const char *cservername = canon_servername(servername);
4690 r->version = driver->version;
4692 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4693 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4694 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4695 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4697 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4698 driver->driver_path,
4701 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4705 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4706 driver->config_file,
4709 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4713 FILL_DRIVER_STRING(mem_ctx,
4714 driver->monitor_name,
4717 FILL_DRIVER_STRING(mem_ctx,
4718 driver->default_datatype,
4719 r->default_datatype);
4721 r->dependent_files = string_array_from_driver_info(mem_ctx,
4722 driver->dependent_files,
4724 r->previous_names = string_array_from_driver_info(mem_ctx,
4725 driver->previous_names,
4728 r->driver_date = driver->driver_date;
4729 r->driver_version = driver->driver_version;
4731 FILL_DRIVER_STRING(mem_ctx,
4732 driver->manufacturer_name,
4733 r->manufacturer_name);
4734 FILL_DRIVER_STRING(mem_ctx,
4735 driver->manufacturer_url,
4736 r->manufacturer_url);
4737 FILL_DRIVER_STRING(mem_ctx,
4738 driver->hardware_id,
4740 FILL_DRIVER_STRING(mem_ctx,
4747 /********************************************************************
4748 * fill a spoolss_DriverInfo8 struct
4749 ********************************************************************/
4751 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4752 struct spoolss_DriverInfo8 *r,
4753 const struct spoolss_DriverInfo8 *driver,
4754 const char *servername)
4756 const char *cservername = canon_servername(servername);
4758 r->version = driver->version;
4760 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4761 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4762 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4763 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4765 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4766 driver->driver_path,
4769 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4773 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4774 driver->config_file,
4777 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4781 FILL_DRIVER_STRING(mem_ctx,
4782 driver->monitor_name,
4785 FILL_DRIVER_STRING(mem_ctx,
4786 driver->default_datatype,
4787 r->default_datatype);
4789 r->dependent_files = string_array_from_driver_info(mem_ctx,
4790 driver->dependent_files,
4792 r->previous_names = string_array_from_driver_info(mem_ctx,
4793 driver->previous_names,
4796 r->driver_date = driver->driver_date;
4797 r->driver_version = driver->driver_version;
4799 FILL_DRIVER_STRING(mem_ctx,
4800 driver->manufacturer_name,
4801 r->manufacturer_name);
4802 FILL_DRIVER_STRING(mem_ctx,
4803 driver->manufacturer_url,
4804 r->manufacturer_url);
4805 FILL_DRIVER_STRING(mem_ctx,
4806 driver->hardware_id,
4808 FILL_DRIVER_STRING(mem_ctx,
4812 FILL_DRIVER_STRING(mem_ctx,
4813 driver->print_processor,
4814 r->print_processor);
4815 FILL_DRIVER_STRING(mem_ctx,
4816 driver->vendor_setup,
4819 r->color_profiles = string_array_from_driver_info(mem_ctx,
4820 driver->color_profiles,
4823 FILL_DRIVER_STRING(mem_ctx,
4827 r->printer_driver_attributes = driver->printer_driver_attributes;
4829 r->core_driver_dependencies = string_array_from_driver_info(mem_ctx,
4830 driver->core_driver_dependencies,
4833 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4834 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4839 #if 0 /* disabled until marshalling issues are resolved - gd */
4840 /********************************************************************
4841 ********************************************************************/
4843 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4844 struct spoolss_DriverFileInfo *r,
4845 const char *cservername,
4846 const char *file_name,
4847 enum spoolss_DriverFileType file_type,
4848 uint32_t file_version)
4850 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4851 cservername, file_name);
4852 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4853 r->file_type = file_type;
4854 r->file_version = file_version;
4859 /********************************************************************
4860 ********************************************************************/
4862 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4863 const struct spoolss_DriverInfo8 *driver,
4864 const char *cservername,
4865 struct spoolss_DriverFileInfo **info_p,
4868 struct spoolss_DriverFileInfo *info = NULL;
4876 if (strlen(driver->driver_path)) {
4877 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4878 struct spoolss_DriverFileInfo,
4880 W_ERROR_HAVE_NO_MEMORY(info);
4881 result = fill_spoolss_DriverFileInfo(info,
4884 driver->driver_path,
4885 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4887 W_ERROR_NOT_OK_RETURN(result);
4891 if (strlen(driver->config_file)) {
4892 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4893 struct spoolss_DriverFileInfo,
4895 W_ERROR_HAVE_NO_MEMORY(info);
4896 result = fill_spoolss_DriverFileInfo(info,
4899 driver->config_file,
4900 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4902 W_ERROR_NOT_OK_RETURN(result);
4906 if (strlen(driver->data_file)) {
4907 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4908 struct spoolss_DriverFileInfo,
4910 W_ERROR_HAVE_NO_MEMORY(info);
4911 result = fill_spoolss_DriverFileInfo(info,
4915 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4917 W_ERROR_NOT_OK_RETURN(result);
4921 if (strlen(driver->help_file)) {
4922 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4923 struct spoolss_DriverFileInfo,
4925 W_ERROR_HAVE_NO_MEMORY(info);
4926 result = fill_spoolss_DriverFileInfo(info,
4930 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4932 W_ERROR_NOT_OK_RETURN(result);
4936 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4937 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4938 struct spoolss_DriverFileInfo,
4940 W_ERROR_HAVE_NO_MEMORY(info);
4941 result = fill_spoolss_DriverFileInfo(info,
4944 driver->dependent_files[i],
4945 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4947 W_ERROR_NOT_OK_RETURN(result);
4957 /********************************************************************
4958 * fill a spoolss_DriverInfo101 struct
4959 ********************************************************************/
4961 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4962 struct spoolss_DriverInfo101 *r,
4963 const struct spoolss_DriverInfo8 *driver,
4964 const char *servername)
4966 const char *cservername = canon_servername(servername);
4969 r->version = driver->version;
4971 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4972 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4973 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4974 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4976 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4980 if (!W_ERROR_IS_OK(result)) {
4984 FILL_DRIVER_STRING(mem_ctx,
4985 driver->monitor_name,
4988 FILL_DRIVER_STRING(mem_ctx,
4989 driver->default_datatype,
4990 r->default_datatype);
4992 r->previous_names = string_array_from_driver_info(mem_ctx,
4993 driver->previous_names,
4995 r->driver_date = driver->driver_date;
4996 r->driver_version = driver->driver_version;
4998 FILL_DRIVER_STRING(mem_ctx,
4999 driver->manufacturer_name,
5000 r->manufacturer_name);
5001 FILL_DRIVER_STRING(mem_ctx,
5002 driver->manufacturer_url,
5003 r->manufacturer_url);
5004 FILL_DRIVER_STRING(mem_ctx,
5005 driver->hardware_id,
5007 FILL_DRIVER_STRING(mem_ctx,
5014 /********************************************************************
5015 ********************************************************************/
5017 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5019 union spoolss_DriverInfo *r,
5021 const char *servername,
5022 const char *architecture,
5025 NT_PRINTER_INFO_LEVEL *printer = NULL;
5026 struct spoolss_DriverInfo8 *driver;
5029 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
5031 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5032 win_errstr(result)));
5034 if (!W_ERROR_IS_OK(result)) {
5035 return WERR_INVALID_PRINTER_NAME;
5038 result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5039 architecture, version);
5041 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5042 win_errstr(result)));
5044 if (!W_ERROR_IS_OK(result)) {
5046 * Is this a W2k client ?
5050 free_a_printer(&printer, 2);
5051 return WERR_UNKNOWN_PRINTER_DRIVER;
5054 /* Yes - try again with a WinNT driver. */
5056 result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5057 architecture, version);
5058 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5059 win_errstr(result)));
5060 if (!W_ERROR_IS_OK(result)) {
5061 free_a_printer(&printer, 2);
5062 return WERR_UNKNOWN_PRINTER_DRIVER;
5068 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5071 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5074 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5077 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5080 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5083 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5086 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5088 #if 0 /* disabled until marshalling issues are resolved - gd */
5090 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5094 result = WERR_UNKNOWN_LEVEL;
5098 free_a_printer(&printer, 2);
5099 free_a_printer_driver(driver);
5104 /****************************************************************
5105 _spoolss_GetPrinterDriver2
5106 ****************************************************************/
5108 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5109 struct spoolss_GetPrinterDriver2 *r)
5111 Printer_entry *printer;
5114 const char *servername;
5117 /* that's an [in out] buffer */
5119 if (!r->in.buffer && (r->in.offered != 0)) {
5120 return WERR_INVALID_PARAM;
5123 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5125 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5126 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5127 return WERR_INVALID_PRINTER_NAME;
5131 *r->out.server_major_version = 0;
5132 *r->out.server_minor_version = 0;
5134 servername = get_server_name(printer);
5136 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5140 result = construct_printer_driver_info_level(p->mem_ctx, r->in.level,
5144 r->in.client_major_version);
5145 if (!W_ERROR_IS_OK(result)) {
5146 TALLOC_FREE(r->out.info);
5150 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5151 r->out.info, r->in.level);
5152 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5154 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5158 /****************************************************************
5159 _spoolss_StartPagePrinter
5160 ****************************************************************/
5162 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5163 struct spoolss_StartPagePrinter *r)
5165 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5168 DEBUG(3,("_spoolss_StartPagePrinter: "
5169 "Error in startpageprinter printer handle\n"));
5173 Printer->page_started = true;
5177 /****************************************************************
5178 _spoolss_EndPagePrinter
5179 ****************************************************************/
5181 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5182 struct spoolss_EndPagePrinter *r)
5186 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5189 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5190 OUR_HANDLE(r->in.handle)));
5194 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5197 Printer->page_started = false;
5198 print_job_endpage(snum, Printer->jobid);
5203 /****************************************************************
5204 _spoolss_StartDocPrinter
5205 ****************************************************************/
5207 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5208 struct spoolss_StartDocPrinter *r)
5210 struct spoolss_DocumentInfo1 *info_1;
5212 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5215 DEBUG(2,("_spoolss_StartDocPrinter: "
5216 "Invalid handle (%s:%u:%u)\n",
5217 OUR_HANDLE(r->in.handle)));
5221 if (r->in.level != 1) {
5222 return WERR_UNKNOWN_LEVEL;
5225 info_1 = r->in.info.info1;
5228 * a nice thing with NT is it doesn't listen to what you tell it.
5229 * when asked to send _only_ RAW datas, it tries to send datas
5232 * So I add checks like in NT Server ...
5235 if (info_1->datatype) {
5236 if (strcmp(info_1->datatype, "RAW") != 0) {
5238 return WERR_INVALID_DATATYPE;
5242 /* get the share number of the printer */
5243 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5247 Printer->jobid = print_job_start(p->server_info, snum,
5248 info_1->document_name,
5249 Printer->nt_devmode);
5251 /* An error occured in print_job_start() so return an appropriate
5254 if (Printer->jobid == -1) {
5255 return map_werror_from_unix(errno);
5258 Printer->document_started = true;
5259 *r->out.job_id = Printer->jobid;
5264 /****************************************************************
5265 _spoolss_EndDocPrinter
5266 ****************************************************************/
5268 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5269 struct spoolss_EndDocPrinter *r)
5271 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5275 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5276 OUR_HANDLE(r->in.handle)));
5280 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5284 Printer->document_started = false;
5285 print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5286 /* error codes unhandled so far ... */
5291 /****************************************************************
5292 _spoolss_WritePrinter
5293 ****************************************************************/
5295 WERROR _spoolss_WritePrinter(pipes_struct *p,
5296 struct spoolss_WritePrinter *r)
5298 ssize_t buffer_written;
5300 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5303 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5304 OUR_HANDLE(r->in.handle)));
5305 *r->out.num_written = r->in._data_size;
5309 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5312 buffer_written = print_job_write(snum, Printer->jobid,
5313 (const char *)r->in.data.data,
5315 (size_t)r->in._data_size);
5316 if (buffer_written == (ssize_t)-1) {
5317 *r->out.num_written = 0;
5318 if (errno == ENOSPC)
5319 return WERR_NO_SPOOL_SPACE;
5321 return WERR_ACCESS_DENIED;
5324 *r->out.num_written = r->in._data_size;
5329 /********************************************************************
5330 * api_spoolss_getprinter
5331 * called from the spoolss dispatcher
5333 ********************************************************************/
5335 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5339 WERROR errcode = WERR_BADFUNC;
5340 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5343 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5344 OUR_HANDLE(handle)));
5348 if (!get_printer_snum(p, handle, &snum, NULL))
5352 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5353 errcode = print_queue_pause(p->server_info, snum);
5355 case SPOOLSS_PRINTER_CONTROL_RESUME:
5356 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5357 errcode = print_queue_resume(p->server_info, snum);
5359 case SPOOLSS_PRINTER_CONTROL_PURGE:
5360 errcode = print_queue_purge(p->server_info, snum);
5363 return WERR_UNKNOWN_LEVEL;
5370 /****************************************************************
5371 _spoolss_AbortPrinter
5372 * From MSDN: "Deletes printer's spool file if printer is configured
5374 ****************************************************************/
5376 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5377 struct spoolss_AbortPrinter *r)
5379 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5381 WERROR errcode = WERR_OK;
5384 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5385 OUR_HANDLE(r->in.handle)));
5389 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5392 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5397 /********************************************************************
5398 * called by spoolss_api_setprinter
5399 * when updating a printer description
5400 ********************************************************************/
5402 static WERROR update_printer_sec(struct policy_handle *handle,
5403 pipes_struct *p, struct sec_desc_buf *secdesc_ctr)
5405 struct sec_desc_buf *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5409 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5411 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5412 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5413 OUR_HANDLE(handle)));
5415 result = WERR_BADFID;
5420 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5421 result = WERR_INVALID_PARAM;
5425 /* Check the user has permissions to change the security
5426 descriptor. By experimentation with two NT machines, the user
5427 requires Full Access to the printer to change security
5430 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5431 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5432 result = WERR_ACCESS_DENIED;
5436 /* NT seems to like setting the security descriptor even though
5437 nothing may have actually changed. */
5439 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
5440 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5441 result = WERR_BADFID;
5445 if (DEBUGLEVEL >= 10) {
5449 the_acl = old_secdesc_ctr->sd->dacl;
5450 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5451 PRINTERNAME(snum), the_acl->num_aces));
5453 for (i = 0; i < the_acl->num_aces; i++) {
5454 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5455 &the_acl->aces[i].trustee),
5456 the_acl->aces[i].access_mask));
5459 the_acl = secdesc_ctr->sd->dacl;
5462 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5463 PRINTERNAME(snum), the_acl->num_aces));
5465 for (i = 0; i < the_acl->num_aces; i++) {
5466 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5467 &the_acl->aces[i].trustee),
5468 the_acl->aces[i].access_mask));
5471 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5475 new_secdesc_ctr = sec_desc_merge_buf(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
5476 if (!new_secdesc_ctr) {
5477 result = WERR_NOMEM;
5481 if (security_descriptor_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
5486 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
5493 /********************************************************************
5494 Canonicalize printer info from a client
5496 ATTN: It does not matter what we set the servername to hear
5497 since we do the necessary work in get_a_printer() to set it to
5498 the correct value based on what the client sent in the
5499 _spoolss_open_printer_ex().
5500 ********************************************************************/
5502 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
5504 fstring printername;
5507 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5508 "portname=%s drivername=%s comment=%s location=%s\n",
5509 info->servername, info->printername, info->sharename,
5510 info->portname, info->drivername, info->comment, info->location));
5512 /* we force some elements to "correct" values */
5513 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
5514 fstrcpy(info->sharename, lp_servicename(snum));
5516 /* check to see if we allow printername != sharename */
5518 if ( lp_force_printername(snum) ) {
5519 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5520 global_myname(), info->sharename );
5523 /* make sure printername is in \\server\printername format */
5525 fstrcpy( printername, info->printername );
5527 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5528 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5532 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5533 global_myname(), p );
5536 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5537 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5544 /****************************************************************************
5545 ****************************************************************************/
5547 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5549 char *cmd = lp_addport_cmd();
5550 char *command = NULL;
5552 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5553 bool is_print_op = false;
5556 return WERR_ACCESS_DENIED;
5559 command = talloc_asprintf(ctx,
5560 "%s \"%s\" \"%s\"", cmd, portname, uri );
5566 is_print_op = user_has_privileges( token, &se_printop );
5568 DEBUG(10,("Running [%s]\n", command));
5570 /********* BEGIN SePrintOperatorPrivilege **********/
5575 ret = smbrun(command, NULL);
5580 /********* END SePrintOperatorPrivilege **********/
5582 DEBUGADD(10,("returned [%d]\n", ret));
5584 TALLOC_FREE(command);
5587 return WERR_ACCESS_DENIED;
5593 /****************************************************************************
5594 ****************************************************************************/
5596 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
5598 char *cmd = lp_addprinter_cmd();
5600 char *command = NULL;
5604 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5605 bool is_print_op = false;
5606 char *remote_machine = talloc_strdup(ctx, "%m");
5608 if (!remote_machine) {
5611 remote_machine = talloc_sub_basic(ctx,
5612 current_user_info.smb_name,
5613 current_user_info.domain,
5615 if (!remote_machine) {
5619 command = talloc_asprintf(ctx,
5620 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5621 cmd, printer->info_2->printername, printer->info_2->sharename,
5622 printer->info_2->portname, printer->info_2->drivername,
5623 printer->info_2->location, printer->info_2->comment, remote_machine);
5629 is_print_op = user_has_privileges( token, &se_printop );
5631 DEBUG(10,("Running [%s]\n", command));
5633 /********* BEGIN SePrintOperatorPrivilege **********/
5638 if ( (ret = smbrun(command, &fd)) == 0 ) {
5639 /* Tell everyone we updated smb.conf. */
5640 message_send_all(smbd_messaging_context(),
5641 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5647 /********* END SePrintOperatorPrivilege **********/
5649 DEBUGADD(10,("returned [%d]\n", ret));
5651 TALLOC_FREE(command);
5652 TALLOC_FREE(remote_machine);
5660 /* reload our services immediately */
5662 reload_services(false);
5666 /* Get lines and convert them back to dos-codepage */
5667 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5668 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5671 /* Set the portname to what the script says the portname should be. */
5672 /* but don't require anything to be return from the script exit a good error code */
5675 /* Set the portname to what the script says the portname should be. */
5676 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
5677 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5680 TALLOC_FREE(qlines);
5685 /********************************************************************
5686 * Called by spoolss_api_setprinter
5687 * when updating a printer description.
5688 ********************************************************************/
5690 static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5691 struct spoolss_SetPrinterInfoCtr *info_ctr,
5692 struct spoolss_DeviceMode *devmode)
5695 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
5696 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5701 DEBUG(8,("update_printer\n"));
5706 result = WERR_BADFID;
5710 if (!get_printer_snum(p, handle, &snum, NULL)) {
5711 result = WERR_BADFID;
5715 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
5716 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
5717 result = WERR_BADFID;
5721 DEBUGADD(8,("Converting info_2 struct\n"));
5724 * convert_printer_info converts the incoming
5725 * info from the client and overwrites the info
5726 * just read from the tdb in the pointer 'printer'.
5729 if (!convert_printer_info(info_ctr, printer)) {
5730 result = WERR_NOMEM;
5735 /* we have a valid devmode
5736 convert it and link it*/
5738 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5739 if (!convert_devicemode(printer->info_2->printername, devmode,
5740 &printer->info_2->devmode)) {
5741 result = WERR_NOMEM;
5746 /* Do sanity check on the requested changes for Samba */
5748 if (!check_printer_ok(printer->info_2, snum)) {
5749 result = WERR_INVALID_PARAM;
5753 /* FIXME!!! If the driver has changed we really should verify that
5754 it is installed before doing much else --jerry */
5756 /* Check calling user has permission to update printer description */
5758 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5759 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5760 result = WERR_ACCESS_DENIED;
5764 /* Call addprinter hook */
5765 /* Check changes to see if this is really needed */
5767 if ( *lp_addprinter_cmd()
5768 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
5769 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
5770 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
5771 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
5773 /* add_printer_hook() will call reload_services() */
5775 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
5777 result = WERR_ACCESS_DENIED;
5783 * When a *new* driver is bound to a printer, the drivername is used to
5784 * lookup previously saved driver initialization info, which is then
5785 * bound to the printer, simulating what happens in the Windows arch.
5787 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
5789 if (!set_driver_init(printer, 2))
5791 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
5792 printer->info_2->drivername));
5795 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5796 printer->info_2->drivername));
5798 notify_printer_driver(snum, printer->info_2->drivername);
5802 * flag which changes actually occured. This is a small subset of
5803 * all the possible changes. We also have to update things in the
5807 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
5808 push_reg_sz(talloc_tos(), &buffer, printer->info_2->comment);
5809 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
5810 REG_SZ, buffer.data, buffer.length);
5812 notify_printer_comment(snum, printer->info_2->comment);
5815 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
5816 push_reg_sz(talloc_tos(), &buffer, printer->info_2->sharename);
5817 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
5818 REG_SZ, buffer.data, buffer.length);
5820 notify_printer_sharename(snum, printer->info_2->sharename);
5823 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
5826 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
5829 pname = printer->info_2->printername;
5832 push_reg_sz(talloc_tos(), &buffer, pname);
5833 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
5834 REG_SZ, buffer.data, buffer.length);
5836 notify_printer_printername( snum, pname );
5839 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
5840 push_reg_sz(talloc_tos(), &buffer, printer->info_2->portname);
5841 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
5842 REG_SZ, buffer.data, buffer.length);
5844 notify_printer_port(snum, printer->info_2->portname);
5847 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
5848 push_reg_sz(talloc_tos(), &buffer, printer->info_2->location);
5849 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
5850 REG_SZ, buffer.data, buffer.length);
5852 notify_printer_location(snum, printer->info_2->location);
5855 /* here we need to update some more DsSpooler keys */
5856 /* uNCName, serverName, shortServerName */
5858 push_reg_sz(talloc_tos(), &buffer, global_myname());
5859 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
5860 REG_SZ, buffer.data, buffer.length);
5861 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
5862 REG_SZ, buffer.data, buffer.length);
5864 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
5865 global_myname(), printer->info_2->sharename );
5866 push_reg_sz(talloc_tos(), &buffer, asc_buffer);
5867 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
5868 REG_SZ, buffer.data, buffer.length);
5870 /* Update printer info */
5871 result = mod_a_printer(printer, 2);
5874 free_a_printer(&printer, 2);
5875 free_a_printer(&old_printer, 2);
5881 /****************************************************************************
5882 ****************************************************************************/
5883 static WERROR publish_or_unpublish_printer(pipes_struct *p,
5884 struct policy_handle *handle,
5885 struct spoolss_SetPrinterInfo7 *info7)
5889 Printer_entry *Printer;
5891 if ( lp_security() != SEC_ADS ) {
5892 return WERR_UNKNOWN_LEVEL;
5895 Printer = find_printer_index_by_hnd(p, handle);
5897 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5902 if (!get_printer_snum(p, handle, &snum, NULL))
5905 nt_printer_publish(Printer, snum, info7->action);
5909 return WERR_UNKNOWN_LEVEL;
5913 /********************************************************************
5914 ********************************************************************/
5916 static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
5917 struct spoolss_DeviceMode *devmode)
5920 NT_PRINTER_INFO_LEVEL *printer = NULL;
5921 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5924 DEBUG(8,("update_printer_devmode\n"));
5929 result = WERR_BADFID;
5933 if (!get_printer_snum(p, handle, &snum, NULL)) {
5934 result = WERR_BADFID;
5938 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)))) {
5939 result = WERR_BADFID;
5944 /* we have a valid devmode
5945 convert it and link it*/
5947 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5948 if (!convert_devicemode(printer->info_2->printername, devmode,
5949 &printer->info_2->devmode)) {
5950 result = WERR_NOMEM;
5955 /* Check calling user has permission to update printer description */
5957 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5958 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5959 result = WERR_ACCESS_DENIED;
5964 /* Update printer info */
5965 result = mod_a_printer(printer, 2);
5968 free_a_printer(&printer, 2);
5974 /****************************************************************
5976 ****************************************************************/
5978 WERROR _spoolss_SetPrinter(pipes_struct *p,
5979 struct spoolss_SetPrinter *r)
5983 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5986 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5987 OUR_HANDLE(r->in.handle)));
5991 /* check the level */
5992 switch (r->in.info_ctr->level) {
5994 return control_printer(r->in.handle, r->in.command, p);
5996 result = update_printer(p, r->in.handle,
5998 r->in.devmode_ctr->devmode);
5999 if (!W_ERROR_IS_OK(result))
6001 if (r->in.secdesc_ctr->sd)
6002 result = update_printer_sec(r->in.handle, p,
6006 return update_printer_sec(r->in.handle, p,
6009 return publish_or_unpublish_printer(p, r->in.handle,
6010 r->in.info_ctr->info.info7);
6012 return update_printer_devmode(p, r->in.handle,
6013 r->in.devmode_ctr->devmode);
6015 return WERR_UNKNOWN_LEVEL;
6019 /****************************************************************
6020 _spoolss_FindClosePrinterNotify
6021 ****************************************************************/
6023 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6024 struct spoolss_FindClosePrinterNotify *r)
6026 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6029 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6030 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6034 if (Printer->notify.client_connected == true) {
6037 if ( Printer->printer_type == SPLHND_SERVER)
6039 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6040 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6043 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6046 Printer->notify.flags=0;
6047 Printer->notify.options=0;
6048 Printer->notify.localmachine[0]='\0';
6049 Printer->notify.printerlocal=0;
6050 TALLOC_FREE(Printer->notify.option);
6051 Printer->notify.client_connected = false;
6056 /****************************************************************
6058 ****************************************************************/
6060 WERROR _spoolss_AddJob(pipes_struct *p,
6061 struct spoolss_AddJob *r)
6063 if (!r->in.buffer && (r->in.offered != 0)) {
6064 return WERR_INVALID_PARAM;
6067 /* this is what a NT server returns for AddJob. AddJob must fail on
6068 * non-local printers */
6070 if (r->in.level != 1) {
6071 return WERR_UNKNOWN_LEVEL;
6074 return WERR_INVALID_PARAM;
6077 /****************************************************************************
6079 ****************************************************************************/
6081 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6082 struct spoolss_JobInfo1 *r,
6083 const print_queue_struct *queue,
6084 int position, int snum,
6085 const NT_PRINTER_INFO_LEVEL *ntprinter)
6089 t = gmtime(&queue->time);
6091 r->job_id = queue->job;
6093 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6094 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6095 r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6096 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6097 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6098 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6099 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6100 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6101 r->data_type = talloc_strdup(mem_ctx, "RAW");
6102 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6103 r->text_status = talloc_strdup(mem_ctx, "");
6104 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6106 r->status = nt_printj_status(queue->status);
6107 r->priority = queue->priority;
6108 r->position = position;
6109 r->total_pages = queue->page_count;
6110 r->pages_printed = 0; /* ??? */
6112 init_systemtime(&r->submitted, t);
6117 /****************************************************************************
6119 ****************************************************************************/
6121 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6122 struct spoolss_JobInfo2 *r,
6123 const print_queue_struct *queue,
6124 int position, int snum,
6125 const NT_PRINTER_INFO_LEVEL *ntprinter,
6126 struct spoolss_DeviceMode *devmode)
6130 t = gmtime(&queue->time);
6132 r->job_id = queue->job;
6134 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6135 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6136 r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6137 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6138 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6139 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6140 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6141 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6142 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6143 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6144 r->data_type = talloc_strdup(mem_ctx, "RAW");
6145 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6146 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6147 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6148 r->parameters = talloc_strdup(mem_ctx, "");
6149 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6150 r->driver_name = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
6151 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6153 r->devmode = devmode;
6155 r->text_status = talloc_strdup(mem_ctx, "");
6156 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6160 r->status = nt_printj_status(queue->status);
6161 r->priority = queue->priority;
6162 r->position = position;
6165 r->total_pages = queue->page_count;
6166 r->size = queue->size;
6167 init_systemtime(&r->submitted, t);
6169 r->pages_printed = 0; /* ??? */
6174 /****************************************************************************
6176 ****************************************************************************/
6178 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6179 struct spoolss_JobInfo3 *r,
6180 const print_queue_struct *queue,
6181 const print_queue_struct *next_queue,
6182 int position, int snum,
6183 const NT_PRINTER_INFO_LEVEL *ntprinter)
6185 r->job_id = queue->job;
6188 r->next_job_id = next_queue->job;
6195 /****************************************************************************
6196 Enumjobs at level 1.
6197 ****************************************************************************/
6199 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6200 const print_queue_struct *queue,
6201 uint32_t num_queues, int snum,
6202 const NT_PRINTER_INFO_LEVEL *ntprinter,
6203 union spoolss_JobInfo **info_p,
6206 union spoolss_JobInfo *info;
6208 WERROR result = WERR_OK;
6210 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6211 W_ERROR_HAVE_NO_MEMORY(info);
6213 *count = num_queues;
6215 for (i=0; i<*count; i++) {
6216 result = fill_job_info1(info,
6222 if (!W_ERROR_IS_OK(result)) {
6228 if (!W_ERROR_IS_OK(result)) {
6239 /****************************************************************************
6240 Enumjobs at level 2.
6241 ****************************************************************************/
6243 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6244 const print_queue_struct *queue,
6245 uint32_t num_queues, int snum,
6246 const NT_PRINTER_INFO_LEVEL *ntprinter,
6247 union spoolss_JobInfo **info_p,
6250 union spoolss_JobInfo *info;
6252 WERROR result = WERR_OK;
6254 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6255 W_ERROR_HAVE_NO_MEMORY(info);
6257 *count = num_queues;
6259 for (i=0; i<*count; i++) {
6261 struct spoolss_DeviceMode *devmode;
6263 devmode = construct_dev_mode(info, lp_const_servicename(snum));
6265 result = WERR_NOMEM;
6269 result = fill_job_info2(info,
6276 if (!W_ERROR_IS_OK(result)) {
6282 if (!W_ERROR_IS_OK(result)) {
6293 /****************************************************************************
6294 Enumjobs at level 3.
6295 ****************************************************************************/
6297 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6298 const print_queue_struct *queue,
6299 uint32_t num_queues, int snum,
6300 const NT_PRINTER_INFO_LEVEL *ntprinter,
6301 union spoolss_JobInfo **info_p,
6304 union spoolss_JobInfo *info;
6306 WERROR result = WERR_OK;
6308 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6309 W_ERROR_HAVE_NO_MEMORY(info);
6311 *count = num_queues;
6313 for (i=0; i<*count; i++) {
6314 const print_queue_struct *next_queue = NULL;
6317 next_queue = &queue[i+1];
6320 result = fill_job_info3(info,
6327 if (!W_ERROR_IS_OK(result)) {
6333 if (!W_ERROR_IS_OK(result)) {
6344 /****************************************************************
6346 ****************************************************************/
6348 WERROR _spoolss_EnumJobs(pipes_struct *p,
6349 struct spoolss_EnumJobs *r)
6352 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6354 print_status_struct prt_status;
6355 print_queue_struct *queue = NULL;
6358 /* that's an [in out] buffer */
6360 if (!r->in.buffer && (r->in.offered != 0)) {
6361 return WERR_INVALID_PARAM;
6364 DEBUG(4,("_spoolss_EnumJobs\n"));
6368 *r->out.info = NULL;
6370 /* lookup the printer snum and tdb entry */
6372 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6376 result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6377 if (!W_ERROR_IS_OK(result)) {
6381 count = print_queue_status(snum, &queue, &prt_status);
6382 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6383 count, prt_status.status, prt_status.message));
6387 free_a_printer(&ntprinter, 2);
6391 switch (r->in.level) {
6393 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6394 ntprinter, r->out.info, r->out.count);
6397 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6398 ntprinter, r->out.info, r->out.count);
6401 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6402 ntprinter, r->out.info, r->out.count);
6405 result = WERR_UNKNOWN_LEVEL;
6410 free_a_printer(&ntprinter, 2);
6412 if (!W_ERROR_IS_OK(result)) {
6416 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6418 *r->out.info, r->in.level,
6420 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6421 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6423 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6426 /****************************************************************
6427 _spoolss_ScheduleJob
6428 ****************************************************************/
6430 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6431 struct spoolss_ScheduleJob *r)
6436 /****************************************************************
6437 ****************************************************************/
6439 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6440 const char *printer_name,
6442 struct spoolss_SetJobInfo1 *r)
6446 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6450 if (strequal(old_doc_name, r->document_name)) {
6454 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6461 /****************************************************************
6463 ****************************************************************/
6465 WERROR _spoolss_SetJob(pipes_struct *p,
6466 struct spoolss_SetJob *r)
6469 WERROR errcode = WERR_BADFUNC;
6471 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6475 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6476 return WERR_INVALID_PRINTER_NAME;
6479 switch (r->in.command) {
6480 case SPOOLSS_JOB_CONTROL_CANCEL:
6481 case SPOOLSS_JOB_CONTROL_DELETE:
6482 if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6486 case SPOOLSS_JOB_CONTROL_PAUSE:
6487 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6491 case SPOOLSS_JOB_CONTROL_RESTART:
6492 case SPOOLSS_JOB_CONTROL_RESUME:
6493 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6501 return WERR_UNKNOWN_LEVEL;
6504 if (!W_ERROR_IS_OK(errcode)) {
6508 if (r->in.ctr == NULL) {
6512 switch (r->in.ctr->level) {
6514 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6516 r->in.ctr->info.info1);
6522 return WERR_UNKNOWN_LEVEL;
6528 /****************************************************************************
6529 Enumerates all printer drivers by level and architecture.
6530 ****************************************************************************/
6532 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6533 const char *servername,
6534 const char *architecture,
6536 union spoolss_DriverInfo **info_p,
6542 fstring *list = NULL;
6543 struct spoolss_DriverInfo8 *driver;
6544 union spoolss_DriverInfo *info = NULL;
6546 WERROR result = WERR_OK;
6551 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6553 ndrivers = get_ntdrivers(&list, architecture, version);
6554 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6555 ndrivers, architecture, version));
6557 if (ndrivers == -1) {
6558 result = WERR_NOMEM;
6562 if (ndrivers != 0) {
6563 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6564 union spoolss_DriverInfo,
6567 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6568 "failed to enlarge driver info buffer!\n"));
6569 result = WERR_NOMEM;
6574 for (i=0; i<ndrivers; i++) {
6575 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6576 ZERO_STRUCT(driver);
6577 result = get_a_printer_driver(mem_ctx, &driver, list[i],
6578 architecture, version);
6579 if (!W_ERROR_IS_OK(result)) {
6585 result = fill_printer_driver_info1(info, &info[count+i].info1,
6586 driver, servername);
6589 result = fill_printer_driver_info2(info, &info[count+i].info2,
6590 driver, servername);
6593 result = fill_printer_driver_info3(info, &info[count+i].info3,
6594 driver, servername);
6597 result = fill_printer_driver_info4(info, &info[count+i].info4,
6598 driver, servername);
6601 result = fill_printer_driver_info5(info, &info[count+i].info5,
6602 driver, servername);
6605 result = fill_printer_driver_info6(info, &info[count+i].info6,
6606 driver, servername);
6609 result = fill_printer_driver_info8(info, &info[count+i].info8,
6610 driver, servername);
6613 result = WERR_UNKNOWN_LEVEL;
6617 free_a_printer_driver(driver);
6619 if (!W_ERROR_IS_OK(result)) {
6631 if (!W_ERROR_IS_OK(result)) {
6642 /****************************************************************************
6643 Enumerates all printer drivers by level.
6644 ****************************************************************************/
6646 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6647 const char *servername,
6648 const char *architecture,
6650 union spoolss_DriverInfo **info_p,
6654 WERROR result = WERR_OK;
6656 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6658 for (a=0; archi_table[a].long_archi != NULL; a++) {
6660 union spoolss_DriverInfo *info = NULL;
6663 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6665 archi_table[a].long_archi,
6669 if (!W_ERROR_IS_OK(result)) {
6673 for (i=0; i < count; i++) {
6674 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6675 info[i], info_p, count_p);
6682 return enumprinterdrivers_level_by_architecture(mem_ctx,
6690 /****************************************************************
6691 _spoolss_EnumPrinterDrivers
6692 ****************************************************************/
6694 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6695 struct spoolss_EnumPrinterDrivers *r)
6697 const char *cservername;
6700 /* that's an [in out] buffer */
6702 if (!r->in.buffer && (r->in.offered != 0)) {
6703 return WERR_INVALID_PARAM;
6706 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6710 *r->out.info = NULL;
6712 cservername = canon_servername(r->in.server);
6714 if (!is_myname_or_ipaddr(cservername)) {
6715 return WERR_UNKNOWN_PRINTER_DRIVER;
6718 result = enumprinterdrivers_level(p->mem_ctx, cservername,
6723 if (!W_ERROR_IS_OK(result)) {
6727 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6728 spoolss_EnumPrinterDrivers,
6729 *r->out.info, r->in.level,
6731 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6732 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6734 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6737 /****************************************************************************
6738 ****************************************************************************/
6740 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
6741 struct spoolss_FormInfo1 *r,
6742 const nt_forms_struct *form)
6744 r->form_name = talloc_strdup(mem_ctx, form->name);
6745 W_ERROR_HAVE_NO_MEMORY(r->form_name);
6747 r->flags = form->flag;
6748 r->size.width = form->width;
6749 r->size.height = form->length;
6750 r->area.left = form->left;
6751 r->area.top = form->top;
6752 r->area.right = form->right;
6753 r->area.bottom = form->bottom;
6758 /****************************************************************
6759 spoolss_enumforms_level1
6760 ****************************************************************/
6762 static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
6763 const nt_forms_struct *builtin_forms,
6764 uint32_t num_builtin_forms,
6765 const nt_forms_struct *user_forms,
6766 uint32_t num_user_forms,
6767 union spoolss_FormInfo **info_p,
6770 union spoolss_FormInfo *info;
6771 WERROR result = WERR_OK;
6774 *count = num_builtin_forms + num_user_forms;
6776 info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
6777 W_ERROR_HAVE_NO_MEMORY(info);
6779 /* construct the list of form structures */
6780 for (i=0; i<num_builtin_forms; i++) {
6781 DEBUGADD(6,("Filling builtin form number [%d]\n",i));
6782 result = fill_form_info_1(info, &info[i].info1,
6784 if (!W_ERROR_IS_OK(result)) {
6789 for (i=0; i<num_user_forms; i++) {
6790 DEBUGADD(6,("Filling user form number [%d]\n",i));
6791 result = fill_form_info_1(info, &info[i+num_builtin_forms].info1,
6793 if (!W_ERROR_IS_OK(result)) {
6799 if (!W_ERROR_IS_OK(result)) {
6810 /****************************************************************
6812 ****************************************************************/
6814 WERROR _spoolss_EnumForms(pipes_struct *p,
6815 struct spoolss_EnumForms *r)
6818 nt_forms_struct *user_forms = NULL;
6819 nt_forms_struct *builtin_forms = NULL;
6820 uint32_t num_user_forms;
6821 uint32_t num_builtin_forms;
6825 *r->out.info = NULL;
6827 /* that's an [in out] buffer */
6829 if (!r->in.buffer && (r->in.offered != 0) ) {
6830 return WERR_INVALID_PARAM;
6833 DEBUG(4,("_spoolss_EnumForms\n"));
6834 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6835 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6837 num_builtin_forms = get_builtin_ntforms(&builtin_forms);
6838 DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
6839 num_user_forms = get_ntforms(&user_forms);
6840 DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
6842 if (num_user_forms + num_builtin_forms == 0) {
6843 SAFE_FREE(builtin_forms);
6844 SAFE_FREE(user_forms);
6845 return WERR_NO_MORE_ITEMS;
6848 switch (r->in.level) {
6850 result = spoolss_enumforms_level1(p->mem_ctx,
6859 result = WERR_UNKNOWN_LEVEL;
6863 SAFE_FREE(user_forms);
6864 SAFE_FREE(builtin_forms);
6866 if (!W_ERROR_IS_OK(result)) {
6870 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6872 *r->out.info, r->in.level,
6874 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6875 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6877 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6880 /****************************************************************
6881 ****************************************************************/
6883 static WERROR find_form_byname(const char *name,
6884 nt_forms_struct *form)
6886 nt_forms_struct *list = NULL;
6887 int num_forms = 0, i = 0;
6889 if (get_a_builtin_ntform_by_string(name, form)) {
6893 num_forms = get_ntforms(&list);
6894 DEBUGADD(5,("Number of forms [%d]\n", num_forms));
6896 if (num_forms == 0) {
6900 /* Check if the requested name is in the list of form structures */
6901 for (i = 0; i < num_forms; i++) {
6903 DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
6905 if (strequal(name, list[i].name)) {
6906 DEBUGADD(6,("Found form %s number [%d]\n", name, i));
6918 /****************************************************************
6920 ****************************************************************/
6922 WERROR _spoolss_GetForm(pipes_struct *p,
6923 struct spoolss_GetForm *r)
6926 nt_forms_struct form;
6928 /* that's an [in out] buffer */
6930 if (!r->in.buffer && (r->in.offered != 0)) {
6931 return WERR_INVALID_PARAM;
6934 DEBUG(4,("_spoolss_GetForm\n"));
6935 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6936 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6938 result = find_form_byname(r->in.form_name, &form);
6939 if (!W_ERROR_IS_OK(result)) {
6940 TALLOC_FREE(r->out.info);
6944 switch (r->in.level) {
6946 result = fill_form_info_1(p->mem_ctx,
6947 &r->out.info->info1,
6952 result = WERR_UNKNOWN_LEVEL;
6956 if (!W_ERROR_IS_OK(result)) {
6957 TALLOC_FREE(r->out.info);
6961 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6962 r->out.info, r->in.level);
6963 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6965 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6968 /****************************************************************************
6969 ****************************************************************************/
6971 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6972 struct spoolss_PortInfo1 *r,
6975 r->port_name = talloc_strdup(mem_ctx, name);
6976 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6981 /****************************************************************************
6982 TODO: This probably needs distinguish between TCP/IP and Local ports
6984 ****************************************************************************/
6986 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6987 struct spoolss_PortInfo2 *r,
6990 r->port_name = talloc_strdup(mem_ctx, name);
6991 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6993 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6994 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6996 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6997 W_ERROR_HAVE_NO_MEMORY(r->description);
6999 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7006 /****************************************************************************
7007 wrapper around the enumer ports command
7008 ****************************************************************************/
7010 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7012 char *cmd = lp_enumports_cmd();
7013 char **qlines = NULL;
7014 char *command = NULL;
7022 /* if no hook then just fill in the default port */
7025 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7028 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7029 TALLOC_FREE(qlines);
7036 /* we have a valid enumport command */
7038 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7043 DEBUG(10,("Running [%s]\n", command));
7044 ret = smbrun(command, &fd);
7045 DEBUG(10,("Returned [%d]\n", ret));
7046 TALLOC_FREE(command);
7051 return WERR_ACCESS_DENIED;
7055 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7056 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7066 /****************************************************************************
7068 ****************************************************************************/
7070 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7071 union spoolss_PortInfo **info_p,
7074 union spoolss_PortInfo *info = NULL;
7076 WERROR result = WERR_OK;
7077 char **qlines = NULL;
7080 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7081 if (!W_ERROR_IS_OK(result)) {
7086 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7088 DEBUG(10,("Returning WERR_NOMEM\n"));
7089 result = WERR_NOMEM;
7093 for (i=0; i<numlines; i++) {
7094 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7095 result = fill_port_1(info, &info[i].info1, qlines[i]);
7096 if (!W_ERROR_IS_OK(result)) {
7101 TALLOC_FREE(qlines);
7104 if (!W_ERROR_IS_OK(result)) {
7106 TALLOC_FREE(qlines);
7118 /****************************************************************************
7120 ****************************************************************************/
7122 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7123 union spoolss_PortInfo **info_p,
7126 union spoolss_PortInfo *info = NULL;
7128 WERROR result = WERR_OK;
7129 char **qlines = NULL;
7132 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7133 if (!W_ERROR_IS_OK(result)) {
7138 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7140 DEBUG(10,("Returning WERR_NOMEM\n"));
7141 result = WERR_NOMEM;
7145 for (i=0; i<numlines; i++) {
7146 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7147 result = fill_port_2(info, &info[i].info2, qlines[i]);
7148 if (!W_ERROR_IS_OK(result)) {
7153 TALLOC_FREE(qlines);
7156 if (!W_ERROR_IS_OK(result)) {
7158 TALLOC_FREE(qlines);
7170 /****************************************************************
7172 ****************************************************************/
7174 WERROR _spoolss_EnumPorts(pipes_struct *p,
7175 struct spoolss_EnumPorts *r)
7179 /* that's an [in out] buffer */
7181 if (!r->in.buffer && (r->in.offered != 0)) {
7182 return WERR_INVALID_PARAM;
7185 DEBUG(4,("_spoolss_EnumPorts\n"));
7189 *r->out.info = NULL;
7191 switch (r->in.level) {
7193 result = enumports_level_1(p->mem_ctx, r->out.info,
7197 result = enumports_level_2(p->mem_ctx, r->out.info,
7201 return WERR_UNKNOWN_LEVEL;
7204 if (!W_ERROR_IS_OK(result)) {
7208 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7210 *r->out.info, r->in.level,
7212 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7213 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7215 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7218 /****************************************************************************
7219 ****************************************************************************/
7221 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7223 struct spoolss_SetPrinterInfoCtr *info_ctr,
7224 struct spoolss_DeviceMode *devmode,
7225 struct security_descriptor *sec_desc,
7226 struct spoolss_UserLevelCtr *user_ctr,
7227 struct policy_handle *handle)
7229 NT_PRINTER_INFO_LEVEL *printer = NULL;
7232 WERROR err = WERR_OK;
7234 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7235 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7239 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7240 if (!convert_printer_info(info_ctr, printer)) {
7241 free_a_printer(&printer, 2);
7245 /* samba does not have a concept of local, non-shared printers yet, so
7246 * make sure we always setup sharename - gd */
7247 if ((printer->info_2->sharename[0] == '\0') && (printer->info_2->printername != '\0')) {
7248 DEBUG(5, ("spoolss_addprinterex_level_2: "
7249 "no sharename has been set, setting printername %s as sharename\n",
7250 printer->info_2->printername));
7251 fstrcpy(printer->info_2->sharename, printer->info_2->printername);
7254 /* check to see if the printer already exists */
7256 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7257 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7258 printer->info_2->sharename));
7259 free_a_printer(&printer, 2);
7260 return WERR_PRINTER_ALREADY_EXISTS;
7263 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7264 if ((snum = print_queue_snum(printer->info_2->printername)) != -1) {
7265 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7266 printer->info_2->printername));
7267 free_a_printer(&printer, 2);
7268 return WERR_PRINTER_ALREADY_EXISTS;
7272 /* validate printer info struct */
7273 if (!info_ctr->info.info2->printername ||
7274 strlen(info_ctr->info.info2->printername) == 0) {
7275 free_a_printer(&printer,2);
7276 return WERR_INVALID_PRINTER_NAME;
7278 if (!info_ctr->info.info2->portname ||
7279 strlen(info_ctr->info.info2->portname) == 0) {
7280 free_a_printer(&printer,2);
7281 return WERR_UNKNOWN_PORT;
7283 if (!info_ctr->info.info2->drivername ||
7284 strlen(info_ctr->info.info2->drivername) == 0) {
7285 free_a_printer(&printer,2);
7286 return WERR_UNKNOWN_PRINTER_DRIVER;
7288 if (!info_ctr->info.info2->printprocessor ||
7289 strlen(info_ctr->info.info2->printprocessor) == 0) {
7290 free_a_printer(&printer,2);
7291 return WERR_UNKNOWN_PRINTPROCESSOR;
7294 /* FIXME!!! smbd should check to see if the driver is installed before
7295 trying to add a printer like this --jerry */
7297 if (*lp_addprinter_cmd() ) {
7298 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7300 free_a_printer(&printer,2);
7301 return WERR_ACCESS_DENIED;
7304 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7305 "smb.conf parameter \"addprinter command\" is defined. This"
7306 "parameter must exist for this call to succeed\n",
7307 printer->info_2->sharename ));
7310 /* use our primary netbios name since get_a_printer() will convert
7311 it to what the client expects on a case by case basis */
7313 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7314 printer->info_2->sharename);
7317 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7318 free_a_printer(&printer,2);
7319 return WERR_ACCESS_DENIED;
7322 /* you must be a printer admin to add a new printer */
7323 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7324 free_a_printer(&printer,2);
7325 return WERR_ACCESS_DENIED;
7329 * Do sanity check on the requested changes for Samba.
7332 if (!check_printer_ok(printer->info_2, snum)) {
7333 free_a_printer(&printer,2);
7334 return WERR_INVALID_PARAM;
7338 * When a printer is created, the drivername bound to the printer is used
7339 * to lookup previously saved driver initialization info, which is then
7340 * bound to the new printer, simulating what happens in the Windows arch.
7345 set_driver_init(printer, 2);
7349 /* A valid devmode was included, convert and link it
7351 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7353 if (!convert_devicemode(printer->info_2->printername, devmode,
7354 &printer->info_2->devmode)) {
7359 /* write the ASCII on disk */
7360 err = mod_a_printer(printer, 2);
7361 if (!W_ERROR_IS_OK(err)) {
7362 free_a_printer(&printer,2);
7366 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7367 /* Handle open failed - remove addition. */
7368 del_a_printer(printer->info_2->sharename);
7369 free_a_printer(&printer,2);
7370 ZERO_STRUCTP(handle);
7371 return WERR_ACCESS_DENIED;
7374 update_c_setprinter(false);
7375 free_a_printer(&printer,2);
7380 /****************************************************************
7381 _spoolss_AddPrinterEx
7382 ****************************************************************/
7384 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7385 struct spoolss_AddPrinterEx *r)
7387 switch (r->in.info_ctr->level) {
7389 /* we don't handle yet */
7390 /* but I know what to do ... */
7391 return WERR_UNKNOWN_LEVEL;
7393 return spoolss_addprinterex_level_2(p, r->in.server,
7395 r->in.devmode_ctr->devmode,
7396 r->in.secdesc_ctr->sd,
7397 r->in.userlevel_ctr,
7400 return WERR_UNKNOWN_LEVEL;
7404 /****************************************************************
7406 ****************************************************************/
7408 WERROR _spoolss_AddPrinter(pipes_struct *p,
7409 struct spoolss_AddPrinter *r)
7411 struct spoolss_AddPrinterEx a;
7412 struct spoolss_UserLevelCtr userlevel_ctr;
7414 ZERO_STRUCT(userlevel_ctr);
7416 userlevel_ctr.level = 1;
7418 a.in.server = r->in.server;
7419 a.in.info_ctr = r->in.info_ctr;
7420 a.in.devmode_ctr = r->in.devmode_ctr;
7421 a.in.secdesc_ctr = r->in.secdesc_ctr;
7422 a.in.userlevel_ctr = &userlevel_ctr;
7423 a.out.handle = r->out.handle;
7425 return _spoolss_AddPrinterEx(p, &a);
7428 /****************************************************************
7429 _spoolss_AddPrinterDriverEx
7430 ****************************************************************/
7432 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7433 struct spoolss_AddPrinterDriverEx *r)
7435 WERROR err = WERR_OK;
7436 char *driver_name = NULL;
7440 switch (p->hdr_req.opnum) {
7441 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7442 fn = "_spoolss_AddPrinterDriver";
7444 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7445 fn = "_spoolss_AddPrinterDriverEx";
7448 return WERR_INVALID_PARAM;
7452 * we only support the semantics of AddPrinterDriver()
7453 * i.e. only copy files that are newer than existing ones
7456 if (r->in.flags == 0) {
7457 return WERR_INVALID_PARAM;
7460 if (r->in.flags != APD_COPY_NEW_FILES) {
7461 return WERR_ACCESS_DENIED;
7465 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7466 /* Clever hack from Martin Zielinski <mz@seh.de>
7467 * to allow downgrade from level 8 (Vista).
7469 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7470 r->in.info_ctr->level));
7471 return WERR_UNKNOWN_LEVEL;
7474 DEBUG(5,("Cleaning driver's information\n"));
7475 err = clean_up_driver_struct(p, r->in.info_ctr);
7476 if (!W_ERROR_IS_OK(err))
7479 DEBUG(5,("Moving driver to final destination\n"));
7480 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7485 if (add_a_printer_driver(p->mem_ctx, r->in.info_ctr, &driver_name, &version)!=0) {
7486 err = WERR_ACCESS_DENIED;
7491 * I think this is where he DrvUpgradePrinter() hook would be
7492 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7493 * server. Right now, we just need to send ourselves a message
7494 * to update each printer bound to this driver. --jerry
7497 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7498 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7503 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7504 * decide if the driver init data should be deleted. The rules are:
7505 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7506 * 2) delete init data only if there is no 2k/Xp driver
7507 * 3) always delete init data
7508 * The generalized rule is always use init data from the highest order driver.
7509 * It is necessary to follow the driver install by an initialization step to
7510 * finish off this process.
7515 * 9x printer driver - never delete init data
7518 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7523 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7524 * there is no 2k/Xp driver init data for this driver name.
7528 struct spoolss_DriverInfo8 *driver1;
7530 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &driver1, driver_name, "Windows NT x86", 3))) {
7532 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7534 if (!del_driver_init(driver_name))
7535 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7539 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7541 free_a_printer_driver(driver1);
7542 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7549 * 2k or Xp printer driver - always delete init data
7552 if (!del_driver_init(driver_name))
7553 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7558 DEBUG(0,("%s: invalid level=%d\n", fn,
7559 r->in.info_ctr->level));
7568 /****************************************************************
7569 _spoolss_AddPrinterDriver
7570 ****************************************************************/
7572 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7573 struct spoolss_AddPrinterDriver *r)
7575 struct spoolss_AddPrinterDriverEx a;
7577 switch (r->in.info_ctr->level) {
7584 return WERR_UNKNOWN_LEVEL;
7587 a.in.servername = r->in.servername;
7588 a.in.info_ctr = r->in.info_ctr;
7589 a.in.flags = APD_COPY_NEW_FILES;
7591 return _spoolss_AddPrinterDriverEx(p, &a);
7594 /****************************************************************************
7595 ****************************************************************************/
7597 struct _spoolss_paths {
7603 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7605 static const struct _spoolss_paths spoolss_paths[]= {
7606 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7607 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7610 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7611 const char *servername,
7612 const char *environment,
7616 const char *pservername = NULL;
7617 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7618 const char *short_archi;
7622 /* environment may be empty */
7623 if (environment && strlen(environment)) {
7624 long_archi = environment;
7627 /* servername may be empty */
7628 if (servername && strlen(servername)) {
7629 pservername = canon_servername(servername);
7631 if (!is_myname_or_ipaddr(pservername)) {
7632 return WERR_INVALID_PARAM;
7636 if (!(short_archi = get_short_archi(long_archi))) {
7637 return WERR_INVALID_ENVIRONMENT;
7640 switch (component) {
7641 case SPOOLSS_PRTPROCS_PATH:
7642 case SPOOLSS_DRIVER_PATH:
7644 *path = talloc_asprintf(mem_ctx,
7647 spoolss_paths[component].share,
7650 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7651 SPOOLSS_DEFAULT_SERVER_PATH,
7652 spoolss_paths[component].dir,
7657 return WERR_INVALID_PARAM;
7667 /****************************************************************************
7668 ****************************************************************************/
7670 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7671 const char *servername,
7672 const char *environment,
7673 struct spoolss_DriverDirectoryInfo1 *r)
7678 werr = compose_spoolss_server_path(mem_ctx,
7681 SPOOLSS_DRIVER_PATH,
7683 if (!W_ERROR_IS_OK(werr)) {
7687 DEBUG(4,("printer driver directory: [%s]\n", path));
7689 r->directory_name = path;
7694 /****************************************************************
7695 _spoolss_GetPrinterDriverDirectory
7696 ****************************************************************/
7698 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7699 struct spoolss_GetPrinterDriverDirectory *r)
7703 /* that's an [in out] buffer */
7705 if (!r->in.buffer && (r->in.offered != 0)) {
7706 return WERR_INVALID_PARAM;
7709 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7714 /* r->in.level is ignored */
7716 werror = getprinterdriverdir_level_1(p->mem_ctx,
7719 &r->out.info->info1);
7720 if (!W_ERROR_IS_OK(werror)) {
7721 TALLOC_FREE(r->out.info);
7725 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7726 r->out.info, r->in.level);
7727 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7729 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7732 /****************************************************************
7733 _spoolss_EnumPrinterData
7734 ****************************************************************/
7736 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7737 struct spoolss_EnumPrinterData *r)
7740 struct spoolss_EnumPrinterDataEx r2;
7742 struct spoolss_PrinterEnumValues *info, *val = NULL;
7745 r2.in.handle = r->in.handle;
7746 r2.in.key_name = "PrinterDriverData";
7748 r2.out.count = &count;
7749 r2.out.info = &info;
7750 r2.out.needed = &needed;
7752 result = _spoolss_EnumPrinterDataEx(p, &r2);
7753 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7754 r2.in.offered = needed;
7755 result = _spoolss_EnumPrinterDataEx(p, &r2);
7757 if (!W_ERROR_IS_OK(result)) {
7762 * The NT machine wants to know the biggest size of value and data
7764 * cf: MSDN EnumPrinterData remark section
7767 if (!r->in.value_offered && !r->in.data_offered) {
7768 uint32_t biggest_valuesize = 0;
7769 uint32_t biggest_datasize = 0;
7772 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7774 for (i=0; i<count; i++) {
7776 name_length = strlen(info[i].value_name);
7777 if (strlen(info[i].value_name) > biggest_valuesize) {
7778 biggest_valuesize = name_length;
7781 if (info[i].data_length > biggest_datasize) {
7782 biggest_datasize = info[i].data_length;
7785 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7789 /* the value is an UNICODE string but real_value_size is the length
7790 in bytes including the trailing 0 */
7792 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7793 *r->out.data_needed = biggest_datasize;
7795 DEBUG(6,("final values: [%d], [%d]\n",
7796 *r->out.value_needed, *r->out.data_needed));
7801 if (r->in.enum_index < count) {
7802 val = &info[r->in.enum_index];
7806 /* out_value should default to "" or else NT4 has
7807 problems unmarshalling the response */
7809 if (r->in.value_offered) {
7810 *r->out.value_needed = 1;
7811 r->out.value_name = talloc_strdup(r, "");
7812 if (!r->out.value_name) {
7816 r->out.value_name = NULL;
7817 *r->out.value_needed = 0;
7820 /* the data is counted in bytes */
7822 *r->out.data_needed = r->in.data_offered;
7824 result = WERR_NO_MORE_ITEMS;
7828 * - counted in bytes in the request
7829 * - counted in UNICODE chars in the max reply
7830 * - counted in bytes in the real size
7832 * take a pause *before* coding not *during* coding
7836 if (r->in.value_offered) {
7837 r->out.value_name = talloc_strdup(r, val->value_name);
7838 if (!r->out.value_name) {
7841 *r->out.value_needed = val->value_name_len;
7843 r->out.value_name = NULL;
7844 *r->out.value_needed = 0;
7849 *r->out.type = val->type;
7851 /* data - counted in bytes */
7854 * See the section "Dynamically Typed Query Parameters"
7858 if (r->out.data && val->data && val->data->data &&
7859 val->data_length && r->in.data_offered) {
7860 memcpy(r->out.data, val->data->data,
7861 MIN(val->data_length,r->in.data_offered));
7864 *r->out.data_needed = val->data_length;
7872 /****************************************************************
7873 _spoolss_SetPrinterData
7874 ****************************************************************/
7876 WERROR _spoolss_SetPrinterData(pipes_struct *p,
7877 struct spoolss_SetPrinterData *r)
7879 struct spoolss_SetPrinterDataEx r2;
7881 r2.in.handle = r->in.handle;
7882 r2.in.key_name = "PrinterDriverData";
7883 r2.in.value_name = r->in.value_name;
7884 r2.in.type = r->in.type;
7885 r2.in.data = r->in.data;
7886 r2.in.offered = r->in.offered;
7888 return _spoolss_SetPrinterDataEx(p, &r2);
7891 /****************************************************************
7892 _spoolss_ResetPrinter
7893 ****************************************************************/
7895 WERROR _spoolss_ResetPrinter(pipes_struct *p,
7896 struct spoolss_ResetPrinter *r)
7898 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7901 DEBUG(5,("_spoolss_ResetPrinter\n"));
7904 * All we do is to check to see if the handle and queue is valid.
7905 * This call really doesn't mean anything to us because we only
7906 * support RAW printing. --jerry
7910 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7911 OUR_HANDLE(r->in.handle)));
7915 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7919 /* blindly return success */
7923 /****************************************************************
7924 _spoolss_DeletePrinterData
7925 ****************************************************************/
7927 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7928 struct spoolss_DeletePrinterData *r)
7930 struct spoolss_DeletePrinterDataEx r2;
7932 r2.in.handle = r->in.handle;
7933 r2.in.key_name = "PrinterDriverData";
7934 r2.in.value_name = r->in.value_name;
7936 return _spoolss_DeletePrinterDataEx(p, &r2);
7939 /****************************************************************
7941 ****************************************************************/
7943 WERROR _spoolss_AddForm(pipes_struct *p,
7944 struct spoolss_AddForm *r)
7946 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7947 nt_forms_struct tmpForm;
7949 WERROR status = WERR_OK;
7950 NT_PRINTER_INFO_LEVEL *printer = NULL;
7951 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7954 nt_forms_struct *list=NULL;
7955 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7958 DEBUG(5,("_spoolss_AddForm\n"));
7961 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7962 OUR_HANDLE(r->in.handle)));
7967 /* forms can be added on printer or on the print server handle */
7969 if ( Printer->printer_type == SPLHND_PRINTER )
7971 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7974 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7975 if (!W_ERROR_IS_OK(status))
7979 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7980 and not a printer admin, then fail */
7982 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7983 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7984 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7986 p->server_info->ptok,
7987 lp_printer_admin(snum))) {
7988 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7989 status = WERR_ACCESS_DENIED;
7993 switch (form->flags) {
7994 case SPOOLSS_FORM_USER:
7995 case SPOOLSS_FORM_BUILTIN:
7996 case SPOOLSS_FORM_PRINTER:
7999 status = WERR_INVALID_PARAM;
8003 /* can't add if builtin */
8005 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8006 status = WERR_FILE_EXISTS;
8010 count = get_ntforms(&list);
8012 for (i=0; i < count; i++) {
8013 if (strequal(form->form_name, list[i].name)) {
8014 status = WERR_FILE_EXISTS;
8019 if(!add_a_form(&list, form, &count)) {
8020 status = WERR_NOMEM;
8025 write_ntforms(&list, count);
8029 * ChangeID must always be set if this is a printer
8032 if ( Printer->printer_type == SPLHND_PRINTER )
8033 status = mod_a_printer(printer, 2);
8037 free_a_printer(&printer, 2);
8043 /****************************************************************
8045 ****************************************************************/
8047 WERROR _spoolss_DeleteForm(pipes_struct *p,
8048 struct spoolss_DeleteForm *r)
8050 const char *form_name = r->in.form_name;
8051 nt_forms_struct tmpForm;
8053 nt_forms_struct *list=NULL;
8054 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8056 WERROR status = WERR_OK;
8057 NT_PRINTER_INFO_LEVEL *printer = NULL;
8058 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8061 DEBUG(5,("_spoolss_DeleteForm\n"));
8064 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8065 OUR_HANDLE(r->in.handle)));
8069 /* forms can be deleted on printer of on the print server handle */
8071 if ( Printer->printer_type == SPLHND_PRINTER )
8073 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8076 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8077 if (!W_ERROR_IS_OK(status))
8081 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8082 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8083 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8085 p->server_info->ptok,
8086 lp_printer_admin(snum))) {
8087 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8088 return WERR_ACCESS_DENIED;
8092 /* can't delete if builtin */
8094 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8095 status = WERR_INVALID_PARAM;
8099 count = get_ntforms(&list);
8102 ret = delete_a_form(&list, form_name, &count, &status);
8109 * ChangeID must always be set if this is a printer
8112 if ( Printer->printer_type == SPLHND_PRINTER )
8113 status = mod_a_printer(printer, 2);
8117 free_a_printer(&printer, 2);
8123 /****************************************************************
8125 ****************************************************************/
8127 WERROR _spoolss_SetForm(pipes_struct *p,
8128 struct spoolss_SetForm *r)
8130 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8131 nt_forms_struct tmpForm;
8133 WERROR status = WERR_OK;
8134 NT_PRINTER_INFO_LEVEL *printer = NULL;
8135 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8138 nt_forms_struct *list=NULL;
8139 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8141 DEBUG(5,("_spoolss_SetForm\n"));
8144 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8145 OUR_HANDLE(r->in.handle)));
8149 /* forms can be modified on printer of on the print server handle */
8151 if ( Printer->printer_type == SPLHND_PRINTER )
8153 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8156 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8157 if (!W_ERROR_IS_OK(status))
8161 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8162 and not a printer admin, then fail */
8164 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8165 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8166 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8168 p->server_info->ptok,
8169 lp_printer_admin(snum))) {
8170 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8171 status = WERR_ACCESS_DENIED;
8175 /* can't set if builtin */
8176 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8177 status = WERR_INVALID_PARAM;
8181 count = get_ntforms(&list);
8182 update_a_form(&list, form, count);
8184 write_ntforms(&list, count);
8188 * ChangeID must always be set if this is a printer
8191 if ( Printer->printer_type == SPLHND_PRINTER )
8192 status = mod_a_printer(printer, 2);
8197 free_a_printer(&printer, 2);
8203 /****************************************************************************
8204 fill_print_processor1
8205 ****************************************************************************/
8207 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8208 struct spoolss_PrintProcessorInfo1 *r,
8209 const char *print_processor_name)
8211 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8212 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8217 /****************************************************************************
8218 enumprintprocessors level 1.
8219 ****************************************************************************/
8221 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8222 union spoolss_PrintProcessorInfo **info_p,
8225 union spoolss_PrintProcessorInfo *info;
8228 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8229 W_ERROR_HAVE_NO_MEMORY(info);
8233 result = fill_print_processor1(info, &info[0].info1, "winprint");
8234 if (!W_ERROR_IS_OK(result)) {
8239 if (!W_ERROR_IS_OK(result)) {
8250 /****************************************************************
8251 _spoolss_EnumPrintProcessors
8252 ****************************************************************/
8254 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8255 struct spoolss_EnumPrintProcessors *r)
8259 /* that's an [in out] buffer */
8261 if (!r->in.buffer && (r->in.offered != 0)) {
8262 return WERR_INVALID_PARAM;
8265 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8268 * Enumerate the print processors ...
8270 * Just reply with "winprint", to keep NT happy
8271 * and I can use my nice printer checker.
8276 *r->out.info = NULL;
8278 switch (r->in.level) {
8280 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8284 return WERR_UNKNOWN_LEVEL;
8287 if (!W_ERROR_IS_OK(result)) {
8291 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8292 spoolss_EnumPrintProcessors,
8293 *r->out.info, r->in.level,
8295 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8296 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8298 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8301 /****************************************************************************
8302 fill_printprocdatatype1
8303 ****************************************************************************/
8305 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8306 struct spoolss_PrintProcDataTypesInfo1 *r,
8307 const char *name_array)
8309 r->name_array = talloc_strdup(mem_ctx, name_array);
8310 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8315 /****************************************************************************
8316 enumprintprocdatatypes level 1.
8317 ****************************************************************************/
8319 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8320 union spoolss_PrintProcDataTypesInfo **info_p,
8324 union spoolss_PrintProcDataTypesInfo *info;
8326 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8327 W_ERROR_HAVE_NO_MEMORY(info);
8331 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8332 if (!W_ERROR_IS_OK(result)) {
8337 if (!W_ERROR_IS_OK(result)) {
8348 /****************************************************************
8349 _spoolss_EnumPrintProcDataTypes
8350 ****************************************************************/
8352 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8353 struct spoolss_EnumPrintProcDataTypes *r)
8357 /* that's an [in out] buffer */
8359 if (!r->in.buffer && (r->in.offered != 0)) {
8360 return WERR_INVALID_PARAM;
8363 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8367 *r->out.info = NULL;
8369 switch (r->in.level) {
8371 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8375 return WERR_UNKNOWN_LEVEL;
8378 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8379 spoolss_EnumPrintProcDataTypes,
8380 *r->out.info, r->in.level,
8382 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8383 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8385 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8388 /****************************************************************************
8390 ****************************************************************************/
8392 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8393 struct spoolss_MonitorInfo1 *r,
8394 const char *monitor_name)
8396 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8397 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8402 /****************************************************************************
8404 ****************************************************************************/
8406 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8407 struct spoolss_MonitorInfo2 *r,
8408 const char *monitor_name,
8409 const char *environment,
8410 const char *dll_name)
8412 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8413 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8414 r->environment = talloc_strdup(mem_ctx, environment);
8415 W_ERROR_HAVE_NO_MEMORY(r->environment);
8416 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8417 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8422 /****************************************************************************
8423 enumprintmonitors level 1.
8424 ****************************************************************************/
8426 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8427 union spoolss_MonitorInfo **info_p,
8430 union spoolss_MonitorInfo *info;
8431 WERROR result = WERR_OK;
8433 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8434 W_ERROR_HAVE_NO_MEMORY(info);
8438 result = fill_monitor_1(info, &info[0].info1,
8440 if (!W_ERROR_IS_OK(result)) {
8444 result = fill_monitor_1(info, &info[1].info1,
8446 if (!W_ERROR_IS_OK(result)) {
8451 if (!W_ERROR_IS_OK(result)) {
8462 /****************************************************************************
8463 enumprintmonitors level 2.
8464 ****************************************************************************/
8466 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8467 union spoolss_MonitorInfo **info_p,
8470 union spoolss_MonitorInfo *info;
8471 WERROR result = WERR_OK;
8473 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8474 W_ERROR_HAVE_NO_MEMORY(info);
8478 result = fill_monitor_2(info, &info[0].info2,
8480 "Windows NT X86", /* FIXME */
8482 if (!W_ERROR_IS_OK(result)) {
8486 result = fill_monitor_2(info, &info[1].info2,
8488 "Windows NT X86", /* FIXME */
8490 if (!W_ERROR_IS_OK(result)) {
8495 if (!W_ERROR_IS_OK(result)) {
8506 /****************************************************************
8507 _spoolss_EnumMonitors
8508 ****************************************************************/
8510 WERROR _spoolss_EnumMonitors(pipes_struct *p,
8511 struct spoolss_EnumMonitors *r)
8515 /* that's an [in out] buffer */
8517 if (!r->in.buffer && (r->in.offered != 0)) {
8518 return WERR_INVALID_PARAM;
8521 DEBUG(5,("_spoolss_EnumMonitors\n"));
8524 * Enumerate the print monitors ...
8526 * Just reply with "Local Port", to keep NT happy
8527 * and I can use my nice printer checker.
8532 *r->out.info = NULL;
8534 switch (r->in.level) {
8536 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8540 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8544 return WERR_UNKNOWN_LEVEL;
8547 if (!W_ERROR_IS_OK(result)) {
8551 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8552 spoolss_EnumMonitors,
8553 *r->out.info, r->in.level,
8555 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8556 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8558 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8561 /****************************************************************************
8562 ****************************************************************************/
8564 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8565 const print_queue_struct *queue,
8566 int count, int snum,
8567 const NT_PRINTER_INFO_LEVEL *ntprinter,
8569 struct spoolss_JobInfo1 *r)
8574 for (i=0; i<count; i++) {
8575 if (queue[i].job == (int)jobid) {
8581 if (found == false) {
8582 /* NT treats not found as bad param... yet another bad choice */
8583 return WERR_INVALID_PARAM;
8586 return fill_job_info1(mem_ctx,
8594 /****************************************************************************
8595 ****************************************************************************/
8597 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8598 const print_queue_struct *queue,
8599 int count, int snum,
8600 const NT_PRINTER_INFO_LEVEL *ntprinter,
8602 struct spoolss_JobInfo2 *r)
8606 struct spoolss_DeviceMode *devmode;
8607 NT_DEVICEMODE *nt_devmode;
8610 for (i=0; i<count; i++) {
8611 if (queue[i].job == (int)jobid) {
8617 if (found == false) {
8618 /* NT treats not found as bad param... yet another bad
8620 return WERR_INVALID_PARAM;
8624 * if the print job does not have a DEVMODE associated with it,
8625 * just use the one for the printer. A NULL devicemode is not
8626 * a failure condition
8629 nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8631 devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
8632 W_ERROR_HAVE_NO_MEMORY(devmode);
8633 result = convert_nt_devicemode(devmode, devmode, nt_devmode);
8634 if (!W_ERROR_IS_OK(result)) {
8638 devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
8639 W_ERROR_HAVE_NO_MEMORY(devmode);
8642 return fill_job_info2(mem_ctx,
8651 /****************************************************************
8653 ****************************************************************/
8655 WERROR _spoolss_GetJob(pipes_struct *p,
8656 struct spoolss_GetJob *r)
8658 WERROR result = WERR_OK;
8659 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
8662 print_queue_struct *queue = NULL;
8663 print_status_struct prt_status;
8665 /* that's an [in out] buffer */
8667 if (!r->in.buffer && (r->in.offered != 0)) {
8668 return WERR_INVALID_PARAM;
8671 DEBUG(5,("_spoolss_GetJob\n"));
8675 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8679 result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
8680 if (!W_ERROR_IS_OK(result)) {
8684 count = print_queue_status(snum, &queue, &prt_status);
8686 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8687 count, prt_status.status, prt_status.message));
8689 switch (r->in.level) {
8691 result = getjob_level_1(p->mem_ctx,
8692 queue, count, snum, ntprinter,
8693 r->in.job_id, &r->out.info->info1);
8696 result = getjob_level_2(p->mem_ctx,
8697 queue, count, snum, ntprinter,
8698 r->in.job_id, &r->out.info->info2);
8701 result = WERR_UNKNOWN_LEVEL;
8706 free_a_printer(&ntprinter, 2);
8708 if (!W_ERROR_IS_OK(result)) {
8709 TALLOC_FREE(r->out.info);
8713 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8715 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8717 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8720 /****************************************************************
8721 _spoolss_GetPrinterDataEx
8722 ****************************************************************/
8724 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8725 struct spoolss_GetPrinterDataEx *r)
8728 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8729 struct regval_blob *val = NULL;
8730 NT_PRINTER_INFO_LEVEL *printer = NULL;
8732 WERROR result = WERR_OK;
8735 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8737 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8738 r->in.key_name, r->in.value_name));
8740 /* in case of problem, return some default values */
8743 *r->out.type = REG_NONE;
8746 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8747 OUR_HANDLE(r->in.handle)));
8748 result = WERR_BADFID;
8752 /* Is the handle to a printer or to the server? */
8754 if (Printer->printer_type == SPLHND_SERVER) {
8756 union spoolss_PrinterData data;
8758 result = getprinterdata_printer_server(p->mem_ctx,
8762 if (!W_ERROR_IS_OK(result)) {
8766 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8767 *r->out.type, &data);
8768 if (!W_ERROR_IS_OK(result)) {
8772 *r->out.needed = blob.length;
8774 if (r->in.offered >= *r->out.needed) {
8775 memcpy(r->out.data, blob.data, blob.length);
8778 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8781 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8782 result = WERR_BADFID;
8786 result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8787 if (!W_ERROR_IS_OK(result)) {
8791 /* check to see if the keyname is valid */
8792 if (!strlen(r->in.key_name)) {
8793 result = WERR_INVALID_PARAM;
8797 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
8799 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8800 strequal(r->in.value_name, "ChangeId")) {
8801 *r->out.type = REG_DWORD;
8803 if (r->in.offered >= *r->out.needed) {
8804 SIVAL(r->out.data, 0, printer->info_2->changeid);
8810 if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
8811 DEBUG(4,("_spoolss_GetPrinterDataEx: "
8812 "Invalid keyname [%s]\n", r->in.key_name ));
8813 result = WERR_BADFILE;
8817 val = get_printer_data(printer->info_2,
8818 r->in.key_name, r->in.value_name);
8820 result = WERR_BADFILE;
8824 *r->out.needed = regval_size(val);
8825 *r->out.type = regval_type(val);
8827 if (r->in.offered >= *r->out.needed) {
8828 memcpy(r->out.data, regval_data_p(val), regval_size(val));
8832 free_a_printer(&printer, 2);
8835 if (!W_ERROR_IS_OK(result)) {
8839 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8840 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8842 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8845 /****************************************************************
8846 _spoolss_SetPrinterDataEx
8847 ****************************************************************/
8849 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8850 struct spoolss_SetPrinterDataEx *r)
8852 NT_PRINTER_INFO_LEVEL *printer = NULL;
8854 WERROR result = WERR_OK;
8855 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8858 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8860 /* From MSDN documentation of SetPrinterDataEx: pass request to
8861 SetPrinterData if key is "PrinterDriverData" */
8864 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8865 OUR_HANDLE(r->in.handle)));
8869 if (Printer->printer_type == SPLHND_SERVER) {
8870 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8871 "Not implemented for server handles yet\n"));
8872 return WERR_INVALID_PARAM;
8875 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8880 * Access check : NT returns "access denied" if you make a
8881 * SetPrinterData call without the necessary privildge.
8882 * we were originally returning OK if nothing changed
8883 * which made Win2k issue **a lot** of SetPrinterData
8884 * when connecting to a printer --jerry
8887 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8888 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8889 "change denied by handle access permissions\n"));
8890 return WERR_ACCESS_DENIED;
8893 result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8894 if (!W_ERROR_IS_OK(result)) {
8898 /* check for OID in valuename */
8900 oid_string = strchr(r->in.value_name, ',');
8907 * When client side code sets a magic printer data key, detect it and save
8908 * the current printer data and the magic key's data (its the DEVMODE) for
8909 * future printer/driver initializations.
8911 if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
8912 /* Set devmode and printer initialization info */
8913 result = save_driver_init(printer, 2, r->in.data, r->in.offered);
8915 srv_spoolss_reset_printerdata(printer->info_2->drivername);
8920 /* save the registry data */
8922 result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
8923 r->in.type, r->in.data, r->in.offered);
8925 if (W_ERROR_IS_OK(result)) {
8926 /* save the OID if one was specified */
8928 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8929 r->in.key_name, SPOOL_OID_KEY);
8931 result = WERR_NOMEM;
8936 * I'm not checking the status here on purpose. Don't know
8937 * if this is right, but I'm returning the status from the
8938 * previous set_printer_dataex() call. I have no idea if
8939 * this is right. --jerry
8942 set_printer_dataex(printer, str, r->in.value_name,
8943 REG_SZ, (uint8_t *)oid_string,
8944 strlen(oid_string)+1);
8947 result = mod_a_printer(printer, 2);
8951 free_a_printer(&printer, 2);
8956 /****************************************************************
8957 _spoolss_DeletePrinterDataEx
8958 ****************************************************************/
8960 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8961 struct spoolss_DeletePrinterDataEx *r)
8963 NT_PRINTER_INFO_LEVEL *printer = NULL;
8965 WERROR status = WERR_OK;
8966 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8968 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8971 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8972 "Invalid handle (%s:%u:%u).\n",
8973 OUR_HANDLE(r->in.handle)));
8977 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8980 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8981 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8982 "printer properties change denied by handle\n"));
8983 return WERR_ACCESS_DENIED;
8986 if (!r->in.value_name || !r->in.key_name) {
8990 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8991 if (!W_ERROR_IS_OK(status))
8994 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
8996 if ( W_ERROR_IS_OK(status) )
8997 mod_a_printer( printer, 2 );
8999 free_a_printer(&printer, 2);
9004 /****************************************************************
9005 _spoolss_EnumPrinterKey
9006 ****************************************************************/
9008 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
9009 struct spoolss_EnumPrinterKey *r)
9011 fstring *keynames = NULL;
9013 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9014 NT_PRINTER_DATA *data;
9015 NT_PRINTER_INFO_LEVEL *printer = NULL;
9017 WERROR result = WERR_BADFILE;
9019 const char **array = NULL;
9022 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9025 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9026 OUR_HANDLE(r->in.handle)));
9030 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9034 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9035 if (!W_ERROR_IS_OK(result)) {
9039 /* get the list of subkey names */
9041 data = printer->info_2->data;
9043 num_keys = get_printer_subkeys(data, r->in.key_name, &keynames);
9044 if (num_keys == -1) {
9045 result = WERR_BADFILE;
9049 array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 2);
9051 result = WERR_NOMEM;
9056 array[0] = talloc_strdup(array, "");
9058 result = WERR_NOMEM;
9063 for (i=0; i < num_keys; i++) {
9065 DEBUG(10,("_spoolss_EnumPrinterKey: adding keyname: %s\n",
9068 array[i] = talloc_strdup(array, keynames[i]);
9070 result = WERR_NOMEM;
9075 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
9076 result = WERR_NOMEM;
9080 *r->out._ndr_size = r->in.offered / 2;
9081 *r->out.needed = blob.length;
9083 if (r->in.offered < *r->out.needed) {
9084 result = WERR_MORE_DATA;
9087 r->out.key_buffer->string_array = array;
9091 if (!W_ERROR_IS_OK(result)) {
9093 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9098 free_a_printer(&printer, 2);
9099 SAFE_FREE(keynames);
9104 /****************************************************************
9105 _spoolss_DeletePrinterKey
9106 ****************************************************************/
9108 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9109 struct spoolss_DeletePrinterKey *r)
9111 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9112 NT_PRINTER_INFO_LEVEL *printer = NULL;
9116 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9119 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9120 OUR_HANDLE(r->in.handle)));
9124 /* if keyname == NULL, return error */
9126 if ( !r->in.key_name )
9127 return WERR_INVALID_PARAM;
9129 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
9132 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9133 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9134 "printer properties change denied by handle\n"));
9135 return WERR_ACCESS_DENIED;
9138 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9139 if (!W_ERROR_IS_OK(status))
9142 /* delete the key and all subneys */
9144 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9146 if ( W_ERROR_IS_OK(status) )
9147 status = mod_a_printer(printer, 2);
9149 free_a_printer( &printer, 2 );
9154 /****************************************************************
9155 ****************************************************************/
9157 static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
9158 struct regval_blob *v,
9159 struct spoolss_PrinterEnumValues *r)
9161 r->data = TALLOC_ZERO_P(mem_ctx, DATA_BLOB);
9162 W_ERROR_HAVE_NO_MEMORY(r->data);
9164 r->value_name = talloc_strdup(mem_ctx, regval_name(v));
9165 W_ERROR_HAVE_NO_MEMORY(r->value_name);
9167 r->value_name_len = strlen_m_term(regval_name(v)) * 2;
9169 r->type = regval_type(v);
9170 r->data_length = regval_size(v);
9172 if (r->data_length) {
9173 *r->data = data_blob_talloc(r->data, regval_data_p(v), regval_size(v));
9179 /****************************************************************
9180 _spoolss_EnumPrinterDataEx
9181 ****************************************************************/
9183 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
9184 struct spoolss_EnumPrinterDataEx *r)
9187 NT_PRINTER_INFO_LEVEL *printer = NULL;
9188 struct spoolss_PrinterEnumValues *info = NULL;
9189 NT_PRINTER_DATA *p_data;
9190 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9196 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9200 *r->out.info = NULL;
9203 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9204 OUR_HANDLE(r->in.handle)));
9209 * first check for a keyname of NULL or "". Win2k seems to send
9210 * this a lot and we should send back WERR_INVALID_PARAM
9211 * no need to spend time looking up the printer in this case.
9215 if (!strlen(r->in.key_name)) {
9216 result = WERR_INVALID_PARAM;
9220 /* get the printer off of disk */
9222 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9226 ZERO_STRUCT(printer);
9227 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9228 if (!W_ERROR_IS_OK(result)) {
9232 /* now look for a match on the key name */
9234 p_data = printer->info_2->data;
9236 key_index = lookup_printerkey(p_data, r->in.key_name);
9237 if (key_index == -1) {
9238 DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
9240 result = WERR_INVALID_PARAM;
9244 /* allocate the memory for the array of pointers -- if necessary */
9246 count = regval_ctr_numvals(p_data->keys[key_index].values);
9248 result = WERR_OK; /* ??? */
9252 info = TALLOC_ZERO_ARRAY(p->mem_ctx,
9253 struct spoolss_PrinterEnumValues,
9256 DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
9257 result = WERR_NOMEM;
9262 * loop through all params and build the array to pass
9263 * back to the client
9266 for (i=0; i < count; i++) {
9268 struct regval_blob *val;
9270 /* lookup the registry value */
9272 val = regval_ctr_specific_value(p_data->keys[key_index].values, i);
9274 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val)));
9278 result = registry_value_to_printer_enum_value(info, val, &info[i]);
9279 if (!W_ERROR_IS_OK(result)) {
9284 #if 0 /* FIXME - gd */
9285 /* housekeeping information in the reply */
9287 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9288 * the hand marshalled container size is a multiple
9289 * of 4 bytes for RPC alignment.
9293 needed += 4-(needed % 4);
9296 *r->out.count = count;
9297 *r->out.info = info;
9302 free_a_printer(&printer, 2);
9305 if (!W_ERROR_IS_OK(result)) {
9309 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9310 spoolss_EnumPrinterDataEx,
9313 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9314 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9316 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9319 /****************************************************************************
9320 ****************************************************************************/
9322 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9323 const char *servername,
9324 const char *environment,
9325 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9330 werr = compose_spoolss_server_path(mem_ctx,
9333 SPOOLSS_PRTPROCS_PATH,
9335 if (!W_ERROR_IS_OK(werr)) {
9339 DEBUG(4,("print processor directory: [%s]\n", path));
9341 r->directory_name = path;
9346 /****************************************************************
9347 _spoolss_GetPrintProcessorDirectory
9348 ****************************************************************/
9350 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9351 struct spoolss_GetPrintProcessorDirectory *r)
9355 /* that's an [in out] buffer */
9357 if (!r->in.buffer && (r->in.offered != 0)) {
9358 return WERR_INVALID_PARAM;
9361 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9366 /* r->in.level is ignored */
9368 /* We always should reply with a local print processor directory so that
9369 * users are not forced to have a [prnproc$] share on the Samba spoolss
9370 * server - Guenther */
9372 result = getprintprocessordirectory_level_1(p->mem_ctx,
9373 NULL, /* r->in.server */
9375 &r->out.info->info1);
9376 if (!W_ERROR_IS_OK(result)) {
9377 TALLOC_FREE(r->out.info);
9381 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9382 r->out.info, r->in.level);
9383 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9385 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9388 /*******************************************************************
9389 ********************************************************************/
9391 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9392 const char *dllname)
9394 enum ndr_err_code ndr_err;
9395 struct spoolss_MonitorUi ui;
9397 ui.dll_name = dllname;
9399 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9400 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9401 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9402 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9404 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9407 /*******************************************************************
9408 Streams the monitor UI DLL name in UNICODE
9409 *******************************************************************/
9411 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9412 NT_USER_TOKEN *token, DATA_BLOB *in,
9413 DATA_BLOB *out, uint32_t *needed)
9415 const char *dllname = "tcpmonui.dll";
9417 *needed = (strlen(dllname)+1) * 2;
9419 if (out->length < *needed) {
9420 return WERR_INSUFFICIENT_BUFFER;
9423 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9430 /*******************************************************************
9431 ********************************************************************/
9433 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9434 struct spoolss_PortData1 *port1,
9435 const DATA_BLOB *buf)
9437 enum ndr_err_code ndr_err;
9438 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9439 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9440 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9441 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9443 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9446 /*******************************************************************
9447 ********************************************************************/
9449 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9450 struct spoolss_PortData2 *port2,
9451 const DATA_BLOB *buf)
9453 enum ndr_err_code ndr_err;
9454 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9455 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9456 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9457 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9459 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9462 /*******************************************************************
9463 Create a new TCP/IP port
9464 *******************************************************************/
9466 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9467 NT_USER_TOKEN *token, DATA_BLOB *in,
9468 DATA_BLOB *out, uint32_t *needed)
9470 struct spoolss_PortData1 port1;
9471 struct spoolss_PortData2 port2;
9472 char *device_uri = NULL;
9475 const char *portname;
9476 const char *hostaddress;
9478 uint32_t port_number;
9481 /* peek for spoolss_PortData version */
9483 if (!in || (in->length < (128 + 4))) {
9484 return WERR_GENERAL_FAILURE;
9487 version = IVAL(in->data, 128);
9493 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9497 portname = port1.portname;
9498 hostaddress = port1.hostaddress;
9499 queue = port1.queue;
9500 protocol = port1.protocol;
9501 port_number = port1.port_number;
9507 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9511 portname = port2.portname;
9512 hostaddress = port2.hostaddress;
9513 queue = port2.queue;
9514 protocol = port2.protocol;
9515 port_number = port2.port_number;
9519 DEBUG(1,("xcvtcp_addport: "
9520 "unknown version of port_data: %d\n", version));
9521 return WERR_UNKNOWN_PORT;
9524 /* create the device URI and call the add_port_hook() */
9527 case PROTOCOL_RAWTCP_TYPE:
9528 device_uri = talloc_asprintf(mem_ctx,
9529 "socket://%s:%d/", hostaddress,
9533 case PROTOCOL_LPR_TYPE:
9534 device_uri = talloc_asprintf(mem_ctx,
9535 "lpr://%s/%s", hostaddress, queue );
9539 return WERR_UNKNOWN_PORT;
9546 return add_port_hook(mem_ctx, token, portname, device_uri);
9549 /*******************************************************************
9550 *******************************************************************/
9552 struct xcv_api_table xcvtcp_cmds[] = {
9553 { "MonitorUI", xcvtcp_monitorui },
9554 { "AddPort", xcvtcp_addport},
9558 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9559 NT_USER_TOKEN *token, const char *command,
9566 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9568 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9569 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9570 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9573 return WERR_BADFUNC;
9576 /*******************************************************************
9577 *******************************************************************/
9578 #if 0 /* don't support management using the "Local Port" monitor */
9580 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9581 NT_USER_TOKEN *token, DATA_BLOB *in,
9582 DATA_BLOB *out, uint32_t *needed)
9584 const char *dllname = "localui.dll";
9586 *needed = (strlen(dllname)+1) * 2;
9588 if (out->length < *needed) {
9589 return WERR_INSUFFICIENT_BUFFER;
9592 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9599 /*******************************************************************
9600 *******************************************************************/
9602 struct xcv_api_table xcvlocal_cmds[] = {
9603 { "MonitorUI", xcvlocal_monitorui },
9607 struct xcv_api_table xcvlocal_cmds[] = {
9614 /*******************************************************************
9615 *******************************************************************/
9617 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9618 NT_USER_TOKEN *token, const char *command,
9619 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9624 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9626 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9627 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9628 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9630 return WERR_BADFUNC;
9633 /****************************************************************
9635 ****************************************************************/
9637 WERROR _spoolss_XcvData(pipes_struct *p,
9638 struct spoolss_XcvData *r)
9640 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9641 DATA_BLOB out_data = data_blob_null;
9645 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9646 OUR_HANDLE(r->in.handle)));
9650 /* Has to be a handle to the TCP/IP port monitor */
9652 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9653 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9657 /* requires administrative access to the server */
9659 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9660 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9661 return WERR_ACCESS_DENIED;
9664 /* Allocate the outgoing buffer */
9666 if (r->in.out_data_size) {
9667 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9668 if (out_data.data == NULL) {
9673 switch ( Printer->printer_type ) {
9674 case SPLHND_PORTMON_TCP:
9675 werror = process_xcvtcp_command(p->mem_ctx,
9676 p->server_info->ptok,
9677 r->in.function_name,
9678 &r->in.in_data, &out_data,
9681 case SPLHND_PORTMON_LOCAL:
9682 werror = process_xcvlocal_command(p->mem_ctx,
9683 p->server_info->ptok,
9684 r->in.function_name,
9685 &r->in.in_data, &out_data,
9689 werror = WERR_INVALID_PRINT_MONITOR;
9692 if (!W_ERROR_IS_OK(werror)) {
9696 *r->out.status_code = 0;
9698 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9699 memcpy(r->out.out_data, out_data.data,
9700 MIN(r->in.out_data_size, out_data.length));
9706 /****************************************************************
9707 _spoolss_AddPrintProcessor
9708 ****************************************************************/
9710 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9711 struct spoolss_AddPrintProcessor *r)
9713 /* for now, just indicate success and ignore the add. We'll
9714 automatically set the winprint processor for printer
9715 entries later. Used to debug the LexMark Optra S 1855 PCL
9721 /****************************************************************
9723 ****************************************************************/
9725 WERROR _spoolss_AddPort(pipes_struct *p,
9726 struct spoolss_AddPort *r)
9728 /* do what w2k3 does */
9730 return WERR_NOT_SUPPORTED;
9733 /****************************************************************
9734 _spoolss_GetPrinterDriver
9735 ****************************************************************/
9737 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9738 struct spoolss_GetPrinterDriver *r)
9740 p->rng_fault_state = true;
9741 return WERR_NOT_SUPPORTED;
9744 /****************************************************************
9745 _spoolss_ReadPrinter
9746 ****************************************************************/
9748 WERROR _spoolss_ReadPrinter(pipes_struct *p,
9749 struct spoolss_ReadPrinter *r)
9751 p->rng_fault_state = true;
9752 return WERR_NOT_SUPPORTED;
9755 /****************************************************************
9756 _spoolss_WaitForPrinterChange
9757 ****************************************************************/
9759 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9760 struct spoolss_WaitForPrinterChange *r)
9762 p->rng_fault_state = true;
9763 return WERR_NOT_SUPPORTED;
9766 /****************************************************************
9767 _spoolss_ConfigurePort
9768 ****************************************************************/
9770 WERROR _spoolss_ConfigurePort(pipes_struct *p,
9771 struct spoolss_ConfigurePort *r)
9773 p->rng_fault_state = true;
9774 return WERR_NOT_SUPPORTED;
9777 /****************************************************************
9779 ****************************************************************/
9781 WERROR _spoolss_DeletePort(pipes_struct *p,
9782 struct spoolss_DeletePort *r)
9784 p->rng_fault_state = true;
9785 return WERR_NOT_SUPPORTED;
9788 /****************************************************************
9789 _spoolss_CreatePrinterIC
9790 ****************************************************************/
9792 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9793 struct spoolss_CreatePrinterIC *r)
9795 p->rng_fault_state = true;
9796 return WERR_NOT_SUPPORTED;
9799 /****************************************************************
9800 _spoolss_PlayGDIScriptOnPrinterIC
9801 ****************************************************************/
9803 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9804 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9806 p->rng_fault_state = true;
9807 return WERR_NOT_SUPPORTED;
9810 /****************************************************************
9811 _spoolss_DeletePrinterIC
9812 ****************************************************************/
9814 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9815 struct spoolss_DeletePrinterIC *r)
9817 p->rng_fault_state = true;
9818 return WERR_NOT_SUPPORTED;
9821 /****************************************************************
9822 _spoolss_AddPrinterConnection
9823 ****************************************************************/
9825 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9826 struct spoolss_AddPrinterConnection *r)
9828 p->rng_fault_state = true;
9829 return WERR_NOT_SUPPORTED;
9832 /****************************************************************
9833 _spoolss_DeletePrinterConnection
9834 ****************************************************************/
9836 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9837 struct spoolss_DeletePrinterConnection *r)
9839 p->rng_fault_state = true;
9840 return WERR_NOT_SUPPORTED;
9843 /****************************************************************
9844 _spoolss_PrinterMessageBox
9845 ****************************************************************/
9847 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9848 struct spoolss_PrinterMessageBox *r)
9850 p->rng_fault_state = true;
9851 return WERR_NOT_SUPPORTED;
9854 /****************************************************************
9856 ****************************************************************/
9858 WERROR _spoolss_AddMonitor(pipes_struct *p,
9859 struct spoolss_AddMonitor *r)
9861 p->rng_fault_state = true;
9862 return WERR_NOT_SUPPORTED;
9865 /****************************************************************
9866 _spoolss_DeleteMonitor
9867 ****************************************************************/
9869 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9870 struct spoolss_DeleteMonitor *r)
9872 p->rng_fault_state = true;
9873 return WERR_NOT_SUPPORTED;
9876 /****************************************************************
9877 _spoolss_DeletePrintProcessor
9878 ****************************************************************/
9880 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9881 struct spoolss_DeletePrintProcessor *r)
9883 p->rng_fault_state = true;
9884 return WERR_NOT_SUPPORTED;
9887 /****************************************************************
9888 _spoolss_AddPrintProvidor
9889 ****************************************************************/
9891 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9892 struct spoolss_AddPrintProvidor *r)
9894 p->rng_fault_state = true;
9895 return WERR_NOT_SUPPORTED;
9898 /****************************************************************
9899 _spoolss_DeletePrintProvidor
9900 ****************************************************************/
9902 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9903 struct spoolss_DeletePrintProvidor *r)
9905 p->rng_fault_state = true;
9906 return WERR_NOT_SUPPORTED;
9909 /****************************************************************
9910 _spoolss_FindFirstPrinterChangeNotification
9911 ****************************************************************/
9913 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9914 struct spoolss_FindFirstPrinterChangeNotification *r)
9916 p->rng_fault_state = true;
9917 return WERR_NOT_SUPPORTED;
9920 /****************************************************************
9921 _spoolss_FindNextPrinterChangeNotification
9922 ****************************************************************/
9924 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9925 struct spoolss_FindNextPrinterChangeNotification *r)
9927 p->rng_fault_state = true;
9928 return WERR_NOT_SUPPORTED;
9931 /****************************************************************
9932 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9933 ****************************************************************/
9935 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9936 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9938 p->rng_fault_state = true;
9939 return WERR_NOT_SUPPORTED;
9942 /****************************************************************
9943 _spoolss_ReplyOpenPrinter
9944 ****************************************************************/
9946 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9947 struct spoolss_ReplyOpenPrinter *r)
9949 p->rng_fault_state = true;
9950 return WERR_NOT_SUPPORTED;
9953 /****************************************************************
9954 _spoolss_RouterReplyPrinter
9955 ****************************************************************/
9957 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9958 struct spoolss_RouterReplyPrinter *r)
9960 p->rng_fault_state = true;
9961 return WERR_NOT_SUPPORTED;
9964 /****************************************************************
9965 _spoolss_ReplyClosePrinter
9966 ****************************************************************/
9968 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9969 struct spoolss_ReplyClosePrinter *r)
9971 p->rng_fault_state = true;
9972 return WERR_NOT_SUPPORTED;
9975 /****************************************************************
9977 ****************************************************************/
9979 WERROR _spoolss_AddPortEx(pipes_struct *p,
9980 struct spoolss_AddPortEx *r)
9982 p->rng_fault_state = true;
9983 return WERR_NOT_SUPPORTED;
9986 /****************************************************************
9987 _spoolss_RouterFindFirstPrinterChangeNotification
9988 ****************************************************************/
9990 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9991 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9993 p->rng_fault_state = true;
9994 return WERR_NOT_SUPPORTED;
9997 /****************************************************************
9998 _spoolss_SpoolerInit
9999 ****************************************************************/
10001 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10002 struct spoolss_SpoolerInit *r)
10004 p->rng_fault_state = true;
10005 return WERR_NOT_SUPPORTED;
10008 /****************************************************************
10009 _spoolss_ResetPrinterEx
10010 ****************************************************************/
10012 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10013 struct spoolss_ResetPrinterEx *r)
10015 p->rng_fault_state = true;
10016 return WERR_NOT_SUPPORTED;
10019 /****************************************************************
10020 _spoolss_RouterReplyPrinterEx
10021 ****************************************************************/
10023 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10024 struct spoolss_RouterReplyPrinterEx *r)
10026 p->rng_fault_state = true;
10027 return WERR_NOT_SUPPORTED;
10030 /****************************************************************
10032 ****************************************************************/
10034 WERROR _spoolss_44(pipes_struct *p,
10035 struct spoolss_44 *r)
10037 p->rng_fault_state = true;
10038 return WERR_NOT_SUPPORTED;
10041 /****************************************************************
10043 ****************************************************************/
10045 WERROR _spoolss_47(pipes_struct *p,
10046 struct spoolss_47 *r)
10048 p->rng_fault_state = true;
10049 return WERR_NOT_SUPPORTED;
10052 /****************************************************************
10054 ****************************************************************/
10056 WERROR _spoolss_4a(pipes_struct *p,
10057 struct spoolss_4a *r)
10059 p->rng_fault_state = true;
10060 return WERR_NOT_SUPPORTED;
10063 /****************************************************************
10065 ****************************************************************/
10067 WERROR _spoolss_4b(pipes_struct *p,
10068 struct spoolss_4b *r)
10070 p->rng_fault_state = true;
10071 return WERR_NOT_SUPPORTED;
10074 /****************************************************************
10076 ****************************************************************/
10078 WERROR _spoolss_4c(pipes_struct *p,
10079 struct spoolss_4c *r)
10081 p->rng_fault_state = true;
10082 return WERR_NOT_SUPPORTED;
10085 /****************************************************************
10087 ****************************************************************/
10089 WERROR _spoolss_53(pipes_struct *p,
10090 struct spoolss_53 *r)
10092 p->rng_fault_state = true;
10093 return WERR_NOT_SUPPORTED;
10096 /****************************************************************
10098 ****************************************************************/
10100 WERROR _spoolss_55(pipes_struct *p,
10101 struct spoolss_55 *r)
10103 p->rng_fault_state = true;
10104 return WERR_NOT_SUPPORTED;
10107 /****************************************************************
10109 ****************************************************************/
10111 WERROR _spoolss_56(pipes_struct *p,
10112 struct spoolss_56 *r)
10114 p->rng_fault_state = true;
10115 return WERR_NOT_SUPPORTED;
10118 /****************************************************************
10120 ****************************************************************/
10122 WERROR _spoolss_57(pipes_struct *p,
10123 struct spoolss_57 *r)
10125 p->rng_fault_state = true;
10126 return WERR_NOT_SUPPORTED;
10129 /****************************************************************
10131 ****************************************************************/
10133 WERROR _spoolss_5a(pipes_struct *p,
10134 struct spoolss_5a *r)
10136 p->rng_fault_state = true;
10137 return WERR_NOT_SUPPORTED;
10140 /****************************************************************
10142 ****************************************************************/
10144 WERROR _spoolss_5b(pipes_struct *p,
10145 struct spoolss_5b *r)
10147 p->rng_fault_state = true;
10148 return WERR_NOT_SUPPORTED;
10151 /****************************************************************
10153 ****************************************************************/
10155 WERROR _spoolss_5c(pipes_struct *p,
10156 struct spoolss_5c *r)
10158 p->rng_fault_state = true;
10159 return WERR_NOT_SUPPORTED;
10162 /****************************************************************
10164 ****************************************************************/
10166 WERROR _spoolss_5d(pipes_struct *p,
10167 struct spoolss_5d *r)
10169 p->rng_fault_state = true;
10170 return WERR_NOT_SUPPORTED;
10173 /****************************************************************
10175 ****************************************************************/
10177 WERROR _spoolss_5e(pipes_struct *p,
10178 struct spoolss_5e *r)
10180 p->rng_fault_state = true;
10181 return WERR_NOT_SUPPORTED;
10184 /****************************************************************
10186 ****************************************************************/
10188 WERROR _spoolss_5f(pipes_struct *p,
10189 struct spoolss_5f *r)
10191 p->rng_fault_state = true;
10192 return WERR_NOT_SUPPORTED;
10195 /****************************************************************
10197 ****************************************************************/
10199 WERROR _spoolss_60(pipes_struct *p,
10200 struct spoolss_60 *r)
10202 p->rng_fault_state = true;
10203 return WERR_NOT_SUPPORTED;
10206 /****************************************************************
10208 ****************************************************************/
10210 WERROR _spoolss_61(pipes_struct *p,
10211 struct spoolss_61 *r)
10213 p->rng_fault_state = true;
10214 return WERR_NOT_SUPPORTED;
10217 /****************************************************************
10219 ****************************************************************/
10221 WERROR _spoolss_62(pipes_struct *p,
10222 struct spoolss_62 *r)
10224 p->rng_fault_state = true;
10225 return WERR_NOT_SUPPORTED;
10228 /****************************************************************
10230 ****************************************************************/
10232 WERROR _spoolss_63(pipes_struct *p,
10233 struct spoolss_63 *r)
10235 p->rng_fault_state = true;
10236 return WERR_NOT_SUPPORTED;
10239 /****************************************************************
10241 ****************************************************************/
10243 WERROR _spoolss_64(pipes_struct *p,
10244 struct spoolss_64 *r)
10246 p->rng_fault_state = true;
10247 return WERR_NOT_SUPPORTED;
10250 /****************************************************************
10252 ****************************************************************/
10254 WERROR _spoolss_65(pipes_struct *p,
10255 struct spoolss_65 *r)
10257 p->rng_fault_state = true;
10258 return WERR_NOT_SUPPORTED;
10261 /****************************************************************
10262 _spoolss_GetCorePrinterDrivers
10263 ****************************************************************/
10265 WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
10266 struct spoolss_GetCorePrinterDrivers *r)
10268 p->rng_fault_state = true;
10269 return WERR_NOT_SUPPORTED;
10272 /****************************************************************
10274 ****************************************************************/
10276 WERROR _spoolss_67(pipes_struct *p,
10277 struct spoolss_67 *r)
10279 p->rng_fault_state = true;
10280 return WERR_NOT_SUPPORTED;
10283 /****************************************************************
10284 _spoolss_GetPrinterDriverPackagePath
10285 ****************************************************************/
10287 WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
10288 struct spoolss_GetPrinterDriverPackagePath *r)
10290 p->rng_fault_state = true;
10291 return WERR_NOT_SUPPORTED;
10294 /****************************************************************
10296 ****************************************************************/
10298 WERROR _spoolss_69(pipes_struct *p,
10299 struct spoolss_69 *r)
10301 p->rng_fault_state = true;
10302 return WERR_NOT_SUPPORTED;
10305 /****************************************************************
10307 ****************************************************************/
10309 WERROR _spoolss_6a(pipes_struct *p,
10310 struct spoolss_6a *r)
10312 p->rng_fault_state = true;
10313 return WERR_NOT_SUPPORTED;
10316 /****************************************************************
10318 ****************************************************************/
10320 WERROR _spoolss_6b(pipes_struct *p,
10321 struct spoolss_6b *r)
10323 p->rng_fault_state = true;
10324 return WERR_NOT_SUPPORTED;
10327 /****************************************************************
10329 ****************************************************************/
10331 WERROR _spoolss_6c(pipes_struct *p,
10332 struct spoolss_6c *r)
10334 p->rng_fault_state = true;
10335 return WERR_NOT_SUPPORTED;
10338 /****************************************************************
10340 ****************************************************************/
10342 WERROR _spoolss_6d(pipes_struct *p,
10343 struct spoolss_6d *r)
10345 p->rng_fault_state = true;
10346 return WERR_NOT_SUPPORTED;