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"
34 /* macros stolen from s4 spoolss server */
35 #define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
36 ((info)?ndr_size_##fn(info, level, ic, 0):0)
38 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
39 ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
41 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \
42 ((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0)
44 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
47 extern userdom_struct current_user_info;
50 #define DBGC_CLASS DBGC_RPC_SRV
52 #ifndef MAX_OPEN_PRINTER_EXS
53 #define MAX_OPEN_PRINTER_EXS 50
56 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
57 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
59 static Printer_entry *printers_list;
61 typedef struct _counter_printer_0 {
62 struct _counter_printer_0 *next;
63 struct _counter_printer_0 *prev;
69 static counter_printer_0 *counter_list;
71 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
72 static uint32_t smb_connections = 0;
75 /* in printing/nt_printing.c */
77 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
79 /* API table for Xcv Monitor functions */
81 struct xcv_api_table {
83 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
86 /********************************************************************
87 * Canonicalize servername.
88 ********************************************************************/
90 static const char *canon_servername(const char *servername)
92 const char *pservername = servername;
93 while (*pservername == '\\') {
99 /* translate between internal status numbers and NT status numbers */
100 static int nt_printj_status(int v)
106 return JOB_STATUS_PAUSED;
108 return JOB_STATUS_SPOOLING;
110 return JOB_STATUS_PRINTING;
112 return JOB_STATUS_ERROR;
114 return JOB_STATUS_DELETING;
116 return JOB_STATUS_OFFLINE;
118 return JOB_STATUS_PAPEROUT;
120 return JOB_STATUS_PRINTED;
122 return JOB_STATUS_DELETED;
124 return JOB_STATUS_BLOCKED_DEVQ;
125 case LPQ_USER_INTERVENTION:
126 return JOB_STATUS_USER_INTERVENTION;
131 static int nt_printq_status(int v)
135 return PRINTER_STATUS_PAUSED;
144 /***************************************************************************
145 Disconnect from the client
146 ****************************************************************************/
148 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
154 * Tell the specific printing tdb we no longer want messages for this printer
155 * by deregistering our PID.
158 if (!print_notify_deregister_pid(snum))
159 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
161 /* weird if the test succeds !!! */
162 if (smb_connections==0) {
163 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
167 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
170 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
171 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
172 win_errstr(result)));
174 /* if it's the last connection, deconnect the IPC$ share */
175 if (smb_connections==1) {
177 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
178 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
180 messaging_deregister(smbd_messaging_context(),
181 MSG_PRINTER_NOTIFY2, NULL);
183 /* Tell the connections db we're no longer interested in
184 * printer notify messages. */
186 register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
192 /****************************************************************************
193 Functions to free a printer entry datastruct.
194 ****************************************************************************/
196 static int printer_entry_destructor(Printer_entry *Printer)
198 if (Printer->notify.client_connected == true) {
201 if ( Printer->printer_type == SPLHND_SERVER) {
203 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
204 } else if (Printer->printer_type == SPLHND_PRINTER) {
205 snum = print_queue_snum(Printer->sharename);
207 srv_spoolss_replycloseprinter(snum,
208 &Printer->notify.client_hnd);
212 Printer->notify.flags=0;
213 Printer->notify.options=0;
214 Printer->notify.localmachine[0]='\0';
215 Printer->notify.printerlocal=0;
216 TALLOC_FREE(Printer->notify.option);
217 Printer->notify.client_connected = false;
219 free_nt_devicemode( &Printer->nt_devmode );
220 free_a_printer( &Printer->printer_info, 2 );
222 /* Remove from the internal list. */
223 DLIST_REMOVE(printers_list, Printer);
227 /****************************************************************************
228 find printer index by handle
229 ****************************************************************************/
231 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
232 struct policy_handle *hnd)
234 Printer_entry *find_printer = NULL;
236 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
237 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
244 /****************************************************************************
245 Close printer index by handle.
246 ****************************************************************************/
248 static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
250 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
253 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
258 close_policy_hnd(p, hnd);
263 /****************************************************************************
264 Delete a printer given a handle.
265 ****************************************************************************/
267 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
269 char *cmd = lp_deleteprinter_cmd();
270 char *command = NULL;
272 SE_PRIV se_printop = SE_PRINT_OPERATOR;
273 bool is_print_op = false;
275 /* can't fail if we don't try */
280 command = talloc_asprintf(ctx,
287 is_print_op = user_has_privileges( token, &se_printop );
289 DEBUG(10,("Running [%s]\n", command));
291 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
296 if ( (ret = smbrun(command, NULL)) == 0 ) {
297 /* Tell everyone we updated smb.conf. */
298 message_send_all(smbd_messaging_context(),
299 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
305 /********** END SePrintOperatorPrivlege BLOCK **********/
307 DEBUGADD(10,("returned [%d]\n", ret));
309 TALLOC_FREE(command);
312 return WERR_BADFID; /* What to return here? */
314 /* go ahead and re-read the services immediately */
316 reload_services(false);
319 if ( lp_servicenumber( sharename ) > 0 )
320 return WERR_ACCESS_DENIED;
325 /****************************************************************************
326 Delete a printer given a handle.
327 ****************************************************************************/
329 static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
331 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
334 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
340 * It turns out that Windows allows delete printer on a handle
341 * opened by an admin user, then used on a pipe handle created
342 * by an anonymous user..... but they're working on security.... riiight !
346 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
347 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
348 return WERR_ACCESS_DENIED;
351 /* this does not need a become root since the access check has been
352 done on the handle already */
354 if (del_a_printer( Printer->sharename ) != 0) {
355 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
359 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
360 Printer->sharename );
363 /****************************************************************************
364 Return the snum of a printer corresponding to an handle.
365 ****************************************************************************/
367 static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
368 int *number, struct share_params **params)
370 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
373 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
378 switch (Printer->printer_type) {
380 DEBUG(4,("short name:%s\n", Printer->sharename));
381 *number = print_queue_snum(Printer->sharename);
382 return (*number != -1);
390 /****************************************************************************
391 Set printer handle type.
392 Check if it's \\server or \\server\printer
393 ****************************************************************************/
395 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
397 DEBUG(3,("Setting printer type=%s\n", handlename));
399 if ( strlen(handlename) < 3 ) {
400 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
404 /* it's a print server */
405 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
406 DEBUGADD(4,("Printer is a print server\n"));
407 Printer->printer_type = SPLHND_SERVER;
409 /* it's a printer (set_printer_hnd_name() will handle port monitors */
411 DEBUGADD(4,("Printer is a printer\n"));
412 Printer->printer_type = SPLHND_PRINTER;
418 /****************************************************************************
419 Set printer handle name.. Accept names like \\server, \\server\printer,
420 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
421 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
422 XcvDataPort() interface.
423 ****************************************************************************/
425 static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
428 int n_services=lp_numservices();
429 char *aprinter, *printername;
430 const char *servername;
433 NT_PRINTER_INFO_LEVEL *printer = NULL;
436 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
437 (unsigned long)strlen(handlename)));
439 aprinter = CONST_DISCARD(char *, handlename);
440 if ( *handlename == '\\' ) {
441 servername = canon_servername(handlename);
442 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
447 servername = global_myname();
450 /* save the servername to fill in replies on this handle */
452 if ( !is_myname_or_ipaddr( servername ) )
455 fstrcpy( Printer->servername, servername );
457 if ( Printer->printer_type == SPLHND_SERVER )
460 if ( Printer->printer_type != SPLHND_PRINTER )
463 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
465 /* check for the Port Monitor Interface */
467 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
468 Printer->printer_type = SPLHND_PORTMON_TCP;
469 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
472 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
473 Printer->printer_type = SPLHND_PORTMON_LOCAL;
474 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
478 /* Search all sharenames first as this is easier than pulling
479 the printer_info_2 off of disk. Don't use find_service() since
480 that calls out to map_username() */
482 /* do another loop to look for printernames */
484 for (snum=0; !found && snum<n_services; snum++) {
486 /* no point going on if this is not a printer */
488 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
491 fstrcpy(sname, lp_servicename(snum));
492 if ( strequal( aprinter, sname ) ) {
497 /* no point looking up the printer object if
498 we aren't allowing printername != sharename */
500 if ( lp_force_printername(snum) )
503 fstrcpy(sname, lp_servicename(snum));
507 /* This call doesn't fill in the location or comment from
508 * a CUPS server for efficiency with large numbers of printers.
512 result = get_a_printer_search( NULL, &printer, 2, sname );
513 if ( !W_ERROR_IS_OK(result) ) {
514 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
515 sname, win_errstr(result)));
519 /* printername is always returned as \\server\printername */
520 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
521 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
522 printer->info_2->printername));
523 free_a_printer( &printer, 2);
529 if ( strequal(printername, aprinter) ) {
530 free_a_printer( &printer, 2);
535 DEBUGADD(10, ("printername: %s\n", printername));
537 free_a_printer( &printer, 2);
540 free_a_printer( &printer, 2);
543 DEBUGADD(4,("Printer not found\n"));
547 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
549 fstrcpy(Printer->sharename, sname);
554 /****************************************************************************
555 Find first available printer slot. creates a printer handle for you.
556 ****************************************************************************/
558 static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
559 const char *name, uint32_t access_granted)
561 Printer_entry *new_printer;
563 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
565 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
566 if (new_printer == NULL) {
569 talloc_set_destructor(new_printer, printer_entry_destructor);
571 if (!create_policy_hnd(p, hnd, new_printer)) {
572 TALLOC_FREE(new_printer);
576 /* Add to the internal list. */
577 DLIST_ADD(printers_list, new_printer);
579 new_printer->notify.option=NULL;
581 if (!set_printer_hnd_printertype(new_printer, name)) {
582 close_printer_handle(p, hnd);
586 if (!set_printer_hnd_name(new_printer, name)) {
587 close_printer_handle(p, hnd);
591 new_printer->access_granted = access_granted;
593 DEBUG(5, ("%d printer handles active\n",
594 (int)num_pipe_handles(p->pipe_handles)));
599 /***************************************************************************
600 check to see if the client motify handle is monitoring the notification
601 given by (notify_type, notify_field).
602 **************************************************************************/
604 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
605 uint16_t notify_field)
610 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
611 uint16_t notify_field)
613 struct spoolss_NotifyOption *option = p->notify.option;
617 * Flags should always be zero when the change notify
618 * is registered by the client's spooler. A user Win32 app
619 * might use the flags though instead of the NOTIFY_OPTION_INFO
628 return is_monitoring_event_flags(
629 p->notify.flags, notify_type, notify_field);
631 for (i = 0; i < option->count; i++) {
633 /* Check match for notify_type */
635 if (option->types[i].type != notify_type)
638 /* Check match for field */
640 for (j = 0; j < option->types[i].count; j++) {
641 if (option->types[i].fields[j].field == notify_field) {
647 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
648 p->servername, p->sharename, notify_type, notify_field));
653 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
654 _data->data.integer[0] = _integer; \
655 _data->data.integer[1] = 0;
658 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
659 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
660 if (!_data->data.string.string) {\
661 _data->data.string.size = 0; \
663 _data->data.string.size = strlen_m_term(_p) * 2;
665 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
666 _data->data.devmode.devmode = _devmode;
668 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
669 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
670 if (!_data->data.sd.sd) { \
671 _data->data.sd.sd_size = 0; \
673 _data->data.sd.sd_size = _size;
675 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
680 struct spoolss_Time st;
684 if (!init_systemtime(&st, t)) {
688 p = talloc_array(mem_ctx, char, len);
694 * Systemtime must be linearized as a set of UINT16's.
695 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
698 SSVAL(p, 0, st.year);
699 SSVAL(p, 2, st.month);
700 SSVAL(p, 4, st.day_of_week);
702 SSVAL(p, 8, st.hour);
703 SSVAL(p, 10, st.minute);
704 SSVAL(p, 12, st.second);
705 SSVAL(p, 14, st.millisecond);
711 /* Convert a notification message to a struct spoolss_Notify */
713 static void notify_one_value(struct spoolss_notify_msg *msg,
714 struct spoolss_Notify *data,
717 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
720 static void notify_string(struct spoolss_notify_msg *msg,
721 struct spoolss_Notify *data,
724 /* The length of the message includes the trailing \0 */
726 data->data.string.size = msg->len * 2;
727 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
728 if (!data->data.string.string) {
729 data->data.string.size = 0;
734 static void notify_system_time(struct spoolss_notify_msg *msg,
735 struct spoolss_Notify *data,
738 data->data.string.string = NULL;
739 data->data.string.size = 0;
741 if (msg->len != sizeof(time_t)) {
742 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
747 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
748 &data->data.string.string,
749 &data->data.string.size);
752 struct notify2_message_table {
754 void (*fn)(struct spoolss_notify_msg *msg,
755 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
758 static struct notify2_message_table printer_notify_table[] = {
759 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
760 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
761 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
762 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
763 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
764 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
765 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
766 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
767 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
768 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
769 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
770 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
771 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
772 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
773 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
774 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
775 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
776 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
777 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
780 static struct notify2_message_table job_notify_table[] = {
781 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
782 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
783 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
784 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
785 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
786 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
787 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
788 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
789 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
790 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
791 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
792 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
793 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
794 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
795 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
796 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
797 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
798 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
799 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
800 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
801 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
802 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
803 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
804 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
808 /***********************************************************************
809 Allocate talloc context for container object
810 **********************************************************************/
812 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
817 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
822 /***********************************************************************
823 release all allocated memory and zero out structure
824 **********************************************************************/
826 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
832 talloc_destroy(ctr->ctx);
839 /***********************************************************************
840 **********************************************************************/
842 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
850 /***********************************************************************
851 **********************************************************************/
853 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
855 if ( !ctr || !ctr->msg_groups )
858 if ( idx >= ctr->num_groups )
861 return &ctr->msg_groups[idx];
865 /***********************************************************************
866 How many groups of change messages do we have ?
867 **********************************************************************/
869 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
874 return ctr->num_groups;
877 /***********************************************************************
878 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
879 **********************************************************************/
881 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
883 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
884 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
885 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
891 /* loop over all groups looking for a matching printer name */
893 for ( i=0; i<ctr->num_groups; i++ ) {
894 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
898 /* add a new group? */
900 if ( i == ctr->num_groups ) {
903 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
904 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
907 ctr->msg_groups = groups;
909 /* clear the new entry and set the printer name */
911 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
912 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
915 /* add the change messages; 'i' is the correct index now regardless */
917 msg_grp = &ctr->msg_groups[i];
921 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
922 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
925 msg_grp->msgs = msg_list;
927 new_slot = msg_grp->num_msgs-1;
928 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
930 /* need to allocate own copy of data */
933 msg_grp->msgs[new_slot].notify.data = (char *)
934 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
936 return ctr->num_groups;
939 /***********************************************************************
940 Send a change notication message on all handles which have a call
942 **********************************************************************/
944 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
947 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
948 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
949 SPOOLSS_NOTIFY_MSG *messages;
950 int sending_msg_count;
953 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
957 messages = msg_group->msgs;
960 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
964 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
966 /* loop over all printers */
968 for (p = printers_list; p; p = p->next) {
969 struct spoolss_Notify *notifies;
974 /* Is there notification on this handle? */
976 if ( !p->notify.client_connected )
979 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
981 /* For this printer? Print servers always receive
984 if ( ( p->printer_type == SPLHND_PRINTER ) &&
985 ( !strequal(msg_group->printername, p->sharename) ) )
988 DEBUG(10,("Our printer\n"));
990 /* allocate the max entries possible */
992 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
997 /* build the array of change notifications */
999 sending_msg_count = 0;
1001 for ( i=0; i<msg_group->num_msgs; i++ ) {
1002 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1004 /* Are we monitoring this event? */
1006 if (!is_monitoring_event(p, msg->type, msg->field))
1009 sending_msg_count++;
1012 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1013 msg->type, msg->field, p->sharename));
1016 * if the is a printer notification handle and not a job notification
1017 * type, then set the id to 0. Other wise just use what was specified
1020 * When registering change notification on a print server handle
1021 * we always need to send back the id (snum) matching the printer
1022 * for which the change took place. For change notify registered
1023 * on a printer handle, this does not matter and the id should be 0.
1028 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1034 /* Convert unix jobid to smb jobid */
1036 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1037 id = sysjob_to_jobid(msg->id);
1040 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1045 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1048 case PRINTER_NOTIFY_TYPE:
1049 if ( printer_notify_table[msg->field].fn )
1050 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1053 case JOB_NOTIFY_TYPE:
1054 if ( job_notify_table[msg->field].fn )
1055 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1059 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1066 if ( sending_msg_count ) {
1069 union spoolss_ReplyPrinterInfo info;
1070 struct spoolss_NotifyInfo info0;
1071 uint32_t reply_result;
1073 info0.version = 0x2;
1074 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1075 info0.count = count;
1076 info0.notifies = notifies;
1078 info.info0 = &info0;
1080 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1081 &p->notify.client_hnd,
1082 p->notify.change, /* color */
1085 0, /* reply_type, must be 0 */
1088 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1089 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1090 notify_cli_pipe->srv_name_slash,
1093 switch (reply_result) {
1096 case PRINTER_NOTIFY_INFO_DISCARDED:
1097 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1098 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1107 DEBUG(8,("send_notify2_changes: Exit...\n"));
1111 /***********************************************************************
1112 **********************************************************************/
1114 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1117 uint32_t tv_sec, tv_usec;
1120 /* Unpack message */
1122 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1125 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1127 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1130 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1131 &msg->notify.value[0], &msg->notify.value[1]);
1133 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1134 &msg->len, &msg->notify.data);
1136 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1137 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1139 tv->tv_sec = tv_sec;
1140 tv->tv_usec = tv_usec;
1143 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1144 msg->notify.value[1]));
1146 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1151 /********************************************************************
1152 Receive a notify2 message list
1153 ********************************************************************/
1155 static void receive_notify2_message_list(struct messaging_context *msg,
1158 struct server_id server_id,
1161 size_t msg_count, i;
1162 char *buf = (char *)data->data;
1165 SPOOLSS_NOTIFY_MSG notify;
1166 SPOOLSS_NOTIFY_MSG_CTR messages;
1169 if (data->length < 4) {
1170 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1174 msg_count = IVAL(buf, 0);
1177 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1179 if (msg_count == 0) {
1180 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1184 /* initialize the container */
1186 ZERO_STRUCT( messages );
1187 notify_msg_ctr_init( &messages );
1190 * build message groups for each printer identified
1191 * in a change_notify msg. Remember that a PCN message
1192 * includes the handle returned for the srv_spoolss_replyopenprinter()
1193 * call. Therefore messages are grouped according to printer handle.
1196 for ( i=0; i<msg_count; i++ ) {
1197 struct timeval msg_tv;
1199 if (msg_ptr + 4 - buf > data->length) {
1200 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1204 msg_len = IVAL(msg_ptr,0);
1207 if (msg_ptr + msg_len - buf > data->length) {
1208 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1212 /* unpack messages */
1214 ZERO_STRUCT( notify );
1215 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1218 /* add to correct list in container */
1220 notify_msg_ctr_addmsg( &messages, ¬ify );
1222 /* free memory that might have been allocated by notify2_unpack_msg() */
1224 if ( notify.len != 0 )
1225 SAFE_FREE( notify.notify.data );
1228 /* process each group of messages */
1230 num_groups = notify_msg_ctr_numgroups( &messages );
1231 for ( i=0; i<num_groups; i++ )
1232 send_notify2_changes( &messages, i );
1237 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1238 (uint32_t)msg_count ));
1240 notify_msg_ctr_destroy( &messages );
1245 /********************************************************************
1246 Send a message to ourself about new driver being installed
1247 so we can upgrade the information for each printer bound to this
1249 ********************************************************************/
1251 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1253 int len = strlen(drivername);
1258 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1261 messaging_send_buf(smbd_messaging_context(), procid_self(),
1262 MSG_PRINTER_DRVUPGRADE,
1263 (uint8_t *)drivername, len+1);
1268 /**********************************************************************
1269 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1270 over all printers, upgrading ones as necessary
1271 **********************************************************************/
1273 void do_drv_upgrade_printer(struct messaging_context *msg,
1276 struct server_id server_id,
1281 int n_services = lp_numservices();
1284 len = MIN(data->length,sizeof(drivername)-1);
1285 strncpy(drivername, (const char *)data->data, len);
1287 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1289 /* Iterate the printer list */
1291 for (snum=0; snum<n_services; snum++)
1293 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1296 NT_PRINTER_INFO_LEVEL *printer = NULL;
1298 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1299 if (!W_ERROR_IS_OK(result))
1302 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1304 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1306 /* all we care about currently is the change_id */
1308 result = mod_a_printer(printer, 2);
1309 if (!W_ERROR_IS_OK(result)) {
1310 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1311 win_errstr(result)));
1315 free_a_printer(&printer, 2);
1322 /********************************************************************
1323 Update the cache for all printq's with a registered client
1325 ********************************************************************/
1327 void update_monitored_printq_cache( void )
1329 Printer_entry *printer = printers_list;
1332 /* loop through all printers and update the cache where
1333 client_connected == true */
1336 if ( (printer->printer_type == SPLHND_PRINTER)
1337 && printer->notify.client_connected )
1339 snum = print_queue_snum(printer->sharename);
1340 print_queue_status( snum, NULL, NULL );
1343 printer = printer->next;
1348 /********************************************************************
1349 Send a message to ourself about new driver being installed
1350 so we can upgrade the information for each printer bound to this
1352 ********************************************************************/
1354 static bool srv_spoolss_reset_printerdata(char* drivername)
1356 int len = strlen(drivername);
1361 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1364 messaging_send_buf(smbd_messaging_context(), procid_self(),
1365 MSG_PRINTERDATA_INIT_RESET,
1366 (uint8_t *)drivername, len+1);
1371 /**********************************************************************
1372 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1373 over all printers, resetting printer data as neessary
1374 **********************************************************************/
1376 void reset_all_printerdata(struct messaging_context *msg,
1379 struct server_id server_id,
1384 int n_services = lp_numservices();
1387 len = MIN( data->length, sizeof(drivername)-1 );
1388 strncpy( drivername, (const char *)data->data, len );
1390 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1392 /* Iterate the printer list */
1394 for ( snum=0; snum<n_services; snum++ )
1396 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1399 NT_PRINTER_INFO_LEVEL *printer = NULL;
1401 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1402 if ( !W_ERROR_IS_OK(result) )
1406 * if the printer is bound to the driver,
1407 * then reset to the new driver initdata
1410 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1412 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1414 if ( !set_driver_init(printer, 2) ) {
1415 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1416 printer->info_2->printername, printer->info_2->drivername));
1419 result = mod_a_printer( printer, 2 );
1420 if ( !W_ERROR_IS_OK(result) ) {
1421 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1422 get_dos_error_msg(result)));
1426 free_a_printer( &printer, 2 );
1435 /****************************************************************
1436 _spoolss_OpenPrinter
1437 ****************************************************************/
1439 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1440 struct spoolss_OpenPrinter *r)
1442 struct spoolss_OpenPrinterEx e;
1445 ZERO_STRUCT(e.in.userlevel);
1447 e.in.printername = r->in.printername;
1448 e.in.datatype = r->in.datatype;
1449 e.in.devmode_ctr = r->in.devmode_ctr;
1450 e.in.access_mask = r->in.access_mask;
1453 e.out.handle = r->out.handle;
1455 werr = _spoolss_OpenPrinterEx(p, &e);
1457 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1458 /* OpenPrinterEx returns this for a bad
1459 * printer name. We must return WERR_INVALID_PRINTER_NAME
1462 werr = WERR_INVALID_PRINTER_NAME;
1468 /********************************************************************
1469 ********************************************************************/
1471 bool convert_devicemode(const char *printername,
1472 const struct spoolss_DeviceMode *devmode,
1473 NT_DEVICEMODE **pp_nt_devmode)
1475 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1478 * Ensure nt_devmode is a valid pointer
1479 * as we will be overwriting it.
1482 if (nt_devmode == NULL) {
1483 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1484 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1488 fstrcpy(nt_devmode->devicename, devmode->devicename);
1489 fstrcpy(nt_devmode->formname, devmode->formname);
1491 nt_devmode->devicename[31] = '\0';
1492 nt_devmode->formname[31] = '\0';
1494 nt_devmode->specversion = devmode->specversion;
1495 nt_devmode->driverversion = devmode->driverversion;
1496 nt_devmode->size = devmode->size;
1497 nt_devmode->fields = devmode->fields;
1498 nt_devmode->orientation = devmode->orientation;
1499 nt_devmode->papersize = devmode->papersize;
1500 nt_devmode->paperlength = devmode->paperlength;
1501 nt_devmode->paperwidth = devmode->paperwidth;
1502 nt_devmode->scale = devmode->scale;
1503 nt_devmode->copies = devmode->copies;
1504 nt_devmode->defaultsource = devmode->defaultsource;
1505 nt_devmode->printquality = devmode->printquality;
1506 nt_devmode->color = devmode->color;
1507 nt_devmode->duplex = devmode->duplex;
1508 nt_devmode->yresolution = devmode->yresolution;
1509 nt_devmode->ttoption = devmode->ttoption;
1510 nt_devmode->collate = devmode->collate;
1512 nt_devmode->logpixels = devmode->logpixels;
1513 nt_devmode->bitsperpel = devmode->bitsperpel;
1514 nt_devmode->pelswidth = devmode->pelswidth;
1515 nt_devmode->pelsheight = devmode->pelsheight;
1516 nt_devmode->displayflags = devmode->displayflags;
1517 nt_devmode->displayfrequency = devmode->displayfrequency;
1518 nt_devmode->icmmethod = devmode->icmmethod;
1519 nt_devmode->icmintent = devmode->icmintent;
1520 nt_devmode->mediatype = devmode->mediatype;
1521 nt_devmode->dithertype = devmode->dithertype;
1522 nt_devmode->reserved1 = devmode->reserved1;
1523 nt_devmode->reserved2 = devmode->reserved2;
1524 nt_devmode->panningwidth = devmode->panningwidth;
1525 nt_devmode->panningheight = devmode->panningheight;
1528 * Only change private and driverextra if the incoming devmode
1529 * has a new one. JRA.
1532 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1533 SAFE_FREE(nt_devmode->nt_dev_private);
1534 nt_devmode->driverextra = devmode->__driverextra_length;
1535 if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
1537 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1540 *pp_nt_devmode = nt_devmode;
1545 /****************************************************************
1546 _spoolss_OpenPrinterEx
1547 ****************************************************************/
1549 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1550 struct spoolss_OpenPrinterEx *r)
1553 Printer_entry *Printer=NULL;
1555 if (!r->in.printername) {
1556 return WERR_INVALID_PARAM;
1559 /* some sanity check because you can open a printer or a print server */
1560 /* aka: \\server\printer or \\server */
1562 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1564 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1565 ZERO_STRUCTP(r->out.handle);
1566 return WERR_INVALID_PARAM;
1569 Printer = find_printer_index_by_hnd(p, r->out.handle);
1571 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1572 "handle we created for printer %s\n", r->in.printername));
1573 close_printer_handle(p, r->out.handle);
1574 ZERO_STRUCTP(r->out.handle);
1575 return WERR_INVALID_PARAM;
1579 * First case: the user is opening the print server:
1581 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1582 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1584 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1585 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1586 * or if the user is listed in the smb.conf printer admin parameter.
1588 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1589 * client view printer folder, but does not show the MSAPW.
1591 * Note: this test needs code to check access rights here too. Jeremy
1592 * could you look at this?
1594 * Second case: the user is opening a printer:
1595 * NT doesn't let us connect to a printer if the connecting user
1596 * doesn't have print permission.
1598 * Third case: user is opening a Port Monitor
1599 * access checks same as opening a handle to the print server.
1602 switch (Printer->printer_type )
1605 case SPLHND_PORTMON_TCP:
1606 case SPLHND_PORTMON_LOCAL:
1607 /* Printserver handles use global struct... */
1611 /* Map standard access rights to object specific access rights */
1613 se_map_standard(&r->in.access_mask,
1614 &printserver_std_mapping);
1616 /* Deny any object specific bits that don't apply to print
1617 servers (i.e printer and job specific bits) */
1619 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1621 if (r->in.access_mask &
1622 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1623 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1624 close_printer_handle(p, r->out.handle);
1625 ZERO_STRUCTP(r->out.handle);
1626 return WERR_ACCESS_DENIED;
1629 /* Allow admin access */
1631 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1633 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1635 if (!lp_ms_add_printer_wizard()) {
1636 close_printer_handle(p, r->out.handle);
1637 ZERO_STRUCTP(r->out.handle);
1638 return WERR_ACCESS_DENIED;
1641 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1642 and not a printer admin, then fail */
1644 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1645 !user_has_privileges(p->server_info->ptok,
1647 !token_contains_name_in_list(
1648 uidtoname(p->server_info->utok.uid),
1650 p->server_info->ptok,
1651 lp_printer_admin(snum))) {
1652 close_printer_handle(p, r->out.handle);
1653 ZERO_STRUCTP(r->out.handle);
1654 return WERR_ACCESS_DENIED;
1657 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1661 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1664 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1665 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1667 /* We fall through to return WERR_OK */
1670 case SPLHND_PRINTER:
1671 /* NT doesn't let us connect to a printer if the connecting user
1672 doesn't have print permission. */
1674 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1675 close_printer_handle(p, r->out.handle);
1676 ZERO_STRUCTP(r->out.handle);
1680 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1681 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1684 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1686 /* map an empty access mask to the minimum access mask */
1687 if (r->in.access_mask == 0x0)
1688 r->in.access_mask = PRINTER_ACCESS_USE;
1691 * If we are not serving the printer driver for this printer,
1692 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1693 * will keep NT clients happy --jerry
1696 if (lp_use_client_driver(snum)
1697 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1699 r->in.access_mask = PRINTER_ACCESS_USE;
1702 /* check smb.conf parameters and the the sec_desc */
1704 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1705 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1706 ZERO_STRUCTP(r->out.handle);
1707 return WERR_ACCESS_DENIED;
1710 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1711 p->server_info->ptok, snum) ||
1712 !print_access_check(p->server_info, snum,
1713 r->in.access_mask)) {
1714 DEBUG(3, ("access DENIED for printer open\n"));
1715 close_printer_handle(p, r->out.handle);
1716 ZERO_STRUCTP(r->out.handle);
1717 return WERR_ACCESS_DENIED;
1720 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1721 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1722 close_printer_handle(p, r->out.handle);
1723 ZERO_STRUCTP(r->out.handle);
1724 return WERR_ACCESS_DENIED;
1727 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1728 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1730 r->in.access_mask = PRINTER_ACCESS_USE;
1732 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1733 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1738 /* sanity check to prevent programmer error */
1739 ZERO_STRUCTP(r->out.handle);
1743 Printer->access_granted = r->in.access_mask;
1746 * If the client sent a devmode in the OpenPrinter() call, then
1747 * save it here in case we get a job submission on this handle
1750 if ((Printer->printer_type != SPLHND_SERVER) &&
1751 r->in.devmode_ctr.devmode) {
1752 convert_devicemode(Printer->sharename,
1753 r->in.devmode_ctr.devmode,
1754 &Printer->nt_devmode);
1757 #if 0 /* JERRY -- I'm doubtful this is really effective */
1758 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1759 optimization in Windows 2000 clients --jerry */
1761 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1762 && (RA_WIN2K == get_remote_arch()) )
1764 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1765 sys_usleep( 500000 );
1772 /****************************************************************************
1773 ****************************************************************************/
1775 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1776 NT_PRINTER_INFO_LEVEL_2 *d)
1778 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1784 d->attributes = r->attributes;
1785 d->priority = r->priority;
1786 d->default_priority = r->defaultpriority;
1787 d->starttime = r->starttime;
1788 d->untiltime = r->untiltime;
1789 d->status = r->status;
1790 d->cjobs = r->cjobs;
1792 fstrcpy(d->servername, r->servername);
1793 fstrcpy(d->printername, r->printername);
1794 fstrcpy(d->sharename, r->sharename);
1795 fstrcpy(d->portname, r->portname);
1796 fstrcpy(d->drivername, r->drivername);
1797 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1798 fstrcpy(d->location, r->location);
1799 fstrcpy(d->sepfile, r->sepfile);
1800 fstrcpy(d->printprocessor, r->printprocessor);
1801 fstrcpy(d->datatype, r->datatype);
1802 fstrcpy(d->parameters, r->parameters);
1807 /****************************************************************************
1808 ****************************************************************************/
1810 static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
1811 NT_PRINTER_INFO_LEVEL *printer)
1815 switch (info_ctr->level) {
1817 /* allocate memory if needed. Messy because
1818 convert_printer_info is used to update an existing
1819 printer or build a new one */
1821 if (!printer->info_2) {
1822 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1823 if (!printer->info_2) {
1824 DEBUG(0,("convert_printer_info: "
1825 "talloc() failed!\n"));
1830 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1832 printer->info_2->setuptime = time(NULL);
1839 /****************************************************************
1840 _spoolss_ClosePrinter
1841 ****************************************************************/
1843 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1844 struct spoolss_ClosePrinter *r)
1846 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1848 if (Printer && Printer->document_started) {
1849 struct spoolss_EndDocPrinter e;
1851 e.in.handle = r->in.handle;
1853 _spoolss_EndDocPrinter(p, &e);
1856 if (!close_printer_handle(p, r->in.handle))
1859 /* clear the returned printer handle. Observed behavior
1860 from Win2k server. Don't think this really matters.
1861 Previous code just copied the value of the closed
1864 ZERO_STRUCTP(r->out.handle);
1869 /****************************************************************
1870 _spoolss_DeletePrinter
1871 ****************************************************************/
1873 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1874 struct spoolss_DeletePrinter *r)
1876 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1879 if (Printer && Printer->document_started) {
1880 struct spoolss_EndDocPrinter e;
1882 e.in.handle = r->in.handle;
1884 _spoolss_EndDocPrinter(p, &e);
1887 result = delete_printer_handle(p, r->in.handle);
1889 update_c_setprinter(false);
1894 /*******************************************************************
1895 * static function to lookup the version id corresponding to an
1896 * long architecture string
1897 ******************************************************************/
1899 static const struct print_architecture_table_node archi_table[]= {
1901 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1902 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1903 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1904 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1905 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1906 {"Windows IA64", SPL_ARCH_IA64, 3 },
1907 {"Windows x64", SPL_ARCH_X64, 3 },
1911 static int get_version_id(const char *arch)
1915 for (i=0; archi_table[i].long_archi != NULL; i++)
1917 if (strcmp(arch, archi_table[i].long_archi) == 0)
1918 return (archi_table[i].version);
1924 /****************************************************************
1925 _spoolss_DeletePrinterDriver
1926 ****************************************************************/
1928 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1929 struct spoolss_DeletePrinterDriver *r)
1932 struct spoolss_DriverInfo8 *info = NULL;
1933 struct spoolss_DriverInfo8 *info_win2k = NULL;
1936 WERROR status_win2k = WERR_ACCESS_DENIED;
1937 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1939 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1940 and not a printer admin, then fail */
1942 if ( (p->server_info->utok.uid != sec_initial_uid())
1943 && !user_has_privileges(p->server_info->ptok, &se_printop )
1944 && !token_contains_name_in_list(
1945 uidtoname(p->server_info->utok.uid), NULL,
1946 NULL, p->server_info->ptok,
1947 lp_printer_admin(-1)) )
1949 return WERR_ACCESS_DENIED;
1952 /* check that we have a valid driver name first */
1954 if ((version = get_version_id(r->in.architecture)) == -1)
1955 return WERR_INVALID_ENVIRONMENT;
1957 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
1961 /* try for Win2k driver if "Windows NT x86" */
1963 if ( version == 2 ) {
1965 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1970 status = WERR_UNKNOWN_PRINTER_DRIVER;
1974 /* otherwise it was a failure */
1976 status = WERR_UNKNOWN_PRINTER_DRIVER;
1982 if (printer_driver_in_use(info)) {
1983 status = WERR_PRINTER_DRIVER_IN_USE;
1989 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1992 r->in.architecture, 3)))
1994 /* if we get to here, we now have 2 driver info structures to remove */
1995 /* remove the Win2k driver first*/
1997 status_win2k = delete_printer_driver(
1998 p, info_win2k, 3, false);
1999 free_a_printer_driver(info_win2k);
2001 /* this should not have failed---if it did, report to client */
2002 if ( !W_ERROR_IS_OK(status_win2k) )
2004 status = status_win2k;
2010 status = delete_printer_driver(p, info, version, false);
2012 /* if at least one of the deletes succeeded return OK */
2014 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2018 free_a_printer_driver(info);
2023 /****************************************************************
2024 _spoolss_DeletePrinterDriverEx
2025 ****************************************************************/
2027 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2028 struct spoolss_DeletePrinterDriverEx *r)
2030 struct spoolss_DriverInfo8 *info = NULL;
2031 struct spoolss_DriverInfo8 *info_win2k = NULL;
2035 WERROR status_win2k = WERR_ACCESS_DENIED;
2036 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2038 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2039 and not a printer admin, then fail */
2041 if ( (p->server_info->utok.uid != sec_initial_uid())
2042 && !user_has_privileges(p->server_info->ptok, &se_printop )
2043 && !token_contains_name_in_list(
2044 uidtoname(p->server_info->utok.uid), NULL, NULL,
2045 p->server_info->ptok, lp_printer_admin(-1)) )
2047 return WERR_ACCESS_DENIED;
2050 /* check that we have a valid driver name first */
2051 if ((version = get_version_id(r->in.architecture)) == -1) {
2052 /* this is what NT returns */
2053 return WERR_INVALID_ENVIRONMENT;
2056 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2057 version = r->in.version;
2059 status = get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2060 r->in.architecture, version);
2062 if ( !W_ERROR_IS_OK(status) )
2065 * if the client asked for a specific version,
2066 * or this is something other than Windows NT x86,
2070 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2073 /* try for Win2k driver if "Windows NT x86" */
2076 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2079 status = WERR_UNKNOWN_PRINTER_DRIVER;
2084 if (printer_driver_in_use(info)) {
2085 status = WERR_PRINTER_DRIVER_IN_USE;
2090 * we have a couple of cases to consider.
2091 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2092 * then the delete should fail if **any** files overlap with
2094 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2095 * non-overlapping files
2096 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2097 * is set, the do not delete any files
2098 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2101 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2103 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2105 if (delete_files && printer_driver_files_in_use(info, info) & (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
2106 /* no idea of the correct error here */
2107 status = WERR_ACCESS_DENIED;
2112 /* also check for W32X86/3 if necessary; maybe we already have? */
2114 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2115 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info_win2k,
2117 r->in.architecture, 3)))
2120 if (delete_files && printer_driver_files_in_use(info, info_win2k) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2121 /* no idea of the correct error here */
2122 free_a_printer_driver(info_win2k);
2123 status = WERR_ACCESS_DENIED;
2127 /* if we get to here, we now have 2 driver info structures to remove */
2128 /* remove the Win2k driver first*/
2130 status_win2k = delete_printer_driver(
2131 p, info_win2k, 3, delete_files);
2132 free_a_printer_driver(info_win2k);
2134 /* this should not have failed---if it did, report to client */
2136 if ( !W_ERROR_IS_OK(status_win2k) )
2141 status = delete_printer_driver(p, info, version, delete_files);
2143 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2146 free_a_printer_driver(info);
2152 /****************************************************************************
2153 Internal routine for removing printerdata
2154 ***************************************************************************/
2156 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2158 return delete_printer_data( printer->info_2, key, value );
2161 /****************************************************************************
2162 Internal routine for storing printerdata
2163 ***************************************************************************/
2165 WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2166 const char *key, const char *value,
2167 uint32_t type, uint8_t *data, int real_len)
2169 /* the registry objects enforce uniqueness based on value name */
2171 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2174 /********************************************************************
2175 GetPrinterData on a printer server Handle.
2176 ********************************************************************/
2178 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2180 enum winreg_Type *type,
2181 union spoolss_PrinterData *data)
2183 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2185 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2191 if (!StrCaseCmp(value, "BeepEnabled")) {
2197 if (!StrCaseCmp(value, "EventLog")) {
2199 /* formally was 0x1b */
2204 if (!StrCaseCmp(value, "NetPopup")) {
2210 if (!StrCaseCmp(value, "MajorVersion")) {
2213 /* Windows NT 4.0 seems to not allow uploading of drivers
2214 to a server that reports 0x3 as the MajorVersion.
2215 need to investigate more how Win2k gets around this .
2218 if (RA_WINNT == get_remote_arch()) {
2227 if (!StrCaseCmp(value, "MinorVersion")) {
2234 * uint32_t size = 0x114
2235 * uint32_t major = 5
2236 * uint32_t minor = [0|1]
2237 * uint32_t build = [2195|2600]
2238 * extra unicode string = e.g. "Service Pack 3"
2240 if (!StrCaseCmp(value, "OSVersion")) {
2242 enum ndr_err_code ndr_err;
2243 struct spoolss_OSVersion os;
2245 os.major = 5; /* Windows 2000 == 5.0 */
2247 os.build = 2195; /* build */
2248 os.extra_string = ""; /* leave extra string empty */
2250 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
2251 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2252 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2253 return WERR_GENERAL_FAILURE;
2257 data->binary = blob;
2263 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2266 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2267 W_ERROR_HAVE_NO_MEMORY(data->string);
2272 if (!StrCaseCmp(value, "Architecture")) {
2274 data->string = talloc_strdup(mem_ctx,
2275 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2276 W_ERROR_HAVE_NO_MEMORY(data->string);
2281 if (!StrCaseCmp(value, "DsPresent")) {
2284 /* only show the publish check box if we are a
2285 member of a AD domain */
2287 if (lp_security() == SEC_ADS) {
2295 if (!StrCaseCmp(value, "DNSMachineName")) {
2296 const char *hostname = get_mydnsfullname();
2299 return WERR_BADFILE;
2303 data->string = talloc_strdup(mem_ctx, hostname);
2304 W_ERROR_HAVE_NO_MEMORY(data->string);
2311 return WERR_INVALID_PARAM;
2314 /****************************************************************
2315 _spoolss_GetPrinterData
2316 ****************************************************************/
2318 WERROR _spoolss_GetPrinterData(pipes_struct *p,
2319 struct spoolss_GetPrinterData *r)
2321 struct spoolss_GetPrinterDataEx r2;
2323 r2.in.handle = r->in.handle;
2324 r2.in.key_name = "PrinterDriverData";
2325 r2.in.value_name = r->in.value_name;
2326 r2.in.offered = r->in.offered;
2327 r2.out.type = r->out.type;
2328 r2.out.data = r->out.data;
2329 r2.out.needed = r->out.needed;
2331 return _spoolss_GetPrinterDataEx(p, &r2);
2334 /*********************************************************
2335 Connect to the client machine.
2336 **********************************************************/
2338 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2339 struct sockaddr_storage *client_ss, const char *remote_machine)
2342 struct cli_state *the_cli;
2343 struct sockaddr_storage rm_addr;
2344 char addr[INET6_ADDRSTRLEN];
2346 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2347 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2349 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2350 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2353 print_sockaddr(addr, sizeof(addr), &rm_addr);
2355 rm_addr = *client_ss;
2356 print_sockaddr(addr, sizeof(addr), &rm_addr);
2357 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2361 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2362 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2367 /* setup the connection */
2368 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2369 &rm_addr, 0, "IPC$", "IPC",
2373 0, lp_client_signing(), NULL );
2375 if ( !NT_STATUS_IS_OK( ret ) ) {
2376 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2381 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2382 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2383 cli_shutdown(the_cli);
2388 * Ok - we have an anonymous connection to the IPC$ share.
2389 * Now start the NT Domain stuff :-).
2392 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2393 if (!NT_STATUS_IS_OK(ret)) {
2394 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2395 remote_machine, nt_errstr(ret)));
2396 cli_shutdown(the_cli);
2403 /***************************************************************************
2404 Connect to the client.
2405 ****************************************************************************/
2407 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2408 uint32_t localprinter, uint32_t type,
2409 struct policy_handle *handle,
2410 struct sockaddr_storage *client_ss)
2416 * If it's the first connection, contact the client
2417 * and connect to the IPC$ share anonymously
2419 if (smb_connections==0) {
2420 fstring unix_printer;
2422 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2424 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2427 messaging_register(smbd_messaging_context(), NULL,
2428 MSG_PRINTER_NOTIFY2,
2429 receive_notify2_message_list);
2430 /* Tell the connections db we're now interested in printer
2431 * notify messages. */
2432 register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
2436 * Tell the specific printing tdb we want messages for this printer
2437 * by registering our PID.
2440 if (!print_notify_register_pid(snum))
2441 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2445 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2453 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2454 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2455 win_errstr(result)));
2457 return (W_ERROR_IS_OK(result));
2460 /****************************************************************
2461 ****************************************************************/
2463 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2464 const struct spoolss_NotifyOption *r)
2466 struct spoolss_NotifyOption *option;
2473 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2480 if (!option->count) {
2484 option->types = talloc_zero_array(option,
2485 struct spoolss_NotifyOptionType, option->count);
2486 if (!option->types) {
2487 talloc_free(option);
2491 for (i=0; i < option->count; i++) {
2492 option->types[i] = r->types[i];
2494 if (option->types[i].count) {
2495 option->types[i].fields = talloc_zero_array(option,
2496 union spoolss_Field, option->types[i].count);
2497 if (!option->types[i].fields) {
2498 talloc_free(option);
2501 for (k=0; k<option->types[i].count; k++) {
2502 option->types[i].fields[k] =
2503 r->types[i].fields[k];
2511 /****************************************************************
2512 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2514 * before replying OK: status=0 a rpc call is made to the workstation
2515 * asking ReplyOpenPrinter
2517 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2518 * called from api_spoolss_rffpcnex
2519 ****************************************************************/
2521 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2522 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2525 struct spoolss_NotifyOption *option = r->in.notify_options;
2526 struct sockaddr_storage client_ss;
2528 /* store the notify value in the printer struct */
2530 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2533 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2534 "Invalid handle (%s:%u:%u).\n",
2535 OUR_HANDLE(r->in.handle)));
2539 Printer->notify.flags = r->in.flags;
2540 Printer->notify.options = r->in.options;
2541 Printer->notify.printerlocal = r->in.printer_local;
2543 TALLOC_FREE(Printer->notify.option);
2544 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2546 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2548 /* Connect to the client machine and send a ReplyOpenPrinter */
2550 if ( Printer->printer_type == SPLHND_SERVER)
2552 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2553 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2556 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2557 "client_address is %s\n", p->client_address));
2559 if (!interpret_string_addr(&client_ss, p->client_address,
2561 return WERR_SERVER_UNAVAILABLE;
2564 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2565 Printer->notify.printerlocal, 1,
2566 &Printer->notify.client_hnd, &client_ss))
2567 return WERR_SERVER_UNAVAILABLE;
2569 Printer->notify.client_connected = true;
2574 /*******************************************************************
2575 * fill a notify_info_data with the servername
2576 ********************************************************************/
2578 void spoolss_notify_server_name(int snum,
2579 struct spoolss_Notify *data,
2580 print_queue_struct *queue,
2581 NT_PRINTER_INFO_LEVEL *printer,
2582 TALLOC_CTX *mem_ctx)
2584 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2587 /*******************************************************************
2588 * fill a notify_info_data with the printername (not including the servername).
2589 ********************************************************************/
2591 void spoolss_notify_printer_name(int snum,
2592 struct spoolss_Notify *data,
2593 print_queue_struct *queue,
2594 NT_PRINTER_INFO_LEVEL *printer,
2595 TALLOC_CTX *mem_ctx)
2597 /* the notify name should not contain the \\server\ part */
2598 char *p = strrchr(printer->info_2->printername, '\\');
2601 p = printer->info_2->printername;
2606 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2609 /*******************************************************************
2610 * fill a notify_info_data with the servicename
2611 ********************************************************************/
2613 void spoolss_notify_share_name(int snum,
2614 struct spoolss_Notify *data,
2615 print_queue_struct *queue,
2616 NT_PRINTER_INFO_LEVEL *printer,
2617 TALLOC_CTX *mem_ctx)
2619 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2622 /*******************************************************************
2623 * fill a notify_info_data with the port name
2624 ********************************************************************/
2626 void spoolss_notify_port_name(int snum,
2627 struct spoolss_Notify *data,
2628 print_queue_struct *queue,
2629 NT_PRINTER_INFO_LEVEL *printer,
2630 TALLOC_CTX *mem_ctx)
2632 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2635 /*******************************************************************
2636 * fill a notify_info_data with the printername
2637 * but it doesn't exist, have to see what to do
2638 ********************************************************************/
2640 void spoolss_notify_driver_name(int snum,
2641 struct spoolss_Notify *data,
2642 print_queue_struct *queue,
2643 NT_PRINTER_INFO_LEVEL *printer,
2644 TALLOC_CTX *mem_ctx)
2646 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2649 /*******************************************************************
2650 * fill a notify_info_data with the comment
2651 ********************************************************************/
2653 void spoolss_notify_comment(int snum,
2654 struct spoolss_Notify *data,
2655 print_queue_struct *queue,
2656 NT_PRINTER_INFO_LEVEL *printer,
2657 TALLOC_CTX *mem_ctx)
2661 if (*printer->info_2->comment == '\0') {
2662 p = lp_comment(snum);
2664 p = printer->info_2->comment;
2667 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
2670 /*******************************************************************
2671 * fill a notify_info_data with the comment
2672 * location = "Room 1, floor 2, building 3"
2673 ********************************************************************/
2675 void spoolss_notify_location(int snum,
2676 struct spoolss_Notify *data,
2677 print_queue_struct *queue,
2678 NT_PRINTER_INFO_LEVEL *printer,
2679 TALLOC_CTX *mem_ctx)
2681 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
2684 /*******************************************************************
2685 * fill a notify_info_data with the device mode
2686 * jfm:xxxx don't to it for know but that's a real problem !!!
2687 ********************************************************************/
2689 static void spoolss_notify_devmode(int snum,
2690 struct spoolss_Notify *data,
2691 print_queue_struct *queue,
2692 NT_PRINTER_INFO_LEVEL *printer,
2693 TALLOC_CTX *mem_ctx)
2695 /* for a dummy implementation we have to zero the fields */
2696 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2699 /*******************************************************************
2700 * fill a notify_info_data with the separator file name
2701 ********************************************************************/
2703 void spoolss_notify_sepfile(int snum,
2704 struct spoolss_Notify *data,
2705 print_queue_struct *queue,
2706 NT_PRINTER_INFO_LEVEL *printer,
2707 TALLOC_CTX *mem_ctx)
2709 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
2712 /*******************************************************************
2713 * fill a notify_info_data with the print processor
2714 * jfm:xxxx return always winprint to indicate we don't do anything to it
2715 ********************************************************************/
2717 void spoolss_notify_print_processor(int snum,
2718 struct spoolss_Notify *data,
2719 print_queue_struct *queue,
2720 NT_PRINTER_INFO_LEVEL *printer,
2721 TALLOC_CTX *mem_ctx)
2723 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
2726 /*******************************************************************
2727 * fill a notify_info_data with the print processor options
2728 * jfm:xxxx send an empty string
2729 ********************************************************************/
2731 void spoolss_notify_parameters(int snum,
2732 struct spoolss_Notify *data,
2733 print_queue_struct *queue,
2734 NT_PRINTER_INFO_LEVEL *printer,
2735 TALLOC_CTX *mem_ctx)
2737 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
2740 /*******************************************************************
2741 * fill a notify_info_data with the data type
2742 * jfm:xxxx always send RAW as data type
2743 ********************************************************************/
2745 void spoolss_notify_datatype(int snum,
2746 struct spoolss_Notify *data,
2747 print_queue_struct *queue,
2748 NT_PRINTER_INFO_LEVEL *printer,
2749 TALLOC_CTX *mem_ctx)
2751 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
2754 /*******************************************************************
2755 * fill a notify_info_data with the security descriptor
2756 * jfm:xxxx send an null pointer to say no security desc
2757 * have to implement security before !
2758 ********************************************************************/
2760 static void spoolss_notify_security_desc(int snum,
2761 struct spoolss_Notify *data,
2762 print_queue_struct *queue,
2763 NT_PRINTER_INFO_LEVEL *printer,
2764 TALLOC_CTX *mem_ctx)
2766 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
2767 printer->info_2->secdesc_buf->sd_size,
2768 printer->info_2->secdesc_buf->sd);
2771 /*******************************************************************
2772 * fill a notify_info_data with the attributes
2773 * jfm:xxxx a samba printer is always shared
2774 ********************************************************************/
2776 void spoolss_notify_attributes(int snum,
2777 struct spoolss_Notify *data,
2778 print_queue_struct *queue,
2779 NT_PRINTER_INFO_LEVEL *printer,
2780 TALLOC_CTX *mem_ctx)
2782 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
2785 /*******************************************************************
2786 * fill a notify_info_data with the priority
2787 ********************************************************************/
2789 static void spoolss_notify_priority(int snum,
2790 struct spoolss_Notify *data,
2791 print_queue_struct *queue,
2792 NT_PRINTER_INFO_LEVEL *printer,
2793 TALLOC_CTX *mem_ctx)
2795 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
2798 /*******************************************************************
2799 * fill a notify_info_data with the default priority
2800 ********************************************************************/
2802 static void spoolss_notify_default_priority(int snum,
2803 struct spoolss_Notify *data,
2804 print_queue_struct *queue,
2805 NT_PRINTER_INFO_LEVEL *printer,
2806 TALLOC_CTX *mem_ctx)
2808 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
2811 /*******************************************************************
2812 * fill a notify_info_data with the start time
2813 ********************************************************************/
2815 static void spoolss_notify_start_time(int snum,
2816 struct spoolss_Notify *data,
2817 print_queue_struct *queue,
2818 NT_PRINTER_INFO_LEVEL *printer,
2819 TALLOC_CTX *mem_ctx)
2821 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
2824 /*******************************************************************
2825 * fill a notify_info_data with the until time
2826 ********************************************************************/
2828 static void spoolss_notify_until_time(int snum,
2829 struct spoolss_Notify *data,
2830 print_queue_struct *queue,
2831 NT_PRINTER_INFO_LEVEL *printer,
2832 TALLOC_CTX *mem_ctx)
2834 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
2837 /*******************************************************************
2838 * fill a notify_info_data with the status
2839 ********************************************************************/
2841 static void spoolss_notify_status(int snum,
2842 struct spoolss_Notify *data,
2843 print_queue_struct *queue,
2844 NT_PRINTER_INFO_LEVEL *printer,
2845 TALLOC_CTX *mem_ctx)
2847 print_status_struct status;
2849 print_queue_length(snum, &status);
2850 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2853 /*******************************************************************
2854 * fill a notify_info_data with the number of jobs queued
2855 ********************************************************************/
2857 void spoolss_notify_cjobs(int snum,
2858 struct spoolss_Notify *data,
2859 print_queue_struct *queue,
2860 NT_PRINTER_INFO_LEVEL *printer,
2861 TALLOC_CTX *mem_ctx)
2863 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2866 /*******************************************************************
2867 * fill a notify_info_data with the average ppm
2868 ********************************************************************/
2870 static void spoolss_notify_average_ppm(int snum,
2871 struct spoolss_Notify *data,
2872 print_queue_struct *queue,
2873 NT_PRINTER_INFO_LEVEL *printer,
2874 TALLOC_CTX *mem_ctx)
2876 /* always respond 8 pages per minutes */
2877 /* a little hard ! */
2878 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
2881 /*******************************************************************
2882 * fill a notify_info_data with username
2883 ********************************************************************/
2885 static void spoolss_notify_username(int snum,
2886 struct spoolss_Notify *data,
2887 print_queue_struct *queue,
2888 NT_PRINTER_INFO_LEVEL *printer,
2889 TALLOC_CTX *mem_ctx)
2891 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2894 /*******************************************************************
2895 * fill a notify_info_data with job status
2896 ********************************************************************/
2898 static void spoolss_notify_job_status(int snum,
2899 struct spoolss_Notify *data,
2900 print_queue_struct *queue,
2901 NT_PRINTER_INFO_LEVEL *printer,
2902 TALLOC_CTX *mem_ctx)
2904 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2907 /*******************************************************************
2908 * fill a notify_info_data with job name
2909 ********************************************************************/
2911 static void spoolss_notify_job_name(int snum,
2912 struct spoolss_Notify *data,
2913 print_queue_struct *queue,
2914 NT_PRINTER_INFO_LEVEL *printer,
2915 TALLOC_CTX *mem_ctx)
2917 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2920 /*******************************************************************
2921 * fill a notify_info_data with job status
2922 ********************************************************************/
2924 static void spoolss_notify_job_status_string(int snum,
2925 struct spoolss_Notify *data,
2926 print_queue_struct *queue,
2927 NT_PRINTER_INFO_LEVEL *printer,
2928 TALLOC_CTX *mem_ctx)
2931 * Now we're returning job status codes we just return a "" here. JRA.
2936 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2939 switch (queue->status) {
2944 p = ""; /* NT provides the paused string */
2953 #endif /* NO LONGER NEEDED. */
2955 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2958 /*******************************************************************
2959 * fill a notify_info_data with job time
2960 ********************************************************************/
2962 static void spoolss_notify_job_time(int snum,
2963 struct spoolss_Notify *data,
2964 print_queue_struct *queue,
2965 NT_PRINTER_INFO_LEVEL *printer,
2966 TALLOC_CTX *mem_ctx)
2968 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2971 /*******************************************************************
2972 * fill a notify_info_data with job size
2973 ********************************************************************/
2975 static void spoolss_notify_job_size(int snum,
2976 struct spoolss_Notify *data,
2977 print_queue_struct *queue,
2978 NT_PRINTER_INFO_LEVEL *printer,
2979 TALLOC_CTX *mem_ctx)
2981 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2984 /*******************************************************************
2985 * fill a notify_info_data with page info
2986 ********************************************************************/
2987 static void spoolss_notify_total_pages(int snum,
2988 struct spoolss_Notify *data,
2989 print_queue_struct *queue,
2990 NT_PRINTER_INFO_LEVEL *printer,
2991 TALLOC_CTX *mem_ctx)
2993 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2996 /*******************************************************************
2997 * fill a notify_info_data with pages printed info.
2998 ********************************************************************/
2999 static void spoolss_notify_pages_printed(int snum,
3000 struct spoolss_Notify *data,
3001 print_queue_struct *queue,
3002 NT_PRINTER_INFO_LEVEL *printer,
3003 TALLOC_CTX *mem_ctx)
3005 /* Add code when back-end tracks this */
3006 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3009 /*******************************************************************
3010 Fill a notify_info_data with job position.
3011 ********************************************************************/
3013 static void spoolss_notify_job_position(int snum,
3014 struct spoolss_Notify *data,
3015 print_queue_struct *queue,
3016 NT_PRINTER_INFO_LEVEL *printer,
3017 TALLOC_CTX *mem_ctx)
3019 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3022 /*******************************************************************
3023 Fill a notify_info_data with submitted time.
3024 ********************************************************************/
3026 static void spoolss_notify_submitted_time(int snum,
3027 struct spoolss_Notify *data,
3028 print_queue_struct *queue,
3029 NT_PRINTER_INFO_LEVEL *printer,
3030 TALLOC_CTX *mem_ctx)
3032 data->data.string.string = NULL;
3033 data->data.string.size = 0;
3035 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3036 &data->data.string.string,
3037 &data->data.string.size);
3041 struct s_notify_info_data_table
3043 enum spoolss_NotifyType type;
3046 enum spoolss_NotifyTable variable_type;
3047 void (*fn) (int snum, struct spoolss_Notify *data,
3048 print_queue_struct *queue,
3049 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3052 /* A table describing the various print notification constants and
3053 whether the notification data is a pointer to a variable sized
3054 buffer, a one value uint32_t or a two value uint32_t. */
3056 static const struct s_notify_info_data_table notify_info_data_table[] =
3058 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3059 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3060 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3061 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3062 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3063 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3064 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3065 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3066 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3067 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3068 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3069 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3070 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3071 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3081 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3082 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3083 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3084 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3085 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3086 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3087 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3088 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3089 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3090 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3091 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3092 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3093 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3094 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3095 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3096 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3097 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3098 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3099 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3100 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3101 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3102 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3103 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3104 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3105 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3106 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3109 /*******************************************************************
3110 Return the variable_type of info_data structure.
3111 ********************************************************************/
3113 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3118 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3119 if ( (notify_info_data_table[i].type == type) &&
3120 (notify_info_data_table[i].field == field) ) {
3121 return notify_info_data_table[i].variable_type;
3125 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3130 /****************************************************************************
3131 ****************************************************************************/
3133 static bool search_notify(enum spoolss_NotifyType type,
3139 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3140 if (notify_info_data_table[i].type == type &&
3141 notify_info_data_table[i].field == field &&
3142 notify_info_data_table[i].fn != NULL) {
3151 /****************************************************************************
3152 ****************************************************************************/
3154 void construct_info_data(struct spoolss_Notify *info_data,
3155 enum spoolss_NotifyType type,
3159 info_data->type = type;
3160 info_data->field.field = field;
3161 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3162 info_data->job_id = id;
3165 /*******************************************************************
3167 * fill a notify_info struct with info asked
3169 ********************************************************************/
3171 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3172 struct spoolss_NotifyInfo *info,
3174 const struct spoolss_NotifyOptionType *option_type,
3176 TALLOC_CTX *mem_ctx)
3179 enum spoolss_NotifyType type;
3182 struct spoolss_Notify *current_data;
3183 NT_PRINTER_INFO_LEVEL *printer = NULL;
3184 print_queue_struct *queue=NULL;
3186 type = option_type->type;
3188 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3189 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3190 option_type->count, lp_servicename(snum)));
3192 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3195 for(field_num=0; field_num < option_type->count; field_num++) {
3196 field = option_type->fields[field_num].field;
3198 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3200 if (!search_notify(type, field, &j) )
3203 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3204 struct spoolss_Notify,
3206 if (info->notifies == NULL) {
3207 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3208 free_a_printer(&printer, 2);
3212 current_data = &info->notifies[info->count];
3214 construct_info_data(current_data, type, field, id);
3216 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3217 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3219 notify_info_data_table[j].fn(snum, current_data, queue,
3225 free_a_printer(&printer, 2);
3229 /*******************************************************************
3231 * fill a notify_info struct with info asked
3233 ********************************************************************/
3235 static bool construct_notify_jobs_info(print_queue_struct *queue,
3236 struct spoolss_NotifyInfo *info,
3237 NT_PRINTER_INFO_LEVEL *printer,
3239 const struct spoolss_NotifyOptionType *option_type,
3241 TALLOC_CTX *mem_ctx)
3244 enum spoolss_NotifyType type;
3246 struct spoolss_Notify *current_data;
3248 DEBUG(4,("construct_notify_jobs_info\n"));
3250 type = option_type->type;
3252 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3253 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3254 option_type->count));
3256 for(field_num=0; field_num<option_type->count; field_num++) {
3257 field = option_type->fields[field_num].field;
3259 if (!search_notify(type, field, &j) )
3262 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3263 struct spoolss_Notify,
3265 if (info->notifies == NULL) {
3266 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3270 current_data=&(info->notifies[info->count]);
3272 construct_info_data(current_data, type, field, id);
3273 notify_info_data_table[j].fn(snum, current_data, queue,
3282 * JFM: The enumeration is not that simple, it's even non obvious.
3284 * let's take an example: I want to monitor the PRINTER SERVER for
3285 * the printer's name and the number of jobs currently queued.
3286 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3287 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3289 * I have 3 printers on the back of my server.
3291 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3294 * 1 printer 1 name 1
3295 * 2 printer 1 cjob 1
3296 * 3 printer 2 name 2
3297 * 4 printer 2 cjob 2
3298 * 5 printer 3 name 3
3299 * 6 printer 3 name 3
3301 * that's the print server case, the printer case is even worse.
3304 /*******************************************************************
3306 * enumerate all printers on the printserver
3307 * fill a notify_info struct with info asked
3309 ********************************************************************/
3311 static WERROR printserver_notify_info(pipes_struct *p,
3312 struct policy_handle *hnd,
3313 struct spoolss_NotifyInfo *info,
3314 TALLOC_CTX *mem_ctx)
3317 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3318 int n_services=lp_numservices();
3320 struct spoolss_NotifyOption *option;
3321 struct spoolss_NotifyOptionType option_type;
3323 DEBUG(4,("printserver_notify_info\n"));
3328 option = Printer->notify.option;
3331 info->notifies = NULL;
3334 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3335 sending a ffpcn() request first */
3340 for (i=0; i<option->count; i++) {
3341 option_type = option->types[i];
3343 if (option_type.type != PRINTER_NOTIFY_TYPE)
3346 for (snum=0; snum<n_services; snum++)
3348 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3349 construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3355 * Debugging information, don't delete.
3358 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3359 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3360 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3362 for (i=0; i<info->count; i++) {
3363 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3364 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3365 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3372 /*******************************************************************
3374 * fill a notify_info struct with info asked
3376 ********************************************************************/
3378 static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3379 struct spoolss_NotifyInfo *info,
3380 TALLOC_CTX *mem_ctx)
3383 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3386 struct spoolss_NotifyOption *option;
3387 struct spoolss_NotifyOptionType option_type;
3389 print_queue_struct *queue=NULL;
3390 print_status_struct status;
3392 DEBUG(4,("printer_notify_info\n"));
3397 option = Printer->notify.option;
3401 info->notifies = NULL;
3404 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3405 sending a ffpcn() request first */
3410 get_printer_snum(p, hnd, &snum, NULL);
3412 for (i=0; i<option->count; i++) {
3413 option_type = option->types[i];
3415 switch (option_type.type) {
3416 case PRINTER_NOTIFY_TYPE:
3417 if(construct_notify_printer_info(Printer, info, snum,
3423 case JOB_NOTIFY_TYPE: {
3424 NT_PRINTER_INFO_LEVEL *printer = NULL;
3426 count = print_queue_status(snum, &queue, &status);
3428 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3431 for (j=0; j<count; j++) {
3432 construct_notify_jobs_info(&queue[j], info,
3439 free_a_printer(&printer, 2);
3449 * Debugging information, don't delete.
3452 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3453 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3454 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3456 for (i=0; i<info->count; i++) {
3457 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3458 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3459 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3465 /****************************************************************
3466 _spoolss_RouterRefreshPrinterChangeNotify
3467 ****************************************************************/
3469 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3470 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3472 struct spoolss_NotifyInfo *info;
3474 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3475 WERROR result = WERR_BADFID;
3477 /* we always have a spoolss_NotifyInfo struct */
3478 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3480 result = WERR_NOMEM;
3484 *r->out.info = info;
3487 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3488 "Invalid handle (%s:%u:%u).\n",
3489 OUR_HANDLE(r->in.handle)));
3493 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3496 * We are now using the change value, and
3497 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3498 * I don't have a global notification system, I'm sending back all the
3499 * informations even when _NOTHING_ has changed.
3502 /* We need to keep track of the change value to send back in
3503 RRPCN replies otherwise our updates are ignored. */
3505 Printer->notify.fnpcn = true;
3507 if (Printer->notify.client_connected) {
3508 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3509 "Saving change value in request [%x]\n",
3511 Printer->notify.change = r->in.change_low;
3514 /* just ignore the spoolss_NotifyOption */
3516 switch (Printer->printer_type) {
3518 result = printserver_notify_info(p, r->in.handle,
3522 case SPLHND_PRINTER:
3523 result = printer_notify_info(p, r->in.handle,
3528 Printer->notify.fnpcn = false;
3534 /********************************************************************
3535 * construct_printer_info_0
3536 * fill a printer_info_0 struct
3537 ********************************************************************/
3539 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3540 const NT_PRINTER_INFO_LEVEL *ntprinter,
3541 struct spoolss_PrinterInfo0 *r,
3545 counter_printer_0 *session_counter;
3547 print_status_struct status;
3549 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3550 W_ERROR_HAVE_NO_MEMORY(r->printername);
3552 r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3553 W_ERROR_HAVE_NO_MEMORY(r->servername);
3555 count = print_queue_length(snum, &status);
3557 /* check if we already have a counter for this printer */
3558 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3559 if (session_counter->snum == snum)
3563 /* it's the first time, add it to the list */
3564 if (session_counter == NULL) {
3565 session_counter = SMB_MALLOC_P(counter_printer_0);
3566 W_ERROR_HAVE_NO_MEMORY(session_counter);
3567 ZERO_STRUCTP(session_counter);
3568 session_counter->snum = snum;
3569 session_counter->counter = 0;
3570 DLIST_ADD(counter_list, session_counter);
3574 session_counter->counter++;
3580 setuptime = (time_t)ntprinter->info_2->setuptime;
3582 init_systemtime(&r->time, gmtime(&setuptime));
3585 * the global_counter should be stored in a TDB as it's common to all the clients
3586 * and should be zeroed on samba startup
3588 r->global_counter = session_counter->counter;
3590 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3591 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3592 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3593 r->free_build = SPOOLSS_RELEASE_BUILD;
3595 r->max_spooling = 0;
3596 r->session_counter = session_counter->counter;
3597 r->num_error_out_of_paper = 0x0;
3598 r->num_error_not_ready = 0x0; /* number of print failure */
3600 r->number_of_processors = 0x1;
3601 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3602 r->high_part_total_bytes = 0x0;
3603 r->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3604 r->last_error = WERR_OK;
3605 r->status = nt_printq_status(status.status);
3606 r->enumerate_network_printers = 0x0;
3607 r->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3608 r->processor_architecture = 0x0;
3609 r->processor_level = 0x6; /* 6 ???*/
3617 /****************************************************************************
3618 Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers
3619 should be valid upon entry
3620 ****************************************************************************/
3622 static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
3623 struct spoolss_DeviceMode *r,
3624 const NT_DEVICEMODE *ntdevmode)
3626 if (!r || !ntdevmode) {
3627 return WERR_INVALID_PARAM;
3630 r->devicename = talloc_strdup(mem_ctx, ntdevmode->devicename);
3631 W_ERROR_HAVE_NO_MEMORY(r->devicename);
3633 r->specversion = ntdevmode->specversion;
3634 r->driverversion = ntdevmode->driverversion;
3635 r->size = ntdevmode->size;
3636 r->__driverextra_length = ntdevmode->driverextra;
3637 r->fields = ntdevmode->fields;
3639 r->orientation = ntdevmode->orientation;
3640 r->papersize = ntdevmode->papersize;
3641 r->paperlength = ntdevmode->paperlength;
3642 r->paperwidth = ntdevmode->paperwidth;
3643 r->scale = ntdevmode->scale;
3644 r->copies = ntdevmode->copies;
3645 r->defaultsource = ntdevmode->defaultsource;
3646 r->printquality = ntdevmode->printquality;
3647 r->color = ntdevmode->color;
3648 r->duplex = ntdevmode->duplex;
3649 r->yresolution = ntdevmode->yresolution;
3650 r->ttoption = ntdevmode->ttoption;
3651 r->collate = ntdevmode->collate;
3653 r->formname = talloc_strdup(mem_ctx, ntdevmode->formname);
3654 W_ERROR_HAVE_NO_MEMORY(r->formname);
3656 r->logpixels = ntdevmode->logpixels;
3657 r->bitsperpel = ntdevmode->bitsperpel;
3658 r->pelswidth = ntdevmode->pelswidth;
3659 r->pelsheight = ntdevmode->pelsheight;
3660 r->displayflags = ntdevmode->displayflags;
3661 r->displayfrequency = ntdevmode->displayfrequency;
3662 r->icmmethod = ntdevmode->icmmethod;
3663 r->icmintent = ntdevmode->icmintent;
3664 r->mediatype = ntdevmode->mediatype;
3665 r->dithertype = ntdevmode->dithertype;
3666 r->reserved1 = ntdevmode->reserved1;
3667 r->reserved2 = ntdevmode->reserved2;
3668 r->panningwidth = ntdevmode->panningwidth;
3669 r->panningheight = ntdevmode->panningheight;
3671 if (ntdevmode->nt_dev_private != NULL) {
3672 r->driverextra_data = data_blob_talloc(mem_ctx,
3673 ntdevmode->nt_dev_private,
3674 ntdevmode->driverextra);
3675 W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
3682 /****************************************************************************
3683 Create a spoolss_DeviceMode struct. Returns talloced memory.
3684 ****************************************************************************/
3686 struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
3687 const char *servicename)
3690 NT_PRINTER_INFO_LEVEL *printer = NULL;
3691 struct spoolss_DeviceMode *devmode = NULL;
3693 DEBUG(7,("construct_dev_mode\n"));
3695 DEBUGADD(8,("getting printer characteristics\n"));
3697 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
3700 if (!printer->info_2->devmode) {
3701 DEBUG(5, ("BONG! There was no device mode!\n"));
3705 devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
3707 DEBUG(2,("construct_dev_mode: talloc fail.\n"));
3711 DEBUGADD(8,("loading DEVICEMODE\n"));
3713 result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode);
3714 if (!W_ERROR_IS_OK(result)) {
3715 TALLOC_FREE(devmode);
3719 free_a_printer(&printer,2);
3724 /********************************************************************
3725 * construct_printer_info1
3726 * fill a spoolss_PrinterInfo1 struct
3727 ********************************************************************/
3729 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3730 const NT_PRINTER_INFO_LEVEL *ntprinter,
3732 struct spoolss_PrinterInfo1 *r,
3737 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3738 ntprinter->info_2->printername,
3739 ntprinter->info_2->drivername,
3740 ntprinter->info_2->location);
3741 W_ERROR_HAVE_NO_MEMORY(r->description);
3743 if (*ntprinter->info_2->comment == '\0') {
3744 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3746 r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
3748 W_ERROR_HAVE_NO_MEMORY(r->comment);
3750 r->name = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3751 W_ERROR_HAVE_NO_MEMORY(r->name);
3756 /********************************************************************
3757 * construct_printer_info2
3758 * fill a spoolss_PrinterInfo2 struct
3759 ********************************************************************/
3761 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3762 const NT_PRINTER_INFO_LEVEL *ntprinter,
3763 struct spoolss_PrinterInfo2 *r,
3768 print_status_struct status;
3770 count = print_queue_length(snum, &status);
3772 r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3773 W_ERROR_HAVE_NO_MEMORY(r->servername);
3774 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3775 W_ERROR_HAVE_NO_MEMORY(r->printername);
3776 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3777 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3778 r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3779 W_ERROR_HAVE_NO_MEMORY(r->portname);
3780 r->drivername = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
3781 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3783 if (*ntprinter->info_2->comment == '\0') {
3784 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3786 r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
3788 W_ERROR_HAVE_NO_MEMORY(r->comment);
3790 r->location = talloc_strdup(mem_ctx, ntprinter->info_2->location);
3791 W_ERROR_HAVE_NO_MEMORY(r->location);
3792 r->sepfile = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
3793 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3794 r->printprocessor = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
3795 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3796 r->datatype = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
3797 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3798 r->parameters = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
3799 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3801 r->attributes = ntprinter->info_2->attributes;
3803 r->priority = ntprinter->info_2->priority;
3804 r->defaultpriority = ntprinter->info_2->default_priority;
3805 r->starttime = ntprinter->info_2->starttime;
3806 r->untiltime = ntprinter->info_2->untiltime;
3807 r->status = nt_printq_status(status.status);
3809 r->averageppm = ntprinter->info_2->averageppm;
3811 r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3813 DEBUG(8,("Returning NULL Devicemode!\n"));
3818 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3819 /* don't use talloc_steal() here unless you do a deep steal of all
3820 the SEC_DESC members */
3822 r->secdesc = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
3828 /********************************************************************
3829 * construct_printer_info3
3830 * fill a spoolss_PrinterInfo3 struct
3831 ********************************************************************/
3833 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3834 const NT_PRINTER_INFO_LEVEL *ntprinter,
3835 struct spoolss_PrinterInfo3 *r,
3838 /* These are the components of the SD we are returning. */
3840 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3841 /* don't use talloc_steal() here unless you do a deep steal of all
3842 the SEC_DESC members */
3844 r->secdesc = dup_sec_desc(mem_ctx,
3845 ntprinter->info_2->secdesc_buf->sd);
3846 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3852 /********************************************************************
3853 * construct_printer_info4
3854 * fill a spoolss_PrinterInfo4 struct
3855 ********************************************************************/
3857 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3858 const NT_PRINTER_INFO_LEVEL *ntprinter,
3859 struct spoolss_PrinterInfo4 *r,
3862 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3863 W_ERROR_HAVE_NO_MEMORY(r->printername);
3864 r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3865 W_ERROR_HAVE_NO_MEMORY(r->servername);
3867 r->attributes = ntprinter->info_2->attributes;
3872 /********************************************************************
3873 * construct_printer_info5
3874 * fill a spoolss_PrinterInfo5 struct
3875 ********************************************************************/
3877 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3878 const NT_PRINTER_INFO_LEVEL *ntprinter,
3879 struct spoolss_PrinterInfo5 *r,
3882 r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3883 W_ERROR_HAVE_NO_MEMORY(r->printername);
3884 r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3885 W_ERROR_HAVE_NO_MEMORY(r->portname);
3887 r->attributes = ntprinter->info_2->attributes;
3889 /* these two are not used by NT+ according to MSDN */
3891 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3892 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3897 /********************************************************************
3898 * construct_printer_info_6
3899 * fill a spoolss_PrinterInfo6 struct
3900 ********************************************************************/
3902 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3903 const NT_PRINTER_INFO_LEVEL *ntprinter,
3904 struct spoolss_PrinterInfo6 *r,
3908 print_status_struct status;
3910 count = print_queue_length(snum, &status);
3912 r->status = nt_printq_status(status.status);
3917 /********************************************************************
3918 * construct_printer_info7
3919 * fill a spoolss_PrinterInfo7 struct
3920 ********************************************************************/
3922 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3923 Printer_entry *print_hnd,
3924 struct spoolss_PrinterInfo7 *r,
3929 if (is_printer_published(print_hnd, snum, &guid)) {
3930 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3931 r->action = DSPRINT_PUBLISH;
3933 r->guid = talloc_strdup(mem_ctx, "");
3934 r->action = DSPRINT_UNPUBLISH;
3936 W_ERROR_HAVE_NO_MEMORY(r->guid);
3941 /********************************************************************
3942 * construct_printer_info8
3943 * fill a spoolss_PrinterInfo8 struct
3944 ********************************************************************/
3946 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3947 const NT_PRINTER_INFO_LEVEL *ntprinter,
3948 struct spoolss_DeviceModeInfo *r,
3951 r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3953 DEBUG(8,("Returning NULL Devicemode!\n"));
3960 /********************************************************************
3961 ********************************************************************/
3963 static bool snum_is_shared_printer(int snum)
3965 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3968 /********************************************************************
3969 Spoolss_enumprinters.
3970 ********************************************************************/
3972 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3975 union spoolss_PrinterInfo **info_p,
3979 int n_services = lp_numservices();
3980 union spoolss_PrinterInfo *info = NULL;
3982 WERROR result = WERR_OK;
3987 for (snum = 0; snum < n_services; snum++) {
3989 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3991 if (!snum_is_shared_printer(snum)) {
3995 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3996 lp_servicename(snum), snum));
3998 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3999 union spoolss_PrinterInfo,
4002 result = WERR_NOMEM;
4006 result = get_a_printer(NULL, &ntprinter, 2,
4007 lp_const_servicename(snum));
4008 if (!W_ERROR_IS_OK(result)) {
4014 result = construct_printer_info0(info, ntprinter,
4015 &info[count].info0, snum);
4018 result = construct_printer_info1(info, ntprinter, flags,
4019 &info[count].info1, snum);
4022 result = construct_printer_info2(info, ntprinter,
4023 &info[count].info2, snum);
4026 result = construct_printer_info4(info, ntprinter,
4027 &info[count].info4, snum);
4030 result = construct_printer_info5(info, ntprinter,
4031 &info[count].info5, snum);
4035 result = WERR_UNKNOWN_LEVEL;
4036 free_a_printer(&ntprinter, 2);
4040 free_a_printer(&ntprinter, 2);
4041 if (!W_ERROR_IS_OK(result)) {
4052 if (!W_ERROR_IS_OK(result)) {
4062 /********************************************************************
4063 * handle enumeration of printers at level 0
4064 ********************************************************************/
4066 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4068 const char *servername,
4069 union spoolss_PrinterInfo **info,
4072 DEBUG(4,("enum_all_printers_info_0\n"));
4074 return enum_all_printers_info_level(mem_ctx, 0, flags, info, count);
4078 /********************************************************************
4079 ********************************************************************/
4081 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4083 union spoolss_PrinterInfo **info,
4086 DEBUG(4,("enum_all_printers_info_1\n"));
4088 return enum_all_printers_info_level(mem_ctx, 1, flags, info, count);
4091 /********************************************************************
4092 enum_all_printers_info_1_local.
4093 *********************************************************************/
4095 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4096 union spoolss_PrinterInfo **info,
4099 DEBUG(4,("enum_all_printers_info_1_local\n"));
4101 return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4104 /********************************************************************
4105 enum_all_printers_info_1_name.
4106 *********************************************************************/
4108 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4110 union spoolss_PrinterInfo **info,
4113 const char *s = name;
4115 DEBUG(4,("enum_all_printers_info_1_name\n"));
4117 if ((name[0] == '\\') && (name[1] == '\\')) {
4121 if (!is_myname_or_ipaddr(s)) {
4122 return WERR_INVALID_NAME;
4125 return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4128 /********************************************************************
4129 enum_all_printers_info_1_network.
4130 *********************************************************************/
4132 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4134 union spoolss_PrinterInfo **info,
4137 const char *s = name;
4139 DEBUG(4,("enum_all_printers_info_1_network\n"));
4141 /* If we respond to a enum_printers level 1 on our name with flags
4142 set to PRINTER_ENUM_REMOTE with a list of printers then these
4143 printers incorrectly appear in the APW browse list.
4144 Specifically the printers for the server appear at the workgroup
4145 level where all the other servers in the domain are
4146 listed. Windows responds to this call with a
4147 WERR_CAN_NOT_COMPLETE so we should do the same. */
4149 if (name[0] == '\\' && name[1] == '\\') {
4153 if (is_myname_or_ipaddr(s)) {
4154 return WERR_CAN_NOT_COMPLETE;
4157 return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
4160 /********************************************************************
4161 * api_spoolss_enumprinters
4163 * called from api_spoolss_enumprinters (see this to understand)
4164 ********************************************************************/
4166 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4167 union spoolss_PrinterInfo **info,
4170 DEBUG(4,("enum_all_printers_info_2\n"));
4172 return enum_all_printers_info_level(mem_ctx, 2, 0, info, count);
4175 /********************************************************************
4176 * handle enumeration of printers at level 1
4177 ********************************************************************/
4179 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4182 union spoolss_PrinterInfo **info,
4185 /* Not all the flags are equals */
4187 if (flags & PRINTER_ENUM_LOCAL) {
4188 return enum_all_printers_info_1_local(mem_ctx, info, count);
4191 if (flags & PRINTER_ENUM_NAME) {
4192 return enum_all_printers_info_1_name(mem_ctx, name, info, count);
4195 if (flags & PRINTER_ENUM_NETWORK) {
4196 return enum_all_printers_info_1_network(mem_ctx, name, info, count);
4199 return WERR_OK; /* NT4sp5 does that */
4202 /********************************************************************
4203 * handle enumeration of printers at level 2
4204 ********************************************************************/
4206 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4208 const char *servername,
4209 union spoolss_PrinterInfo **info,
4212 if (flags & PRINTER_ENUM_LOCAL) {
4213 return enum_all_printers_info_2(mem_ctx, info, count);
4216 if (flags & PRINTER_ENUM_NAME) {
4217 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4218 return WERR_INVALID_NAME;
4221 return enum_all_printers_info_2(mem_ctx, info, count);
4224 if (flags & PRINTER_ENUM_REMOTE) {
4225 return WERR_UNKNOWN_LEVEL;
4231 /********************************************************************
4232 * handle enumeration of printers at level 4
4233 ********************************************************************/
4235 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4237 const char *servername,
4238 union spoolss_PrinterInfo **info,
4241 DEBUG(4,("enum_all_printers_info_4\n"));
4243 return enum_all_printers_info_level(mem_ctx, 4, flags, info, count);
4247 /********************************************************************
4248 * handle enumeration of printers at level 5
4249 ********************************************************************/
4251 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4253 const char *servername,
4254 union spoolss_PrinterInfo **info,
4257 DEBUG(4,("enum_all_printers_info_5\n"));
4259 return enum_all_printers_info_level(mem_ctx, 5, flags, info, count);
4262 /****************************************************************
4263 _spoolss_EnumPrinters
4264 ****************************************************************/
4266 WERROR _spoolss_EnumPrinters(pipes_struct *p,
4267 struct spoolss_EnumPrinters *r)
4269 const char *name = NULL;
4272 /* that's an [in out] buffer */
4274 if (!r->in.buffer && (r->in.offered != 0)) {
4275 return WERR_INVALID_PARAM;
4278 DEBUG(4,("_spoolss_EnumPrinters\n"));
4282 *r->out.info = NULL;
4286 * flags==PRINTER_ENUM_NAME
4287 * if name=="" then enumerates all printers
4288 * if name!="" then enumerate the printer
4289 * flags==PRINTER_ENUM_REMOTE
4290 * name is NULL, enumerate printers
4291 * Level 2: name!="" enumerates printers, name can't be NULL
4292 * Level 3: doesn't exist
4293 * Level 4: does a local registry lookup
4294 * Level 5: same as Level 2
4298 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4299 W_ERROR_HAVE_NO_MEMORY(name);
4302 switch (r->in.level) {
4304 result = enumprinters_level0(p->mem_ctx, r->in.flags, name,
4305 r->out.info, r->out.count);
4308 result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
4309 r->out.info, r->out.count);
4312 result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
4313 r->out.info, r->out.count);
4316 result = enumprinters_level4(p->mem_ctx, r->in.flags, name,
4317 r->out.info, r->out.count);
4320 result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
4321 r->out.info, r->out.count);
4324 return WERR_UNKNOWN_LEVEL;
4327 if (!W_ERROR_IS_OK(result)) {
4331 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4332 spoolss_EnumPrinters, NULL,
4333 *r->out.info, r->in.level,
4335 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4336 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4338 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4341 /****************************************************************
4343 ****************************************************************/
4345 WERROR _spoolss_GetPrinter(pipes_struct *p,
4346 struct spoolss_GetPrinter *r)
4348 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4349 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4350 WERROR result = WERR_OK;
4354 /* that's an [in out] buffer */
4356 if (!r->in.buffer && (r->in.offered != 0)) {
4357 return WERR_INVALID_PARAM;
4362 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4366 result = get_a_printer(Printer, &ntprinter, 2,
4367 lp_const_servicename(snum));
4368 if (!W_ERROR_IS_OK(result)) {
4372 switch (r->in.level) {
4374 result = construct_printer_info0(p->mem_ctx, ntprinter,
4375 &r->out.info->info0, snum);
4378 result = construct_printer_info1(p->mem_ctx, ntprinter,
4380 &r->out.info->info1, snum);
4383 result = construct_printer_info2(p->mem_ctx, ntprinter,
4384 &r->out.info->info2, snum);
4387 result = construct_printer_info3(p->mem_ctx, ntprinter,
4388 &r->out.info->info3, snum);
4391 result = construct_printer_info4(p->mem_ctx, ntprinter,
4392 &r->out.info->info4, snum);
4395 result = construct_printer_info5(p->mem_ctx, ntprinter,
4396 &r->out.info->info5, snum);
4399 result = construct_printer_info6(p->mem_ctx, ntprinter,
4400 &r->out.info->info6, snum);
4403 result = construct_printer_info7(p->mem_ctx, Printer,
4404 &r->out.info->info7, snum);
4407 result = construct_printer_info8(p->mem_ctx, ntprinter,
4408 &r->out.info->info8, snum);
4411 result = WERR_UNKNOWN_LEVEL;
4415 free_a_printer(&ntprinter, 2);
4417 if (!W_ERROR_IS_OK(result)) {
4418 TALLOC_FREE(r->out.info);
4422 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL,
4423 r->out.info, r->in.level);
4424 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4426 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4429 /********************************************************************
4430 ********************************************************************/
4432 static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4433 const char **string_array,
4434 const char *cservername)
4436 int i, num_strings = 0;
4437 const char **array = NULL;
4439 if (!string_array) {
4443 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4445 const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
4446 cservername, string_array[i]);
4453 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4460 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4461 &array, &num_strings);
4467 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4469 if (in && strlen(in)) { \
4470 out = talloc_strdup(mem_ctx, in); \
4471 W_ERROR_HAVE_NO_MEMORY(out); \
4477 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
4479 if (in && strlen(in)) { \
4480 out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
4482 out = talloc_strdup(mem_ctx, ""); \
4484 W_ERROR_HAVE_NO_MEMORY(out); \
4487 /********************************************************************
4488 * fill a spoolss_DriverInfo1 struct
4489 ********************************************************************/
4491 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4492 struct spoolss_DriverInfo1 *r,
4493 const struct spoolss_DriverInfo8 *driver,
4494 const char *servername)
4496 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4497 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4502 /********************************************************************
4503 * fill a spoolss_DriverInfo2 struct
4504 ********************************************************************/
4506 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4507 struct spoolss_DriverInfo2 *r,
4508 const struct spoolss_DriverInfo8 *driver,
4509 const char *servername)
4512 const char *cservername = canon_servername(servername);
4514 r->version = driver->version;
4516 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4517 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4518 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4519 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4521 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4522 driver->driver_path,
4525 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4529 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4530 driver->config_file,
4536 /********************************************************************
4537 * fill a spoolss_DriverInfo3 struct
4538 ********************************************************************/
4540 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4541 struct spoolss_DriverInfo3 *r,
4542 const struct spoolss_DriverInfo8 *driver,
4543 const char *servername)
4545 const char *cservername = canon_servername(servername);
4547 r->version = driver->version;
4549 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4550 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4551 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4552 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4554 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4555 driver->driver_path,
4558 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4562 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4563 driver->config_file,
4566 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4570 FILL_DRIVER_STRING(mem_ctx,
4571 driver->monitor_name,
4574 FILL_DRIVER_STRING(mem_ctx,
4575 driver->default_datatype,
4576 r->default_datatype);
4578 r->dependent_files = string_array_from_driver_info(mem_ctx,
4579 driver->dependent_files,
4584 /********************************************************************
4585 * fill a spoolss_DriverInfo4 struct
4586 ********************************************************************/
4588 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4589 struct spoolss_DriverInfo4 *r,
4590 const struct spoolss_DriverInfo8 *driver,
4591 const char *servername)
4593 const char *cservername = canon_servername(servername);
4595 r->version = driver->version;
4597 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4598 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4599 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4600 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4602 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4603 driver->driver_path,
4606 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4610 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4611 driver->config_file,
4614 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4618 r->dependent_files = string_array_from_driver_info(mem_ctx,
4619 driver->dependent_files,
4622 FILL_DRIVER_STRING(mem_ctx,
4623 driver->monitor_name,
4626 FILL_DRIVER_STRING(mem_ctx,
4627 driver->default_datatype,
4628 r->default_datatype);
4630 r->previous_names = string_array_from_driver_info(mem_ctx,
4631 driver->previous_names,
4637 /********************************************************************
4638 * fill a spoolss_DriverInfo5 struct
4639 ********************************************************************/
4641 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4642 struct spoolss_DriverInfo5 *r,
4643 const struct spoolss_DriverInfo8 *driver,
4644 const char *servername)
4646 const char *cservername = canon_servername(servername);
4648 r->version = driver->version;
4650 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4651 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4652 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4653 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4655 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4656 driver->driver_path,
4659 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4663 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4664 driver->config_file,
4667 r->driver_attributes = 0;
4668 r->config_version = 0;
4669 r->driver_version = 0;
4673 /********************************************************************
4674 * fill a spoolss_DriverInfo6 struct
4675 ********************************************************************/
4677 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4678 struct spoolss_DriverInfo6 *r,
4679 const struct spoolss_DriverInfo8 *driver,
4680 const char *servername)
4682 const char *cservername = canon_servername(servername);
4684 r->version = driver->version;
4686 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4687 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4688 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4689 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4691 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4692 driver->driver_path,
4695 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4699 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4700 driver->config_file,
4703 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4707 FILL_DRIVER_STRING(mem_ctx,
4708 driver->monitor_name,
4711 FILL_DRIVER_STRING(mem_ctx,
4712 driver->default_datatype,
4713 r->default_datatype);
4715 r->dependent_files = string_array_from_driver_info(mem_ctx,
4716 driver->dependent_files,
4718 r->previous_names = string_array_from_driver_info(mem_ctx,
4719 driver->previous_names,
4722 r->driver_date = driver->driver_date;
4723 r->driver_version = driver->driver_version;
4725 FILL_DRIVER_STRING(mem_ctx,
4726 driver->manufacturer_name,
4727 r->manufacturer_name);
4728 FILL_DRIVER_STRING(mem_ctx,
4729 driver->manufacturer_url,
4730 r->manufacturer_url);
4731 FILL_DRIVER_STRING(mem_ctx,
4732 driver->hardware_id,
4734 FILL_DRIVER_STRING(mem_ctx,
4741 /********************************************************************
4742 * fill a spoolss_DriverInfo8 struct
4743 ********************************************************************/
4745 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4746 struct spoolss_DriverInfo8 *r,
4747 const struct spoolss_DriverInfo8 *driver,
4748 const char *servername)
4750 const char *cservername = canon_servername(servername);
4752 r->version = driver->version;
4754 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4755 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4756 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4757 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4759 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4760 driver->driver_path,
4763 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4767 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4768 driver->config_file,
4771 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4775 FILL_DRIVER_STRING(mem_ctx,
4776 driver->monitor_name,
4779 FILL_DRIVER_STRING(mem_ctx,
4780 driver->default_datatype,
4781 r->default_datatype);
4783 r->dependent_files = string_array_from_driver_info(mem_ctx,
4784 driver->dependent_files,
4786 r->previous_names = string_array_from_driver_info(mem_ctx,
4787 driver->previous_names,
4790 r->driver_date = driver->driver_date;
4791 r->driver_version = driver->driver_version;
4793 FILL_DRIVER_STRING(mem_ctx,
4794 driver->manufacturer_name,
4795 r->manufacturer_name);
4796 FILL_DRIVER_STRING(mem_ctx,
4797 driver->manufacturer_url,
4798 r->manufacturer_url);
4799 FILL_DRIVER_STRING(mem_ctx,
4800 driver->hardware_id,
4802 FILL_DRIVER_STRING(mem_ctx,
4806 FILL_DRIVER_STRING(mem_ctx,
4807 driver->print_processor,
4808 r->print_processor);
4809 FILL_DRIVER_STRING(mem_ctx,
4810 driver->vendor_setup,
4813 r->color_profiles = string_array_from_driver_info(mem_ctx,
4814 driver->color_profiles,
4817 FILL_DRIVER_STRING(mem_ctx,
4821 r->printer_driver_attributes = driver->printer_driver_attributes;
4823 r->core_driver_dependencies = string_array_from_driver_info(mem_ctx,
4824 driver->core_driver_dependencies,
4827 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4828 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4833 #if 0 /* disabled until marshalling issues are resolved - gd */
4834 /********************************************************************
4835 ********************************************************************/
4837 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4838 struct spoolss_DriverFileInfo *r,
4839 const char *cservername,
4840 const char *file_name,
4841 enum spoolss_DriverFileType file_type,
4842 uint32_t file_version)
4844 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4845 cservername, file_name);
4846 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4847 r->file_type = file_type;
4848 r->file_version = file_version;
4853 /********************************************************************
4854 ********************************************************************/
4856 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4857 const struct spoolss_DriverInfo8 *driver,
4858 const char *cservername,
4859 struct spoolss_DriverFileInfo **info_p,
4862 struct spoolss_DriverFileInfo *info = NULL;
4870 if (strlen(driver->driver_path)) {
4871 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4872 struct spoolss_DriverFileInfo,
4874 W_ERROR_HAVE_NO_MEMORY(info);
4875 result = fill_spoolss_DriverFileInfo(info,
4878 driver->driver_path,
4879 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4881 W_ERROR_NOT_OK_RETURN(result);
4885 if (strlen(driver->config_file)) {
4886 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4887 struct spoolss_DriverFileInfo,
4889 W_ERROR_HAVE_NO_MEMORY(info);
4890 result = fill_spoolss_DriverFileInfo(info,
4893 driver->config_file,
4894 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4896 W_ERROR_NOT_OK_RETURN(result);
4900 if (strlen(driver->data_file)) {
4901 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4902 struct spoolss_DriverFileInfo,
4904 W_ERROR_HAVE_NO_MEMORY(info);
4905 result = fill_spoolss_DriverFileInfo(info,
4909 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4911 W_ERROR_NOT_OK_RETURN(result);
4915 if (strlen(driver->help_file)) {
4916 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4917 struct spoolss_DriverFileInfo,
4919 W_ERROR_HAVE_NO_MEMORY(info);
4920 result = fill_spoolss_DriverFileInfo(info,
4924 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4926 W_ERROR_NOT_OK_RETURN(result);
4930 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4931 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4932 struct spoolss_DriverFileInfo,
4934 W_ERROR_HAVE_NO_MEMORY(info);
4935 result = fill_spoolss_DriverFileInfo(info,
4938 driver->dependent_files[i],
4939 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4941 W_ERROR_NOT_OK_RETURN(result);
4951 /********************************************************************
4952 * fill a spoolss_DriverInfo101 struct
4953 ********************************************************************/
4955 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4956 struct spoolss_DriverInfo101 *r,
4957 const struct spoolss_DriverInfo8 *driver,
4958 const char *servername)
4960 const char *cservername = canon_servername(servername);
4963 r->version = driver->version;
4965 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4966 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4967 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4968 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4970 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4974 if (!W_ERROR_IS_OK(result)) {
4978 FILL_DRIVER_STRING(mem_ctx,
4979 driver->monitor_name,
4982 FILL_DRIVER_STRING(mem_ctx,
4983 driver->default_datatype,
4984 r->default_datatype);
4986 r->previous_names = string_array_from_driver_info(mem_ctx,
4987 driver->previous_names,
4989 r->driver_date = driver->driver_date;
4990 r->driver_version = driver->driver_version;
4992 FILL_DRIVER_STRING(mem_ctx,
4993 driver->manufacturer_name,
4994 r->manufacturer_name);
4995 FILL_DRIVER_STRING(mem_ctx,
4996 driver->manufacturer_url,
4997 r->manufacturer_url);
4998 FILL_DRIVER_STRING(mem_ctx,
4999 driver->hardware_id,
5001 FILL_DRIVER_STRING(mem_ctx,
5008 /********************************************************************
5009 ********************************************************************/
5011 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5013 union spoolss_DriverInfo *r,
5015 const char *servername,
5016 const char *architecture,
5019 NT_PRINTER_INFO_LEVEL *printer = NULL;
5020 struct spoolss_DriverInfo8 *driver;
5023 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
5025 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5026 win_errstr(result)));
5028 if (!W_ERROR_IS_OK(result)) {
5029 return WERR_INVALID_PRINTER_NAME;
5032 result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5033 architecture, version);
5035 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5036 win_errstr(result)));
5038 if (!W_ERROR_IS_OK(result)) {
5040 * Is this a W2k client ?
5044 free_a_printer(&printer, 2);
5045 return WERR_UNKNOWN_PRINTER_DRIVER;
5048 /* Yes - try again with a WinNT driver. */
5050 result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5051 architecture, version);
5052 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5053 win_errstr(result)));
5054 if (!W_ERROR_IS_OK(result)) {
5055 free_a_printer(&printer, 2);
5056 return WERR_UNKNOWN_PRINTER_DRIVER;
5062 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5065 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5068 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5071 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5074 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5077 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5080 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5082 #if 0 /* disabled until marshalling issues are resolved - gd */
5084 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5088 result = WERR_UNKNOWN_LEVEL;
5092 free_a_printer(&printer, 2);
5093 free_a_printer_driver(driver);
5098 /****************************************************************
5099 _spoolss_GetPrinterDriver2
5100 ****************************************************************/
5102 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5103 struct spoolss_GetPrinterDriver2 *r)
5105 Printer_entry *printer;
5108 const char *servername;
5111 /* that's an [in out] buffer */
5113 if (!r->in.buffer && (r->in.offered != 0)) {
5114 return WERR_INVALID_PARAM;
5117 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5119 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5120 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5121 return WERR_INVALID_PRINTER_NAME;
5125 *r->out.server_major_version = 0;
5126 *r->out.server_minor_version = 0;
5128 servername = get_server_name(printer);
5130 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5134 result = construct_printer_driver_info_level(p->mem_ctx, r->in.level,
5138 r->in.client_major_version);
5139 if (!W_ERROR_IS_OK(result)) {
5140 TALLOC_FREE(r->out.info);
5144 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL,
5145 r->out.info, r->in.level);
5146 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5148 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5152 /****************************************************************
5153 _spoolss_StartPagePrinter
5154 ****************************************************************/
5156 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5157 struct spoolss_StartPagePrinter *r)
5159 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5162 DEBUG(3,("_spoolss_StartPagePrinter: "
5163 "Error in startpageprinter printer handle\n"));
5167 Printer->page_started = true;
5171 /****************************************************************
5172 _spoolss_EndPagePrinter
5173 ****************************************************************/
5175 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5176 struct spoolss_EndPagePrinter *r)
5180 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5183 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5184 OUR_HANDLE(r->in.handle)));
5188 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5191 Printer->page_started = false;
5192 print_job_endpage(snum, Printer->jobid);
5197 /****************************************************************
5198 _spoolss_StartDocPrinter
5199 ****************************************************************/
5201 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5202 struct spoolss_StartDocPrinter *r)
5204 struct spoolss_DocumentInfo1 *info_1;
5206 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5209 DEBUG(2,("_spoolss_StartDocPrinter: "
5210 "Invalid handle (%s:%u:%u)\n",
5211 OUR_HANDLE(r->in.handle)));
5215 if (r->in.level != 1) {
5216 return WERR_UNKNOWN_LEVEL;
5219 info_1 = r->in.info.info1;
5222 * a nice thing with NT is it doesn't listen to what you tell it.
5223 * when asked to send _only_ RAW datas, it tries to send datas
5226 * So I add checks like in NT Server ...
5229 if (info_1->datatype) {
5230 if (strcmp(info_1->datatype, "RAW") != 0) {
5232 return WERR_INVALID_DATATYPE;
5236 /* get the share number of the printer */
5237 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5241 Printer->jobid = print_job_start(p->server_info, snum,
5242 info_1->document_name,
5243 Printer->nt_devmode);
5245 /* An error occured in print_job_start() so return an appropriate
5248 if (Printer->jobid == -1) {
5249 return map_werror_from_unix(errno);
5252 Printer->document_started = true;
5253 *r->out.job_id = Printer->jobid;
5258 /****************************************************************
5259 _spoolss_EndDocPrinter
5260 ****************************************************************/
5262 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5263 struct spoolss_EndDocPrinter *r)
5265 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5269 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5270 OUR_HANDLE(r->in.handle)));
5274 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5278 Printer->document_started = false;
5279 print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5280 /* error codes unhandled so far ... */
5285 /****************************************************************
5286 _spoolss_WritePrinter
5287 ****************************************************************/
5289 WERROR _spoolss_WritePrinter(pipes_struct *p,
5290 struct spoolss_WritePrinter *r)
5292 ssize_t buffer_written;
5294 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5297 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5298 OUR_HANDLE(r->in.handle)));
5299 *r->out.num_written = r->in._data_size;
5303 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5306 buffer_written = print_job_write(snum, Printer->jobid,
5307 (const char *)r->in.data.data,
5309 (size_t)r->in._data_size);
5310 if (buffer_written == (ssize_t)-1) {
5311 *r->out.num_written = 0;
5312 if (errno == ENOSPC)
5313 return WERR_NO_SPOOL_SPACE;
5315 return WERR_ACCESS_DENIED;
5318 *r->out.num_written = r->in._data_size;
5323 /********************************************************************
5324 * api_spoolss_getprinter
5325 * called from the spoolss dispatcher
5327 ********************************************************************/
5329 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5333 WERROR errcode = WERR_BADFUNC;
5334 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5337 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5338 OUR_HANDLE(handle)));
5342 if (!get_printer_snum(p, handle, &snum, NULL))
5346 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5347 errcode = print_queue_pause(p->server_info, snum);
5349 case SPOOLSS_PRINTER_CONTROL_RESUME:
5350 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5351 errcode = print_queue_resume(p->server_info, snum);
5353 case SPOOLSS_PRINTER_CONTROL_PURGE:
5354 errcode = print_queue_purge(p->server_info, snum);
5357 return WERR_UNKNOWN_LEVEL;
5364 /****************************************************************
5365 _spoolss_AbortPrinter
5366 * From MSDN: "Deletes printer's spool file if printer is configured
5368 ****************************************************************/
5370 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5371 struct spoolss_AbortPrinter *r)
5373 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5375 WERROR errcode = WERR_OK;
5378 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5379 OUR_HANDLE(r->in.handle)));
5383 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5386 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5391 /********************************************************************
5392 * called by spoolss_api_setprinter
5393 * when updating a printer description
5394 ********************************************************************/
5396 static WERROR update_printer_sec(struct policy_handle *handle,
5397 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
5399 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5403 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5405 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5406 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5407 OUR_HANDLE(handle)));
5409 result = WERR_BADFID;
5414 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5415 result = WERR_INVALID_PARAM;
5419 /* Check the user has permissions to change the security
5420 descriptor. By experimentation with two NT machines, the user
5421 requires Full Access to the printer to change security
5424 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5425 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5426 result = WERR_ACCESS_DENIED;
5430 /* NT seems to like setting the security descriptor even though
5431 nothing may have actually changed. */
5433 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
5434 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5435 result = WERR_BADFID;
5439 if (DEBUGLEVEL >= 10) {
5443 the_acl = old_secdesc_ctr->sd->dacl;
5444 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5445 PRINTERNAME(snum), the_acl->num_aces));
5447 for (i = 0; i < the_acl->num_aces; i++) {
5448 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5449 &the_acl->aces[i].trustee),
5450 the_acl->aces[i].access_mask));
5453 the_acl = secdesc_ctr->sd->dacl;
5456 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5457 PRINTERNAME(snum), the_acl->num_aces));
5459 for (i = 0; i < the_acl->num_aces; i++) {
5460 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5461 &the_acl->aces[i].trustee),
5462 the_acl->aces[i].access_mask));
5465 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5469 new_secdesc_ctr = sec_desc_merge_buf(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
5470 if (!new_secdesc_ctr) {
5471 result = WERR_NOMEM;
5475 if (security_descriptor_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
5480 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
5487 /********************************************************************
5488 Canonicalize printer info from a client
5490 ATTN: It does not matter what we set the servername to hear
5491 since we do the necessary work in get_a_printer() to set it to
5492 the correct value based on what the client sent in the
5493 _spoolss_open_printer_ex().
5494 ********************************************************************/
5496 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
5498 fstring printername;
5501 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5502 "portname=%s drivername=%s comment=%s location=%s\n",
5503 info->servername, info->printername, info->sharename,
5504 info->portname, info->drivername, info->comment, info->location));
5506 /* we force some elements to "correct" values */
5507 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
5508 fstrcpy(info->sharename, lp_servicename(snum));
5510 /* check to see if we allow printername != sharename */
5512 if ( lp_force_printername(snum) ) {
5513 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5514 global_myname(), info->sharename );
5517 /* make sure printername is in \\server\printername format */
5519 fstrcpy( printername, info->printername );
5521 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5522 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5526 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5527 global_myname(), p );
5530 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5531 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5538 /****************************************************************************
5539 ****************************************************************************/
5541 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5543 char *cmd = lp_addport_cmd();
5544 char *command = NULL;
5546 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5547 bool is_print_op = false;
5550 return WERR_ACCESS_DENIED;
5553 command = talloc_asprintf(ctx,
5554 "%s \"%s\" \"%s\"", cmd, portname, uri );
5560 is_print_op = user_has_privileges( token, &se_printop );
5562 DEBUG(10,("Running [%s]\n", command));
5564 /********* BEGIN SePrintOperatorPrivilege **********/
5569 ret = smbrun(command, NULL);
5574 /********* END SePrintOperatorPrivilege **********/
5576 DEBUGADD(10,("returned [%d]\n", ret));
5578 TALLOC_FREE(command);
5581 return WERR_ACCESS_DENIED;
5587 /****************************************************************************
5588 ****************************************************************************/
5590 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
5592 char *cmd = lp_addprinter_cmd();
5594 char *command = NULL;
5598 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5599 bool is_print_op = false;
5600 char *remote_machine = talloc_strdup(ctx, "%m");
5602 if (!remote_machine) {
5605 remote_machine = talloc_sub_basic(ctx,
5606 current_user_info.smb_name,
5607 current_user_info.domain,
5609 if (!remote_machine) {
5613 command = talloc_asprintf(ctx,
5614 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5615 cmd, printer->info_2->printername, printer->info_2->sharename,
5616 printer->info_2->portname, printer->info_2->drivername,
5617 printer->info_2->location, printer->info_2->comment, remote_machine);
5623 is_print_op = user_has_privileges( token, &se_printop );
5625 DEBUG(10,("Running [%s]\n", command));
5627 /********* BEGIN SePrintOperatorPrivilege **********/
5632 if ( (ret = smbrun(command, &fd)) == 0 ) {
5633 /* Tell everyone we updated smb.conf. */
5634 message_send_all(smbd_messaging_context(),
5635 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5641 /********* END SePrintOperatorPrivilege **********/
5643 DEBUGADD(10,("returned [%d]\n", ret));
5645 TALLOC_FREE(command);
5646 TALLOC_FREE(remote_machine);
5654 /* reload our services immediately */
5656 reload_services(false);
5660 /* Get lines and convert them back to dos-codepage */
5661 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5662 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5665 /* Set the portname to what the script says the portname should be. */
5666 /* but don't require anything to be return from the script exit a good error code */
5669 /* Set the portname to what the script says the portname should be. */
5670 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
5671 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5674 TALLOC_FREE(qlines);
5679 /********************************************************************
5680 * Called by spoolss_api_setprinter
5681 * when updating a printer description.
5682 ********************************************************************/
5684 static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5685 struct spoolss_SetPrinterInfoCtr *info_ctr,
5686 struct spoolss_DeviceMode *devmode)
5689 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
5690 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5695 DEBUG(8,("update_printer\n"));
5700 result = WERR_BADFID;
5704 if (!get_printer_snum(p, handle, &snum, NULL)) {
5705 result = WERR_BADFID;
5709 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
5710 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
5711 result = WERR_BADFID;
5715 DEBUGADD(8,("Converting info_2 struct\n"));
5718 * convert_printer_info converts the incoming
5719 * info from the client and overwrites the info
5720 * just read from the tdb in the pointer 'printer'.
5723 if (!convert_printer_info(info_ctr, printer)) {
5724 result = WERR_NOMEM;
5729 /* we have a valid devmode
5730 convert it and link it*/
5732 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5733 if (!convert_devicemode(printer->info_2->printername, devmode,
5734 &printer->info_2->devmode)) {
5735 result = WERR_NOMEM;
5740 /* Do sanity check on the requested changes for Samba */
5742 if (!check_printer_ok(printer->info_2, snum)) {
5743 result = WERR_INVALID_PARAM;
5747 /* FIXME!!! If the driver has changed we really should verify that
5748 it is installed before doing much else --jerry */
5750 /* Check calling user has permission to update printer description */
5752 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5753 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5754 result = WERR_ACCESS_DENIED;
5758 /* Call addprinter hook */
5759 /* Check changes to see if this is really needed */
5761 if ( *lp_addprinter_cmd()
5762 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
5763 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
5764 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
5765 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
5767 /* add_printer_hook() will call reload_services() */
5769 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
5771 result = WERR_ACCESS_DENIED;
5777 * When a *new* driver is bound to a printer, the drivername is used to
5778 * lookup previously saved driver initialization info, which is then
5779 * bound to the printer, simulating what happens in the Windows arch.
5781 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
5783 if (!set_driver_init(printer, 2))
5785 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
5786 printer->info_2->drivername));
5789 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5790 printer->info_2->drivername));
5792 notify_printer_driver(snum, printer->info_2->drivername);
5796 * flag which changes actually occured. This is a small subset of
5797 * all the possible changes. We also have to update things in the
5801 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
5802 push_reg_sz(talloc_tos(), NULL, &buffer, printer->info_2->comment);
5803 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
5804 REG_SZ, buffer.data, buffer.length);
5806 notify_printer_comment(snum, printer->info_2->comment);
5809 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
5810 push_reg_sz(talloc_tos(), NULL, &buffer, printer->info_2->sharename);
5811 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
5812 REG_SZ, buffer.data, buffer.length);
5814 notify_printer_sharename(snum, printer->info_2->sharename);
5817 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
5820 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
5823 pname = printer->info_2->printername;
5826 push_reg_sz(talloc_tos(), NULL, &buffer, pname);
5827 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
5828 REG_SZ, buffer.data, buffer.length);
5830 notify_printer_printername( snum, pname );
5833 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
5834 push_reg_sz(talloc_tos(), NULL, &buffer, printer->info_2->portname);
5835 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
5836 REG_SZ, buffer.data, buffer.length);
5838 notify_printer_port(snum, printer->info_2->portname);
5841 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
5842 push_reg_sz(talloc_tos(), NULL, &buffer, printer->info_2->location);
5843 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
5844 REG_SZ, buffer.data, buffer.length);
5846 notify_printer_location(snum, printer->info_2->location);
5849 /* here we need to update some more DsSpooler keys */
5850 /* uNCName, serverName, shortServerName */
5852 push_reg_sz(talloc_tos(), NULL, &buffer, global_myname());
5853 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
5854 REG_SZ, buffer.data, buffer.length);
5855 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
5856 REG_SZ, buffer.data, buffer.length);
5858 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
5859 global_myname(), printer->info_2->sharename );
5860 push_reg_sz(talloc_tos(), NULL, &buffer, asc_buffer);
5861 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
5862 REG_SZ, buffer.data, buffer.length);
5864 /* Update printer info */
5865 result = mod_a_printer(printer, 2);
5868 free_a_printer(&printer, 2);
5869 free_a_printer(&old_printer, 2);
5875 /****************************************************************************
5876 ****************************************************************************/
5877 static WERROR publish_or_unpublish_printer(pipes_struct *p,
5878 struct policy_handle *handle,
5879 struct spoolss_SetPrinterInfo7 *info7)
5883 Printer_entry *Printer;
5885 if ( lp_security() != SEC_ADS ) {
5886 return WERR_UNKNOWN_LEVEL;
5889 Printer = find_printer_index_by_hnd(p, handle);
5891 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5896 if (!get_printer_snum(p, handle, &snum, NULL))
5899 nt_printer_publish(Printer, snum, info7->action);
5903 return WERR_UNKNOWN_LEVEL;
5907 /********************************************************************
5908 ********************************************************************/
5910 static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
5911 struct spoolss_DeviceMode *devmode)
5914 NT_PRINTER_INFO_LEVEL *printer = NULL;
5915 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5918 DEBUG(8,("update_printer_devmode\n"));
5923 result = WERR_BADFID;
5927 if (!get_printer_snum(p, handle, &snum, NULL)) {
5928 result = WERR_BADFID;
5932 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)))) {
5933 result = WERR_BADFID;
5938 /* we have a valid devmode
5939 convert it and link it*/
5941 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5942 if (!convert_devicemode(printer->info_2->printername, devmode,
5943 &printer->info_2->devmode)) {
5944 result = WERR_NOMEM;
5949 /* Check calling user has permission to update printer description */
5951 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5952 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5953 result = WERR_ACCESS_DENIED;
5958 /* Update printer info */
5959 result = mod_a_printer(printer, 2);
5962 free_a_printer(&printer, 2);
5968 /****************************************************************
5970 ****************************************************************/
5972 WERROR _spoolss_SetPrinter(pipes_struct *p,
5973 struct spoolss_SetPrinter *r)
5977 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5980 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5981 OUR_HANDLE(r->in.handle)));
5985 /* check the level */
5986 switch (r->in.info_ctr->level) {
5988 return control_printer(r->in.handle, r->in.command, p);
5990 result = update_printer(p, r->in.handle,
5992 r->in.devmode_ctr->devmode);
5993 if (!W_ERROR_IS_OK(result))
5995 if (r->in.secdesc_ctr->sd)
5996 result = update_printer_sec(r->in.handle, p,
6000 return update_printer_sec(r->in.handle, p,
6003 return publish_or_unpublish_printer(p, r->in.handle,
6004 r->in.info_ctr->info.info7);
6006 return update_printer_devmode(p, r->in.handle,
6007 r->in.devmode_ctr->devmode);
6009 return WERR_UNKNOWN_LEVEL;
6013 /****************************************************************
6014 _spoolss_FindClosePrinterNotify
6015 ****************************************************************/
6017 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6018 struct spoolss_FindClosePrinterNotify *r)
6020 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6023 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6024 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6028 if (Printer->notify.client_connected == true) {
6031 if ( Printer->printer_type == SPLHND_SERVER)
6033 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6034 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6037 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6040 Printer->notify.flags=0;
6041 Printer->notify.options=0;
6042 Printer->notify.localmachine[0]='\0';
6043 Printer->notify.printerlocal=0;
6044 TALLOC_FREE(Printer->notify.option);
6045 Printer->notify.client_connected = false;
6050 /****************************************************************
6052 ****************************************************************/
6054 WERROR _spoolss_AddJob(pipes_struct *p,
6055 struct spoolss_AddJob *r)
6057 if (!r->in.buffer && (r->in.offered != 0)) {
6058 return WERR_INVALID_PARAM;
6061 /* this is what a NT server returns for AddJob. AddJob must fail on
6062 * non-local printers */
6064 if (r->in.level != 1) {
6065 return WERR_UNKNOWN_LEVEL;
6068 return WERR_INVALID_PARAM;
6071 /****************************************************************************
6073 ****************************************************************************/
6075 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6076 struct spoolss_JobInfo1 *r,
6077 const print_queue_struct *queue,
6078 int position, int snum,
6079 const NT_PRINTER_INFO_LEVEL *ntprinter)
6083 t = gmtime(&queue->time);
6085 r->job_id = queue->job;
6087 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6088 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6089 r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6090 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6091 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6092 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6093 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6094 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6095 r->data_type = talloc_strdup(mem_ctx, "RAW");
6096 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6097 r->text_status = talloc_strdup(mem_ctx, "");
6098 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6100 r->status = nt_printj_status(queue->status);
6101 r->priority = queue->priority;
6102 r->position = position;
6103 r->total_pages = queue->page_count;
6104 r->pages_printed = 0; /* ??? */
6106 init_systemtime(&r->submitted, t);
6111 /****************************************************************************
6113 ****************************************************************************/
6115 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6116 struct spoolss_JobInfo2 *r,
6117 const print_queue_struct *queue,
6118 int position, int snum,
6119 const NT_PRINTER_INFO_LEVEL *ntprinter,
6120 struct spoolss_DeviceMode *devmode)
6124 t = gmtime(&queue->time);
6126 r->job_id = queue->job;
6128 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6129 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6130 r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6131 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6132 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6133 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6134 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6135 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6136 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6137 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6138 r->data_type = talloc_strdup(mem_ctx, "RAW");
6139 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6140 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6141 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6142 r->parameters = talloc_strdup(mem_ctx, "");
6143 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6144 r->driver_name = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
6145 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6147 r->devmode = devmode;
6149 r->text_status = talloc_strdup(mem_ctx, "");
6150 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6154 r->status = nt_printj_status(queue->status);
6155 r->priority = queue->priority;
6156 r->position = position;
6159 r->total_pages = queue->page_count;
6160 r->size = queue->size;
6161 init_systemtime(&r->submitted, t);
6163 r->pages_printed = 0; /* ??? */
6168 /****************************************************************************
6170 ****************************************************************************/
6172 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6173 struct spoolss_JobInfo3 *r,
6174 const print_queue_struct *queue,
6175 const print_queue_struct *next_queue,
6176 int position, int snum,
6177 const NT_PRINTER_INFO_LEVEL *ntprinter)
6179 r->job_id = queue->job;
6182 r->next_job_id = next_queue->job;
6189 /****************************************************************************
6190 Enumjobs at level 1.
6191 ****************************************************************************/
6193 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6194 const print_queue_struct *queue,
6195 uint32_t num_queues, int snum,
6196 const NT_PRINTER_INFO_LEVEL *ntprinter,
6197 union spoolss_JobInfo **info_p,
6200 union spoolss_JobInfo *info;
6202 WERROR result = WERR_OK;
6204 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6205 W_ERROR_HAVE_NO_MEMORY(info);
6207 *count = num_queues;
6209 for (i=0; i<*count; i++) {
6210 result = fill_job_info1(info,
6216 if (!W_ERROR_IS_OK(result)) {
6222 if (!W_ERROR_IS_OK(result)) {
6233 /****************************************************************************
6234 Enumjobs at level 2.
6235 ****************************************************************************/
6237 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6238 const print_queue_struct *queue,
6239 uint32_t num_queues, int snum,
6240 const NT_PRINTER_INFO_LEVEL *ntprinter,
6241 union spoolss_JobInfo **info_p,
6244 union spoolss_JobInfo *info;
6246 WERROR result = WERR_OK;
6248 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6249 W_ERROR_HAVE_NO_MEMORY(info);
6251 *count = num_queues;
6253 for (i=0; i<*count; i++) {
6255 struct spoolss_DeviceMode *devmode;
6257 devmode = construct_dev_mode(info, lp_const_servicename(snum));
6259 result = WERR_NOMEM;
6263 result = fill_job_info2(info,
6270 if (!W_ERROR_IS_OK(result)) {
6276 if (!W_ERROR_IS_OK(result)) {
6287 /****************************************************************************
6288 Enumjobs at level 3.
6289 ****************************************************************************/
6291 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6292 const print_queue_struct *queue,
6293 uint32_t num_queues, int snum,
6294 const NT_PRINTER_INFO_LEVEL *ntprinter,
6295 union spoolss_JobInfo **info_p,
6298 union spoolss_JobInfo *info;
6300 WERROR result = WERR_OK;
6302 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6303 W_ERROR_HAVE_NO_MEMORY(info);
6305 *count = num_queues;
6307 for (i=0; i<*count; i++) {
6308 const print_queue_struct *next_queue = NULL;
6311 next_queue = &queue[i+1];
6314 result = fill_job_info3(info,
6321 if (!W_ERROR_IS_OK(result)) {
6327 if (!W_ERROR_IS_OK(result)) {
6338 /****************************************************************
6340 ****************************************************************/
6342 WERROR _spoolss_EnumJobs(pipes_struct *p,
6343 struct spoolss_EnumJobs *r)
6346 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6348 print_status_struct prt_status;
6349 print_queue_struct *queue = NULL;
6352 /* that's an [in out] buffer */
6354 if (!r->in.buffer && (r->in.offered != 0)) {
6355 return WERR_INVALID_PARAM;
6358 DEBUG(4,("_spoolss_EnumJobs\n"));
6362 *r->out.info = NULL;
6364 /* lookup the printer snum and tdb entry */
6366 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6370 result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6371 if (!W_ERROR_IS_OK(result)) {
6375 count = print_queue_status(snum, &queue, &prt_status);
6376 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6377 count, prt_status.status, prt_status.message));
6381 free_a_printer(&ntprinter, 2);
6385 switch (r->in.level) {
6387 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6388 ntprinter, r->out.info, r->out.count);
6391 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6392 ntprinter, r->out.info, r->out.count);
6395 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6396 ntprinter, r->out.info, r->out.count);
6399 result = WERR_UNKNOWN_LEVEL;
6404 free_a_printer(&ntprinter, 2);
6406 if (!W_ERROR_IS_OK(result)) {
6410 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6411 spoolss_EnumJobs, NULL,
6412 *r->out.info, r->in.level,
6414 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6415 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6417 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6420 /****************************************************************
6421 _spoolss_ScheduleJob
6422 ****************************************************************/
6424 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6425 struct spoolss_ScheduleJob *r)
6430 /****************************************************************
6431 ****************************************************************/
6433 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6434 const char *printer_name,
6436 struct spoolss_SetJobInfo1 *r)
6440 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6444 if (strequal(old_doc_name, r->document_name)) {
6448 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6455 /****************************************************************
6457 ****************************************************************/
6459 WERROR _spoolss_SetJob(pipes_struct *p,
6460 struct spoolss_SetJob *r)
6463 WERROR errcode = WERR_BADFUNC;
6465 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6469 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6470 return WERR_INVALID_PRINTER_NAME;
6473 switch (r->in.command) {
6474 case SPOOLSS_JOB_CONTROL_CANCEL:
6475 case SPOOLSS_JOB_CONTROL_DELETE:
6476 if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6480 case SPOOLSS_JOB_CONTROL_PAUSE:
6481 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6485 case SPOOLSS_JOB_CONTROL_RESTART:
6486 case SPOOLSS_JOB_CONTROL_RESUME:
6487 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6495 return WERR_UNKNOWN_LEVEL;
6498 if (!W_ERROR_IS_OK(errcode)) {
6502 if (r->in.ctr == NULL) {
6506 switch (r->in.ctr->level) {
6508 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6510 r->in.ctr->info.info1);
6516 return WERR_UNKNOWN_LEVEL;
6522 /****************************************************************************
6523 Enumerates all printer drivers by level and architecture.
6524 ****************************************************************************/
6526 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6527 const char *servername,
6528 const char *architecture,
6530 union spoolss_DriverInfo **info_p,
6536 fstring *list = NULL;
6537 struct spoolss_DriverInfo8 *driver;
6538 union spoolss_DriverInfo *info = NULL;
6540 WERROR result = WERR_OK;
6545 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6547 ndrivers = get_ntdrivers(&list, architecture, version);
6548 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6549 ndrivers, architecture, version));
6551 if (ndrivers == -1) {
6552 result = WERR_NOMEM;
6556 if (ndrivers != 0) {
6557 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6558 union spoolss_DriverInfo,
6561 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6562 "failed to enlarge driver info buffer!\n"));
6563 result = WERR_NOMEM;
6568 for (i=0; i<ndrivers; i++) {
6569 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6570 ZERO_STRUCT(driver);
6571 result = get_a_printer_driver(mem_ctx, &driver, list[i],
6572 architecture, version);
6573 if (!W_ERROR_IS_OK(result)) {
6579 result = fill_printer_driver_info1(info, &info[count+i].info1,
6580 driver, servername);
6583 result = fill_printer_driver_info2(info, &info[count+i].info2,
6584 driver, servername);
6587 result = fill_printer_driver_info3(info, &info[count+i].info3,
6588 driver, servername);
6591 result = fill_printer_driver_info4(info, &info[count+i].info4,
6592 driver, servername);
6595 result = fill_printer_driver_info5(info, &info[count+i].info5,
6596 driver, servername);
6599 result = fill_printer_driver_info6(info, &info[count+i].info6,
6600 driver, servername);
6603 result = fill_printer_driver_info8(info, &info[count+i].info8,
6604 driver, servername);
6607 result = WERR_UNKNOWN_LEVEL;
6611 free_a_printer_driver(driver);
6613 if (!W_ERROR_IS_OK(result)) {
6625 if (!W_ERROR_IS_OK(result)) {
6636 /****************************************************************************
6637 Enumerates all printer drivers by level.
6638 ****************************************************************************/
6640 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6641 const char *servername,
6642 const char *architecture,
6644 union spoolss_DriverInfo **info_p,
6648 WERROR result = WERR_OK;
6650 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6652 for (a=0; archi_table[a].long_archi != NULL; a++) {
6654 union spoolss_DriverInfo *info = NULL;
6657 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6659 archi_table[a].long_archi,
6663 if (!W_ERROR_IS_OK(result)) {
6667 for (i=0; i < count; i++) {
6668 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6669 info[i], info_p, count_p);
6676 return enumprinterdrivers_level_by_architecture(mem_ctx,
6684 /****************************************************************
6685 _spoolss_EnumPrinterDrivers
6686 ****************************************************************/
6688 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6689 struct spoolss_EnumPrinterDrivers *r)
6691 const char *cservername;
6694 /* that's an [in out] buffer */
6696 if (!r->in.buffer && (r->in.offered != 0)) {
6697 return WERR_INVALID_PARAM;
6700 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6704 *r->out.info = NULL;
6706 cservername = canon_servername(r->in.server);
6708 if (!is_myname_or_ipaddr(cservername)) {
6709 return WERR_UNKNOWN_PRINTER_DRIVER;
6712 result = enumprinterdrivers_level(p->mem_ctx, cservername,
6717 if (!W_ERROR_IS_OK(result)) {
6721 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6722 spoolss_EnumPrinterDrivers, NULL,
6723 *r->out.info, r->in.level,
6725 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6726 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6728 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6731 /****************************************************************************
6732 ****************************************************************************/
6734 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
6735 struct spoolss_FormInfo1 *r,
6736 const nt_forms_struct *form)
6738 r->form_name = talloc_strdup(mem_ctx, form->name);
6739 W_ERROR_HAVE_NO_MEMORY(r->form_name);
6741 r->flags = form->flag;
6742 r->size.width = form->width;
6743 r->size.height = form->length;
6744 r->area.left = form->left;
6745 r->area.top = form->top;
6746 r->area.right = form->right;
6747 r->area.bottom = form->bottom;
6752 /****************************************************************
6753 spoolss_enumforms_level1
6754 ****************************************************************/
6756 static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
6757 const nt_forms_struct *builtin_forms,
6758 uint32_t num_builtin_forms,
6759 const nt_forms_struct *user_forms,
6760 uint32_t num_user_forms,
6761 union spoolss_FormInfo **info_p,
6764 union spoolss_FormInfo *info;
6765 WERROR result = WERR_OK;
6768 *count = num_builtin_forms + num_user_forms;
6770 info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
6771 W_ERROR_HAVE_NO_MEMORY(info);
6773 /* construct the list of form structures */
6774 for (i=0; i<num_builtin_forms; i++) {
6775 DEBUGADD(6,("Filling builtin form number [%d]\n",i));
6776 result = fill_form_info_1(info, &info[i].info1,
6778 if (!W_ERROR_IS_OK(result)) {
6783 for (i=0; i<num_user_forms; i++) {
6784 DEBUGADD(6,("Filling user form number [%d]\n",i));
6785 result = fill_form_info_1(info, &info[i+num_builtin_forms].info1,
6787 if (!W_ERROR_IS_OK(result)) {
6793 if (!W_ERROR_IS_OK(result)) {
6804 /****************************************************************
6806 ****************************************************************/
6808 WERROR _spoolss_EnumForms(pipes_struct *p,
6809 struct spoolss_EnumForms *r)
6812 nt_forms_struct *user_forms = NULL;
6813 nt_forms_struct *builtin_forms = NULL;
6814 uint32_t num_user_forms;
6815 uint32_t num_builtin_forms;
6819 *r->out.info = NULL;
6821 /* that's an [in out] buffer */
6823 if (!r->in.buffer && (r->in.offered != 0) ) {
6824 return WERR_INVALID_PARAM;
6827 DEBUG(4,("_spoolss_EnumForms\n"));
6828 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6829 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6831 num_builtin_forms = get_builtin_ntforms(&builtin_forms);
6832 DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
6833 num_user_forms = get_ntforms(&user_forms);
6834 DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
6836 if (num_user_forms + num_builtin_forms == 0) {
6837 SAFE_FREE(builtin_forms);
6838 SAFE_FREE(user_forms);
6839 return WERR_NO_MORE_ITEMS;
6842 switch (r->in.level) {
6844 result = spoolss_enumforms_level1(p->mem_ctx,
6853 result = WERR_UNKNOWN_LEVEL;
6857 SAFE_FREE(user_forms);
6858 SAFE_FREE(builtin_forms);
6860 if (!W_ERROR_IS_OK(result)) {
6864 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6865 spoolss_EnumForms, NULL,
6866 *r->out.info, r->in.level,
6868 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6869 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6871 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6874 /****************************************************************
6875 ****************************************************************/
6877 static WERROR find_form_byname(const char *name,
6878 nt_forms_struct *form)
6880 nt_forms_struct *list = NULL;
6881 int num_forms = 0, i = 0;
6883 if (get_a_builtin_ntform_by_string(name, form)) {
6887 num_forms = get_ntforms(&list);
6888 DEBUGADD(5,("Number of forms [%d]\n", num_forms));
6890 if (num_forms == 0) {
6894 /* Check if the requested name is in the list of form structures */
6895 for (i = 0; i < num_forms; i++) {
6897 DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
6899 if (strequal(name, list[i].name)) {
6900 DEBUGADD(6,("Found form %s number [%d]\n", name, i));
6912 /****************************************************************
6914 ****************************************************************/
6916 WERROR _spoolss_GetForm(pipes_struct *p,
6917 struct spoolss_GetForm *r)
6920 nt_forms_struct form;
6922 /* that's an [in out] buffer */
6924 if (!r->in.buffer && (r->in.offered != 0)) {
6925 return WERR_INVALID_PARAM;
6928 DEBUG(4,("_spoolss_GetForm\n"));
6929 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6930 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6932 result = find_form_byname(r->in.form_name, &form);
6933 if (!W_ERROR_IS_OK(result)) {
6934 TALLOC_FREE(r->out.info);
6938 switch (r->in.level) {
6940 result = fill_form_info_1(p->mem_ctx,
6941 &r->out.info->info1,
6946 result = WERR_UNKNOWN_LEVEL;
6950 if (!W_ERROR_IS_OK(result)) {
6951 TALLOC_FREE(r->out.info);
6955 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL,
6956 r->out.info, r->in.level);
6957 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6959 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6962 /****************************************************************************
6963 ****************************************************************************/
6965 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6966 struct spoolss_PortInfo1 *r,
6969 r->port_name = talloc_strdup(mem_ctx, name);
6970 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6975 /****************************************************************************
6976 TODO: This probably needs distinguish between TCP/IP and Local ports
6978 ****************************************************************************/
6980 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6981 struct spoolss_PortInfo2 *r,
6984 r->port_name = talloc_strdup(mem_ctx, name);
6985 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6987 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6988 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6990 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6991 W_ERROR_HAVE_NO_MEMORY(r->description);
6993 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7000 /****************************************************************************
7001 wrapper around the enumer ports command
7002 ****************************************************************************/
7004 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7006 char *cmd = lp_enumports_cmd();
7007 char **qlines = NULL;
7008 char *command = NULL;
7016 /* if no hook then just fill in the default port */
7019 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7022 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7023 TALLOC_FREE(qlines);
7030 /* we have a valid enumport command */
7032 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7037 DEBUG(10,("Running [%s]\n", command));
7038 ret = smbrun(command, &fd);
7039 DEBUG(10,("Returned [%d]\n", ret));
7040 TALLOC_FREE(command);
7045 return WERR_ACCESS_DENIED;
7049 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7050 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7060 /****************************************************************************
7062 ****************************************************************************/
7064 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7065 union spoolss_PortInfo **info_p,
7068 union spoolss_PortInfo *info = NULL;
7070 WERROR result = WERR_OK;
7071 char **qlines = NULL;
7074 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7075 if (!W_ERROR_IS_OK(result)) {
7080 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7082 DEBUG(10,("Returning WERR_NOMEM\n"));
7083 result = WERR_NOMEM;
7087 for (i=0; i<numlines; i++) {
7088 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7089 result = fill_port_1(info, &info[i].info1, qlines[i]);
7090 if (!W_ERROR_IS_OK(result)) {
7095 TALLOC_FREE(qlines);
7098 if (!W_ERROR_IS_OK(result)) {
7100 TALLOC_FREE(qlines);
7112 /****************************************************************************
7114 ****************************************************************************/
7116 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7117 union spoolss_PortInfo **info_p,
7120 union spoolss_PortInfo *info = NULL;
7122 WERROR result = WERR_OK;
7123 char **qlines = NULL;
7126 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7127 if (!W_ERROR_IS_OK(result)) {
7132 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7134 DEBUG(10,("Returning WERR_NOMEM\n"));
7135 result = WERR_NOMEM;
7139 for (i=0; i<numlines; i++) {
7140 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7141 result = fill_port_2(info, &info[i].info2, qlines[i]);
7142 if (!W_ERROR_IS_OK(result)) {
7147 TALLOC_FREE(qlines);
7150 if (!W_ERROR_IS_OK(result)) {
7152 TALLOC_FREE(qlines);
7164 /****************************************************************
7166 ****************************************************************/
7168 WERROR _spoolss_EnumPorts(pipes_struct *p,
7169 struct spoolss_EnumPorts *r)
7173 /* that's an [in out] buffer */
7175 if (!r->in.buffer && (r->in.offered != 0)) {
7176 return WERR_INVALID_PARAM;
7179 DEBUG(4,("_spoolss_EnumPorts\n"));
7183 *r->out.info = NULL;
7185 switch (r->in.level) {
7187 result = enumports_level_1(p->mem_ctx, r->out.info,
7191 result = enumports_level_2(p->mem_ctx, r->out.info,
7195 return WERR_UNKNOWN_LEVEL;
7198 if (!W_ERROR_IS_OK(result)) {
7202 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7203 spoolss_EnumPorts, NULL,
7204 *r->out.info, r->in.level,
7206 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7207 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7209 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7212 /****************************************************************************
7213 ****************************************************************************/
7215 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7217 struct spoolss_SetPrinterInfoCtr *info_ctr,
7218 struct spoolss_DeviceMode *devmode,
7219 struct security_descriptor *sec_desc,
7220 struct spoolss_UserLevelCtr *user_ctr,
7221 struct policy_handle *handle)
7223 NT_PRINTER_INFO_LEVEL *printer = NULL;
7226 WERROR err = WERR_OK;
7228 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7229 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7233 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7234 if (!convert_printer_info(info_ctr, printer)) {
7235 free_a_printer(&printer, 2);
7239 /* samba does not have a concept of local, non-shared printers yet, so
7240 * make sure we always setup sharename - gd */
7241 if ((printer->info_2->sharename[0] == '\0') && (printer->info_2->printername != '\0')) {
7242 DEBUG(5, ("spoolss_addprinterex_level_2: "
7243 "no sharename has been set, setting printername %s as sharename\n",
7244 printer->info_2->printername));
7245 fstrcpy(printer->info_2->sharename, printer->info_2->printername);
7248 /* check to see if the printer already exists */
7250 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7251 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7252 printer->info_2->sharename));
7253 free_a_printer(&printer, 2);
7254 return WERR_PRINTER_ALREADY_EXISTS;
7257 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7258 if ((snum = print_queue_snum(printer->info_2->printername)) != -1) {
7259 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7260 printer->info_2->printername));
7261 free_a_printer(&printer, 2);
7262 return WERR_PRINTER_ALREADY_EXISTS;
7266 /* validate printer info struct */
7267 if (!info_ctr->info.info2->printername ||
7268 strlen(info_ctr->info.info2->printername) == 0) {
7269 free_a_printer(&printer,2);
7270 return WERR_INVALID_PRINTER_NAME;
7272 if (!info_ctr->info.info2->portname ||
7273 strlen(info_ctr->info.info2->portname) == 0) {
7274 free_a_printer(&printer,2);
7275 return WERR_UNKNOWN_PORT;
7277 if (!info_ctr->info.info2->drivername ||
7278 strlen(info_ctr->info.info2->drivername) == 0) {
7279 free_a_printer(&printer,2);
7280 return WERR_UNKNOWN_PRINTER_DRIVER;
7282 if (!info_ctr->info.info2->printprocessor ||
7283 strlen(info_ctr->info.info2->printprocessor) == 0) {
7284 free_a_printer(&printer,2);
7285 return WERR_UNKNOWN_PRINTPROCESSOR;
7288 /* FIXME!!! smbd should check to see if the driver is installed before
7289 trying to add a printer like this --jerry */
7291 if (*lp_addprinter_cmd() ) {
7292 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7294 free_a_printer(&printer,2);
7295 return WERR_ACCESS_DENIED;
7298 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7299 "smb.conf parameter \"addprinter command\" is defined. This"
7300 "parameter must exist for this call to succeed\n",
7301 printer->info_2->sharename ));
7304 /* use our primary netbios name since get_a_printer() will convert
7305 it to what the client expects on a case by case basis */
7307 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7308 printer->info_2->sharename);
7311 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7312 free_a_printer(&printer,2);
7313 return WERR_ACCESS_DENIED;
7316 /* you must be a printer admin to add a new printer */
7317 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7318 free_a_printer(&printer,2);
7319 return WERR_ACCESS_DENIED;
7323 * Do sanity check on the requested changes for Samba.
7326 if (!check_printer_ok(printer->info_2, snum)) {
7327 free_a_printer(&printer,2);
7328 return WERR_INVALID_PARAM;
7332 * When a printer is created, the drivername bound to the printer is used
7333 * to lookup previously saved driver initialization info, which is then
7334 * bound to the new printer, simulating what happens in the Windows arch.
7339 set_driver_init(printer, 2);
7343 /* A valid devmode was included, convert and link it
7345 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7347 if (!convert_devicemode(printer->info_2->printername, devmode,
7348 &printer->info_2->devmode)) {
7353 /* write the ASCII on disk */
7354 err = mod_a_printer(printer, 2);
7355 if (!W_ERROR_IS_OK(err)) {
7356 free_a_printer(&printer,2);
7360 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7361 /* Handle open failed - remove addition. */
7362 del_a_printer(printer->info_2->sharename);
7363 free_a_printer(&printer,2);
7364 ZERO_STRUCTP(handle);
7365 return WERR_ACCESS_DENIED;
7368 update_c_setprinter(false);
7369 free_a_printer(&printer,2);
7374 /****************************************************************
7375 _spoolss_AddPrinterEx
7376 ****************************************************************/
7378 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7379 struct spoolss_AddPrinterEx *r)
7381 switch (r->in.info_ctr->level) {
7383 /* we don't handle yet */
7384 /* but I know what to do ... */
7385 return WERR_UNKNOWN_LEVEL;
7387 return spoolss_addprinterex_level_2(p, r->in.server,
7389 r->in.devmode_ctr->devmode,
7390 r->in.secdesc_ctr->sd,
7391 r->in.userlevel_ctr,
7394 return WERR_UNKNOWN_LEVEL;
7398 /****************************************************************
7400 ****************************************************************/
7402 WERROR _spoolss_AddPrinter(pipes_struct *p,
7403 struct spoolss_AddPrinter *r)
7405 struct spoolss_AddPrinterEx a;
7406 struct spoolss_UserLevelCtr userlevel_ctr;
7408 ZERO_STRUCT(userlevel_ctr);
7410 userlevel_ctr.level = 1;
7412 a.in.server = r->in.server;
7413 a.in.info_ctr = r->in.info_ctr;
7414 a.in.devmode_ctr = r->in.devmode_ctr;
7415 a.in.secdesc_ctr = r->in.secdesc_ctr;
7416 a.in.userlevel_ctr = &userlevel_ctr;
7417 a.out.handle = r->out.handle;
7419 return _spoolss_AddPrinterEx(p, &a);
7422 /****************************************************************
7423 _spoolss_AddPrinterDriverEx
7424 ****************************************************************/
7426 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7427 struct spoolss_AddPrinterDriverEx *r)
7429 WERROR err = WERR_OK;
7430 char *driver_name = NULL;
7434 switch (p->hdr_req.opnum) {
7435 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7436 fn = "_spoolss_AddPrinterDriver";
7438 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7439 fn = "_spoolss_AddPrinterDriverEx";
7442 return WERR_INVALID_PARAM;
7446 * we only support the semantics of AddPrinterDriver()
7447 * i.e. only copy files that are newer than existing ones
7450 if (r->in.flags == 0) {
7451 return WERR_INVALID_PARAM;
7454 if (r->in.flags != APD_COPY_NEW_FILES) {
7455 return WERR_ACCESS_DENIED;
7459 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7460 /* Clever hack from Martin Zielinski <mz@seh.de>
7461 * to allow downgrade from level 8 (Vista).
7463 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7464 r->in.info_ctr->level));
7465 return WERR_UNKNOWN_LEVEL;
7468 DEBUG(5,("Cleaning driver's information\n"));
7469 err = clean_up_driver_struct(p, r->in.info_ctr);
7470 if (!W_ERROR_IS_OK(err))
7473 DEBUG(5,("Moving driver to final destination\n"));
7474 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7479 if (add_a_printer_driver(p->mem_ctx, r->in.info_ctr, &driver_name, &version)!=0) {
7480 err = WERR_ACCESS_DENIED;
7485 * I think this is where he DrvUpgradePrinter() hook would be
7486 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7487 * server. Right now, we just need to send ourselves a message
7488 * to update each printer bound to this driver. --jerry
7491 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7492 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7497 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7498 * decide if the driver init data should be deleted. The rules are:
7499 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7500 * 2) delete init data only if there is no 2k/Xp driver
7501 * 3) always delete init data
7502 * The generalized rule is always use init data from the highest order driver.
7503 * It is necessary to follow the driver install by an initialization step to
7504 * finish off this process.
7509 * 9x printer driver - never delete init data
7512 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7517 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7518 * there is no 2k/Xp driver init data for this driver name.
7522 struct spoolss_DriverInfo8 *driver1;
7524 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &driver1, driver_name, "Windows NT x86", 3))) {
7526 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7528 if (!del_driver_init(driver_name))
7529 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7533 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7535 free_a_printer_driver(driver1);
7536 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7543 * 2k or Xp printer driver - always delete init data
7546 if (!del_driver_init(driver_name))
7547 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7552 DEBUG(0,("%s: invalid level=%d\n", fn,
7553 r->in.info_ctr->level));
7562 /****************************************************************
7563 _spoolss_AddPrinterDriver
7564 ****************************************************************/
7566 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7567 struct spoolss_AddPrinterDriver *r)
7569 struct spoolss_AddPrinterDriverEx a;
7571 switch (r->in.info_ctr->level) {
7578 return WERR_UNKNOWN_LEVEL;
7581 a.in.servername = r->in.servername;
7582 a.in.info_ctr = r->in.info_ctr;
7583 a.in.flags = APD_COPY_NEW_FILES;
7585 return _spoolss_AddPrinterDriverEx(p, &a);
7588 /****************************************************************************
7589 ****************************************************************************/
7591 struct _spoolss_paths {
7597 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7599 static const struct _spoolss_paths spoolss_paths[]= {
7600 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7601 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7604 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7605 const char *servername,
7606 const char *environment,
7610 const char *pservername = NULL;
7611 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7612 const char *short_archi;
7616 /* environment may be empty */
7617 if (environment && strlen(environment)) {
7618 long_archi = environment;
7621 /* servername may be empty */
7622 if (servername && strlen(servername)) {
7623 pservername = canon_servername(servername);
7625 if (!is_myname_or_ipaddr(pservername)) {
7626 return WERR_INVALID_PARAM;
7630 if (!(short_archi = get_short_archi(long_archi))) {
7631 return WERR_INVALID_ENVIRONMENT;
7634 switch (component) {
7635 case SPOOLSS_PRTPROCS_PATH:
7636 case SPOOLSS_DRIVER_PATH:
7638 *path = talloc_asprintf(mem_ctx,
7641 spoolss_paths[component].share,
7644 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7645 SPOOLSS_DEFAULT_SERVER_PATH,
7646 spoolss_paths[component].dir,
7651 return WERR_INVALID_PARAM;
7661 /****************************************************************************
7662 ****************************************************************************/
7664 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7665 const char *servername,
7666 const char *environment,
7667 struct spoolss_DriverDirectoryInfo1 *r)
7672 werr = compose_spoolss_server_path(mem_ctx,
7675 SPOOLSS_DRIVER_PATH,
7677 if (!W_ERROR_IS_OK(werr)) {
7681 DEBUG(4,("printer driver directory: [%s]\n", path));
7683 r->directory_name = path;
7688 /****************************************************************
7689 _spoolss_GetPrinterDriverDirectory
7690 ****************************************************************/
7692 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7693 struct spoolss_GetPrinterDriverDirectory *r)
7697 /* that's an [in out] buffer */
7699 if (!r->in.buffer && (r->in.offered != 0)) {
7700 return WERR_INVALID_PARAM;
7703 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7708 /* r->in.level is ignored */
7710 werror = getprinterdriverdir_level_1(p->mem_ctx,
7713 &r->out.info->info1);
7714 if (!W_ERROR_IS_OK(werror)) {
7715 TALLOC_FREE(r->out.info);
7719 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL,
7720 r->out.info, r->in.level);
7721 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7723 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7726 /****************************************************************
7727 _spoolss_EnumPrinterData
7728 ****************************************************************/
7730 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7731 struct spoolss_EnumPrinterData *r)
7734 struct spoolss_EnumPrinterDataEx r2;
7736 struct spoolss_PrinterEnumValues *info, *val = NULL;
7739 r2.in.handle = r->in.handle;
7740 r2.in.key_name = "PrinterDriverData";
7742 r2.out.count = &count;
7743 r2.out.info = &info;
7744 r2.out.needed = &needed;
7746 result = _spoolss_EnumPrinterDataEx(p, &r2);
7747 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7748 r2.in.offered = needed;
7749 result = _spoolss_EnumPrinterDataEx(p, &r2);
7751 if (!W_ERROR_IS_OK(result)) {
7756 * The NT machine wants to know the biggest size of value and data
7758 * cf: MSDN EnumPrinterData remark section
7761 if (!r->in.value_offered && !r->in.data_offered) {
7762 uint32_t biggest_valuesize = 0;
7763 uint32_t biggest_datasize = 0;
7766 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7768 for (i=0; i<count; i++) {
7770 name_length = strlen(info[i].value_name);
7771 if (strlen(info[i].value_name) > biggest_valuesize) {
7772 biggest_valuesize = name_length;
7775 if (info[i].data_length > biggest_datasize) {
7776 biggest_datasize = info[i].data_length;
7779 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7783 /* the value is an UNICODE string but real_value_size is the length
7784 in bytes including the trailing 0 */
7786 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7787 *r->out.data_needed = biggest_datasize;
7789 DEBUG(6,("final values: [%d], [%d]\n",
7790 *r->out.value_needed, *r->out.data_needed));
7795 if (r->in.enum_index < count) {
7796 val = &info[r->in.enum_index];
7800 /* out_value should default to "" or else NT4 has
7801 problems unmarshalling the response */
7803 if (r->in.value_offered) {
7804 *r->out.value_needed = 1;
7805 r->out.value_name = talloc_strdup(r, "");
7806 if (!r->out.value_name) {
7810 r->out.value_name = NULL;
7811 *r->out.value_needed = 0;
7814 /* the data is counted in bytes */
7816 *r->out.data_needed = r->in.data_offered;
7818 result = WERR_NO_MORE_ITEMS;
7822 * - counted in bytes in the request
7823 * - counted in UNICODE chars in the max reply
7824 * - counted in bytes in the real size
7826 * take a pause *before* coding not *during* coding
7830 if (r->in.value_offered) {
7831 r->out.value_name = talloc_strdup(r, val->value_name);
7832 if (!r->out.value_name) {
7835 *r->out.value_needed = val->value_name_len;
7837 r->out.value_name = NULL;
7838 *r->out.value_needed = 0;
7843 *r->out.type = val->type;
7845 /* data - counted in bytes */
7848 * See the section "Dynamically Typed Query Parameters"
7852 if (r->out.data && val->data && val->data->data &&
7853 val->data_length && r->in.data_offered) {
7854 memcpy(r->out.data, val->data->data,
7855 MIN(val->data_length,r->in.data_offered));
7858 *r->out.data_needed = val->data_length;
7866 /****************************************************************
7867 _spoolss_SetPrinterData
7868 ****************************************************************/
7870 WERROR _spoolss_SetPrinterData(pipes_struct *p,
7871 struct spoolss_SetPrinterData *r)
7873 struct spoolss_SetPrinterDataEx r2;
7875 r2.in.handle = r->in.handle;
7876 r2.in.key_name = "PrinterDriverData";
7877 r2.in.value_name = r->in.value_name;
7878 r2.in.type = r->in.type;
7879 r2.in.data = r->in.data;
7880 r2.in.offered = r->in.offered;
7882 return _spoolss_SetPrinterDataEx(p, &r2);
7885 /****************************************************************
7886 _spoolss_ResetPrinter
7887 ****************************************************************/
7889 WERROR _spoolss_ResetPrinter(pipes_struct *p,
7890 struct spoolss_ResetPrinter *r)
7892 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7895 DEBUG(5,("_spoolss_ResetPrinter\n"));
7898 * All we do is to check to see if the handle and queue is valid.
7899 * This call really doesn't mean anything to us because we only
7900 * support RAW printing. --jerry
7904 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7905 OUR_HANDLE(r->in.handle)));
7909 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7913 /* blindly return success */
7917 /****************************************************************
7918 _spoolss_DeletePrinterData
7919 ****************************************************************/
7921 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7922 struct spoolss_DeletePrinterData *r)
7924 struct spoolss_DeletePrinterDataEx r2;
7926 r2.in.handle = r->in.handle;
7927 r2.in.key_name = "PrinterDriverData";
7928 r2.in.value_name = r->in.value_name;
7930 return _spoolss_DeletePrinterDataEx(p, &r2);
7933 /****************************************************************
7935 ****************************************************************/
7937 WERROR _spoolss_AddForm(pipes_struct *p,
7938 struct spoolss_AddForm *r)
7940 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7941 nt_forms_struct tmpForm;
7943 WERROR status = WERR_OK;
7944 NT_PRINTER_INFO_LEVEL *printer = NULL;
7945 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7948 nt_forms_struct *list=NULL;
7949 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7952 DEBUG(5,("_spoolss_AddForm\n"));
7955 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7956 OUR_HANDLE(r->in.handle)));
7961 /* forms can be added on printer or on the print server handle */
7963 if ( Printer->printer_type == SPLHND_PRINTER )
7965 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7968 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7969 if (!W_ERROR_IS_OK(status))
7973 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7974 and not a printer admin, then fail */
7976 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7977 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7978 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7980 p->server_info->ptok,
7981 lp_printer_admin(snum))) {
7982 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7983 status = WERR_ACCESS_DENIED;
7987 switch (form->flags) {
7988 case SPOOLSS_FORM_USER:
7989 case SPOOLSS_FORM_BUILTIN:
7990 case SPOOLSS_FORM_PRINTER:
7993 status = WERR_INVALID_PARAM;
7997 /* can't add if builtin */
7999 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8000 status = WERR_FILE_EXISTS;
8004 count = get_ntforms(&list);
8006 for (i=0; i < count; i++) {
8007 if (strequal(form->form_name, list[i].name)) {
8008 status = WERR_FILE_EXISTS;
8013 if(!add_a_form(&list, form, &count)) {
8014 status = WERR_NOMEM;
8019 write_ntforms(&list, count);
8023 * ChangeID must always be set if this is a printer
8026 if ( Printer->printer_type == SPLHND_PRINTER )
8027 status = mod_a_printer(printer, 2);
8031 free_a_printer(&printer, 2);
8037 /****************************************************************
8039 ****************************************************************/
8041 WERROR _spoolss_DeleteForm(pipes_struct *p,
8042 struct spoolss_DeleteForm *r)
8044 const char *form_name = r->in.form_name;
8045 nt_forms_struct tmpForm;
8047 nt_forms_struct *list=NULL;
8048 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8050 WERROR status = WERR_OK;
8051 NT_PRINTER_INFO_LEVEL *printer = NULL;
8052 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8055 DEBUG(5,("_spoolss_DeleteForm\n"));
8058 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8059 OUR_HANDLE(r->in.handle)));
8063 /* forms can be deleted on printer of on the print server handle */
8065 if ( Printer->printer_type == SPLHND_PRINTER )
8067 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8070 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8071 if (!W_ERROR_IS_OK(status))
8075 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8076 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8077 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8079 p->server_info->ptok,
8080 lp_printer_admin(snum))) {
8081 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8082 return WERR_ACCESS_DENIED;
8086 /* can't delete if builtin */
8088 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8089 status = WERR_INVALID_PARAM;
8093 count = get_ntforms(&list);
8096 ret = delete_a_form(&list, form_name, &count, &status);
8103 * ChangeID must always be set if this is a printer
8106 if ( Printer->printer_type == SPLHND_PRINTER )
8107 status = mod_a_printer(printer, 2);
8111 free_a_printer(&printer, 2);
8117 /****************************************************************
8119 ****************************************************************/
8121 WERROR _spoolss_SetForm(pipes_struct *p,
8122 struct spoolss_SetForm *r)
8124 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8125 nt_forms_struct tmpForm;
8127 WERROR status = WERR_OK;
8128 NT_PRINTER_INFO_LEVEL *printer = NULL;
8129 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8132 nt_forms_struct *list=NULL;
8133 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8135 DEBUG(5,("_spoolss_SetForm\n"));
8138 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8139 OUR_HANDLE(r->in.handle)));
8143 /* forms can be modified on printer of on the print server handle */
8145 if ( Printer->printer_type == SPLHND_PRINTER )
8147 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8150 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8151 if (!W_ERROR_IS_OK(status))
8155 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8156 and not a printer admin, then fail */
8158 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8159 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8160 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8162 p->server_info->ptok,
8163 lp_printer_admin(snum))) {
8164 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8165 status = WERR_ACCESS_DENIED;
8169 /* can't set if builtin */
8170 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8171 status = WERR_INVALID_PARAM;
8175 count = get_ntforms(&list);
8176 update_a_form(&list, form, count);
8178 write_ntforms(&list, count);
8182 * ChangeID must always be set if this is a printer
8185 if ( Printer->printer_type == SPLHND_PRINTER )
8186 status = mod_a_printer(printer, 2);
8191 free_a_printer(&printer, 2);
8197 /****************************************************************************
8198 fill_print_processor1
8199 ****************************************************************************/
8201 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8202 struct spoolss_PrintProcessorInfo1 *r,
8203 const char *print_processor_name)
8205 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8206 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8211 /****************************************************************************
8212 enumprintprocessors level 1.
8213 ****************************************************************************/
8215 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8216 union spoolss_PrintProcessorInfo **info_p,
8219 union spoolss_PrintProcessorInfo *info;
8222 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8223 W_ERROR_HAVE_NO_MEMORY(info);
8227 result = fill_print_processor1(info, &info[0].info1, "winprint");
8228 if (!W_ERROR_IS_OK(result)) {
8233 if (!W_ERROR_IS_OK(result)) {
8244 /****************************************************************
8245 _spoolss_EnumPrintProcessors
8246 ****************************************************************/
8248 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8249 struct spoolss_EnumPrintProcessors *r)
8253 /* that's an [in out] buffer */
8255 if (!r->in.buffer && (r->in.offered != 0)) {
8256 return WERR_INVALID_PARAM;
8259 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8262 * Enumerate the print processors ...
8264 * Just reply with "winprint", to keep NT happy
8265 * and I can use my nice printer checker.
8270 *r->out.info = NULL;
8272 switch (r->in.level) {
8274 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8278 return WERR_UNKNOWN_LEVEL;
8281 if (!W_ERROR_IS_OK(result)) {
8285 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8286 spoolss_EnumPrintProcessors, NULL,
8287 *r->out.info, r->in.level,
8289 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8290 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8292 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8295 /****************************************************************************
8296 fill_printprocdatatype1
8297 ****************************************************************************/
8299 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8300 struct spoolss_PrintProcDataTypesInfo1 *r,
8301 const char *name_array)
8303 r->name_array = talloc_strdup(mem_ctx, name_array);
8304 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8309 /****************************************************************************
8310 enumprintprocdatatypes level 1.
8311 ****************************************************************************/
8313 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8314 union spoolss_PrintProcDataTypesInfo **info_p,
8318 union spoolss_PrintProcDataTypesInfo *info;
8320 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8321 W_ERROR_HAVE_NO_MEMORY(info);
8325 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8326 if (!W_ERROR_IS_OK(result)) {
8331 if (!W_ERROR_IS_OK(result)) {
8342 /****************************************************************
8343 _spoolss_EnumPrintProcDataTypes
8344 ****************************************************************/
8346 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8347 struct spoolss_EnumPrintProcDataTypes *r)
8351 /* that's an [in out] buffer */
8353 if (!r->in.buffer && (r->in.offered != 0)) {
8354 return WERR_INVALID_PARAM;
8357 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8361 *r->out.info = NULL;
8363 switch (r->in.level) {
8365 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8369 return WERR_UNKNOWN_LEVEL;
8372 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8373 spoolss_EnumPrintProcDataTypes, NULL,
8374 *r->out.info, r->in.level,
8376 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8377 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8379 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8382 /****************************************************************************
8384 ****************************************************************************/
8386 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8387 struct spoolss_MonitorInfo1 *r,
8388 const char *monitor_name)
8390 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8391 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8396 /****************************************************************************
8398 ****************************************************************************/
8400 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8401 struct spoolss_MonitorInfo2 *r,
8402 const char *monitor_name,
8403 const char *environment,
8404 const char *dll_name)
8406 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8407 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8408 r->environment = talloc_strdup(mem_ctx, environment);
8409 W_ERROR_HAVE_NO_MEMORY(r->environment);
8410 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8411 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8416 /****************************************************************************
8417 enumprintmonitors level 1.
8418 ****************************************************************************/
8420 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8421 union spoolss_MonitorInfo **info_p,
8424 union spoolss_MonitorInfo *info;
8425 WERROR result = WERR_OK;
8427 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8428 W_ERROR_HAVE_NO_MEMORY(info);
8432 result = fill_monitor_1(info, &info[0].info1,
8434 if (!W_ERROR_IS_OK(result)) {
8438 result = fill_monitor_1(info, &info[1].info1,
8440 if (!W_ERROR_IS_OK(result)) {
8445 if (!W_ERROR_IS_OK(result)) {
8456 /****************************************************************************
8457 enumprintmonitors level 2.
8458 ****************************************************************************/
8460 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8461 union spoolss_MonitorInfo **info_p,
8464 union spoolss_MonitorInfo *info;
8465 WERROR result = WERR_OK;
8467 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8468 W_ERROR_HAVE_NO_MEMORY(info);
8472 result = fill_monitor_2(info, &info[0].info2,
8474 "Windows NT X86", /* FIXME */
8476 if (!W_ERROR_IS_OK(result)) {
8480 result = fill_monitor_2(info, &info[1].info2,
8482 "Windows NT X86", /* FIXME */
8484 if (!W_ERROR_IS_OK(result)) {
8489 if (!W_ERROR_IS_OK(result)) {
8500 /****************************************************************
8501 _spoolss_EnumMonitors
8502 ****************************************************************/
8504 WERROR _spoolss_EnumMonitors(pipes_struct *p,
8505 struct spoolss_EnumMonitors *r)
8509 /* that's an [in out] buffer */
8511 if (!r->in.buffer && (r->in.offered != 0)) {
8512 return WERR_INVALID_PARAM;
8515 DEBUG(5,("_spoolss_EnumMonitors\n"));
8518 * Enumerate the print monitors ...
8520 * Just reply with "Local Port", to keep NT happy
8521 * and I can use my nice printer checker.
8526 *r->out.info = NULL;
8528 switch (r->in.level) {
8530 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8534 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8538 return WERR_UNKNOWN_LEVEL;
8541 if (!W_ERROR_IS_OK(result)) {
8545 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8546 spoolss_EnumMonitors, NULL,
8547 *r->out.info, r->in.level,
8549 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8550 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8552 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8555 /****************************************************************************
8556 ****************************************************************************/
8558 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8559 const print_queue_struct *queue,
8560 int count, int snum,
8561 const NT_PRINTER_INFO_LEVEL *ntprinter,
8563 struct spoolss_JobInfo1 *r)
8568 for (i=0; i<count; i++) {
8569 if (queue[i].job == (int)jobid) {
8575 if (found == false) {
8576 /* NT treats not found as bad param... yet another bad choice */
8577 return WERR_INVALID_PARAM;
8580 return fill_job_info1(mem_ctx,
8588 /****************************************************************************
8589 ****************************************************************************/
8591 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8592 const print_queue_struct *queue,
8593 int count, int snum,
8594 const NT_PRINTER_INFO_LEVEL *ntprinter,
8596 struct spoolss_JobInfo2 *r)
8600 struct spoolss_DeviceMode *devmode;
8601 NT_DEVICEMODE *nt_devmode;
8604 for (i=0; i<count; i++) {
8605 if (queue[i].job == (int)jobid) {
8611 if (found == false) {
8612 /* NT treats not found as bad param... yet another bad
8614 return WERR_INVALID_PARAM;
8618 * if the print job does not have a DEVMODE associated with it,
8619 * just use the one for the printer. A NULL devicemode is not
8620 * a failure condition
8623 nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8625 devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
8626 W_ERROR_HAVE_NO_MEMORY(devmode);
8627 result = convert_nt_devicemode(devmode, devmode, nt_devmode);
8628 if (!W_ERROR_IS_OK(result)) {
8632 devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
8633 W_ERROR_HAVE_NO_MEMORY(devmode);
8636 return fill_job_info2(mem_ctx,
8645 /****************************************************************
8647 ****************************************************************/
8649 WERROR _spoolss_GetJob(pipes_struct *p,
8650 struct spoolss_GetJob *r)
8652 WERROR result = WERR_OK;
8653 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
8656 print_queue_struct *queue = NULL;
8657 print_status_struct prt_status;
8659 /* that's an [in out] buffer */
8661 if (!r->in.buffer && (r->in.offered != 0)) {
8662 return WERR_INVALID_PARAM;
8665 DEBUG(5,("_spoolss_GetJob\n"));
8669 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8673 result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
8674 if (!W_ERROR_IS_OK(result)) {
8678 count = print_queue_status(snum, &queue, &prt_status);
8680 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8681 count, prt_status.status, prt_status.message));
8683 switch (r->in.level) {
8685 result = getjob_level_1(p->mem_ctx,
8686 queue, count, snum, ntprinter,
8687 r->in.job_id, &r->out.info->info1);
8690 result = getjob_level_2(p->mem_ctx,
8691 queue, count, snum, ntprinter,
8692 r->in.job_id, &r->out.info->info2);
8695 result = WERR_UNKNOWN_LEVEL;
8700 free_a_printer(&ntprinter, 2);
8702 if (!W_ERROR_IS_OK(result)) {
8703 TALLOC_FREE(r->out.info);
8707 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL,
8708 r->out.info, r->in.level);
8709 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8711 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8714 /****************************************************************
8715 _spoolss_GetPrinterDataEx
8716 ****************************************************************/
8718 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8719 struct spoolss_GetPrinterDataEx *r)
8722 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8723 struct regval_blob *val = NULL;
8724 NT_PRINTER_INFO_LEVEL *printer = NULL;
8726 WERROR result = WERR_OK;
8729 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8731 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8732 r->in.key_name, r->in.value_name));
8734 /* in case of problem, return some default values */
8737 *r->out.type = REG_NONE;
8740 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8741 OUR_HANDLE(r->in.handle)));
8742 result = WERR_BADFID;
8746 /* Is the handle to a printer or to the server? */
8748 if (Printer->printer_type == SPLHND_SERVER) {
8750 union spoolss_PrinterData data;
8752 result = getprinterdata_printer_server(p->mem_ctx,
8756 if (!W_ERROR_IS_OK(result)) {
8760 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8761 *r->out.type, &data);
8762 if (!W_ERROR_IS_OK(result)) {
8766 *r->out.needed = blob.length;
8768 if (r->in.offered >= *r->out.needed) {
8769 memcpy(r->out.data, blob.data, blob.length);
8772 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8775 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8776 result = WERR_BADFID;
8780 result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8781 if (!W_ERROR_IS_OK(result)) {
8785 /* check to see if the keyname is valid */
8786 if (!strlen(r->in.key_name)) {
8787 result = WERR_INVALID_PARAM;
8791 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
8793 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8794 strequal(r->in.value_name, "ChangeId")) {
8795 *r->out.type = REG_DWORD;
8797 if (r->in.offered >= *r->out.needed) {
8798 SIVAL(r->out.data, 0, printer->info_2->changeid);
8804 if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
8805 DEBUG(4,("_spoolss_GetPrinterDataEx: "
8806 "Invalid keyname [%s]\n", r->in.key_name ));
8807 result = WERR_BADFILE;
8811 val = get_printer_data(printer->info_2,
8812 r->in.key_name, r->in.value_name);
8814 result = WERR_BADFILE;
8818 *r->out.needed = regval_size(val);
8819 *r->out.type = regval_type(val);
8821 if (r->in.offered >= *r->out.needed) {
8822 memcpy(r->out.data, regval_data_p(val), regval_size(val));
8826 free_a_printer(&printer, 2);
8829 if (!W_ERROR_IS_OK(result)) {
8833 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8834 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8836 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8839 /****************************************************************
8840 _spoolss_SetPrinterDataEx
8841 ****************************************************************/
8843 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8844 struct spoolss_SetPrinterDataEx *r)
8846 NT_PRINTER_INFO_LEVEL *printer = NULL;
8848 WERROR result = WERR_OK;
8849 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8852 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8854 /* From MSDN documentation of SetPrinterDataEx: pass request to
8855 SetPrinterData if key is "PrinterDriverData" */
8858 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8859 OUR_HANDLE(r->in.handle)));
8863 if (Printer->printer_type == SPLHND_SERVER) {
8864 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8865 "Not implemented for server handles yet\n"));
8866 return WERR_INVALID_PARAM;
8869 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8874 * Access check : NT returns "access denied" if you make a
8875 * SetPrinterData call without the necessary privildge.
8876 * we were originally returning OK if nothing changed
8877 * which made Win2k issue **a lot** of SetPrinterData
8878 * when connecting to a printer --jerry
8881 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8882 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8883 "change denied by handle access permissions\n"));
8884 return WERR_ACCESS_DENIED;
8887 result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8888 if (!W_ERROR_IS_OK(result)) {
8892 /* check for OID in valuename */
8894 oid_string = strchr(r->in.value_name, ',');
8901 * When client side code sets a magic printer data key, detect it and save
8902 * the current printer data and the magic key's data (its the DEVMODE) for
8903 * future printer/driver initializations.
8905 if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
8906 /* Set devmode and printer initialization info */
8907 result = save_driver_init(printer, 2, r->in.data, r->in.offered);
8909 srv_spoolss_reset_printerdata(printer->info_2->drivername);
8914 /* save the registry data */
8916 result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
8917 r->in.type, r->in.data, r->in.offered);
8919 if (W_ERROR_IS_OK(result)) {
8920 /* save the OID if one was specified */
8922 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8923 r->in.key_name, SPOOL_OID_KEY);
8925 result = WERR_NOMEM;
8930 * I'm not checking the status here on purpose. Don't know
8931 * if this is right, but I'm returning the status from the
8932 * previous set_printer_dataex() call. I have no idea if
8933 * this is right. --jerry
8936 set_printer_dataex(printer, str, r->in.value_name,
8937 REG_SZ, (uint8_t *)oid_string,
8938 strlen(oid_string)+1);
8941 result = mod_a_printer(printer, 2);
8945 free_a_printer(&printer, 2);
8950 /****************************************************************
8951 _spoolss_DeletePrinterDataEx
8952 ****************************************************************/
8954 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8955 struct spoolss_DeletePrinterDataEx *r)
8957 NT_PRINTER_INFO_LEVEL *printer = NULL;
8959 WERROR status = WERR_OK;
8960 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8962 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8965 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8966 "Invalid handle (%s:%u:%u).\n",
8967 OUR_HANDLE(r->in.handle)));
8971 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8974 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8975 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8976 "printer properties change denied by handle\n"));
8977 return WERR_ACCESS_DENIED;
8980 if (!r->in.value_name || !r->in.key_name) {
8984 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8985 if (!W_ERROR_IS_OK(status))
8988 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
8990 if ( W_ERROR_IS_OK(status) )
8991 mod_a_printer( printer, 2 );
8993 free_a_printer(&printer, 2);
8998 /****************************************************************
8999 _spoolss_EnumPrinterKey
9000 ****************************************************************/
9002 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
9003 struct spoolss_EnumPrinterKey *r)
9005 fstring *keynames = NULL;
9007 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9008 NT_PRINTER_DATA *data;
9009 NT_PRINTER_INFO_LEVEL *printer = NULL;
9011 WERROR result = WERR_BADFILE;
9013 const char **array = NULL;
9016 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9019 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9020 OUR_HANDLE(r->in.handle)));
9024 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9028 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9029 if (!W_ERROR_IS_OK(result)) {
9033 /* get the list of subkey names */
9035 data = printer->info_2->data;
9037 num_keys = get_printer_subkeys(data, r->in.key_name, &keynames);
9038 if (num_keys == -1) {
9039 result = WERR_BADFILE;
9043 array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 2);
9045 result = WERR_NOMEM;
9050 array[0] = talloc_strdup(array, "");
9052 result = WERR_NOMEM;
9057 for (i=0; i < num_keys; i++) {
9059 DEBUG(10,("_spoolss_EnumPrinterKey: adding keyname: %s\n",
9062 array[i] = talloc_strdup(array, keynames[i]);
9064 result = WERR_NOMEM;
9069 if (!push_reg_multi_sz(p->mem_ctx, NULL, &blob, array)) {
9070 result = WERR_NOMEM;
9074 *r->out._ndr_size = r->in.offered / 2;
9075 *r->out.needed = blob.length;
9077 if (r->in.offered < *r->out.needed) {
9078 result = WERR_MORE_DATA;
9081 r->out.key_buffer->string_array = array;
9085 if (!W_ERROR_IS_OK(result)) {
9087 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9092 free_a_printer(&printer, 2);
9093 SAFE_FREE(keynames);
9098 /****************************************************************
9099 _spoolss_DeletePrinterKey
9100 ****************************************************************/
9102 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9103 struct spoolss_DeletePrinterKey *r)
9105 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9106 NT_PRINTER_INFO_LEVEL *printer = NULL;
9110 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9113 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9114 OUR_HANDLE(r->in.handle)));
9118 /* if keyname == NULL, return error */
9120 if ( !r->in.key_name )
9121 return WERR_INVALID_PARAM;
9123 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
9126 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9127 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9128 "printer properties change denied by handle\n"));
9129 return WERR_ACCESS_DENIED;
9132 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9133 if (!W_ERROR_IS_OK(status))
9136 /* delete the key and all subneys */
9138 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9140 if ( W_ERROR_IS_OK(status) )
9141 status = mod_a_printer(printer, 2);
9143 free_a_printer( &printer, 2 );
9148 /****************************************************************
9149 ****************************************************************/
9151 static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
9152 struct regval_blob *v,
9153 struct spoolss_PrinterEnumValues *r)
9155 r->data = TALLOC_ZERO_P(mem_ctx, DATA_BLOB);
9156 W_ERROR_HAVE_NO_MEMORY(r->data);
9158 r->value_name = talloc_strdup(mem_ctx, regval_name(v));
9159 W_ERROR_HAVE_NO_MEMORY(r->value_name);
9161 r->value_name_len = strlen_m_term(regval_name(v)) * 2;
9163 r->type = regval_type(v);
9164 r->data_length = regval_size(v);
9166 if (r->data_length) {
9167 *r->data = data_blob_talloc(r->data, regval_data_p(v), regval_size(v));
9173 /****************************************************************
9174 _spoolss_EnumPrinterDataEx
9175 ****************************************************************/
9177 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
9178 struct spoolss_EnumPrinterDataEx *r)
9181 NT_PRINTER_INFO_LEVEL *printer = NULL;
9182 struct spoolss_PrinterEnumValues *info = NULL;
9183 NT_PRINTER_DATA *p_data;
9184 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9190 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9194 *r->out.info = NULL;
9197 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9198 OUR_HANDLE(r->in.handle)));
9203 * first check for a keyname of NULL or "". Win2k seems to send
9204 * this a lot and we should send back WERR_INVALID_PARAM
9205 * no need to spend time looking up the printer in this case.
9209 if (!strlen(r->in.key_name)) {
9210 result = WERR_INVALID_PARAM;
9214 /* get the printer off of disk */
9216 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9220 ZERO_STRUCT(printer);
9221 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9222 if (!W_ERROR_IS_OK(result)) {
9226 /* now look for a match on the key name */
9228 p_data = printer->info_2->data;
9230 key_index = lookup_printerkey(p_data, r->in.key_name);
9231 if (key_index == -1) {
9232 DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
9234 result = WERR_INVALID_PARAM;
9238 /* allocate the memory for the array of pointers -- if necessary */
9240 count = regval_ctr_numvals(p_data->keys[key_index].values);
9242 result = WERR_OK; /* ??? */
9246 info = TALLOC_ZERO_ARRAY(p->mem_ctx,
9247 struct spoolss_PrinterEnumValues,
9250 DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
9251 result = WERR_NOMEM;
9256 * loop through all params and build the array to pass
9257 * back to the client
9260 for (i=0; i < count; i++) {
9262 struct regval_blob *val;
9264 /* lookup the registry value */
9266 val = regval_ctr_specific_value(p_data->keys[key_index].values, i);
9268 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val)));
9272 result = registry_value_to_printer_enum_value(info, val, &info[i]);
9273 if (!W_ERROR_IS_OK(result)) {
9278 #if 0 /* FIXME - gd */
9279 /* housekeeping information in the reply */
9281 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9282 * the hand marshalled container size is a multiple
9283 * of 4 bytes for RPC alignment.
9287 needed += 4-(needed % 4);
9290 *r->out.count = count;
9291 *r->out.info = info;
9296 free_a_printer(&printer, 2);
9299 if (!W_ERROR_IS_OK(result)) {
9303 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9304 spoolss_EnumPrinterDataEx, NULL,
9307 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9308 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9310 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9313 /****************************************************************************
9314 ****************************************************************************/
9316 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9317 const char *servername,
9318 const char *environment,
9319 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9324 werr = compose_spoolss_server_path(mem_ctx,
9327 SPOOLSS_PRTPROCS_PATH,
9329 if (!W_ERROR_IS_OK(werr)) {
9333 DEBUG(4,("print processor directory: [%s]\n", path));
9335 r->directory_name = path;
9340 /****************************************************************
9341 _spoolss_GetPrintProcessorDirectory
9342 ****************************************************************/
9344 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9345 struct spoolss_GetPrintProcessorDirectory *r)
9349 /* that's an [in out] buffer */
9351 if (!r->in.buffer && (r->in.offered != 0)) {
9352 return WERR_INVALID_PARAM;
9355 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9360 /* r->in.level is ignored */
9362 /* We always should reply with a local print processor directory so that
9363 * users are not forced to have a [prnproc$] share on the Samba spoolss
9364 * server - Guenther */
9366 result = getprintprocessordirectory_level_1(p->mem_ctx,
9367 NULL, /* r->in.server */
9369 &r->out.info->info1);
9370 if (!W_ERROR_IS_OK(result)) {
9371 TALLOC_FREE(r->out.info);
9375 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL,
9376 r->out.info, r->in.level);
9377 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9379 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9382 /*******************************************************************
9383 ********************************************************************/
9385 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9386 const char *dllname)
9388 enum ndr_err_code ndr_err;
9389 struct spoolss_MonitorUi ui;
9391 ui.dll_name = dllname;
9393 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9394 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9395 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9396 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9398 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9401 /*******************************************************************
9402 Streams the monitor UI DLL name in UNICODE
9403 *******************************************************************/
9405 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9406 NT_USER_TOKEN *token, DATA_BLOB *in,
9407 DATA_BLOB *out, uint32_t *needed)
9409 const char *dllname = "tcpmonui.dll";
9411 *needed = (strlen(dllname)+1) * 2;
9413 if (out->length < *needed) {
9414 return WERR_INSUFFICIENT_BUFFER;
9417 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9424 /*******************************************************************
9425 ********************************************************************/
9427 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9428 struct spoolss_PortData1 *port1,
9429 const DATA_BLOB *buf)
9431 enum ndr_err_code ndr_err;
9432 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9433 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9434 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9435 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9437 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9440 /*******************************************************************
9441 ********************************************************************/
9443 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9444 struct spoolss_PortData2 *port2,
9445 const DATA_BLOB *buf)
9447 enum ndr_err_code ndr_err;
9448 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9449 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9450 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9451 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9453 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9456 /*******************************************************************
9457 Create a new TCP/IP port
9458 *******************************************************************/
9460 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9461 NT_USER_TOKEN *token, DATA_BLOB *in,
9462 DATA_BLOB *out, uint32_t *needed)
9464 struct spoolss_PortData1 port1;
9465 struct spoolss_PortData2 port2;
9466 char *device_uri = NULL;
9469 const char *portname;
9470 const char *hostaddress;
9472 uint32_t port_number;
9475 /* peek for spoolss_PortData version */
9477 if (!in || (in->length < (128 + 4))) {
9478 return WERR_GENERAL_FAILURE;
9481 version = IVAL(in->data, 128);
9487 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9491 portname = port1.portname;
9492 hostaddress = port1.hostaddress;
9493 queue = port1.queue;
9494 protocol = port1.protocol;
9495 port_number = port1.port_number;
9501 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9505 portname = port2.portname;
9506 hostaddress = port2.hostaddress;
9507 queue = port2.queue;
9508 protocol = port2.protocol;
9509 port_number = port2.port_number;
9513 DEBUG(1,("xcvtcp_addport: "
9514 "unknown version of port_data: %d\n", version));
9515 return WERR_UNKNOWN_PORT;
9518 /* create the device URI and call the add_port_hook() */
9521 case PROTOCOL_RAWTCP_TYPE:
9522 device_uri = talloc_asprintf(mem_ctx,
9523 "socket://%s:%d/", hostaddress,
9527 case PROTOCOL_LPR_TYPE:
9528 device_uri = talloc_asprintf(mem_ctx,
9529 "lpr://%s/%s", hostaddress, queue );
9533 return WERR_UNKNOWN_PORT;
9540 return add_port_hook(mem_ctx, token, portname, device_uri);
9543 /*******************************************************************
9544 *******************************************************************/
9546 struct xcv_api_table xcvtcp_cmds[] = {
9547 { "MonitorUI", xcvtcp_monitorui },
9548 { "AddPort", xcvtcp_addport},
9552 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9553 NT_USER_TOKEN *token, const char *command,
9560 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9562 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9563 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9564 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9567 return WERR_BADFUNC;
9570 /*******************************************************************
9571 *******************************************************************/
9572 #if 0 /* don't support management using the "Local Port" monitor */
9574 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9575 NT_USER_TOKEN *token, DATA_BLOB *in,
9576 DATA_BLOB *out, uint32_t *needed)
9578 const char *dllname = "localui.dll";
9580 *needed = (strlen(dllname)+1) * 2;
9582 if (out->length < *needed) {
9583 return WERR_INSUFFICIENT_BUFFER;
9586 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9593 /*******************************************************************
9594 *******************************************************************/
9596 struct xcv_api_table xcvlocal_cmds[] = {
9597 { "MonitorUI", xcvlocal_monitorui },
9601 struct xcv_api_table xcvlocal_cmds[] = {
9608 /*******************************************************************
9609 *******************************************************************/
9611 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9612 NT_USER_TOKEN *token, const char *command,
9613 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9618 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9620 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9621 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9622 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9624 return WERR_BADFUNC;
9627 /****************************************************************
9629 ****************************************************************/
9631 WERROR _spoolss_XcvData(pipes_struct *p,
9632 struct spoolss_XcvData *r)
9634 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9635 DATA_BLOB out_data = data_blob_null;
9639 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9640 OUR_HANDLE(r->in.handle)));
9644 /* Has to be a handle to the TCP/IP port monitor */
9646 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9647 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9651 /* requires administrative access to the server */
9653 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9654 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9655 return WERR_ACCESS_DENIED;
9658 /* Allocate the outgoing buffer */
9660 if (r->in.out_data_size) {
9661 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9662 if (out_data.data == NULL) {
9667 switch ( Printer->printer_type ) {
9668 case SPLHND_PORTMON_TCP:
9669 werror = process_xcvtcp_command(p->mem_ctx,
9670 p->server_info->ptok,
9671 r->in.function_name,
9672 &r->in.in_data, &out_data,
9675 case SPLHND_PORTMON_LOCAL:
9676 werror = process_xcvlocal_command(p->mem_ctx,
9677 p->server_info->ptok,
9678 r->in.function_name,
9679 &r->in.in_data, &out_data,
9683 werror = WERR_INVALID_PRINT_MONITOR;
9686 if (!W_ERROR_IS_OK(werror)) {
9690 *r->out.status_code = 0;
9692 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9693 memcpy(r->out.out_data, out_data.data,
9694 MIN(r->in.out_data_size, out_data.length));
9700 /****************************************************************
9701 _spoolss_AddPrintProcessor
9702 ****************************************************************/
9704 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9705 struct spoolss_AddPrintProcessor *r)
9707 /* for now, just indicate success and ignore the add. We'll
9708 automatically set the winprint processor for printer
9709 entries later. Used to debug the LexMark Optra S 1855 PCL
9715 /****************************************************************
9717 ****************************************************************/
9719 WERROR _spoolss_AddPort(pipes_struct *p,
9720 struct spoolss_AddPort *r)
9722 /* do what w2k3 does */
9724 return WERR_NOT_SUPPORTED;
9727 /****************************************************************
9728 _spoolss_GetPrinterDriver
9729 ****************************************************************/
9731 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9732 struct spoolss_GetPrinterDriver *r)
9734 p->rng_fault_state = true;
9735 return WERR_NOT_SUPPORTED;
9738 /****************************************************************
9739 _spoolss_ReadPrinter
9740 ****************************************************************/
9742 WERROR _spoolss_ReadPrinter(pipes_struct *p,
9743 struct spoolss_ReadPrinter *r)
9745 p->rng_fault_state = true;
9746 return WERR_NOT_SUPPORTED;
9749 /****************************************************************
9750 _spoolss_WaitForPrinterChange
9751 ****************************************************************/
9753 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9754 struct spoolss_WaitForPrinterChange *r)
9756 p->rng_fault_state = true;
9757 return WERR_NOT_SUPPORTED;
9760 /****************************************************************
9761 _spoolss_ConfigurePort
9762 ****************************************************************/
9764 WERROR _spoolss_ConfigurePort(pipes_struct *p,
9765 struct spoolss_ConfigurePort *r)
9767 p->rng_fault_state = true;
9768 return WERR_NOT_SUPPORTED;
9771 /****************************************************************
9773 ****************************************************************/
9775 WERROR _spoolss_DeletePort(pipes_struct *p,
9776 struct spoolss_DeletePort *r)
9778 p->rng_fault_state = true;
9779 return WERR_NOT_SUPPORTED;
9782 /****************************************************************
9783 _spoolss_CreatePrinterIC
9784 ****************************************************************/
9786 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9787 struct spoolss_CreatePrinterIC *r)
9789 p->rng_fault_state = true;
9790 return WERR_NOT_SUPPORTED;
9793 /****************************************************************
9794 _spoolss_PlayGDIScriptOnPrinterIC
9795 ****************************************************************/
9797 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9798 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9800 p->rng_fault_state = true;
9801 return WERR_NOT_SUPPORTED;
9804 /****************************************************************
9805 _spoolss_DeletePrinterIC
9806 ****************************************************************/
9808 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9809 struct spoolss_DeletePrinterIC *r)
9811 p->rng_fault_state = true;
9812 return WERR_NOT_SUPPORTED;
9815 /****************************************************************
9816 _spoolss_AddPrinterConnection
9817 ****************************************************************/
9819 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9820 struct spoolss_AddPrinterConnection *r)
9822 p->rng_fault_state = true;
9823 return WERR_NOT_SUPPORTED;
9826 /****************************************************************
9827 _spoolss_DeletePrinterConnection
9828 ****************************************************************/
9830 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9831 struct spoolss_DeletePrinterConnection *r)
9833 p->rng_fault_state = true;
9834 return WERR_NOT_SUPPORTED;
9837 /****************************************************************
9838 _spoolss_PrinterMessageBox
9839 ****************************************************************/
9841 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9842 struct spoolss_PrinterMessageBox *r)
9844 p->rng_fault_state = true;
9845 return WERR_NOT_SUPPORTED;
9848 /****************************************************************
9850 ****************************************************************/
9852 WERROR _spoolss_AddMonitor(pipes_struct *p,
9853 struct spoolss_AddMonitor *r)
9855 p->rng_fault_state = true;
9856 return WERR_NOT_SUPPORTED;
9859 /****************************************************************
9860 _spoolss_DeleteMonitor
9861 ****************************************************************/
9863 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9864 struct spoolss_DeleteMonitor *r)
9866 p->rng_fault_state = true;
9867 return WERR_NOT_SUPPORTED;
9870 /****************************************************************
9871 _spoolss_DeletePrintProcessor
9872 ****************************************************************/
9874 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9875 struct spoolss_DeletePrintProcessor *r)
9877 p->rng_fault_state = true;
9878 return WERR_NOT_SUPPORTED;
9881 /****************************************************************
9882 _spoolss_AddPrintProvidor
9883 ****************************************************************/
9885 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9886 struct spoolss_AddPrintProvidor *r)
9888 p->rng_fault_state = true;
9889 return WERR_NOT_SUPPORTED;
9892 /****************************************************************
9893 _spoolss_DeletePrintProvidor
9894 ****************************************************************/
9896 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9897 struct spoolss_DeletePrintProvidor *r)
9899 p->rng_fault_state = true;
9900 return WERR_NOT_SUPPORTED;
9903 /****************************************************************
9904 _spoolss_FindFirstPrinterChangeNotification
9905 ****************************************************************/
9907 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9908 struct spoolss_FindFirstPrinterChangeNotification *r)
9910 p->rng_fault_state = true;
9911 return WERR_NOT_SUPPORTED;
9914 /****************************************************************
9915 _spoolss_FindNextPrinterChangeNotification
9916 ****************************************************************/
9918 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9919 struct spoolss_FindNextPrinterChangeNotification *r)
9921 p->rng_fault_state = true;
9922 return WERR_NOT_SUPPORTED;
9925 /****************************************************************
9926 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9927 ****************************************************************/
9929 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9930 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9932 p->rng_fault_state = true;
9933 return WERR_NOT_SUPPORTED;
9936 /****************************************************************
9937 _spoolss_ReplyOpenPrinter
9938 ****************************************************************/
9940 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9941 struct spoolss_ReplyOpenPrinter *r)
9943 p->rng_fault_state = true;
9944 return WERR_NOT_SUPPORTED;
9947 /****************************************************************
9948 _spoolss_RouterReplyPrinter
9949 ****************************************************************/
9951 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9952 struct spoolss_RouterReplyPrinter *r)
9954 p->rng_fault_state = true;
9955 return WERR_NOT_SUPPORTED;
9958 /****************************************************************
9959 _spoolss_ReplyClosePrinter
9960 ****************************************************************/
9962 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9963 struct spoolss_ReplyClosePrinter *r)
9965 p->rng_fault_state = true;
9966 return WERR_NOT_SUPPORTED;
9969 /****************************************************************
9971 ****************************************************************/
9973 WERROR _spoolss_AddPortEx(pipes_struct *p,
9974 struct spoolss_AddPortEx *r)
9976 p->rng_fault_state = true;
9977 return WERR_NOT_SUPPORTED;
9980 /****************************************************************
9981 _spoolss_RouterFindFirstPrinterChangeNotification
9982 ****************************************************************/
9984 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9985 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9987 p->rng_fault_state = true;
9988 return WERR_NOT_SUPPORTED;
9991 /****************************************************************
9992 _spoolss_SpoolerInit
9993 ****************************************************************/
9995 WERROR _spoolss_SpoolerInit(pipes_struct *p,
9996 struct spoolss_SpoolerInit *r)
9998 p->rng_fault_state = true;
9999 return WERR_NOT_SUPPORTED;
10002 /****************************************************************
10003 _spoolss_ResetPrinterEx
10004 ****************************************************************/
10006 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10007 struct spoolss_ResetPrinterEx *r)
10009 p->rng_fault_state = true;
10010 return WERR_NOT_SUPPORTED;
10013 /****************************************************************
10014 _spoolss_RouterReplyPrinterEx
10015 ****************************************************************/
10017 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10018 struct spoolss_RouterReplyPrinterEx *r)
10020 p->rng_fault_state = true;
10021 return WERR_NOT_SUPPORTED;
10024 /****************************************************************
10026 ****************************************************************/
10028 WERROR _spoolss_44(pipes_struct *p,
10029 struct spoolss_44 *r)
10031 p->rng_fault_state = true;
10032 return WERR_NOT_SUPPORTED;
10035 /****************************************************************
10037 ****************************************************************/
10039 WERROR _spoolss_47(pipes_struct *p,
10040 struct spoolss_47 *r)
10042 p->rng_fault_state = true;
10043 return WERR_NOT_SUPPORTED;
10046 /****************************************************************
10048 ****************************************************************/
10050 WERROR _spoolss_4a(pipes_struct *p,
10051 struct spoolss_4a *r)
10053 p->rng_fault_state = true;
10054 return WERR_NOT_SUPPORTED;
10057 /****************************************************************
10059 ****************************************************************/
10061 WERROR _spoolss_4b(pipes_struct *p,
10062 struct spoolss_4b *r)
10064 p->rng_fault_state = true;
10065 return WERR_NOT_SUPPORTED;
10068 /****************************************************************
10070 ****************************************************************/
10072 WERROR _spoolss_4c(pipes_struct *p,
10073 struct spoolss_4c *r)
10075 p->rng_fault_state = true;
10076 return WERR_NOT_SUPPORTED;
10079 /****************************************************************
10081 ****************************************************************/
10083 WERROR _spoolss_53(pipes_struct *p,
10084 struct spoolss_53 *r)
10086 p->rng_fault_state = true;
10087 return WERR_NOT_SUPPORTED;
10090 /****************************************************************
10092 ****************************************************************/
10094 WERROR _spoolss_55(pipes_struct *p,
10095 struct spoolss_55 *r)
10097 p->rng_fault_state = true;
10098 return WERR_NOT_SUPPORTED;
10101 /****************************************************************
10103 ****************************************************************/
10105 WERROR _spoolss_56(pipes_struct *p,
10106 struct spoolss_56 *r)
10108 p->rng_fault_state = true;
10109 return WERR_NOT_SUPPORTED;
10112 /****************************************************************
10114 ****************************************************************/
10116 WERROR _spoolss_57(pipes_struct *p,
10117 struct spoolss_57 *r)
10119 p->rng_fault_state = true;
10120 return WERR_NOT_SUPPORTED;
10123 /****************************************************************
10125 ****************************************************************/
10127 WERROR _spoolss_5a(pipes_struct *p,
10128 struct spoolss_5a *r)
10130 p->rng_fault_state = true;
10131 return WERR_NOT_SUPPORTED;
10134 /****************************************************************
10136 ****************************************************************/
10138 WERROR _spoolss_5b(pipes_struct *p,
10139 struct spoolss_5b *r)
10141 p->rng_fault_state = true;
10142 return WERR_NOT_SUPPORTED;
10145 /****************************************************************
10147 ****************************************************************/
10149 WERROR _spoolss_5c(pipes_struct *p,
10150 struct spoolss_5c *r)
10152 p->rng_fault_state = true;
10153 return WERR_NOT_SUPPORTED;
10156 /****************************************************************
10158 ****************************************************************/
10160 WERROR _spoolss_5d(pipes_struct *p,
10161 struct spoolss_5d *r)
10163 p->rng_fault_state = true;
10164 return WERR_NOT_SUPPORTED;
10167 /****************************************************************
10169 ****************************************************************/
10171 WERROR _spoolss_5e(pipes_struct *p,
10172 struct spoolss_5e *r)
10174 p->rng_fault_state = true;
10175 return WERR_NOT_SUPPORTED;
10178 /****************************************************************
10180 ****************************************************************/
10182 WERROR _spoolss_5f(pipes_struct *p,
10183 struct spoolss_5f *r)
10185 p->rng_fault_state = true;
10186 return WERR_NOT_SUPPORTED;
10189 /****************************************************************
10191 ****************************************************************/
10193 WERROR _spoolss_60(pipes_struct *p,
10194 struct spoolss_60 *r)
10196 p->rng_fault_state = true;
10197 return WERR_NOT_SUPPORTED;
10200 /****************************************************************
10202 ****************************************************************/
10204 WERROR _spoolss_61(pipes_struct *p,
10205 struct spoolss_61 *r)
10207 p->rng_fault_state = true;
10208 return WERR_NOT_SUPPORTED;
10211 /****************************************************************
10213 ****************************************************************/
10215 WERROR _spoolss_62(pipes_struct *p,
10216 struct spoolss_62 *r)
10218 p->rng_fault_state = true;
10219 return WERR_NOT_SUPPORTED;
10222 /****************************************************************
10224 ****************************************************************/
10226 WERROR _spoolss_63(pipes_struct *p,
10227 struct spoolss_63 *r)
10229 p->rng_fault_state = true;
10230 return WERR_NOT_SUPPORTED;
10233 /****************************************************************
10235 ****************************************************************/
10237 WERROR _spoolss_64(pipes_struct *p,
10238 struct spoolss_64 *r)
10240 p->rng_fault_state = true;
10241 return WERR_NOT_SUPPORTED;
10244 /****************************************************************
10246 ****************************************************************/
10248 WERROR _spoolss_65(pipes_struct *p,
10249 struct spoolss_65 *r)
10251 p->rng_fault_state = true;
10252 return WERR_NOT_SUPPORTED;
10255 /****************************************************************
10256 _spoolss_GetCorePrinterDrivers
10257 ****************************************************************/
10259 WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
10260 struct spoolss_GetCorePrinterDrivers *r)
10262 p->rng_fault_state = true;
10263 return WERR_NOT_SUPPORTED;
10266 /****************************************************************
10268 ****************************************************************/
10270 WERROR _spoolss_67(pipes_struct *p,
10271 struct spoolss_67 *r)
10273 p->rng_fault_state = true;
10274 return WERR_NOT_SUPPORTED;
10277 /****************************************************************
10278 _spoolss_GetPrinterDriverPackagePath
10279 ****************************************************************/
10281 WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
10282 struct spoolss_GetPrinterDriverPackagePath *r)
10284 p->rng_fault_state = true;
10285 return WERR_NOT_SUPPORTED;
10288 /****************************************************************
10290 ****************************************************************/
10292 WERROR _spoolss_69(pipes_struct *p,
10293 struct spoolss_69 *r)
10295 p->rng_fault_state = true;
10296 return WERR_NOT_SUPPORTED;
10299 /****************************************************************
10301 ****************************************************************/
10303 WERROR _spoolss_6a(pipes_struct *p,
10304 struct spoolss_6a *r)
10306 p->rng_fault_state = true;
10307 return WERR_NOT_SUPPORTED;
10310 /****************************************************************
10312 ****************************************************************/
10314 WERROR _spoolss_6b(pipes_struct *p,
10315 struct spoolss_6b *r)
10317 p->rng_fault_state = true;
10318 return WERR_NOT_SUPPORTED;
10321 /****************************************************************
10323 ****************************************************************/
10325 WERROR _spoolss_6c(pipes_struct *p,
10326 struct spoolss_6c *r)
10328 p->rng_fault_state = true;
10329 return WERR_NOT_SUPPORTED;
10332 /****************************************************************
10334 ****************************************************************/
10336 WERROR _spoolss_6d(pipes_struct *p,
10337 struct spoolss_6d *r)
10339 p->rng_fault_state = true;
10340 return WERR_NOT_SUPPORTED;