2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009-2010.
11 * Copyright (C) Andreas Schneider 2010.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
39 #include "registry/reg_objects.h"
41 /* macros stolen from s4 spoolss server */
42 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
43 ((info)?ndr_size_##fn(info, level, 0):0)
45 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
46 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
48 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
49 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
51 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
54 extern userdom_struct current_user_info;
57 #define DBGC_CLASS DBGC_RPC_SRV
59 #ifndef MAX_OPEN_PRINTER_EXS
60 #define MAX_OPEN_PRINTER_EXS 50
63 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
65 static Printer_entry *printers_list;
67 typedef struct _counter_printer_0 {
68 struct _counter_printer_0 *next;
69 struct _counter_printer_0 *prev;
75 static counter_printer_0 *counter_list;
77 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
78 static uint32_t smb_connections = 0;
81 /* in printing/nt_printing.c */
83 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
85 /* API table for Xcv Monitor functions */
87 struct xcv_api_table {
89 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
92 /********************************************************************
93 * Canonicalize servername.
94 ********************************************************************/
96 static const char *canon_servername(const char *servername)
98 const char *pservername = servername;
99 while (*pservername == '\\') {
105 /* translate between internal status numbers and NT status numbers */
106 static int nt_printj_status(int v)
112 return JOB_STATUS_PAUSED;
114 return JOB_STATUS_SPOOLING;
116 return JOB_STATUS_PRINTING;
118 return JOB_STATUS_ERROR;
120 return JOB_STATUS_DELETING;
122 return JOB_STATUS_OFFLINE;
124 return JOB_STATUS_PAPEROUT;
126 return JOB_STATUS_PRINTED;
128 return JOB_STATUS_DELETED;
130 return JOB_STATUS_BLOCKED_DEVQ;
131 case LPQ_USER_INTERVENTION:
132 return JOB_STATUS_USER_INTERVENTION;
137 static int nt_printq_status(int v)
141 return PRINTER_STATUS_PAUSED;
150 /***************************************************************************
151 Disconnect from the client
152 ****************************************************************************/
154 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
160 * Tell the specific printing tdb we no longer want messages for this printer
161 * by deregistering our PID.
164 if (!print_notify_deregister_pid(snum))
165 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
167 /* weird if the test succeds !!! */
168 if (smb_connections==0) {
169 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
173 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
176 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
177 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
178 win_errstr(result)));
180 /* if it's the last connection, deconnect the IPC$ share */
181 if (smb_connections==1) {
183 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
184 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
186 messaging_deregister(smbd_messaging_context(),
187 MSG_PRINTER_NOTIFY2, NULL);
189 /* Tell the connections db we're no longer interested in
190 * printer notify messages. */
192 serverid_register_msg_flags(
193 messaging_server_id(smbd_messaging_context()),
194 false, FLAG_MSG_PRINT_NOTIFY);
200 /****************************************************************************
201 Functions to free a printer entry datastruct.
202 ****************************************************************************/
204 static int printer_entry_destructor(Printer_entry *Printer)
206 if (Printer->notify.client_connected == true) {
209 if ( Printer->printer_type == SPLHND_SERVER) {
211 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
212 } else if (Printer->printer_type == SPLHND_PRINTER) {
213 snum = print_queue_snum(Printer->sharename);
215 srv_spoolss_replycloseprinter(snum,
216 &Printer->notify.client_hnd);
220 Printer->notify.flags=0;
221 Printer->notify.options=0;
222 Printer->notify.localmachine[0]='\0';
223 Printer->notify.printerlocal=0;
224 TALLOC_FREE(Printer->notify.option);
225 Printer->notify.client_connected = false;
227 TALLOC_FREE(Printer->devmode);
229 /* Remove from the internal list. */
230 DLIST_REMOVE(printers_list, Printer);
234 /****************************************************************************
235 find printer index by handle
236 ****************************************************************************/
238 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
239 struct policy_handle *hnd)
241 Printer_entry *find_printer = NULL;
243 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
244 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
251 /****************************************************************************
252 Close printer index by handle.
253 ****************************************************************************/
255 static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
257 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
260 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
265 close_policy_hnd(p, hnd);
270 /****************************************************************************
271 Delete a printer given a handle.
272 ****************************************************************************/
274 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
276 char *cmd = lp_deleteprinter_cmd();
277 char *command = NULL;
279 SE_PRIV se_printop = SE_PRINT_OPERATOR;
280 bool is_print_op = false;
282 /* can't fail if we don't try */
287 command = talloc_asprintf(ctx,
294 is_print_op = user_has_privileges( token, &se_printop );
296 DEBUG(10,("Running [%s]\n", command));
298 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
303 if ( (ret = smbrun(command, NULL)) == 0 ) {
304 /* Tell everyone we updated smb.conf. */
305 message_send_all(smbd_messaging_context(),
306 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
312 /********** END SePrintOperatorPrivlege BLOCK **********/
314 DEBUGADD(10,("returned [%d]\n", ret));
316 TALLOC_FREE(command);
319 return WERR_BADFID; /* What to return here? */
321 /* go ahead and re-read the services immediately */
323 reload_services(false);
326 if ( lp_servicenumber( sharename ) > 0 )
327 return WERR_ACCESS_DENIED;
332 /****************************************************************************
333 Delete a printer given a handle.
334 ****************************************************************************/
336 static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
338 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
342 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
348 * It turns out that Windows allows delete printer on a handle
349 * opened by an admin user, then used on a pipe handle created
350 * by an anonymous user..... but they're working on security.... riiight !
354 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
355 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
356 return WERR_ACCESS_DENIED;
359 /* this does not need a become root since the access check has been
360 done on the handle already */
362 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
363 Printer->sharename, "");
364 if (!W_ERROR_IS_OK(result)) {
365 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
369 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
370 Printer->sharename );
373 /****************************************************************************
374 Return the snum of a printer corresponding to an handle.
375 ****************************************************************************/
377 static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
378 int *number, struct share_params **params)
380 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
383 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
388 switch (Printer->printer_type) {
390 DEBUG(4,("short name:%s\n", Printer->sharename));
391 *number = print_queue_snum(Printer->sharename);
392 return (*number != -1);
400 /****************************************************************************
401 Set printer handle type.
402 Check if it's \\server or \\server\printer
403 ****************************************************************************/
405 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
407 DEBUG(3,("Setting printer type=%s\n", handlename));
409 if ( strlen(handlename) < 3 ) {
410 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
414 /* it's a print server */
415 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
416 DEBUGADD(4,("Printer is a print server\n"));
417 Printer->printer_type = SPLHND_SERVER;
419 /* it's a printer (set_printer_hnd_name() will handle port monitors */
421 DEBUGADD(4,("Printer is a printer\n"));
422 Printer->printer_type = SPLHND_PRINTER;
428 /****************************************************************************
429 Set printer handle name.. Accept names like \\server, \\server\printer,
430 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
431 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
432 XcvDataPort() interface.
433 ****************************************************************************/
435 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
436 struct auth_serversupplied_info *server_info,
437 Printer_entry *Printer,
438 const char *handlename)
441 int n_services=lp_numservices();
443 const char *printername;
444 const char *servername;
447 struct spoolss_PrinterInfo2 *info2 = NULL;
450 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
451 (unsigned long)strlen(handlename)));
453 aprinter = CONST_DISCARD(char *, handlename);
454 if ( *handlename == '\\' ) {
455 servername = canon_servername(handlename);
456 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
460 if (!is_myname_or_ipaddr(servername)) {
464 fstrcpy(Printer->servername, servername);
467 if (Printer->printer_type == SPLHND_SERVER) {
471 if (Printer->printer_type != SPLHND_PRINTER) {
475 DEBUGADD(5, ("searching for [%s]\n", aprinter));
477 /* check for the Port Monitor Interface */
478 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
479 Printer->printer_type = SPLHND_PORTMON_TCP;
480 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
483 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
484 Printer->printer_type = SPLHND_PORTMON_LOCAL;
485 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
489 /* Search all sharenames first as this is easier than pulling
490 the printer_info_2 off of disk. Don't use find_service() since
491 that calls out to map_username() */
493 /* do another loop to look for printernames */
494 for (snum = 0; !found && snum < n_services; snum++) {
495 const char *printer = lp_const_servicename(snum);
497 /* no point going on if this is not a printer */
498 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
502 /* ignore [printers] share */
503 if (strequal(printer, "printers")) {
507 fstrcpy(sname, printer);
508 if (strequal(aprinter, printer)) {
513 /* no point looking up the printer object if
514 we aren't allowing printername != sharename */
515 if (lp_force_printername(snum)) {
519 result = winreg_get_printer(mem_ctx,
524 if ( !W_ERROR_IS_OK(result) ) {
525 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
526 sname, win_errstr(result)));
530 printername = strrchr(info2->printername, '\\');
531 if (printername == NULL) {
532 printername = info2->printername;
537 if (strequal(printername, aprinter)) {
542 DEBUGADD(10, ("printername: %s\n", printername));
548 DEBUGADD(4,("Printer not found\n"));
552 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
554 fstrcpy(Printer->sharename, sname);
559 /****************************************************************************
560 Find first available printer slot. creates a printer handle for you.
561 ****************************************************************************/
563 static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
564 const char *name, uint32_t access_granted)
566 Printer_entry *new_printer;
568 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
570 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
571 if (new_printer == NULL) {
574 talloc_set_destructor(new_printer, printer_entry_destructor);
576 if (!create_policy_hnd(p, hnd, new_printer)) {
577 TALLOC_FREE(new_printer);
581 /* Add to the internal list. */
582 DLIST_ADD(printers_list, new_printer);
584 new_printer->notify.option=NULL;
586 if (!set_printer_hnd_printertype(new_printer, name)) {
587 close_printer_handle(p, hnd);
591 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
592 close_printer_handle(p, hnd);
596 new_printer->access_granted = access_granted;
598 DEBUG(5, ("%d printer handles active\n",
599 (int)num_pipe_handles(p)));
604 /***************************************************************************
605 check to see if the client motify handle is monitoring the notification
606 given by (notify_type, notify_field).
607 **************************************************************************/
609 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
610 uint16_t notify_field)
615 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
616 uint16_t notify_field)
618 struct spoolss_NotifyOption *option = p->notify.option;
622 * Flags should always be zero when the change notify
623 * is registered by the client's spooler. A user Win32 app
624 * might use the flags though instead of the NOTIFY_OPTION_INFO
633 return is_monitoring_event_flags(
634 p->notify.flags, notify_type, notify_field);
636 for (i = 0; i < option->count; i++) {
638 /* Check match for notify_type */
640 if (option->types[i].type != notify_type)
643 /* Check match for field */
645 for (j = 0; j < option->types[i].count; j++) {
646 if (option->types[i].fields[j].field == notify_field) {
652 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
653 p->servername, p->sharename, notify_type, notify_field));
658 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
659 _data->data.integer[0] = _integer; \
660 _data->data.integer[1] = 0;
663 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
664 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
665 if (!_data->data.string.string) {\
666 _data->data.string.size = 0; \
668 _data->data.string.size = strlen_m_term(_p) * 2;
670 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
671 _data->data.devmode.devmode = _devmode;
673 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
674 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
675 if (!_data->data.sd.sd) { \
676 _data->data.sd.sd_size = 0; \
678 _data->data.sd.sd_size = \
679 ndr_size_security_descriptor(_data->data.sd.sd, 0);
681 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
686 struct spoolss_Time st;
690 if (!init_systemtime(&st, t)) {
694 p = talloc_array(mem_ctx, char, len);
700 * Systemtime must be linearized as a set of UINT16's.
701 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
704 SSVAL(p, 0, st.year);
705 SSVAL(p, 2, st.month);
706 SSVAL(p, 4, st.day_of_week);
708 SSVAL(p, 8, st.hour);
709 SSVAL(p, 10, st.minute);
710 SSVAL(p, 12, st.second);
711 SSVAL(p, 14, st.millisecond);
717 /* Convert a notification message to a struct spoolss_Notify */
719 static void notify_one_value(struct spoolss_notify_msg *msg,
720 struct spoolss_Notify *data,
723 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
726 static void notify_string(struct spoolss_notify_msg *msg,
727 struct spoolss_Notify *data,
730 /* The length of the message includes the trailing \0 */
732 data->data.string.size = msg->len * 2;
733 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
734 if (!data->data.string.string) {
735 data->data.string.size = 0;
740 static void notify_system_time(struct spoolss_notify_msg *msg,
741 struct spoolss_Notify *data,
744 data->data.string.string = NULL;
745 data->data.string.size = 0;
747 if (msg->len != sizeof(time_t)) {
748 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
753 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
754 &data->data.string.string,
755 &data->data.string.size);
758 struct notify2_message_table {
760 void (*fn)(struct spoolss_notify_msg *msg,
761 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
764 static struct notify2_message_table printer_notify_table[] = {
765 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
766 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
767 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
768 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
769 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
770 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
771 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
772 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
773 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
774 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
775 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
776 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
777 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
778 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
779 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
780 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
781 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
782 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
783 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
786 static struct notify2_message_table job_notify_table[] = {
787 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
788 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
789 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
790 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
791 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
792 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
793 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
794 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
795 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
796 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
797 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
798 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
799 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
800 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
801 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
802 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
803 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
804 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
805 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
806 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
807 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
808 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
809 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
810 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
814 /***********************************************************************
815 Allocate talloc context for container object
816 **********************************************************************/
818 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
823 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
828 /***********************************************************************
829 release all allocated memory and zero out structure
830 **********************************************************************/
832 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
838 talloc_destroy(ctr->ctx);
845 /***********************************************************************
846 **********************************************************************/
848 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
856 /***********************************************************************
857 **********************************************************************/
859 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
861 if ( !ctr || !ctr->msg_groups )
864 if ( idx >= ctr->num_groups )
867 return &ctr->msg_groups[idx];
871 /***********************************************************************
872 How many groups of change messages do we have ?
873 **********************************************************************/
875 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
880 return ctr->num_groups;
883 /***********************************************************************
884 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
885 **********************************************************************/
887 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
889 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
890 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
891 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
897 /* loop over all groups looking for a matching printer name */
899 for ( i=0; i<ctr->num_groups; i++ ) {
900 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
904 /* add a new group? */
906 if ( i == ctr->num_groups ) {
909 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
910 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
913 ctr->msg_groups = groups;
915 /* clear the new entry and set the printer name */
917 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
918 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
921 /* add the change messages; 'i' is the correct index now regardless */
923 msg_grp = &ctr->msg_groups[i];
927 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
928 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
931 msg_grp->msgs = msg_list;
933 new_slot = msg_grp->num_msgs-1;
934 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
936 /* need to allocate own copy of data */
939 msg_grp->msgs[new_slot].notify.data = (char *)
940 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
942 return ctr->num_groups;
945 static void construct_info_data(struct spoolss_Notify *info_data,
946 enum spoolss_NotifyType type,
947 uint16_t field, int id);
949 /***********************************************************************
950 Send a change notication message on all handles which have a call
952 **********************************************************************/
954 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
957 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
958 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
959 SPOOLSS_NOTIFY_MSG *messages;
960 int sending_msg_count;
963 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
967 messages = msg_group->msgs;
970 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
974 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
976 /* loop over all printers */
978 for (p = printers_list; p; p = p->next) {
979 struct spoolss_Notify *notifies;
984 /* Is there notification on this handle? */
986 if ( !p->notify.client_connected )
989 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
991 /* For this printer? Print servers always receive
994 if ( ( p->printer_type == SPLHND_PRINTER ) &&
995 ( !strequal(msg_group->printername, p->sharename) ) )
998 DEBUG(10,("Our printer\n"));
1000 /* allocate the max entries possible */
1002 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1007 /* build the array of change notifications */
1009 sending_msg_count = 0;
1011 for ( i=0; i<msg_group->num_msgs; i++ ) {
1012 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1014 /* Are we monitoring this event? */
1016 if (!is_monitoring_event(p, msg->type, msg->field))
1019 sending_msg_count++;
1022 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1023 msg->type, msg->field, p->sharename));
1026 * if the is a printer notification handle and not a job notification
1027 * type, then set the id to 0. Other wise just use what was specified
1030 * When registering change notification on a print server handle
1031 * we always need to send back the id (snum) matching the printer
1032 * for which the change took place. For change notify registered
1033 * on a printer handle, this does not matter and the id should be 0.
1038 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1044 /* Convert unix jobid to smb jobid */
1046 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1047 id = sysjob_to_jobid(msg->id);
1050 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1055 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1058 case PRINTER_NOTIFY_TYPE:
1059 if ( printer_notify_table[msg->field].fn )
1060 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1063 case JOB_NOTIFY_TYPE:
1064 if ( job_notify_table[msg->field].fn )
1065 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1069 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1076 if ( sending_msg_count ) {
1079 union spoolss_ReplyPrinterInfo info;
1080 struct spoolss_NotifyInfo info0;
1081 uint32_t reply_result;
1083 info0.version = 0x2;
1084 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1085 info0.count = count;
1086 info0.notifies = notifies;
1088 info.info0 = &info0;
1090 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1091 &p->notify.client_hnd,
1092 p->notify.change, /* color */
1095 0, /* reply_type, must be 0 */
1098 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1099 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1100 notify_cli_pipe->srv_name_slash,
1103 switch (reply_result) {
1106 case PRINTER_NOTIFY_INFO_DISCARDED:
1107 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1108 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1117 DEBUG(8,("send_notify2_changes: Exit...\n"));
1121 /***********************************************************************
1122 **********************************************************************/
1124 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1127 uint32_t tv_sec, tv_usec;
1130 /* Unpack message */
1132 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1135 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1137 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1140 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1141 &msg->notify.value[0], &msg->notify.value[1]);
1143 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1144 &msg->len, &msg->notify.data);
1146 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1147 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1149 tv->tv_sec = tv_sec;
1150 tv->tv_usec = tv_usec;
1153 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1154 msg->notify.value[1]));
1156 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1161 /********************************************************************
1162 Receive a notify2 message list
1163 ********************************************************************/
1165 static void receive_notify2_message_list(struct messaging_context *msg,
1168 struct server_id server_id,
1171 size_t msg_count, i;
1172 char *buf = (char *)data->data;
1175 SPOOLSS_NOTIFY_MSG notify;
1176 SPOOLSS_NOTIFY_MSG_CTR messages;
1179 if (data->length < 4) {
1180 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1184 msg_count = IVAL(buf, 0);
1187 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1189 if (msg_count == 0) {
1190 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1194 /* initialize the container */
1196 ZERO_STRUCT( messages );
1197 notify_msg_ctr_init( &messages );
1200 * build message groups for each printer identified
1201 * in a change_notify msg. Remember that a PCN message
1202 * includes the handle returned for the srv_spoolss_replyopenprinter()
1203 * call. Therefore messages are grouped according to printer handle.
1206 for ( i=0; i<msg_count; i++ ) {
1207 struct timeval msg_tv;
1209 if (msg_ptr + 4 - buf > data->length) {
1210 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1214 msg_len = IVAL(msg_ptr,0);
1217 if (msg_ptr + msg_len - buf > data->length) {
1218 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1222 /* unpack messages */
1224 ZERO_STRUCT( notify );
1225 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1228 /* add to correct list in container */
1230 notify_msg_ctr_addmsg( &messages, ¬ify );
1232 /* free memory that might have been allocated by notify2_unpack_msg() */
1234 if ( notify.len != 0 )
1235 SAFE_FREE( notify.notify.data );
1238 /* process each group of messages */
1240 num_groups = notify_msg_ctr_numgroups( &messages );
1241 for ( i=0; i<num_groups; i++ )
1242 send_notify2_changes( &messages, i );
1247 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1248 (uint32_t)msg_count ));
1250 notify_msg_ctr_destroy( &messages );
1255 /********************************************************************
1256 Send a message to ourself about new driver being installed
1257 so we can upgrade the information for each printer bound to this
1259 ********************************************************************/
1261 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1263 int len = strlen(drivername);
1268 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1271 messaging_send_buf(smbd_messaging_context(),
1272 messaging_server_id(smbd_messaging_context()),
1273 MSG_PRINTER_DRVUPGRADE,
1274 (uint8_t *)drivername, len+1);
1279 /**********************************************************************
1280 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1281 over all printers, upgrading ones as necessary
1282 **********************************************************************/
1284 void do_drv_upgrade_printer(struct messaging_context *msg,
1287 struct server_id server_id,
1290 TALLOC_CTX *tmp_ctx;
1291 struct auth_serversupplied_info *server_info = NULL;
1292 struct spoolss_PrinterInfo2 *pinfo2;
1295 const char *drivername;
1297 int n_services = lp_numservices();
1300 tmp_ctx = talloc_new(NULL);
1301 if (!tmp_ctx) return;
1303 status = make_server_info_system(tmp_ctx, &server_info);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 DEBUG(0, ("do_drv_upgrade_printer: "
1306 "Could not create system server_info\n"));
1310 len = MIN(data->length,sizeof(drivername)-1);
1311 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1313 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1317 DEBUG(10, ("do_drv_upgrade_printer: "
1318 "Got message for new driver [%s]\n", drivername));
1320 /* Iterate the printer list */
1322 for (snum = 0; snum < n_services; snum++) {
1323 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1327 result = winreg_get_printer(tmp_ctx, server_info, NULL,
1328 lp_const_servicename(snum),
1331 if (!W_ERROR_IS_OK(result)) {
1335 if (strcmp(drivername, pinfo2->drivername) != 0) {
1339 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1341 /* all we care about currently is the change_id */
1342 result = winreg_printer_update_changeid(tmp_ctx,
1344 pinfo2->printername);
1346 if (!W_ERROR_IS_OK(result)) {
1347 DEBUG(3, ("do_drv_upgrade_printer: "
1348 "Failed to update changeid [%s]\n",
1349 win_errstr(result)));
1355 talloc_free(tmp_ctx);
1358 /********************************************************************
1359 Update the cache for all printq's with a registered client
1361 ********************************************************************/
1363 void update_monitored_printq_cache( void )
1365 Printer_entry *printer = printers_list;
1368 /* loop through all printers and update the cache where
1369 client_connected == true */
1372 if ( (printer->printer_type == SPLHND_PRINTER)
1373 && printer->notify.client_connected )
1375 snum = print_queue_snum(printer->sharename);
1376 print_queue_status( snum, NULL, NULL );
1379 printer = printer->next;
1385 /****************************************************************
1386 _spoolss_OpenPrinter
1387 ****************************************************************/
1389 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1390 struct spoolss_OpenPrinter *r)
1392 struct spoolss_OpenPrinterEx e;
1395 ZERO_STRUCT(e.in.userlevel);
1397 e.in.printername = r->in.printername;
1398 e.in.datatype = r->in.datatype;
1399 e.in.devmode_ctr = r->in.devmode_ctr;
1400 e.in.access_mask = r->in.access_mask;
1403 e.out.handle = r->out.handle;
1405 werr = _spoolss_OpenPrinterEx(p, &e);
1407 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1408 /* OpenPrinterEx returns this for a bad
1409 * printer name. We must return WERR_INVALID_PRINTER_NAME
1412 werr = WERR_INVALID_PRINTER_NAME;
1418 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1419 struct spoolss_DeviceMode *orig,
1420 struct spoolss_DeviceMode **dest)
1422 struct spoolss_DeviceMode *dm;
1424 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1429 /* copy all values, then duplicate strings and structs */
1432 dm->devicename = talloc_strdup(dm, orig->devicename);
1433 if (!dm->devicename) {
1436 dm->formname = talloc_strdup(dm, orig->formname);
1437 if (!dm->formname) {
1440 if (orig->driverextra_data.data) {
1441 dm->driverextra_data.data =
1442 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1443 orig->driverextra_data.length);
1444 if (!dm->driverextra_data.data) {
1453 /****************************************************************
1454 _spoolss_OpenPrinterEx
1455 ****************************************************************/
1457 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1458 struct spoolss_OpenPrinterEx *r)
1461 Printer_entry *Printer=NULL;
1463 if (!r->in.printername) {
1464 return WERR_INVALID_PARAM;
1467 /* some sanity check because you can open a printer or a print server */
1468 /* aka: \\server\printer or \\server */
1470 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1472 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1473 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1474 " for printer %s\n", r->in.printername));
1475 ZERO_STRUCTP(r->out.handle);
1476 return WERR_INVALID_PARAM;
1479 Printer = find_printer_index_by_hnd(p, r->out.handle);
1481 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1482 "handle we created for printer %s\n", r->in.printername));
1483 close_printer_handle(p, r->out.handle);
1484 ZERO_STRUCTP(r->out.handle);
1485 return WERR_INVALID_PARAM;
1489 * First case: the user is opening the print server:
1491 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1492 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1494 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1495 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1496 * or if the user is listed in the smb.conf printer admin parameter.
1498 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1499 * client view printer folder, but does not show the MSAPW.
1501 * Note: this test needs code to check access rights here too. Jeremy
1502 * could you look at this?
1504 * Second case: the user is opening a printer:
1505 * NT doesn't let us connect to a printer if the connecting user
1506 * doesn't have print permission.
1508 * Third case: user is opening a Port Monitor
1509 * access checks same as opening a handle to the print server.
1512 switch (Printer->printer_type )
1515 case SPLHND_PORTMON_TCP:
1516 case SPLHND_PORTMON_LOCAL:
1517 /* Printserver handles use global struct... */
1521 /* Map standard access rights to object specific access rights */
1523 se_map_standard(&r->in.access_mask,
1524 &printserver_std_mapping);
1526 /* Deny any object specific bits that don't apply to print
1527 servers (i.e printer and job specific bits) */
1529 r->in.access_mask &= SEC_MASK_SPECIFIC;
1531 if (r->in.access_mask &
1532 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1533 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1534 close_printer_handle(p, r->out.handle);
1535 ZERO_STRUCTP(r->out.handle);
1536 return WERR_ACCESS_DENIED;
1539 /* Allow admin access */
1541 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1543 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1545 if (!lp_ms_add_printer_wizard()) {
1546 close_printer_handle(p, r->out.handle);
1547 ZERO_STRUCTP(r->out.handle);
1548 return WERR_ACCESS_DENIED;
1551 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1552 and not a printer admin, then fail */
1554 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1555 !user_has_privileges(p->server_info->ptok,
1557 !token_contains_name_in_list(
1558 uidtoname(p->server_info->utok.uid),
1559 p->server_info->info3->base.domain.string,
1561 p->server_info->ptok,
1562 lp_printer_admin(snum))) {
1563 close_printer_handle(p, r->out.handle);
1564 ZERO_STRUCTP(r->out.handle);
1565 return WERR_ACCESS_DENIED;
1568 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1572 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1575 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1576 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1578 /* We fall through to return WERR_OK */
1581 case SPLHND_PRINTER:
1582 /* NT doesn't let us connect to a printer if the connecting user
1583 doesn't have print permission. */
1585 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1586 close_printer_handle(p, r->out.handle);
1587 ZERO_STRUCTP(r->out.handle);
1591 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1592 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1595 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1597 /* map an empty access mask to the minimum access mask */
1598 if (r->in.access_mask == 0x0)
1599 r->in.access_mask = PRINTER_ACCESS_USE;
1602 * If we are not serving the printer driver for this printer,
1603 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1604 * will keep NT clients happy --jerry
1607 if (lp_use_client_driver(snum)
1608 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1610 r->in.access_mask = PRINTER_ACCESS_USE;
1613 /* check smb.conf parameters and the the sec_desc */
1615 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1616 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1617 ZERO_STRUCTP(r->out.handle);
1618 return WERR_ACCESS_DENIED;
1621 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1622 p->server_info->ptok, snum) ||
1623 !print_access_check(p->server_info, snum,
1624 r->in.access_mask)) {
1625 DEBUG(3, ("access DENIED for printer open\n"));
1626 close_printer_handle(p, r->out.handle);
1627 ZERO_STRUCTP(r->out.handle);
1628 return WERR_ACCESS_DENIED;
1631 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1632 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1633 close_printer_handle(p, r->out.handle);
1634 ZERO_STRUCTP(r->out.handle);
1635 return WERR_ACCESS_DENIED;
1638 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1639 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1641 r->in.access_mask = PRINTER_ACCESS_USE;
1643 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1644 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1646 winreg_create_printer(p->mem_ctx,
1648 Printer->servername,
1649 lp_const_servicename(snum));
1654 /* sanity check to prevent programmer error */
1655 ZERO_STRUCTP(r->out.handle);
1659 Printer->access_granted = r->in.access_mask;
1662 * If the client sent a devmode in the OpenPrinter() call, then
1663 * save it here in case we get a job submission on this handle
1666 if ((Printer->printer_type != SPLHND_SERVER) &&
1667 r->in.devmode_ctr.devmode) {
1668 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1672 #if 0 /* JERRY -- I'm doubtful this is really effective */
1673 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1674 optimization in Windows 2000 clients --jerry */
1676 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1677 && (RA_WIN2K == get_remote_arch()) )
1679 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1680 sys_usleep( 500000 );
1687 /****************************************************************
1688 _spoolss_ClosePrinter
1689 ****************************************************************/
1691 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1692 struct spoolss_ClosePrinter *r)
1694 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1696 if (Printer && Printer->document_started) {
1697 struct spoolss_EndDocPrinter e;
1699 e.in.handle = r->in.handle;
1701 _spoolss_EndDocPrinter(p, &e);
1704 if (!close_printer_handle(p, r->in.handle))
1707 /* clear the returned printer handle. Observed behavior
1708 from Win2k server. Don't think this really matters.
1709 Previous code just copied the value of the closed
1712 ZERO_STRUCTP(r->out.handle);
1717 /****************************************************************
1718 _spoolss_DeletePrinter
1719 ****************************************************************/
1721 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1722 struct spoolss_DeletePrinter *r)
1724 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1728 if (Printer && Printer->document_started) {
1729 struct spoolss_EndDocPrinter e;
1731 e.in.handle = r->in.handle;
1733 _spoolss_EndDocPrinter(p, &e);
1736 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1737 winreg_delete_printer_key(p->mem_ctx,
1739 lp_const_servicename(snum),
1743 result = delete_printer_handle(p, r->in.handle);
1748 /*******************************************************************
1749 * static function to lookup the version id corresponding to an
1750 * long architecture string
1751 ******************************************************************/
1753 static const struct print_architecture_table_node archi_table[]= {
1755 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1756 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1757 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1758 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1759 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1760 {"Windows IA64", SPL_ARCH_IA64, 3 },
1761 {"Windows x64", SPL_ARCH_X64, 3 },
1765 static int get_version_id(const char *arch)
1769 for (i=0; archi_table[i].long_archi != NULL; i++)
1771 if (strcmp(arch, archi_table[i].long_archi) == 0)
1772 return (archi_table[i].version);
1778 /****************************************************************
1779 _spoolss_DeletePrinterDriver
1780 ****************************************************************/
1782 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1783 struct spoolss_DeletePrinterDriver *r)
1786 struct spoolss_DriverInfo8 *info = NULL;
1787 struct spoolss_DriverInfo8 *info_win2k = NULL;
1790 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1792 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1793 and not a printer admin, then fail */
1795 if ( (p->server_info->utok.uid != sec_initial_uid())
1796 && !user_has_privileges(p->server_info->ptok, &se_printop )
1797 && !token_contains_name_in_list(
1798 uidtoname(p->server_info->utok.uid),
1799 p->server_info->info3->base.domain.string,
1801 p->server_info->ptok,
1802 lp_printer_admin(-1)) )
1804 return WERR_ACCESS_DENIED;
1807 /* check that we have a valid driver name first */
1809 if ((version = get_version_id(r->in.architecture)) == -1)
1810 return WERR_INVALID_ENVIRONMENT;
1812 status = winreg_get_driver(p->mem_ctx, p->server_info,
1813 r->in.architecture, r->in.driver,
1815 if (!W_ERROR_IS_OK(status)) {
1816 /* try for Win2k driver if "Windows NT x86" */
1818 if ( version == 2 ) {
1821 status = winreg_get_driver(p->mem_ctx, p->server_info,
1825 if (!W_ERROR_IS_OK(status)) {
1826 status = WERR_UNKNOWN_PRINTER_DRIVER;
1830 /* otherwise it was a failure */
1832 status = WERR_UNKNOWN_PRINTER_DRIVER;
1838 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1839 status = WERR_PRINTER_DRIVER_IN_USE;
1844 status = winreg_get_driver(p->mem_ctx, p->server_info,
1846 r->in.driver, 3, &info_win2k);
1847 if (W_ERROR_IS_OK(status)) {
1848 /* if we get to here, we now have 2 driver info structures to remove */
1849 /* remove the Win2k driver first*/
1851 status = winreg_del_driver(p->mem_ctx,
1854 talloc_free(info_win2k);
1856 /* this should not have failed---if it did, report to client */
1857 if (!W_ERROR_IS_OK(status)) {
1863 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1871 /****************************************************************
1872 _spoolss_DeletePrinterDriverEx
1873 ****************************************************************/
1875 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
1876 struct spoolss_DeletePrinterDriverEx *r)
1878 struct spoolss_DriverInfo8 *info = NULL;
1879 struct spoolss_DriverInfo8 *info_win2k = NULL;
1883 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1885 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1886 and not a printer admin, then fail */
1888 if ( (p->server_info->utok.uid != sec_initial_uid())
1889 && !user_has_privileges(p->server_info->ptok, &se_printop )
1890 && !token_contains_name_in_list(
1891 uidtoname(p->server_info->utok.uid),
1892 p->server_info->info3->base.domain.string,
1894 p->server_info->ptok, lp_printer_admin(-1)) )
1896 return WERR_ACCESS_DENIED;
1899 /* check that we have a valid driver name first */
1900 if ((version = get_version_id(r->in.architecture)) == -1) {
1901 /* this is what NT returns */
1902 return WERR_INVALID_ENVIRONMENT;
1905 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1906 version = r->in.version;
1908 status = winreg_get_driver(p->mem_ctx, p->server_info,
1909 r->in.architecture, r->in.driver,
1911 if (!W_ERROR_IS_OK(status)) {
1912 status = WERR_UNKNOWN_PRINTER_DRIVER;
1915 * if the client asked for a specific version,
1916 * or this is something other than Windows NT x86,
1920 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1923 /* try for Win2k driver if "Windows NT x86" */
1926 status = winreg_get_driver(info, p->server_info,
1930 if (!W_ERROR_IS_OK(status)) {
1931 status = WERR_UNKNOWN_PRINTER_DRIVER;
1936 if (printer_driver_in_use(info, p->server_info, info)) {
1937 status = WERR_PRINTER_DRIVER_IN_USE;
1942 * we have a couple of cases to consider.
1943 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1944 * then the delete should fail if **any** files overlap with
1946 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1947 * non-overlapping files
1948 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1949 * is set, the do not delete any files
1950 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1953 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1955 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1958 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1959 printer_driver_files_in_use(info, p->server_info, info)) {
1960 /* no idea of the correct error here */
1961 status = WERR_ACCESS_DENIED;
1966 /* also check for W32X86/3 if necessary; maybe we already have? */
1968 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1969 status = winreg_get_driver(info, p->server_info,
1971 r->in.driver, 3, &info_win2k);
1972 if (W_ERROR_IS_OK(status)) {
1975 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1976 printer_driver_files_in_use(info, p->server_info,
1978 /* no idea of the correct error here */
1979 talloc_free(info_win2k);
1980 status = WERR_ACCESS_DENIED;
1984 /* if we get to here, we now have 2 driver info structures to remove */
1985 /* remove the Win2k driver first*/
1987 status = winreg_del_driver(info, p->server_info,
1990 /* this should not have failed---if it did, report to client */
1992 if (!W_ERROR_IS_OK(status)) {
1997 * now delete any associated files if delete_files is
1998 * true. Even if this part failes, we return succes
1999 * because the driver doesn not exist any more
2002 delete_driver_files(p->server_info,
2008 status = winreg_del_driver(info, p->server_info, info, version);
2009 if (!W_ERROR_IS_OK(status)) {
2014 * now delete any associated files if delete_files is
2015 * true. Even if this part failes, we return succes
2016 * because the driver doesn not exist any more
2019 delete_driver_files(p->server_info, info);
2028 /********************************************************************
2029 GetPrinterData on a printer server Handle.
2030 ********************************************************************/
2032 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2034 enum winreg_Type *type,
2035 union spoolss_PrinterData *data)
2037 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2039 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2045 if (!StrCaseCmp(value, "BeepEnabled")) {
2051 if (!StrCaseCmp(value, "EventLog")) {
2053 /* formally was 0x1b */
2058 if (!StrCaseCmp(value, "NetPopup")) {
2064 if (!StrCaseCmp(value, "MajorVersion")) {
2067 /* Windows NT 4.0 seems to not allow uploading of drivers
2068 to a server that reports 0x3 as the MajorVersion.
2069 need to investigate more how Win2k gets around this .
2072 if (RA_WINNT == get_remote_arch()) {
2081 if (!StrCaseCmp(value, "MinorVersion")) {
2088 * uint32_t size = 0x114
2089 * uint32_t major = 5
2090 * uint32_t minor = [0|1]
2091 * uint32_t build = [2195|2600]
2092 * extra unicode string = e.g. "Service Pack 3"
2094 if (!StrCaseCmp(value, "OSVersion")) {
2096 enum ndr_err_code ndr_err;
2097 struct spoolss_OSVersion os;
2099 os.major = 5; /* Windows 2000 == 5.0 */
2101 os.build = 2195; /* build */
2102 os.extra_string = ""; /* leave extra string empty */
2104 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2105 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2106 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2107 return WERR_GENERAL_FAILURE;
2111 data->binary = blob;
2117 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2120 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2121 W_ERROR_HAVE_NO_MEMORY(data->string);
2126 if (!StrCaseCmp(value, "Architecture")) {
2128 data->string = talloc_strdup(mem_ctx,
2129 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2130 W_ERROR_HAVE_NO_MEMORY(data->string);
2135 if (!StrCaseCmp(value, "DsPresent")) {
2138 /* only show the publish check box if we are a
2139 member of a AD domain */
2141 if (lp_security() == SEC_ADS) {
2149 if (!StrCaseCmp(value, "DNSMachineName")) {
2150 const char *hostname = get_mydnsfullname();
2153 return WERR_BADFILE;
2157 data->string = talloc_strdup(mem_ctx, hostname);
2158 W_ERROR_HAVE_NO_MEMORY(data->string);
2165 return WERR_INVALID_PARAM;
2168 /****************************************************************
2169 _spoolss_GetPrinterData
2170 ****************************************************************/
2172 WERROR _spoolss_GetPrinterData(pipes_struct *p,
2173 struct spoolss_GetPrinterData *r)
2175 struct spoolss_GetPrinterDataEx r2;
2177 r2.in.handle = r->in.handle;
2178 r2.in.key_name = "PrinterDriverData";
2179 r2.in.value_name = r->in.value_name;
2180 r2.in.offered = r->in.offered;
2181 r2.out.type = r->out.type;
2182 r2.out.data = r->out.data;
2183 r2.out.needed = r->out.needed;
2185 return _spoolss_GetPrinterDataEx(p, &r2);
2188 /*********************************************************
2189 Connect to the client machine.
2190 **********************************************************/
2192 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2193 struct sockaddr_storage *client_ss, const char *remote_machine)
2196 struct cli_state *the_cli;
2197 struct sockaddr_storage rm_addr;
2198 char addr[INET6_ADDRSTRLEN];
2200 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2201 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2203 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2204 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2207 print_sockaddr(addr, sizeof(addr), &rm_addr);
2209 rm_addr = *client_ss;
2210 print_sockaddr(addr, sizeof(addr), &rm_addr);
2211 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2215 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2216 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2221 /* setup the connection */
2222 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2223 &rm_addr, 0, "IPC$", "IPC",
2227 0, lp_client_signing(), NULL );
2229 if ( !NT_STATUS_IS_OK( ret ) ) {
2230 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2235 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2236 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2237 cli_shutdown(the_cli);
2242 * Ok - we have an anonymous connection to the IPC$ share.
2243 * Now start the NT Domain stuff :-).
2246 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2247 if (!NT_STATUS_IS_OK(ret)) {
2248 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2249 remote_machine, nt_errstr(ret)));
2250 cli_shutdown(the_cli);
2257 /***************************************************************************
2258 Connect to the client.
2259 ****************************************************************************/
2261 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2262 uint32_t localprinter, uint32_t type,
2263 struct policy_handle *handle,
2264 struct sockaddr_storage *client_ss)
2270 * If it's the first connection, contact the client
2271 * and connect to the IPC$ share anonymously
2273 if (smb_connections==0) {
2274 fstring unix_printer;
2276 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2278 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2281 messaging_register(smbd_messaging_context(), NULL,
2282 MSG_PRINTER_NOTIFY2,
2283 receive_notify2_message_list);
2284 /* Tell the connections db we're now interested in printer
2285 * notify messages. */
2286 serverid_register_msg_flags(
2287 messaging_server_id(smbd_messaging_context()),
2288 true, FLAG_MSG_PRINT_NOTIFY);
2292 * Tell the specific printing tdb we want messages for this printer
2293 * by registering our PID.
2296 if (!print_notify_register_pid(snum))
2297 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2301 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2309 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2310 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2311 win_errstr(result)));
2313 return (W_ERROR_IS_OK(result));
2316 /****************************************************************
2317 ****************************************************************/
2319 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2320 const struct spoolss_NotifyOption *r)
2322 struct spoolss_NotifyOption *option;
2329 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2336 if (!option->count) {
2340 option->types = talloc_zero_array(option,
2341 struct spoolss_NotifyOptionType, option->count);
2342 if (!option->types) {
2343 talloc_free(option);
2347 for (i=0; i < option->count; i++) {
2348 option->types[i] = r->types[i];
2350 if (option->types[i].count) {
2351 option->types[i].fields = talloc_zero_array(option,
2352 union spoolss_Field, option->types[i].count);
2353 if (!option->types[i].fields) {
2354 talloc_free(option);
2357 for (k=0; k<option->types[i].count; k++) {
2358 option->types[i].fields[k] =
2359 r->types[i].fields[k];
2367 /****************************************************************
2368 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2370 * before replying OK: status=0 a rpc call is made to the workstation
2371 * asking ReplyOpenPrinter
2373 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2374 * called from api_spoolss_rffpcnex
2375 ****************************************************************/
2377 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2378 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2381 struct spoolss_NotifyOption *option = r->in.notify_options;
2382 struct sockaddr_storage client_ss;
2384 /* store the notify value in the printer struct */
2386 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2389 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2390 "Invalid handle (%s:%u:%u).\n",
2391 OUR_HANDLE(r->in.handle)));
2395 Printer->notify.flags = r->in.flags;
2396 Printer->notify.options = r->in.options;
2397 Printer->notify.printerlocal = r->in.printer_local;
2399 TALLOC_FREE(Printer->notify.option);
2400 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2402 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2404 /* Connect to the client machine and send a ReplyOpenPrinter */
2406 if ( Printer->printer_type == SPLHND_SERVER)
2408 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2409 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2412 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2413 "client_address is %s\n", p->client_address));
2415 if (!interpret_string_addr(&client_ss, p->client_address,
2417 return WERR_SERVER_UNAVAILABLE;
2420 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2421 Printer->notify.printerlocal, 1,
2422 &Printer->notify.client_hnd, &client_ss))
2423 return WERR_SERVER_UNAVAILABLE;
2425 Printer->notify.client_connected = true;
2430 /*******************************************************************
2431 * fill a notify_info_data with the servername
2432 ********************************************************************/
2434 static void spoolss_notify_server_name(int snum,
2435 struct spoolss_Notify *data,
2436 print_queue_struct *queue,
2437 struct spoolss_PrinterInfo2 *pinfo2,
2438 TALLOC_CTX *mem_ctx)
2440 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2443 /*******************************************************************
2444 * fill a notify_info_data with the printername (not including the servername).
2445 ********************************************************************/
2447 static void spoolss_notify_printer_name(int snum,
2448 struct spoolss_Notify *data,
2449 print_queue_struct *queue,
2450 struct spoolss_PrinterInfo2 *pinfo2,
2451 TALLOC_CTX *mem_ctx)
2453 /* the notify name should not contain the \\server\ part */
2454 const char *p = strrchr(pinfo2->printername, '\\');
2457 p = pinfo2->printername;
2462 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2465 /*******************************************************************
2466 * fill a notify_info_data with the servicename
2467 ********************************************************************/
2469 static void spoolss_notify_share_name(int snum,
2470 struct spoolss_Notify *data,
2471 print_queue_struct *queue,
2472 struct spoolss_PrinterInfo2 *pinfo2,
2473 TALLOC_CTX *mem_ctx)
2475 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2478 /*******************************************************************
2479 * fill a notify_info_data with the port name
2480 ********************************************************************/
2482 static void spoolss_notify_port_name(int snum,
2483 struct spoolss_Notify *data,
2484 print_queue_struct *queue,
2485 struct spoolss_PrinterInfo2 *pinfo2,
2486 TALLOC_CTX *mem_ctx)
2488 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2491 /*******************************************************************
2492 * fill a notify_info_data with the printername
2493 * but it doesn't exist, have to see what to do
2494 ********************************************************************/
2496 static void spoolss_notify_driver_name(int snum,
2497 struct spoolss_Notify *data,
2498 print_queue_struct *queue,
2499 struct spoolss_PrinterInfo2 *pinfo2,
2500 TALLOC_CTX *mem_ctx)
2502 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2505 /*******************************************************************
2506 * fill a notify_info_data with the comment
2507 ********************************************************************/
2509 static void spoolss_notify_comment(int snum,
2510 struct spoolss_Notify *data,
2511 print_queue_struct *queue,
2512 struct spoolss_PrinterInfo2 *pinfo2,
2513 TALLOC_CTX *mem_ctx)
2517 if (*pinfo2->comment == '\0') {
2518 p = lp_comment(snum);
2520 p = pinfo2->comment;
2523 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2526 /*******************************************************************
2527 * fill a notify_info_data with the comment
2528 * location = "Room 1, floor 2, building 3"
2529 ********************************************************************/
2531 static void spoolss_notify_location(int snum,
2532 struct spoolss_Notify *data,
2533 print_queue_struct *queue,
2534 struct spoolss_PrinterInfo2 *pinfo2,
2535 TALLOC_CTX *mem_ctx)
2537 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2540 /*******************************************************************
2541 * fill a notify_info_data with the device mode
2542 * jfm:xxxx don't to it for know but that's a real problem !!!
2543 ********************************************************************/
2545 static void spoolss_notify_devmode(int snum,
2546 struct spoolss_Notify *data,
2547 print_queue_struct *queue,
2548 struct spoolss_PrinterInfo2 *pinfo2,
2549 TALLOC_CTX *mem_ctx)
2551 /* for a dummy implementation we have to zero the fields */
2552 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2555 /*******************************************************************
2556 * fill a notify_info_data with the separator file name
2557 ********************************************************************/
2559 static void spoolss_notify_sepfile(int snum,
2560 struct spoolss_Notify *data,
2561 print_queue_struct *queue,
2562 struct spoolss_PrinterInfo2 *pinfo2,
2563 TALLOC_CTX *mem_ctx)
2565 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2568 /*******************************************************************
2569 * fill a notify_info_data with the print processor
2570 * jfm:xxxx return always winprint to indicate we don't do anything to it
2571 ********************************************************************/
2573 static void spoolss_notify_print_processor(int snum,
2574 struct spoolss_Notify *data,
2575 print_queue_struct *queue,
2576 struct spoolss_PrinterInfo2 *pinfo2,
2577 TALLOC_CTX *mem_ctx)
2579 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2582 /*******************************************************************
2583 * fill a notify_info_data with the print processor options
2584 * jfm:xxxx send an empty string
2585 ********************************************************************/
2587 static void spoolss_notify_parameters(int snum,
2588 struct spoolss_Notify *data,
2589 print_queue_struct *queue,
2590 struct spoolss_PrinterInfo2 *pinfo2,
2591 TALLOC_CTX *mem_ctx)
2593 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2596 /*******************************************************************
2597 * fill a notify_info_data with the data type
2598 * jfm:xxxx always send RAW as data type
2599 ********************************************************************/
2601 static void spoolss_notify_datatype(int snum,
2602 struct spoolss_Notify *data,
2603 print_queue_struct *queue,
2604 struct spoolss_PrinterInfo2 *pinfo2,
2605 TALLOC_CTX *mem_ctx)
2607 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2610 /*******************************************************************
2611 * fill a notify_info_data with the security descriptor
2612 * jfm:xxxx send an null pointer to say no security desc
2613 * have to implement security before !
2614 ********************************************************************/
2616 static void spoolss_notify_security_desc(int snum,
2617 struct spoolss_Notify *data,
2618 print_queue_struct *queue,
2619 struct spoolss_PrinterInfo2 *pinfo2,
2620 TALLOC_CTX *mem_ctx)
2622 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2625 /*******************************************************************
2626 * fill a notify_info_data with the attributes
2627 * jfm:xxxx a samba printer is always shared
2628 ********************************************************************/
2630 static void spoolss_notify_attributes(int snum,
2631 struct spoolss_Notify *data,
2632 print_queue_struct *queue,
2633 struct spoolss_PrinterInfo2 *pinfo2,
2634 TALLOC_CTX *mem_ctx)
2636 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2639 /*******************************************************************
2640 * fill a notify_info_data with the priority
2641 ********************************************************************/
2643 static void spoolss_notify_priority(int snum,
2644 struct spoolss_Notify *data,
2645 print_queue_struct *queue,
2646 struct spoolss_PrinterInfo2 *pinfo2,
2647 TALLOC_CTX *mem_ctx)
2649 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2652 /*******************************************************************
2653 * fill a notify_info_data with the default priority
2654 ********************************************************************/
2656 static void spoolss_notify_default_priority(int snum,
2657 struct spoolss_Notify *data,
2658 print_queue_struct *queue,
2659 struct spoolss_PrinterInfo2 *pinfo2,
2660 TALLOC_CTX *mem_ctx)
2662 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2665 /*******************************************************************
2666 * fill a notify_info_data with the start time
2667 ********************************************************************/
2669 static void spoolss_notify_start_time(int snum,
2670 struct spoolss_Notify *data,
2671 print_queue_struct *queue,
2672 struct spoolss_PrinterInfo2 *pinfo2,
2673 TALLOC_CTX *mem_ctx)
2675 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2678 /*******************************************************************
2679 * fill a notify_info_data with the until time
2680 ********************************************************************/
2682 static void spoolss_notify_until_time(int snum,
2683 struct spoolss_Notify *data,
2684 print_queue_struct *queue,
2685 struct spoolss_PrinterInfo2 *pinfo2,
2686 TALLOC_CTX *mem_ctx)
2688 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2691 /*******************************************************************
2692 * fill a notify_info_data with the status
2693 ********************************************************************/
2695 static void spoolss_notify_status(int snum,
2696 struct spoolss_Notify *data,
2697 print_queue_struct *queue,
2698 struct spoolss_PrinterInfo2 *pinfo2,
2699 TALLOC_CTX *mem_ctx)
2701 print_status_struct status;
2703 print_queue_length(snum, &status);
2704 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2707 /*******************************************************************
2708 * fill a notify_info_data with the number of jobs queued
2709 ********************************************************************/
2711 static void spoolss_notify_cjobs(int snum,
2712 struct spoolss_Notify *data,
2713 print_queue_struct *queue,
2714 struct spoolss_PrinterInfo2 *pinfo2,
2715 TALLOC_CTX *mem_ctx)
2717 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2720 /*******************************************************************
2721 * fill a notify_info_data with the average ppm
2722 ********************************************************************/
2724 static void spoolss_notify_average_ppm(int snum,
2725 struct spoolss_Notify *data,
2726 print_queue_struct *queue,
2727 struct spoolss_PrinterInfo2 *pinfo2,
2728 TALLOC_CTX *mem_ctx)
2730 /* always respond 8 pages per minutes */
2731 /* a little hard ! */
2732 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2735 /*******************************************************************
2736 * fill a notify_info_data with username
2737 ********************************************************************/
2739 static void spoolss_notify_username(int snum,
2740 struct spoolss_Notify *data,
2741 print_queue_struct *queue,
2742 struct spoolss_PrinterInfo2 *pinfo2,
2743 TALLOC_CTX *mem_ctx)
2745 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2748 /*******************************************************************
2749 * fill a notify_info_data with job status
2750 ********************************************************************/
2752 static void spoolss_notify_job_status(int snum,
2753 struct spoolss_Notify *data,
2754 print_queue_struct *queue,
2755 struct spoolss_PrinterInfo2 *pinfo2,
2756 TALLOC_CTX *mem_ctx)
2758 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2761 /*******************************************************************
2762 * fill a notify_info_data with job name
2763 ********************************************************************/
2765 static void spoolss_notify_job_name(int snum,
2766 struct spoolss_Notify *data,
2767 print_queue_struct *queue,
2768 struct spoolss_PrinterInfo2 *pinfo2,
2769 TALLOC_CTX *mem_ctx)
2771 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2774 /*******************************************************************
2775 * fill a notify_info_data with job status
2776 ********************************************************************/
2778 static void spoolss_notify_job_status_string(int snum,
2779 struct spoolss_Notify *data,
2780 print_queue_struct *queue,
2781 struct spoolss_PrinterInfo2 *pinfo2,
2782 TALLOC_CTX *mem_ctx)
2785 * Now we're returning job status codes we just return a "" here. JRA.
2790 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2793 switch (queue->status) {
2798 p = ""; /* NT provides the paused string */
2807 #endif /* NO LONGER NEEDED. */
2809 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2812 /*******************************************************************
2813 * fill a notify_info_data with job time
2814 ********************************************************************/
2816 static void spoolss_notify_job_time(int snum,
2817 struct spoolss_Notify *data,
2818 print_queue_struct *queue,
2819 struct spoolss_PrinterInfo2 *pinfo2,
2820 TALLOC_CTX *mem_ctx)
2822 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2825 /*******************************************************************
2826 * fill a notify_info_data with job size
2827 ********************************************************************/
2829 static void spoolss_notify_job_size(int snum,
2830 struct spoolss_Notify *data,
2831 print_queue_struct *queue,
2832 struct spoolss_PrinterInfo2 *pinfo2,
2833 TALLOC_CTX *mem_ctx)
2835 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2838 /*******************************************************************
2839 * fill a notify_info_data with page info
2840 ********************************************************************/
2841 static void spoolss_notify_total_pages(int snum,
2842 struct spoolss_Notify *data,
2843 print_queue_struct *queue,
2844 struct spoolss_PrinterInfo2 *pinfo2,
2845 TALLOC_CTX *mem_ctx)
2847 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2850 /*******************************************************************
2851 * fill a notify_info_data with pages printed info.
2852 ********************************************************************/
2853 static void spoolss_notify_pages_printed(int snum,
2854 struct spoolss_Notify *data,
2855 print_queue_struct *queue,
2856 struct spoolss_PrinterInfo2 *pinfo2,
2857 TALLOC_CTX *mem_ctx)
2859 /* Add code when back-end tracks this */
2860 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2863 /*******************************************************************
2864 Fill a notify_info_data with job position.
2865 ********************************************************************/
2867 static void spoolss_notify_job_position(int snum,
2868 struct spoolss_Notify *data,
2869 print_queue_struct *queue,
2870 struct spoolss_PrinterInfo2 *pinfo2,
2871 TALLOC_CTX *mem_ctx)
2873 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2876 /*******************************************************************
2877 Fill a notify_info_data with submitted time.
2878 ********************************************************************/
2880 static void spoolss_notify_submitted_time(int snum,
2881 struct spoolss_Notify *data,
2882 print_queue_struct *queue,
2883 struct spoolss_PrinterInfo2 *pinfo2,
2884 TALLOC_CTX *mem_ctx)
2886 data->data.string.string = NULL;
2887 data->data.string.size = 0;
2889 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2890 &data->data.string.string,
2891 &data->data.string.size);
2895 struct s_notify_info_data_table
2897 enum spoolss_NotifyType type;
2900 enum spoolss_NotifyTable variable_type;
2901 void (*fn) (int snum, struct spoolss_Notify *data,
2902 print_queue_struct *queue,
2903 struct spoolss_PrinterInfo2 *pinfo2,
2904 TALLOC_CTX *mem_ctx);
2907 /* A table describing the various print notification constants and
2908 whether the notification data is a pointer to a variable sized
2909 buffer, a one value uint32_t or a two value uint32_t. */
2911 static const struct s_notify_info_data_table notify_info_data_table[] =
2913 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2914 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2915 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2916 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2917 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2918 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2919 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2920 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2921 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2922 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2923 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2924 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2925 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2926 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2927 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2928 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2929 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2930 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2931 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2932 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2933 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2934 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2935 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2936 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2937 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2938 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2939 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2940 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2941 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2942 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2943 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2944 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2945 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2946 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2947 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2948 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2949 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2950 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2951 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2952 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2953 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2954 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2955 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2956 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2957 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2958 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2959 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2960 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2961 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2964 /*******************************************************************
2965 Return the variable_type of info_data structure.
2966 ********************************************************************/
2968 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
2973 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
2974 if ( (notify_info_data_table[i].type == type) &&
2975 (notify_info_data_table[i].field == field) ) {
2976 return notify_info_data_table[i].variable_type;
2980 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
2985 /****************************************************************************
2986 ****************************************************************************/
2988 static bool search_notify(enum spoolss_NotifyType type,
2994 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
2995 if (notify_info_data_table[i].type == type &&
2996 notify_info_data_table[i].field == field &&
2997 notify_info_data_table[i].fn != NULL) {
3006 /****************************************************************************
3007 ****************************************************************************/
3009 static void construct_info_data(struct spoolss_Notify *info_data,
3010 enum spoolss_NotifyType type,
3011 uint16_t field, int id)
3013 info_data->type = type;
3014 info_data->field.field = field;
3015 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3016 info_data->job_id = id;
3019 /*******************************************************************
3021 * fill a notify_info struct with info asked
3023 ********************************************************************/
3025 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3026 struct spoolss_NotifyInfo *info,
3027 struct spoolss_PrinterInfo2 *pinfo2,
3029 const struct spoolss_NotifyOptionType *option_type,
3031 TALLOC_CTX *mem_ctx)
3034 enum spoolss_NotifyType type;
3037 struct spoolss_Notify *current_data;
3038 print_queue_struct *queue=NULL;
3040 type = option_type->type;
3042 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3043 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3044 option_type->count, lp_servicename(snum)));
3046 for(field_num=0; field_num < option_type->count; field_num++) {
3047 field = option_type->fields[field_num].field;
3049 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3051 if (!search_notify(type, field, &j) )
3054 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3055 struct spoolss_Notify,
3057 if (info->notifies == NULL) {
3058 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3062 current_data = &info->notifies[info->count];
3064 construct_info_data(current_data, type, field, id);
3066 DEBUG(10, ("construct_notify_printer_info: "
3067 "calling [%s] snum=%d printername=[%s])\n",
3068 notify_info_data_table[j].name, snum,
3069 pinfo2->printername));
3071 notify_info_data_table[j].fn(snum, current_data, queue,
3080 /*******************************************************************
3082 * fill a notify_info struct with info asked
3084 ********************************************************************/
3086 static bool construct_notify_jobs_info(print_queue_struct *queue,
3087 struct spoolss_NotifyInfo *info,
3088 struct spoolss_PrinterInfo2 *pinfo2,
3090 const struct spoolss_NotifyOptionType *option_type,
3092 TALLOC_CTX *mem_ctx)
3095 enum spoolss_NotifyType type;
3097 struct spoolss_Notify *current_data;
3099 DEBUG(4,("construct_notify_jobs_info\n"));
3101 type = option_type->type;
3103 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3104 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3105 option_type->count));
3107 for(field_num=0; field_num<option_type->count; field_num++) {
3108 field = option_type->fields[field_num].field;
3110 if (!search_notify(type, field, &j) )
3113 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3114 struct spoolss_Notify,
3116 if (info->notifies == NULL) {
3117 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3121 current_data=&(info->notifies[info->count]);
3123 construct_info_data(current_data, type, field, id);
3124 notify_info_data_table[j].fn(snum, current_data, queue,
3133 * JFM: The enumeration is not that simple, it's even non obvious.
3135 * let's take an example: I want to monitor the PRINTER SERVER for
3136 * the printer's name and the number of jobs currently queued.
3137 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3138 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3140 * I have 3 printers on the back of my server.
3142 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3145 * 1 printer 1 name 1
3146 * 2 printer 1 cjob 1
3147 * 3 printer 2 name 2
3148 * 4 printer 2 cjob 2
3149 * 5 printer 3 name 3
3150 * 6 printer 3 name 3
3152 * that's the print server case, the printer case is even worse.
3155 /*******************************************************************
3157 * enumerate all printers on the printserver
3158 * fill a notify_info struct with info asked
3160 ********************************************************************/
3162 static WERROR printserver_notify_info(pipes_struct *p,
3163 struct policy_handle *hnd,
3164 struct spoolss_NotifyInfo *info,
3165 TALLOC_CTX *mem_ctx)
3168 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3169 int n_services=lp_numservices();
3171 struct spoolss_NotifyOption *option;
3172 struct spoolss_NotifyOptionType option_type;
3173 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3176 DEBUG(4,("printserver_notify_info\n"));
3181 option = Printer->notify.option;
3184 info->notifies = NULL;
3187 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3188 sending a ffpcn() request first */
3193 for (i=0; i<option->count; i++) {
3194 option_type = option->types[i];
3196 if (option_type.type != PRINTER_NOTIFY_TYPE)
3199 for (snum = 0; snum < n_services; snum++) {
3200 if (!lp_browseable(snum) ||
3201 !lp_snum_ok(snum) ||
3202 !lp_print_ok(snum)) {
3203 continue; /* skip */
3206 /* FIXME: should we use a SYSTEM server_info here? */
3207 result = winreg_get_printer(mem_ctx, p->server_info,
3208 Printer->servername,
3209 lp_servicename(snum),
3211 if (!W_ERROR_IS_OK(result)) {
3212 DEBUG(4, ("printserver_notify_info: "
3213 "Failed to get printer [%s]\n",
3214 lp_servicename(snum)));
3219 construct_notify_printer_info(Printer, info,
3224 TALLOC_FREE(pinfo2);
3230 * Debugging information, don't delete.
3233 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3234 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3235 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3237 for (i=0; i<info->count; i++) {
3238 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3239 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3240 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3247 /*******************************************************************
3249 * fill a notify_info struct with info asked
3251 ********************************************************************/
3253 static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3254 struct spoolss_NotifyInfo *info,
3255 TALLOC_CTX *mem_ctx)
3258 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3261 struct spoolss_NotifyOption *option;
3262 struct spoolss_NotifyOptionType option_type;
3264 print_queue_struct *queue=NULL;
3265 print_status_struct status;
3266 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3269 DEBUG(4,("printer_notify_info\n"));
3274 option = Printer->notify.option;
3278 info->notifies = NULL;
3281 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3282 sending a ffpcn() request first */
3287 get_printer_snum(p, hnd, &snum, NULL);
3289 /* FIXME: should we use a SYSTEM server_info here ? */
3290 result = winreg_get_printer(mem_ctx, p->server_info,
3291 Printer->servername,
3292 lp_servicename(snum), &pinfo2);
3293 if (!W_ERROR_IS_OK(result)) {
3297 for (i=0; i<option->count; i++) {
3298 option_type = option->types[i];
3300 switch (option_type.type) {
3301 case PRINTER_NOTIFY_TYPE:
3302 if (construct_notify_printer_info(Printer, info,
3310 case JOB_NOTIFY_TYPE:
3312 count = print_queue_status(snum, &queue, &status);
3314 for (j=0; j<count; j++) {
3315 construct_notify_jobs_info(&queue[j], info,
3328 * Debugging information, don't delete.
3331 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3332 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3333 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3335 for (i=0; i<info->count; i++) {
3336 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3337 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3338 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3342 talloc_free(pinfo2);
3346 /****************************************************************
3347 _spoolss_RouterRefreshPrinterChangeNotify
3348 ****************************************************************/
3350 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3351 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3353 struct spoolss_NotifyInfo *info;
3355 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3356 WERROR result = WERR_BADFID;
3358 /* we always have a spoolss_NotifyInfo struct */
3359 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3361 result = WERR_NOMEM;
3365 *r->out.info = info;
3368 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3369 "Invalid handle (%s:%u:%u).\n",
3370 OUR_HANDLE(r->in.handle)));
3374 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3377 * We are now using the change value, and
3378 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3379 * I don't have a global notification system, I'm sending back all the
3380 * informations even when _NOTHING_ has changed.
3383 /* We need to keep track of the change value to send back in
3384 RRPCN replies otherwise our updates are ignored. */
3386 Printer->notify.fnpcn = true;
3388 if (Printer->notify.client_connected) {
3389 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3390 "Saving change value in request [%x]\n",
3392 Printer->notify.change = r->in.change_low;
3395 /* just ignore the spoolss_NotifyOption */
3397 switch (Printer->printer_type) {
3399 result = printserver_notify_info(p, r->in.handle,
3403 case SPLHND_PRINTER:
3404 result = printer_notify_info(p, r->in.handle,
3409 Printer->notify.fnpcn = false;
3415 /********************************************************************
3416 * construct_printer_info_0
3417 * fill a printer_info_0 struct
3418 ********************************************************************/
3420 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3421 struct auth_serversupplied_info *server_info,
3422 struct spoolss_PrinterInfo2 *info2,
3423 struct spoolss_PrinterInfo0 *r,
3427 counter_printer_0 *session_counter;
3428 struct timeval setuptime;
3429 print_status_struct status;
3431 r->printername = talloc_strdup(mem_ctx, info2->printername);
3432 W_ERROR_HAVE_NO_MEMORY(r->printername);
3434 r->servername = talloc_strdup(mem_ctx, info2->servername);
3435 W_ERROR_HAVE_NO_MEMORY(r->servername);
3437 count = print_queue_length(snum, &status);
3439 /* check if we already have a counter for this printer */
3440 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3441 if (session_counter->snum == snum)
3445 /* it's the first time, add it to the list */
3446 if (session_counter == NULL) {
3447 session_counter = SMB_MALLOC_P(counter_printer_0);
3448 W_ERROR_HAVE_NO_MEMORY(session_counter);
3449 ZERO_STRUCTP(session_counter);
3450 session_counter->snum = snum;
3451 session_counter->counter = 0;
3452 DLIST_ADD(counter_list, session_counter);
3456 session_counter->counter++;
3462 get_startup_time(&setuptime);
3463 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3466 * the global_counter should be stored in a TDB as it's common to all the clients
3467 * and should be zeroed on samba startup
3469 r->global_counter = session_counter->counter;
3471 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3472 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3473 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3474 r->free_build = SPOOLSS_RELEASE_BUILD;
3476 r->max_spooling = 0;
3477 r->session_counter = session_counter->counter;
3478 r->num_error_out_of_paper = 0x0;
3479 r->num_error_not_ready = 0x0; /* number of print failure */
3481 r->number_of_processors = 0x1;
3482 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3483 r->high_part_total_bytes = 0x0;
3484 winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3485 r->last_error = WERR_OK;
3486 r->status = nt_printq_status(status.status);
3487 r->enumerate_network_printers = 0x0;
3488 r->c_setprinter = 0x0;
3489 r->processor_architecture = 0x0;
3490 r->processor_level = 0x6; /* 6 ???*/
3499 /********************************************************************
3500 * construct_printer_info1
3501 * fill a spoolss_PrinterInfo1 struct
3502 ********************************************************************/
3504 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3505 const struct spoolss_PrinterInfo2 *info2,
3507 struct spoolss_PrinterInfo1 *r,
3512 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3516 W_ERROR_HAVE_NO_MEMORY(r->description);
3518 if (info2->comment == NULL || info2->comment[0] == '\0') {
3519 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3521 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3523 W_ERROR_HAVE_NO_MEMORY(r->comment);
3525 r->name = talloc_strdup(mem_ctx, info2->printername);
3526 W_ERROR_HAVE_NO_MEMORY(r->name);
3531 /********************************************************************
3532 * construct_printer_info2
3533 * fill a spoolss_PrinterInfo2 struct
3534 ********************************************************************/
3536 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3537 const struct spoolss_PrinterInfo2 *info2,
3538 struct spoolss_PrinterInfo2 *r,
3542 print_status_struct status;
3544 count = print_queue_length(snum, &status);
3546 r->servername = talloc_strdup(mem_ctx, info2->servername);
3547 W_ERROR_HAVE_NO_MEMORY(r->servername);
3548 r->printername = talloc_strdup(mem_ctx, info2->printername);
3549 W_ERROR_HAVE_NO_MEMORY(r->printername);
3550 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3551 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3552 r->portname = talloc_strdup(mem_ctx, info2->portname);
3553 W_ERROR_HAVE_NO_MEMORY(r->portname);
3554 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3555 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3557 if (info2->comment[0] == '\0') {
3558 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3560 r->comment = talloc_strdup(mem_ctx, info2->comment);
3562 W_ERROR_HAVE_NO_MEMORY(r->comment);
3564 r->location = talloc_strdup(mem_ctx, info2->location);
3565 W_ERROR_HAVE_NO_MEMORY(r->location);
3566 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3567 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3568 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3569 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3570 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3571 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3572 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3573 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3575 r->attributes = info2->attributes;
3577 r->priority = info2->priority;
3578 r->defaultpriority = info2->defaultpriority;
3579 r->starttime = info2->starttime;
3580 r->untiltime = info2->untiltime;
3581 r->status = nt_printq_status(status.status);
3583 r->averageppm = info2->averageppm;
3585 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3587 DEBUG(8,("Returning NULL Devicemode!\n"));
3592 if (info2->secdesc != NULL) {
3593 /* don't use talloc_steal() here unless you do a deep steal of all
3594 the SEC_DESC members */
3596 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3602 /********************************************************************
3603 * construct_printer_info3
3604 * fill a spoolss_PrinterInfo3 struct
3605 ********************************************************************/
3607 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3608 const struct spoolss_PrinterInfo2 *info2,
3609 struct spoolss_PrinterInfo3 *r,
3612 /* These are the components of the SD we are returning. */
3614 if (info2->secdesc != NULL) {
3615 /* don't use talloc_steal() here unless you do a deep steal of all
3616 the SEC_DESC members */
3618 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3619 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3625 /********************************************************************
3626 * construct_printer_info4
3627 * fill a spoolss_PrinterInfo4 struct
3628 ********************************************************************/
3630 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3631 const struct spoolss_PrinterInfo2 *info2,
3632 struct spoolss_PrinterInfo4 *r,
3635 r->printername = talloc_strdup(mem_ctx, info2->printername);
3636 W_ERROR_HAVE_NO_MEMORY(r->printername);
3637 r->servername = talloc_strdup(mem_ctx, info2->servername);
3638 W_ERROR_HAVE_NO_MEMORY(r->servername);
3640 r->attributes = info2->attributes;
3645 /********************************************************************
3646 * construct_printer_info5
3647 * fill a spoolss_PrinterInfo5 struct
3648 ********************************************************************/
3650 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3651 const struct spoolss_PrinterInfo2 *info2,
3652 struct spoolss_PrinterInfo5 *r,
3655 r->printername = talloc_strdup(mem_ctx, info2->printername);
3656 W_ERROR_HAVE_NO_MEMORY(r->printername);
3657 r->portname = talloc_strdup(mem_ctx, info2->portname);
3658 W_ERROR_HAVE_NO_MEMORY(r->portname);
3660 r->attributes = info2->attributes;
3662 /* these two are not used by NT+ according to MSDN */
3663 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3664 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3669 /********************************************************************
3670 * construct_printer_info_6
3671 * fill a spoolss_PrinterInfo6 struct
3672 ********************************************************************/
3674 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3675 const struct spoolss_PrinterInfo2 *info2,
3676 struct spoolss_PrinterInfo6 *r,
3680 print_status_struct status;
3682 count = print_queue_length(snum, &status);
3684 r->status = nt_printq_status(status.status);
3689 /********************************************************************
3690 * construct_printer_info7
3691 * fill a spoolss_PrinterInfo7 struct
3692 ********************************************************************/
3694 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3695 Printer_entry *print_hnd,
3696 struct spoolss_PrinterInfo7 *r,
3699 struct auth_serversupplied_info *server_info;
3703 status = make_server_info_system(mem_ctx, &server_info);
3704 if (!NT_STATUS_IS_OK(status)) {
3705 DEBUG(0, ("construct_printer_info7: "
3706 "Could not create system server_info\n"));
3710 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3711 lp_servicename(snum), &guid, NULL)) {
3712 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3713 r->action = DSPRINT_PUBLISH;
3715 r->guid = talloc_strdup(mem_ctx, "");
3716 r->action = DSPRINT_UNPUBLISH;
3718 W_ERROR_HAVE_NO_MEMORY(r->guid);
3720 TALLOC_FREE(server_info);
3724 /********************************************************************
3725 * construct_printer_info8
3726 * fill a spoolss_PrinterInfo8 struct
3727 ********************************************************************/
3729 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3730 const struct spoolss_PrinterInfo2 *info2,
3731 struct spoolss_DeviceModeInfo *r,
3734 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3736 DEBUG(8,("Returning NULL Devicemode!\n"));
3743 /********************************************************************
3744 ********************************************************************/
3746 static bool snum_is_shared_printer(int snum)
3748 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3751 /********************************************************************
3752 Spoolss_enumprinters.
3753 ********************************************************************/
3755 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3756 struct auth_serversupplied_info *server_info,
3759 union spoolss_PrinterInfo **info_p,
3763 int n_services = lp_numservices();
3764 union spoolss_PrinterInfo *info = NULL;
3766 WERROR result = WERR_OK;
3771 for (snum = 0; snum < n_services; snum++) {
3773 const char *printer;
3774 struct spoolss_PrinterInfo2 *info2;
3776 if (!snum_is_shared_printer(snum)) {
3780 printer = lp_const_servicename(snum);
3782 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3785 result = winreg_create_printer(mem_ctx,
3789 if (!W_ERROR_IS_OK(result)) {
3793 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3794 union spoolss_PrinterInfo,
3797 result = WERR_NOMEM;
3801 result = winreg_get_printer(mem_ctx, server_info,
3802 NULL, printer, &info2);
3803 if (!W_ERROR_IS_OK(result)) {
3809 result = construct_printer_info0(info, server_info, info2,
3810 &info[count].info0, snum);
3813 result = construct_printer_info1(info, info2, flags,
3814 &info[count].info1, snum);
3817 result = construct_printer_info2(info, info2,
3818 &info[count].info2, snum);
3821 result = construct_printer_info4(info, info2,
3822 &info[count].info4, snum);
3825 result = construct_printer_info5(info, info2,
3826 &info[count].info5, snum);
3830 result = WERR_UNKNOWN_LEVEL;
3834 if (!W_ERROR_IS_OK(result)) {
3845 if (!W_ERROR_IS_OK(result)) {
3855 /********************************************************************
3856 * handle enumeration of printers at level 0
3857 ********************************************************************/
3859 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3860 struct auth_serversupplied_info *server_info,
3862 const char *servername,
3863 union spoolss_PrinterInfo **info,
3866 DEBUG(4,("enum_all_printers_info_0\n"));
3868 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3872 /********************************************************************
3873 ********************************************************************/
3875 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3876 struct auth_serversupplied_info *server_info,
3878 union spoolss_PrinterInfo **info,
3881 DEBUG(4,("enum_all_printers_info_1\n"));
3883 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3886 /********************************************************************
3887 enum_all_printers_info_1_local.
3888 *********************************************************************/
3890 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3891 struct auth_serversupplied_info *server_info,
3892 union spoolss_PrinterInfo **info,
3895 DEBUG(4,("enum_all_printers_info_1_local\n"));
3897 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3900 /********************************************************************
3901 enum_all_printers_info_1_name.
3902 *********************************************************************/
3904 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3905 struct auth_serversupplied_info *server_info,
3907 union spoolss_PrinterInfo **info,
3910 const char *s = name;
3912 DEBUG(4,("enum_all_printers_info_1_name\n"));
3914 if ((name[0] == '\\') && (name[1] == '\\')) {
3918 if (!is_myname_or_ipaddr(s)) {
3919 return WERR_INVALID_NAME;
3922 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3925 /********************************************************************
3926 enum_all_printers_info_1_network.
3927 *********************************************************************/
3929 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3930 struct auth_serversupplied_info *server_info,
3932 union spoolss_PrinterInfo **info,
3935 const char *s = name;
3937 DEBUG(4,("enum_all_printers_info_1_network\n"));
3939 /* If we respond to a enum_printers level 1 on our name with flags
3940 set to PRINTER_ENUM_REMOTE with a list of printers then these
3941 printers incorrectly appear in the APW browse list.
3942 Specifically the printers for the server appear at the workgroup
3943 level where all the other servers in the domain are
3944 listed. Windows responds to this call with a
3945 WERR_CAN_NOT_COMPLETE so we should do the same. */
3947 if (name[0] == '\\' && name[1] == '\\') {
3951 if (is_myname_or_ipaddr(s)) {
3952 return WERR_CAN_NOT_COMPLETE;
3955 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3958 /********************************************************************
3959 * api_spoolss_enumprinters
3961 * called from api_spoolss_enumprinters (see this to understand)
3962 ********************************************************************/
3964 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3965 struct auth_serversupplied_info *server_info,
3966 union spoolss_PrinterInfo **info,
3969 DEBUG(4,("enum_all_printers_info_2\n"));
3971 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
3974 /********************************************************************
3975 * handle enumeration of printers at level 1
3976 ********************************************************************/
3978 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
3979 struct auth_serversupplied_info *server_info,
3982 union spoolss_PrinterInfo **info,
3985 /* Not all the flags are equals */
3987 if (flags & PRINTER_ENUM_LOCAL) {
3988 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
3991 if (flags & PRINTER_ENUM_NAME) {
3992 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
3995 if (flags & PRINTER_ENUM_NETWORK) {
3996 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
3999 return WERR_OK; /* NT4sp5 does that */
4002 /********************************************************************
4003 * handle enumeration of printers at level 2
4004 ********************************************************************/
4006 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4007 struct auth_serversupplied_info *server_info,
4009 const char *servername,
4010 union spoolss_PrinterInfo **info,
4013 if (flags & PRINTER_ENUM_LOCAL) {
4014 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4017 if (flags & PRINTER_ENUM_NAME) {
4018 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4019 return WERR_INVALID_NAME;
4022 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4025 if (flags & PRINTER_ENUM_REMOTE) {
4026 return WERR_UNKNOWN_LEVEL;
4032 /********************************************************************
4033 * handle enumeration of printers at level 4
4034 ********************************************************************/
4036 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4037 struct auth_serversupplied_info *server_info,
4039 const char *servername,
4040 union spoolss_PrinterInfo **info,
4043 DEBUG(4,("enum_all_printers_info_4\n"));
4045 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4049 /********************************************************************
4050 * handle enumeration of printers at level 5
4051 ********************************************************************/
4053 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4054 struct auth_serversupplied_info *server_info,
4056 const char *servername,
4057 union spoolss_PrinterInfo **info,
4060 DEBUG(4,("enum_all_printers_info_5\n"));
4062 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4065 /****************************************************************
4066 _spoolss_EnumPrinters
4067 ****************************************************************/
4069 WERROR _spoolss_EnumPrinters(pipes_struct *p,
4070 struct spoolss_EnumPrinters *r)
4072 const char *name = NULL;
4075 /* that's an [in out] buffer */
4077 if (!r->in.buffer && (r->in.offered != 0)) {
4078 return WERR_INVALID_PARAM;
4081 DEBUG(4,("_spoolss_EnumPrinters\n"));
4085 *r->out.info = NULL;
4089 * flags==PRINTER_ENUM_NAME
4090 * if name=="" then enumerates all printers
4091 * if name!="" then enumerate the printer
4092 * flags==PRINTER_ENUM_REMOTE
4093 * name is NULL, enumerate printers
4094 * Level 2: name!="" enumerates printers, name can't be NULL
4095 * Level 3: doesn't exist
4096 * Level 4: does a local registry lookup
4097 * Level 5: same as Level 2
4101 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4102 W_ERROR_HAVE_NO_MEMORY(name);
4105 switch (r->in.level) {
4107 result = enumprinters_level0(p->mem_ctx, p->server_info,
4109 r->out.info, r->out.count);
4112 result = enumprinters_level1(p->mem_ctx, p->server_info,
4114 r->out.info, r->out.count);
4117 result = enumprinters_level2(p->mem_ctx, p->server_info,
4119 r->out.info, r->out.count);
4122 result = enumprinters_level4(p->mem_ctx, p->server_info,
4124 r->out.info, r->out.count);
4127 result = enumprinters_level5(p->mem_ctx, p->server_info,
4129 r->out.info, r->out.count);
4132 return WERR_UNKNOWN_LEVEL;
4135 if (!W_ERROR_IS_OK(result)) {
4139 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4140 spoolss_EnumPrinters,
4141 *r->out.info, r->in.level,
4143 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4144 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4146 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4149 /****************************************************************
4151 ****************************************************************/
4153 WERROR _spoolss_GetPrinter(pipes_struct *p,
4154 struct spoolss_GetPrinter *r)
4156 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4157 struct spoolss_PrinterInfo2 *info2 = NULL;
4158 WERROR result = WERR_OK;
4159 const char *servername = NULL;
4162 /* that's an [in out] buffer */
4164 if (!r->in.buffer && (r->in.offered != 0)) {
4165 return WERR_INVALID_PARAM;
4170 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4174 if (Printer != NULL || Printer->servername != NULL) {
4175 servername = Printer->servername;
4178 result = winreg_get_printer(p->mem_ctx,
4181 lp_const_servicename(snum),
4183 if (!W_ERROR_IS_OK(result)) {
4187 switch (r->in.level) {
4189 result = construct_printer_info0(p->mem_ctx, p->server_info,
4191 &r->out.info->info0, snum);
4194 result = construct_printer_info1(p->mem_ctx, info2,
4196 &r->out.info->info1, snum);
4199 result = construct_printer_info2(p->mem_ctx, info2,
4200 &r->out.info->info2, snum);
4203 result = construct_printer_info3(p->mem_ctx, info2,
4204 &r->out.info->info3, snum);
4207 result = construct_printer_info4(p->mem_ctx, info2,
4208 &r->out.info->info4, snum);
4211 result = construct_printer_info5(p->mem_ctx, info2,
4212 &r->out.info->info5, snum);
4215 result = construct_printer_info6(p->mem_ctx, info2,
4216 &r->out.info->info6, snum);
4219 result = construct_printer_info7(p->mem_ctx, Printer,
4220 &r->out.info->info7, snum);
4223 result = construct_printer_info8(p->mem_ctx, info2,
4224 &r->out.info->info8, snum);
4227 result = WERR_UNKNOWN_LEVEL;
4231 if (!W_ERROR_IS_OK(result)) {
4232 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4233 r->in.level, win_errstr(result)));
4234 TALLOC_FREE(r->out.info);
4238 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4239 r->out.info, r->in.level);
4240 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4242 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4245 /********************************************************************
4246 ********************************************************************/
4248 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4250 if (in && strlen(in)) { \
4251 out = talloc_strdup(mem_ctx, in); \
4252 W_ERROR_HAVE_NO_MEMORY(out); \
4258 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4260 if (in && strlen(in)) { \
4261 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4263 out = talloc_strdup(mem_ctx, ""); \
4265 W_ERROR_HAVE_NO_MEMORY(out); \
4268 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4269 const char **string_array,
4270 const char ***presult,
4271 const char *cservername,
4275 int i, num_strings = 0;
4276 const char **array = NULL;
4278 if (string_array == NULL) {
4279 return WERR_INVALID_PARAMETER;;
4282 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4283 const char *str = NULL;
4285 if (cservername == NULL || arch == NULL) {
4286 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4288 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4291 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4298 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4299 &array, &num_strings);
4309 /********************************************************************
4310 * fill a spoolss_DriverInfo1 struct
4311 ********************************************************************/
4313 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4314 struct spoolss_DriverInfo1 *r,
4315 const struct spoolss_DriverInfo8 *driver,
4316 const char *servername)
4318 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4319 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4324 /********************************************************************
4325 * fill a spoolss_DriverInfo2 struct
4326 ********************************************************************/
4328 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4329 struct spoolss_DriverInfo2 *r,
4330 const struct spoolss_DriverInfo8 *driver,
4331 const char *servername)
4334 const char *cservername = canon_servername(servername);
4336 r->version = driver->version;
4338 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4339 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4340 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4341 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4343 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4344 driver->architecture,
4346 driver->driver_path,
4349 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4350 driver->architecture,
4355 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4356 driver->architecture,
4358 driver->config_file,
4364 /********************************************************************
4365 * fill a spoolss_DriverInfo3 struct
4366 ********************************************************************/
4368 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4369 struct spoolss_DriverInfo3 *r,
4370 const struct spoolss_DriverInfo8 *driver,
4371 const char *servername)
4373 const char *cservername = canon_servername(servername);
4375 r->version = driver->version;
4377 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4378 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4379 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4380 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4382 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4383 driver->architecture,
4385 driver->driver_path,
4388 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4389 driver->architecture,
4394 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4395 driver->architecture,
4397 driver->config_file,
4400 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4401 driver->architecture,
4406 FILL_DRIVER_STRING(mem_ctx,
4407 driver->monitor_name,
4410 FILL_DRIVER_STRING(mem_ctx,
4411 driver->default_datatype,
4412 r->default_datatype);
4414 return string_array_from_driver_info(mem_ctx,
4415 driver->dependent_files,
4416 &r->dependent_files,
4418 driver->architecture,
4422 /********************************************************************
4423 * fill a spoolss_DriverInfo4 struct
4424 ********************************************************************/
4426 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4427 struct spoolss_DriverInfo4 *r,
4428 const struct spoolss_DriverInfo8 *driver,
4429 const char *servername)
4431 const char *cservername = canon_servername(servername);
4434 r->version = driver->version;
4436 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4437 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4438 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4439 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4441 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4442 driver->architecture,
4444 driver->driver_path,
4447 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4448 driver->architecture,
4453 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4454 driver->architecture,
4456 driver->config_file,
4459 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4460 driver->architecture,
4465 result = string_array_from_driver_info(mem_ctx,
4466 driver->dependent_files,
4467 &r->dependent_files,
4469 driver->architecture,
4471 if (!W_ERROR_IS_OK(result)) {
4475 FILL_DRIVER_STRING(mem_ctx,
4476 driver->monitor_name,
4479 FILL_DRIVER_STRING(mem_ctx,
4480 driver->default_datatype,
4481 r->default_datatype);
4484 result = string_array_from_driver_info(mem_ctx,
4485 driver->previous_names,
4492 /********************************************************************
4493 * fill a spoolss_DriverInfo5 struct
4494 ********************************************************************/
4496 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4497 struct spoolss_DriverInfo5 *r,
4498 const struct spoolss_DriverInfo8 *driver,
4499 const char *servername)
4501 const char *cservername = canon_servername(servername);
4503 r->version = driver->version;
4505 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4506 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4507 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4508 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4510 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4511 driver->architecture,
4513 driver->driver_path,
4516 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4517 driver->architecture,
4522 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4523 driver->architecture,
4525 driver->config_file,
4528 r->driver_attributes = 0;
4529 r->config_version = 0;
4530 r->driver_version = 0;
4534 /********************************************************************
4535 * fill a spoolss_DriverInfo6 struct
4536 ********************************************************************/
4538 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4539 struct spoolss_DriverInfo6 *r,
4540 const struct spoolss_DriverInfo8 *driver,
4541 const char *servername)
4543 const char *cservername = canon_servername(servername);
4546 r->version = driver->version;
4548 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4549 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4550 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4551 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4553 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4554 driver->architecture,
4556 driver->driver_path,
4559 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4560 driver->architecture,
4565 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4566 driver->architecture,
4568 driver->config_file,
4571 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4572 driver->architecture,
4577 FILL_DRIVER_STRING(mem_ctx,
4578 driver->monitor_name,
4581 FILL_DRIVER_STRING(mem_ctx,
4582 driver->default_datatype,
4583 r->default_datatype);
4585 result = string_array_from_driver_info(mem_ctx,
4586 driver->dependent_files,
4587 &r->dependent_files,
4589 driver->architecture,
4591 if (!W_ERROR_IS_OK(result)) {
4595 result = string_array_from_driver_info(mem_ctx,
4596 driver->previous_names,
4599 if (!W_ERROR_IS_OK(result)) {
4603 r->driver_date = driver->driver_date;
4604 r->driver_version = driver->driver_version;
4606 FILL_DRIVER_STRING(mem_ctx,
4607 driver->manufacturer_name,
4608 r->manufacturer_name);
4609 FILL_DRIVER_STRING(mem_ctx,
4610 driver->manufacturer_url,
4611 r->manufacturer_url);
4612 FILL_DRIVER_STRING(mem_ctx,
4613 driver->hardware_id,
4615 FILL_DRIVER_STRING(mem_ctx,
4622 /********************************************************************
4623 * fill a spoolss_DriverInfo8 struct
4624 ********************************************************************/
4626 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4627 struct spoolss_DriverInfo8 *r,
4628 const struct spoolss_DriverInfo8 *driver,
4629 const char *servername)
4631 const char *cservername = canon_servername(servername);
4634 r->version = driver->version;
4636 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4637 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4638 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4639 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4641 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4642 driver->architecture,
4644 driver->driver_path,
4647 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4648 driver->architecture,
4653 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4654 driver->architecture,
4656 driver->config_file,
4659 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4660 driver->architecture,
4665 FILL_DRIVER_STRING(mem_ctx,
4666 driver->monitor_name,
4669 FILL_DRIVER_STRING(mem_ctx,
4670 driver->default_datatype,
4671 r->default_datatype);
4673 result = string_array_from_driver_info(mem_ctx,
4674 driver->dependent_files,
4675 &r->dependent_files,
4677 driver->architecture,
4679 if (!W_ERROR_IS_OK(result)) {
4683 result = string_array_from_driver_info(mem_ctx,
4684 driver->previous_names,
4687 if (!W_ERROR_IS_OK(result)) {
4691 r->driver_date = driver->driver_date;
4692 r->driver_version = driver->driver_version;
4694 FILL_DRIVER_STRING(mem_ctx,
4695 driver->manufacturer_name,
4696 r->manufacturer_name);
4697 FILL_DRIVER_STRING(mem_ctx,
4698 driver->manufacturer_url,
4699 r->manufacturer_url);
4700 FILL_DRIVER_STRING(mem_ctx,
4701 driver->hardware_id,
4703 FILL_DRIVER_STRING(mem_ctx,
4707 FILL_DRIVER_STRING(mem_ctx,
4708 driver->print_processor,
4709 r->print_processor);
4710 FILL_DRIVER_STRING(mem_ctx,
4711 driver->vendor_setup,
4714 result = string_array_from_driver_info(mem_ctx,
4715 driver->color_profiles,
4718 if (!W_ERROR_IS_OK(result)) {
4722 FILL_DRIVER_STRING(mem_ctx,
4726 r->printer_driver_attributes = driver->printer_driver_attributes;
4728 result = string_array_from_driver_info(mem_ctx,
4729 driver->core_driver_dependencies,
4730 &r->core_driver_dependencies,
4732 if (!W_ERROR_IS_OK(result)) {
4736 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4737 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4742 #if 0 /* disabled until marshalling issues are resolved - gd */
4743 /********************************************************************
4744 ********************************************************************/
4746 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4747 struct spoolss_DriverFileInfo *r,
4748 const char *cservername,
4749 const char *file_name,
4750 enum spoolss_DriverFileType file_type,
4751 uint32_t file_version)
4753 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4754 cservername, file_name);
4755 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4756 r->file_type = file_type;
4757 r->file_version = file_version;
4762 /********************************************************************
4763 ********************************************************************/
4765 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4766 const struct spoolss_DriverInfo8 *driver,
4767 const char *cservername,
4768 struct spoolss_DriverFileInfo **info_p,
4771 struct spoolss_DriverFileInfo *info = NULL;
4779 if (strlen(driver->driver_path)) {
4780 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4781 struct spoolss_DriverFileInfo,
4783 W_ERROR_HAVE_NO_MEMORY(info);
4784 result = fill_spoolss_DriverFileInfo(info,
4787 driver->driver_path,
4788 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4790 W_ERROR_NOT_OK_RETURN(result);
4794 if (strlen(driver->config_file)) {
4795 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4796 struct spoolss_DriverFileInfo,
4798 W_ERROR_HAVE_NO_MEMORY(info);
4799 result = fill_spoolss_DriverFileInfo(info,
4802 driver->config_file,
4803 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4805 W_ERROR_NOT_OK_RETURN(result);
4809 if (strlen(driver->data_file)) {
4810 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4811 struct spoolss_DriverFileInfo,
4813 W_ERROR_HAVE_NO_MEMORY(info);
4814 result = fill_spoolss_DriverFileInfo(info,
4818 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4820 W_ERROR_NOT_OK_RETURN(result);
4824 if (strlen(driver->help_file)) {
4825 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4826 struct spoolss_DriverFileInfo,
4828 W_ERROR_HAVE_NO_MEMORY(info);
4829 result = fill_spoolss_DriverFileInfo(info,
4833 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4835 W_ERROR_NOT_OK_RETURN(result);
4839 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4840 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4841 struct spoolss_DriverFileInfo,
4843 W_ERROR_HAVE_NO_MEMORY(info);
4844 result = fill_spoolss_DriverFileInfo(info,
4847 driver->dependent_files[i],
4848 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4850 W_ERROR_NOT_OK_RETURN(result);
4860 /********************************************************************
4861 * fill a spoolss_DriverInfo101 struct
4862 ********************************************************************/
4864 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4865 struct spoolss_DriverInfo101 *r,
4866 const struct spoolss_DriverInfo8 *driver,
4867 const char *servername)
4869 const char *cservername = canon_servername(servername);
4872 r->version = driver->version;
4874 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4875 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4876 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4877 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4879 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4883 if (!W_ERROR_IS_OK(result)) {
4887 FILL_DRIVER_STRING(mem_ctx,
4888 driver->monitor_name,
4891 FILL_DRIVER_STRING(mem_ctx,
4892 driver->default_datatype,
4893 r->default_datatype);
4895 result = string_array_from_driver_info(mem_ctx,
4896 driver->previous_names,
4899 if (!W_ERROR_IS_OK(result)) {
4903 r->driver_date = driver->driver_date;
4904 r->driver_version = driver->driver_version;
4906 FILL_DRIVER_STRING(mem_ctx,
4907 driver->manufacturer_name,
4908 r->manufacturer_name);
4909 FILL_DRIVER_STRING(mem_ctx,
4910 driver->manufacturer_url,
4911 r->manufacturer_url);
4912 FILL_DRIVER_STRING(mem_ctx,
4913 driver->hardware_id,
4915 FILL_DRIVER_STRING(mem_ctx,
4922 /********************************************************************
4923 ********************************************************************/
4925 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4926 struct auth_serversupplied_info *server_info,
4928 union spoolss_DriverInfo *r,
4930 const char *servername,
4931 const char *architecture,
4934 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4935 struct spoolss_DriverInfo8 *driver;
4938 result = winreg_get_printer(mem_ctx,
4941 lp_const_servicename(snum),
4944 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4945 win_errstr(result)));
4947 if (!W_ERROR_IS_OK(result)) {
4948 return WERR_INVALID_PRINTER_NAME;
4951 result = winreg_get_driver(mem_ctx, server_info, architecture,
4952 pinfo2->drivername, version, &driver);
4954 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4955 win_errstr(result)));
4957 if (!W_ERROR_IS_OK(result)) {
4959 * Is this a W2k client ?
4963 talloc_free(pinfo2);
4964 return WERR_UNKNOWN_PRINTER_DRIVER;
4967 /* Yes - try again with a WinNT driver. */
4969 result = winreg_get_driver(mem_ctx, server_info, architecture,
4972 DEBUG(8,("construct_printer_driver_level: status: %s\n",
4973 win_errstr(result)));
4974 if (!W_ERROR_IS_OK(result)) {
4975 talloc_free(pinfo2);
4976 return WERR_UNKNOWN_PRINTER_DRIVER;
4982 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
4985 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
4988 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
4991 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
4994 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
4997 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5000 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5002 #if 0 /* disabled until marshalling issues are resolved - gd */
5004 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5008 result = WERR_UNKNOWN_LEVEL;
5012 talloc_free(pinfo2);
5013 talloc_free(driver);
5018 /****************************************************************
5019 _spoolss_GetPrinterDriver2
5020 ****************************************************************/
5022 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5023 struct spoolss_GetPrinterDriver2 *r)
5025 Printer_entry *printer;
5030 /* that's an [in out] buffer */
5032 if (!r->in.buffer && (r->in.offered != 0)) {
5033 return WERR_INVALID_PARAM;
5036 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5038 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5039 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5040 return WERR_INVALID_PRINTER_NAME;
5044 *r->out.server_major_version = 0;
5045 *r->out.server_minor_version = 0;
5047 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5051 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5052 r->in.level, r->out.info,
5053 snum, printer->servername,
5055 r->in.client_major_version);
5056 if (!W_ERROR_IS_OK(result)) {
5057 TALLOC_FREE(r->out.info);
5061 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5062 r->out.info, r->in.level);
5063 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5065 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5069 /****************************************************************
5070 _spoolss_StartPagePrinter
5071 ****************************************************************/
5073 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5074 struct spoolss_StartPagePrinter *r)
5076 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5079 DEBUG(3,("_spoolss_StartPagePrinter: "
5080 "Error in startpageprinter printer handle\n"));
5084 Printer->page_started = true;
5088 /****************************************************************
5089 _spoolss_EndPagePrinter
5090 ****************************************************************/
5092 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5093 struct spoolss_EndPagePrinter *r)
5097 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5100 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5101 OUR_HANDLE(r->in.handle)));
5105 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5108 Printer->page_started = false;
5109 print_job_endpage(snum, Printer->jobid);
5114 /****************************************************************
5115 _spoolss_StartDocPrinter
5116 ****************************************************************/
5118 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5119 struct spoolss_StartDocPrinter *r)
5121 struct spoolss_DocumentInfo1 *info_1;
5123 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5126 DEBUG(2,("_spoolss_StartDocPrinter: "
5127 "Invalid handle (%s:%u:%u)\n",
5128 OUR_HANDLE(r->in.handle)));
5132 if (r->in.level != 1) {
5133 return WERR_UNKNOWN_LEVEL;
5136 info_1 = r->in.info.info1;
5139 * a nice thing with NT is it doesn't listen to what you tell it.
5140 * when asked to send _only_ RAW datas, it tries to send datas
5143 * So I add checks like in NT Server ...
5146 if (info_1->datatype) {
5147 if (strcmp(info_1->datatype, "RAW") != 0) {
5149 return WERR_INVALID_DATATYPE;
5153 /* get the share number of the printer */
5154 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5158 Printer->jobid = print_job_start(p->server_info, snum,
5159 info_1->document_name,
5162 /* An error occured in print_job_start() so return an appropriate
5165 if (Printer->jobid == -1) {
5166 return map_werror_from_unix(errno);
5169 Printer->document_started = true;
5170 *r->out.job_id = Printer->jobid;
5175 /****************************************************************
5176 _spoolss_EndDocPrinter
5177 ****************************************************************/
5179 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5180 struct spoolss_EndDocPrinter *r)
5182 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5186 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5187 OUR_HANDLE(r->in.handle)));
5191 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5195 Printer->document_started = false;
5196 print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5197 /* error codes unhandled so far ... */
5202 /****************************************************************
5203 _spoolss_WritePrinter
5204 ****************************************************************/
5206 WERROR _spoolss_WritePrinter(pipes_struct *p,
5207 struct spoolss_WritePrinter *r)
5209 ssize_t buffer_written;
5211 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5214 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5215 OUR_HANDLE(r->in.handle)));
5216 *r->out.num_written = r->in._data_size;
5220 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5223 buffer_written = print_job_write(snum, Printer->jobid,
5224 (const char *)r->in.data.data,
5226 (size_t)r->in._data_size);
5227 if (buffer_written == (ssize_t)-1) {
5228 *r->out.num_written = 0;
5229 if (errno == ENOSPC)
5230 return WERR_NO_SPOOL_SPACE;
5232 return WERR_ACCESS_DENIED;
5235 *r->out.num_written = r->in._data_size;
5240 /********************************************************************
5241 * api_spoolss_getprinter
5242 * called from the spoolss dispatcher
5244 ********************************************************************/
5246 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5250 WERROR errcode = WERR_BADFUNC;
5251 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5254 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5255 OUR_HANDLE(handle)));
5259 if (!get_printer_snum(p, handle, &snum, NULL))
5263 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5264 errcode = print_queue_pause(p->server_info, snum);
5266 case SPOOLSS_PRINTER_CONTROL_RESUME:
5267 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5268 errcode = print_queue_resume(p->server_info, snum);
5270 case SPOOLSS_PRINTER_CONTROL_PURGE:
5271 errcode = print_queue_purge(p->server_info, snum);
5274 return WERR_UNKNOWN_LEVEL;
5281 /****************************************************************
5282 _spoolss_AbortPrinter
5283 * From MSDN: "Deletes printer's spool file if printer is configured
5285 ****************************************************************/
5287 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5288 struct spoolss_AbortPrinter *r)
5290 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5292 WERROR errcode = WERR_OK;
5295 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5296 OUR_HANDLE(r->in.handle)));
5300 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5303 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5308 /********************************************************************
5309 * called by spoolss_api_setprinter
5310 * when updating a printer description
5311 ********************************************************************/
5313 static WERROR update_printer_sec(struct policy_handle *handle,
5314 pipes_struct *p, struct sec_desc_buf *secdesc_ctr)
5316 struct spoolss_security_descriptor *new_secdesc = NULL;
5317 struct spoolss_security_descriptor *old_secdesc = NULL;
5318 const char *printer;
5322 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5324 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5325 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5326 OUR_HANDLE(handle)));
5328 result = WERR_BADFID;
5332 if (secdesc_ctr == NULL) {
5333 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5334 result = WERR_INVALID_PARAM;
5337 printer = lp_const_servicename(snum);
5339 /* Check the user has permissions to change the security
5340 descriptor. By experimentation with two NT machines, the user
5341 requires Full Access to the printer to change security
5344 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5345 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5346 result = WERR_ACCESS_DENIED;
5350 /* NT seems to like setting the security descriptor even though
5351 nothing may have actually changed. */
5352 result = winreg_get_printer_secdesc(p->mem_ctx,
5356 if (!W_ERROR_IS_OK(result)) {
5357 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5358 result = WERR_BADFID;
5362 if (DEBUGLEVEL >= 10) {
5363 struct security_acl *the_acl;
5366 the_acl = secdesc_ctr->sd->dacl;
5367 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5368 printer, the_acl->num_aces));
5370 for (i = 0; i < the_acl->num_aces; i++) {
5371 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5372 &the_acl->aces[i].trustee),
5373 the_acl->aces[i].access_mask));
5376 the_acl = secdesc_ctr->sd->dacl;
5379 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5380 printer, the_acl->num_aces));
5382 for (i = 0; i < the_acl->num_aces; i++) {
5383 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5384 &the_acl->aces[i].trustee),
5385 the_acl->aces[i].access_mask));
5388 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5392 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5393 if (new_secdesc == NULL) {
5394 result = WERR_NOMEM;
5398 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5403 result = winreg_set_printer_secdesc(p->mem_ctx,
5412 /********************************************************************
5413 Canonicalize printer info from a client
5414 ********************************************************************/
5416 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5417 struct spoolss_SetPrinterInfo2 *info2,
5420 fstring printername;
5423 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5424 "portname=%s drivername=%s comment=%s location=%s\n",
5425 info2->servername, info2->printername, info2->sharename,
5426 info2->portname, info2->drivername, info2->comment,
5429 /* we force some elements to "correct" values */
5430 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5431 if (info2->servername == NULL) {
5434 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5435 if (info2->sharename == NULL) {
5439 /* check to see if we allow printername != sharename */
5440 if (lp_force_printername(snum)) {
5441 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5442 global_myname(), info2->sharename);
5444 /* make sure printername is in \\server\printername format */
5445 fstrcpy(printername, info2->printername);
5447 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5448 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5452 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5453 global_myname(), p);
5455 if (info2->printername == NULL) {
5459 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5460 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5465 /****************************************************************************
5466 ****************************************************************************/
5468 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5470 char *cmd = lp_addport_cmd();
5471 char *command = NULL;
5473 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5474 bool is_print_op = false;
5477 return WERR_ACCESS_DENIED;
5480 command = talloc_asprintf(ctx,
5481 "%s \"%s\" \"%s\"", cmd, portname, uri );
5487 is_print_op = user_has_privileges( token, &se_printop );
5489 DEBUG(10,("Running [%s]\n", command));
5491 /********* BEGIN SePrintOperatorPrivilege **********/
5496 ret = smbrun(command, NULL);
5501 /********* END SePrintOperatorPrivilege **********/
5503 DEBUGADD(10,("returned [%d]\n", ret));
5505 TALLOC_FREE(command);
5508 return WERR_ACCESS_DENIED;
5514 /****************************************************************************
5515 ****************************************************************************/
5517 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5518 struct spoolss_SetPrinterInfo2 *info2)
5520 char *cmd = lp_addprinter_cmd();
5522 char *command = NULL;
5526 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5527 bool is_print_op = false;
5528 char *remote_machine = talloc_strdup(ctx, "%m");
5530 if (!remote_machine) {
5533 remote_machine = talloc_sub_basic(ctx,
5534 current_user_info.smb_name,
5535 current_user_info.domain,
5537 if (!remote_machine) {
5541 command = talloc_asprintf(ctx,
5542 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5543 cmd, info2->printername, info2->sharename,
5544 info2->portname, info2->drivername,
5545 info2->location, info2->comment, remote_machine);
5551 is_print_op = user_has_privileges( token, &se_printop );
5553 DEBUG(10,("Running [%s]\n", command));
5555 /********* BEGIN SePrintOperatorPrivilege **********/
5560 if ( (ret = smbrun(command, &fd)) == 0 ) {
5561 /* Tell everyone we updated smb.conf. */
5562 message_send_all(smbd_messaging_context(),
5563 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5569 /********* END SePrintOperatorPrivilege **********/
5571 DEBUGADD(10,("returned [%d]\n", ret));
5573 TALLOC_FREE(command);
5574 TALLOC_FREE(remote_machine);
5582 /* reload our services immediately */
5584 reload_services(false);
5588 /* Get lines and convert them back to dos-codepage */
5589 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5590 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5593 /* Set the portname to what the script says the portname should be. */
5594 /* but don't require anything to be return from the script exit a good error code */
5597 /* Set the portname to what the script says the portname should be. */
5598 info2->portname = talloc_strdup(ctx, qlines[0]);
5599 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5602 TALLOC_FREE(qlines);
5606 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5607 struct auth_serversupplied_info *server_info,
5609 struct spoolss_SetPrinterInfo2 *printer,
5610 struct spoolss_PrinterInfo2 *old_printer)
5612 bool force_update = (old_printer == NULL);
5613 const char *dnsdomname;
5614 const char *longname;
5615 const char *uncname;
5616 const char *spooling;
5618 WERROR result = WERR_OK;
5620 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5621 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5622 winreg_set_printer_dataex(mem_ctx,
5625 SPOOL_DSSPOOLER_KEY,
5626 SPOOL_REG_DRIVERNAME,
5631 if (!force_update) {
5632 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5633 printer->drivername));
5635 notify_printer_driver(snum, printer->drivername);
5639 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5640 push_reg_sz(mem_ctx, &buffer, printer->comment);
5641 winreg_set_printer_dataex(mem_ctx,
5644 SPOOL_DSSPOOLER_KEY,
5645 SPOOL_REG_DESCRIPTION,
5650 if (!force_update) {
5651 notify_printer_comment(snum, printer->comment);
5655 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5656 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5657 winreg_set_printer_dataex(mem_ctx,
5660 SPOOL_DSSPOOLER_KEY,
5661 SPOOL_REG_PRINTSHARENAME,
5666 if (!force_update) {
5667 notify_printer_sharename(snum, printer->sharename);
5671 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5674 p = strrchr(printer->printername, '\\' );
5678 p = printer->printername;
5681 push_reg_sz(mem_ctx, &buffer, p);
5682 winreg_set_printer_dataex(mem_ctx,
5685 SPOOL_DSSPOOLER_KEY,
5686 SPOOL_REG_PRINTERNAME,
5691 if (!force_update) {
5692 notify_printer_printername(snum, p);
5696 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5697 push_reg_sz(mem_ctx, &buffer, printer->portname);
5698 winreg_set_printer_dataex(mem_ctx,
5701 SPOOL_DSSPOOLER_KEY,
5707 if (!force_update) {
5708 notify_printer_port(snum, printer->portname);
5712 if (force_update || !strequal(printer->location, old_printer->location)) {
5713 push_reg_sz(mem_ctx, &buffer, printer->location);
5714 winreg_set_printer_dataex(mem_ctx,
5717 SPOOL_DSSPOOLER_KEY,
5723 if (!force_update) {
5724 notify_printer_location(snum, printer->location);
5728 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5729 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5730 winreg_set_printer_dataex(mem_ctx,
5733 SPOOL_DSSPOOLER_KEY,
5734 SPOOL_REG_PRINTSEPARATORFILE,
5739 if (!force_update) {
5740 notify_printer_location(snum, printer->location);
5744 if (force_update || printer->starttime != old_printer->starttime) {
5745 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5746 SIVAL(buffer.data, 0, printer->starttime);
5747 winreg_set_printer_dataex(mem_ctx,
5750 SPOOL_DSSPOOLER_KEY,
5751 SPOOL_REG_PRINTSTARTTIME,
5757 if (force_update || printer->untiltime != old_printer->untiltime) {
5758 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5759 SIVAL(buffer.data, 0, printer->untiltime);
5760 winreg_set_printer_dataex(mem_ctx,
5763 SPOOL_DSSPOOLER_KEY,
5764 SPOOL_REG_PRINTENDTIME,
5770 if (force_update || printer->priority != old_printer->priority) {
5771 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5772 SIVAL(buffer.data, 0, printer->priority);
5773 winreg_set_printer_dataex(mem_ctx,
5776 SPOOL_DSSPOOLER_KEY,
5783 if (force_update || printer->attributes != old_printer->attributes) {
5784 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5785 SIVAL(buffer.data, 0, (printer->attributes &
5786 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5787 winreg_set_printer_dataex(mem_ctx,
5790 SPOOL_DSSPOOLER_KEY,
5791 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5796 switch (printer->attributes & 0x3) {
5798 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5801 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5804 spooling = SPOOL_REGVAL_PRINTDIRECT;
5807 spooling = "unknown";
5809 push_reg_sz(mem_ctx, &buffer, spooling);
5810 winreg_set_printer_dataex(mem_ctx,
5813 SPOOL_DSSPOOLER_KEY,
5814 SPOOL_REG_PRINTSPOOLING,
5820 push_reg_sz(mem_ctx, &buffer, global_myname());
5821 winreg_set_printer_dataex(mem_ctx,
5824 SPOOL_DSSPOOLER_KEY,
5825 SPOOL_REG_SHORTSERVERNAME,
5830 dnsdomname = get_mydnsfullname();
5831 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5832 longname = talloc_strdup(mem_ctx, dnsdomname);
5834 longname = talloc_strdup(mem_ctx, global_myname());
5836 if (longname == NULL) {
5837 result = WERR_NOMEM;
5841 push_reg_sz(mem_ctx, &buffer, longname);
5842 winreg_set_printer_dataex(mem_ctx,
5845 SPOOL_DSSPOOLER_KEY,
5846 SPOOL_REG_SERVERNAME,
5851 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5852 global_myname(), printer->sharename);
5853 push_reg_sz(mem_ctx, &buffer, uncname);
5854 winreg_set_printer_dataex(mem_ctx,
5857 SPOOL_DSSPOOLER_KEY,
5867 /********************************************************************
5868 * Called by spoolss_api_setprinter
5869 * when updating a printer description.
5870 ********************************************************************/
5872 static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5873 struct spoolss_SetPrinterInfoCtr *info_ctr,
5874 struct spoolss_DeviceMode *devmode)
5876 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5877 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5878 struct spoolss_PrinterInfo2 *old_printer;
5879 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5880 const char *servername = NULL;
5882 WERROR result = WERR_OK;
5883 TALLOC_CTX *tmp_ctx;
5885 DEBUG(8,("update_printer\n"));
5887 tmp_ctx = talloc_new(p->mem_ctx);
5888 if (tmp_ctx == NULL) {
5893 result = WERR_BADFID;
5897 if (!get_printer_snum(p, handle, &snum, NULL)) {
5898 result = WERR_BADFID;
5902 if (Printer != NULL || Printer->servername != NULL) {
5903 servername = Printer->servername;
5906 result = winreg_get_printer(tmp_ctx,
5909 lp_const_servicename(snum),
5911 if (!W_ERROR_IS_OK(result)) {
5912 result = WERR_BADFID;
5916 /* Do sanity check on the requested changes for Samba */
5917 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5918 result = WERR_INVALID_PARAM;
5922 /* FIXME!!! If the driver has changed we really should verify that
5923 it is installed before doing much else --jerry */
5925 /* Check calling user has permission to update printer description */
5926 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5927 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5928 result = WERR_ACCESS_DENIED;
5932 /* Call addprinter hook */
5933 /* Check changes to see if this is really needed */
5935 if (*lp_addprinter_cmd() &&
5936 (!strequal(printer->drivername, old_printer->drivername) ||
5937 !strequal(printer->comment, old_printer->comment) ||
5938 !strequal(printer->portname, old_printer->portname) ||
5939 !strequal(printer->location, old_printer->location)) )
5941 /* add_printer_hook() will call reload_services() */
5942 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5944 result = WERR_ACCESS_DENIED;
5949 update_dsspooler(tmp_ctx,
5955 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
5957 if (devmode == NULL) {
5958 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
5960 result = winreg_update_printer(tmp_ctx,
5969 talloc_free(tmp_ctx);
5974 /****************************************************************************
5975 ****************************************************************************/
5976 static WERROR publish_or_unpublish_printer(pipes_struct *p,
5977 struct policy_handle *handle,
5978 struct spoolss_SetPrinterInfo7 *info7)
5981 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5984 Printer_entry *Printer;
5986 if ( lp_security() != SEC_ADS ) {
5987 return WERR_UNKNOWN_LEVEL;
5990 Printer = find_printer_index_by_hnd(p, handle);
5992 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5997 if (!get_printer_snum(p, handle, &snum, NULL))
6000 result = winreg_get_printer(p->mem_ctx, p->server_info,
6001 Printer->servername,
6002 lp_servicename(snum), &pinfo2);
6003 if (!W_ERROR_IS_OK(result)) {
6007 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6009 TALLOC_FREE(pinfo2);
6012 return WERR_UNKNOWN_LEVEL;
6016 /********************************************************************
6017 ********************************************************************/
6019 static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
6020 struct spoolss_DeviceMode *devmode)
6023 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6024 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6026 DEBUG(8,("update_printer_devmode\n"));
6032 if (!get_printer_snum(p, handle, &snum, NULL)) {
6036 /* Check calling user has permission to update printer description */
6037 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6038 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6039 return WERR_ACCESS_DENIED;
6042 return winreg_update_printer(p->mem_ctx,
6044 lp_const_servicename(snum),
6052 /****************************************************************
6054 ****************************************************************/
6056 WERROR _spoolss_SetPrinter(pipes_struct *p,
6057 struct spoolss_SetPrinter *r)
6061 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6064 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6065 OUR_HANDLE(r->in.handle)));
6069 /* check the level */
6070 switch (r->in.info_ctr->level) {
6072 return control_printer(r->in.handle, r->in.command, p);
6074 result = update_printer(p, r->in.handle,
6076 r->in.devmode_ctr->devmode);
6077 if (!W_ERROR_IS_OK(result))
6079 if (r->in.secdesc_ctr->sd)
6080 result = update_printer_sec(r->in.handle, p,
6084 return update_printer_sec(r->in.handle, p,
6087 return publish_or_unpublish_printer(p, r->in.handle,
6088 r->in.info_ctr->info.info7);
6090 return update_printer_devmode(p, r->in.handle,
6091 r->in.devmode_ctr->devmode);
6093 return WERR_UNKNOWN_LEVEL;
6097 /****************************************************************
6098 _spoolss_FindClosePrinterNotify
6099 ****************************************************************/
6101 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6102 struct spoolss_FindClosePrinterNotify *r)
6104 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6107 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6108 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6112 if (Printer->notify.client_connected == true) {
6115 if ( Printer->printer_type == SPLHND_SERVER)
6117 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6118 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6121 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6124 Printer->notify.flags=0;
6125 Printer->notify.options=0;
6126 Printer->notify.localmachine[0]='\0';
6127 Printer->notify.printerlocal=0;
6128 TALLOC_FREE(Printer->notify.option);
6129 Printer->notify.client_connected = false;
6134 /****************************************************************
6136 ****************************************************************/
6138 WERROR _spoolss_AddJob(pipes_struct *p,
6139 struct spoolss_AddJob *r)
6141 if (!r->in.buffer && (r->in.offered != 0)) {
6142 return WERR_INVALID_PARAM;
6145 /* this is what a NT server returns for AddJob. AddJob must fail on
6146 * non-local printers */
6148 if (r->in.level != 1) {
6149 return WERR_UNKNOWN_LEVEL;
6152 return WERR_INVALID_PARAM;
6155 /****************************************************************************
6157 ****************************************************************************/
6159 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6160 struct spoolss_JobInfo1 *r,
6161 const print_queue_struct *queue,
6162 int position, int snum,
6163 struct spoolss_PrinterInfo2 *pinfo2)
6167 t = gmtime(&queue->time);
6169 r->job_id = queue->job;
6171 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6172 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6173 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6174 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6175 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6176 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6177 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6178 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6179 r->data_type = talloc_strdup(mem_ctx, "RAW");
6180 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6181 r->text_status = talloc_strdup(mem_ctx, "");
6182 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6184 r->status = nt_printj_status(queue->status);
6185 r->priority = queue->priority;
6186 r->position = position;
6187 r->total_pages = queue->page_count;
6188 r->pages_printed = 0; /* ??? */
6190 init_systemtime(&r->submitted, t);
6195 /****************************************************************************
6197 ****************************************************************************/
6199 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6200 struct spoolss_JobInfo2 *r,
6201 const print_queue_struct *queue,
6202 int position, int snum,
6203 struct spoolss_PrinterInfo2 *pinfo2,
6204 struct spoolss_DeviceMode *devmode)
6208 t = gmtime(&queue->time);
6210 r->job_id = queue->job;
6212 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6213 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6214 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6215 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6216 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6217 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6218 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6219 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6220 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6221 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6222 r->data_type = talloc_strdup(mem_ctx, "RAW");
6223 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6224 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6225 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6226 r->parameters = talloc_strdup(mem_ctx, "");
6227 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6228 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6229 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6231 r->devmode = devmode;
6233 r->text_status = talloc_strdup(mem_ctx, "");
6234 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6238 r->status = nt_printj_status(queue->status);
6239 r->priority = queue->priority;
6240 r->position = position;
6243 r->total_pages = queue->page_count;
6244 r->size = queue->size;
6245 init_systemtime(&r->submitted, t);
6247 r->pages_printed = 0; /* ??? */
6252 /****************************************************************************
6254 ****************************************************************************/
6256 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6257 struct spoolss_JobInfo3 *r,
6258 const print_queue_struct *queue,
6259 const print_queue_struct *next_queue,
6260 int position, int snum,
6261 struct spoolss_PrinterInfo2 *pinfo2)
6263 r->job_id = queue->job;
6266 r->next_job_id = next_queue->job;
6273 /****************************************************************************
6274 Enumjobs at level 1.
6275 ****************************************************************************/
6277 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6278 const print_queue_struct *queue,
6279 uint32_t num_queues, int snum,
6280 struct spoolss_PrinterInfo2 *pinfo2,
6281 union spoolss_JobInfo **info_p,
6284 union spoolss_JobInfo *info;
6286 WERROR result = WERR_OK;
6288 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6289 W_ERROR_HAVE_NO_MEMORY(info);
6291 *count = num_queues;
6293 for (i=0; i<*count; i++) {
6294 result = fill_job_info1(info,
6300 if (!W_ERROR_IS_OK(result)) {
6306 if (!W_ERROR_IS_OK(result)) {
6317 /****************************************************************************
6318 Enumjobs at level 2.
6319 ****************************************************************************/
6321 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6322 const print_queue_struct *queue,
6323 uint32_t num_queues, int snum,
6324 struct spoolss_PrinterInfo2 *pinfo2,
6325 union spoolss_JobInfo **info_p,
6328 union spoolss_JobInfo *info;
6330 WERROR result = WERR_OK;
6332 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6333 W_ERROR_HAVE_NO_MEMORY(info);
6335 *count = num_queues;
6337 for (i=0; i<*count; i++) {
6338 struct spoolss_DeviceMode *devmode;
6340 result = spoolss_create_default_devmode(info,
6341 pinfo2->printername,
6343 if (!W_ERROR_IS_OK(result)) {
6344 DEBUG(3, ("Can't proceed w/o a devmode!"));
6348 result = fill_job_info2(info,
6355 if (!W_ERROR_IS_OK(result)) {
6361 if (!W_ERROR_IS_OK(result)) {
6372 /****************************************************************************
6373 Enumjobs at level 3.
6374 ****************************************************************************/
6376 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6377 const print_queue_struct *queue,
6378 uint32_t num_queues, int snum,
6379 struct spoolss_PrinterInfo2 *pinfo2,
6380 union spoolss_JobInfo **info_p,
6383 union spoolss_JobInfo *info;
6385 WERROR result = WERR_OK;
6387 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6388 W_ERROR_HAVE_NO_MEMORY(info);
6390 *count = num_queues;
6392 for (i=0; i<*count; i++) {
6393 const print_queue_struct *next_queue = NULL;
6396 next_queue = &queue[i+1];
6399 result = fill_job_info3(info,
6406 if (!W_ERROR_IS_OK(result)) {
6412 if (!W_ERROR_IS_OK(result)) {
6423 /****************************************************************
6425 ****************************************************************/
6427 WERROR _spoolss_EnumJobs(pipes_struct *p,
6428 struct spoolss_EnumJobs *r)
6431 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6433 print_status_struct prt_status;
6434 print_queue_struct *queue = NULL;
6437 /* that's an [in out] buffer */
6439 if (!r->in.buffer && (r->in.offered != 0)) {
6440 return WERR_INVALID_PARAM;
6443 DEBUG(4,("_spoolss_EnumJobs\n"));
6447 *r->out.info = NULL;
6449 /* lookup the printer snum and tdb entry */
6451 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6455 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6456 lp_servicename(snum), &pinfo2);
6457 if (!W_ERROR_IS_OK(result)) {
6461 count = print_queue_status(snum, &queue, &prt_status);
6462 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6463 count, prt_status.status, prt_status.message));
6467 TALLOC_FREE(pinfo2);
6471 switch (r->in.level) {
6473 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6474 pinfo2, r->out.info, r->out.count);
6477 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6478 pinfo2, r->out.info, r->out.count);
6481 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6482 pinfo2, r->out.info, r->out.count);
6485 result = WERR_UNKNOWN_LEVEL;
6490 TALLOC_FREE(pinfo2);
6492 if (!W_ERROR_IS_OK(result)) {
6496 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6498 *r->out.info, r->in.level,
6500 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6501 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6503 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6506 /****************************************************************
6507 _spoolss_ScheduleJob
6508 ****************************************************************/
6510 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6511 struct spoolss_ScheduleJob *r)
6516 /****************************************************************
6517 ****************************************************************/
6519 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6520 const char *printer_name,
6522 struct spoolss_SetJobInfo1 *r)
6526 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6530 if (strequal(old_doc_name, r->document_name)) {
6534 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6541 /****************************************************************
6543 ****************************************************************/
6545 WERROR _spoolss_SetJob(pipes_struct *p,
6546 struct spoolss_SetJob *r)
6549 WERROR errcode = WERR_BADFUNC;
6551 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6555 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6556 return WERR_INVALID_PRINTER_NAME;
6559 switch (r->in.command) {
6560 case SPOOLSS_JOB_CONTROL_CANCEL:
6561 case SPOOLSS_JOB_CONTROL_DELETE:
6562 if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6566 case SPOOLSS_JOB_CONTROL_PAUSE:
6567 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6571 case SPOOLSS_JOB_CONTROL_RESTART:
6572 case SPOOLSS_JOB_CONTROL_RESUME:
6573 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6581 return WERR_UNKNOWN_LEVEL;
6584 if (!W_ERROR_IS_OK(errcode)) {
6588 if (r->in.ctr == NULL) {
6592 switch (r->in.ctr->level) {
6594 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6596 r->in.ctr->info.info1);
6602 return WERR_UNKNOWN_LEVEL;
6608 /****************************************************************************
6609 Enumerates all printer drivers by level and architecture.
6610 ****************************************************************************/
6612 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6613 struct auth_serversupplied_info *server_info,
6614 const char *servername,
6615 const char *architecture,
6617 union spoolss_DriverInfo **info_p,
6622 struct spoolss_DriverInfo8 *driver;
6623 union spoolss_DriverInfo *info = NULL;
6625 WERROR result = WERR_OK;
6626 uint32_t num_drivers;
6627 const char **drivers;
6632 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6633 result = winreg_get_driver_list(mem_ctx, server_info,
6634 architecture, version,
6635 &num_drivers, &drivers);
6636 if (!W_ERROR_IS_OK(result)) {
6639 DEBUG(4, ("we have:[%d] drivers in environment"
6640 " [%s] and version [%d]\n",
6641 num_drivers, architecture, version));
6643 if (num_drivers != 0) {
6644 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6645 union spoolss_DriverInfo,
6646 count + num_drivers);
6648 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6649 "failed to enlarge driver info buffer!\n"));
6650 result = WERR_NOMEM;
6655 for (i = 0; i < num_drivers; i++) {
6656 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6658 result = winreg_get_driver(mem_ctx, server_info,
6659 architecture, drivers[i],
6661 if (!W_ERROR_IS_OK(result)) {
6667 result = fill_printer_driver_info1(info, &info[count+i].info1,
6668 driver, servername);
6671 result = fill_printer_driver_info2(info, &info[count+i].info2,
6672 driver, servername);
6675 result = fill_printer_driver_info3(info, &info[count+i].info3,
6676 driver, servername);
6679 result = fill_printer_driver_info4(info, &info[count+i].info4,
6680 driver, servername);
6683 result = fill_printer_driver_info5(info, &info[count+i].info5,
6684 driver, servername);
6687 result = fill_printer_driver_info6(info, &info[count+i].info6,
6688 driver, servername);
6691 result = fill_printer_driver_info8(info, &info[count+i].info8,
6692 driver, servername);
6695 result = WERR_UNKNOWN_LEVEL;
6699 TALLOC_FREE(driver);
6701 if (!W_ERROR_IS_OK(result)) {
6706 count += num_drivers;
6707 TALLOC_FREE(drivers);
6711 TALLOC_FREE(drivers);
6713 if (!W_ERROR_IS_OK(result)) {
6724 /****************************************************************************
6725 Enumerates all printer drivers by level.
6726 ****************************************************************************/
6728 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6729 struct auth_serversupplied_info *server_info,
6730 const char *servername,
6731 const char *architecture,
6733 union spoolss_DriverInfo **info_p,
6737 WERROR result = WERR_OK;
6739 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6741 for (a=0; archi_table[a].long_archi != NULL; a++) {
6743 union spoolss_DriverInfo *info = NULL;
6746 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6749 archi_table[a].long_archi,
6753 if (!W_ERROR_IS_OK(result)) {
6757 for (i=0; i < count; i++) {
6758 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6759 info[i], info_p, count_p);
6766 return enumprinterdrivers_level_by_architecture(mem_ctx,
6775 /****************************************************************
6776 _spoolss_EnumPrinterDrivers
6777 ****************************************************************/
6779 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6780 struct spoolss_EnumPrinterDrivers *r)
6782 const char *cservername;
6785 /* that's an [in out] buffer */
6787 if (!r->in.buffer && (r->in.offered != 0)) {
6788 return WERR_INVALID_PARAM;
6791 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6795 *r->out.info = NULL;
6797 cservername = canon_servername(r->in.server);
6799 if (!is_myname_or_ipaddr(cservername)) {
6800 return WERR_UNKNOWN_PRINTER_DRIVER;
6803 result = enumprinterdrivers_level(p->mem_ctx,
6810 if (!W_ERROR_IS_OK(result)) {
6814 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6815 spoolss_EnumPrinterDrivers,
6816 *r->out.info, r->in.level,
6818 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6819 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6821 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6824 /****************************************************************
6826 ****************************************************************/
6828 WERROR _spoolss_EnumForms(pipes_struct *p,
6829 struct spoolss_EnumForms *r)
6835 *r->out.info = NULL;
6837 /* that's an [in out] buffer */
6839 if (!r->in.buffer && (r->in.offered != 0) ) {
6840 return WERR_INVALID_PARAM;
6843 DEBUG(4,("_spoolss_EnumForms\n"));
6844 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6845 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6847 switch (r->in.level) {
6849 result = winreg_printer_enumforms1(p->mem_ctx,
6855 result = WERR_UNKNOWN_LEVEL;
6859 if (!W_ERROR_IS_OK(result)) {
6863 if (*r->out.count == 0) {
6864 return WERR_NO_MORE_ITEMS;
6867 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6869 *r->out.info, r->in.level,
6871 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6872 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6874 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6877 /****************************************************************
6879 ****************************************************************/
6881 WERROR _spoolss_GetForm(pipes_struct *p,
6882 struct spoolss_GetForm *r)
6886 /* that's an [in out] buffer */
6888 if (!r->in.buffer && (r->in.offered != 0)) {
6889 return WERR_INVALID_PARAM;
6892 DEBUG(4,("_spoolss_GetForm\n"));
6893 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6894 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6896 switch (r->in.level) {
6898 result = winreg_printer_getform1(p->mem_ctx,
6901 &r->out.info->info1);
6904 result = WERR_UNKNOWN_LEVEL;
6908 if (!W_ERROR_IS_OK(result)) {
6909 TALLOC_FREE(r->out.info);
6913 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6914 r->out.info, r->in.level);
6915 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6917 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6920 /****************************************************************************
6921 ****************************************************************************/
6923 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6924 struct spoolss_PortInfo1 *r,
6927 r->port_name = talloc_strdup(mem_ctx, name);
6928 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6933 /****************************************************************************
6934 TODO: This probably needs distinguish between TCP/IP and Local ports
6936 ****************************************************************************/
6938 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6939 struct spoolss_PortInfo2 *r,
6942 r->port_name = talloc_strdup(mem_ctx, name);
6943 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6945 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6946 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6948 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6949 W_ERROR_HAVE_NO_MEMORY(r->description);
6951 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6958 /****************************************************************************
6959 wrapper around the enumer ports command
6960 ****************************************************************************/
6962 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6964 char *cmd = lp_enumports_cmd();
6965 char **qlines = NULL;
6966 char *command = NULL;
6974 /* if no hook then just fill in the default port */
6977 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
6980 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
6981 TALLOC_FREE(qlines);
6988 /* we have a valid enumport command */
6990 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
6995 DEBUG(10,("Running [%s]\n", command));
6996 ret = smbrun(command, &fd);
6997 DEBUG(10,("Returned [%d]\n", ret));
6998 TALLOC_FREE(command);
7003 return WERR_ACCESS_DENIED;
7007 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7008 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7018 /****************************************************************************
7020 ****************************************************************************/
7022 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7023 union spoolss_PortInfo **info_p,
7026 union spoolss_PortInfo *info = NULL;
7028 WERROR result = WERR_OK;
7029 char **qlines = NULL;
7032 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7033 if (!W_ERROR_IS_OK(result)) {
7038 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7040 DEBUG(10,("Returning WERR_NOMEM\n"));
7041 result = WERR_NOMEM;
7045 for (i=0; i<numlines; i++) {
7046 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7047 result = fill_port_1(info, &info[i].info1, qlines[i]);
7048 if (!W_ERROR_IS_OK(result)) {
7053 TALLOC_FREE(qlines);
7056 if (!W_ERROR_IS_OK(result)) {
7058 TALLOC_FREE(qlines);
7070 /****************************************************************************
7072 ****************************************************************************/
7074 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7075 union spoolss_PortInfo **info_p,
7078 union spoolss_PortInfo *info = NULL;
7080 WERROR result = WERR_OK;
7081 char **qlines = NULL;
7084 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7085 if (!W_ERROR_IS_OK(result)) {
7090 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7092 DEBUG(10,("Returning WERR_NOMEM\n"));
7093 result = WERR_NOMEM;
7097 for (i=0; i<numlines; i++) {
7098 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7099 result = fill_port_2(info, &info[i].info2, qlines[i]);
7100 if (!W_ERROR_IS_OK(result)) {
7105 TALLOC_FREE(qlines);
7108 if (!W_ERROR_IS_OK(result)) {
7110 TALLOC_FREE(qlines);
7122 /****************************************************************
7124 ****************************************************************/
7126 WERROR _spoolss_EnumPorts(pipes_struct *p,
7127 struct spoolss_EnumPorts *r)
7131 /* that's an [in out] buffer */
7133 if (!r->in.buffer && (r->in.offered != 0)) {
7134 return WERR_INVALID_PARAM;
7137 DEBUG(4,("_spoolss_EnumPorts\n"));
7141 *r->out.info = NULL;
7143 switch (r->in.level) {
7145 result = enumports_level_1(p->mem_ctx, r->out.info,
7149 result = enumports_level_2(p->mem_ctx, r->out.info,
7153 return WERR_UNKNOWN_LEVEL;
7156 if (!W_ERROR_IS_OK(result)) {
7160 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7162 *r->out.info, r->in.level,
7164 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7165 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7167 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7170 /****************************************************************************
7171 ****************************************************************************/
7173 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7175 struct spoolss_SetPrinterInfoCtr *info_ctr,
7176 struct spoolss_DeviceMode *devmode,
7177 struct security_descriptor *secdesc,
7178 struct spoolss_UserLevelCtr *user_ctr,
7179 struct policy_handle *handle)
7181 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7182 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7184 WERROR err = WERR_OK;
7186 /* samba does not have a concept of local, non-shared printers yet, so
7187 * make sure we always setup sharename - gd */
7188 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7189 (info2->printername != NULL && info2->printername[0] != '\0')) {
7190 DEBUG(5, ("spoolss_addprinterex_level_2: "
7191 "no sharename has been set, setting printername %s as sharename\n",
7192 info2->printername));
7193 info2->sharename = info2->printername;
7196 /* check to see if the printer already exists */
7197 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7198 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7200 return WERR_PRINTER_ALREADY_EXISTS;
7203 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7204 if ((snum = print_queue_snum(info2->printername)) != -1) {
7205 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7206 info2->printername));
7207 return WERR_PRINTER_ALREADY_EXISTS;
7211 /* validate printer info struct */
7212 if (!info2->printername || strlen(info2->printername) == 0) {
7213 return WERR_INVALID_PRINTER_NAME;
7215 if (!info2->portname || strlen(info2->portname) == 0) {
7216 return WERR_UNKNOWN_PORT;
7218 if (!info2->drivername || strlen(info2->drivername) == 0) {
7219 return WERR_UNKNOWN_PRINTER_DRIVER;
7221 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7222 return WERR_UNKNOWN_PRINTPROCESSOR;
7225 /* FIXME!!! smbd should check to see if the driver is installed before
7226 trying to add a printer like this --jerry */
7228 if (*lp_addprinter_cmd() ) {
7229 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7231 return WERR_ACCESS_DENIED;
7234 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7235 "smb.conf parameter \"addprinter command\" is defined. This"
7236 "parameter must exist for this call to succeed\n",
7237 info2->sharename ));
7240 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7241 return WERR_ACCESS_DENIED;
7244 /* you must be a printer admin to add a new printer */
7245 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7246 return WERR_ACCESS_DENIED;
7250 * Do sanity check on the requested changes for Samba.
7253 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7254 return WERR_INVALID_PARAM;
7257 if (devmode == NULL) {
7258 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7261 update_dsspooler(p->mem_ctx,
7267 err = winreg_update_printer(p->mem_ctx,
7274 if (!W_ERROR_IS_OK(err)) {
7278 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7279 /* Handle open failed - remove addition. */
7280 ZERO_STRUCTP(handle);
7281 return WERR_ACCESS_DENIED;
7287 /****************************************************************
7288 _spoolss_AddPrinterEx
7289 ****************************************************************/
7291 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7292 struct spoolss_AddPrinterEx *r)
7294 switch (r->in.info_ctr->level) {
7296 /* we don't handle yet */
7297 /* but I know what to do ... */
7298 return WERR_UNKNOWN_LEVEL;
7300 return spoolss_addprinterex_level_2(p, r->in.server,
7302 r->in.devmode_ctr->devmode,
7303 r->in.secdesc_ctr->sd,
7304 r->in.userlevel_ctr,
7307 return WERR_UNKNOWN_LEVEL;
7311 /****************************************************************
7313 ****************************************************************/
7315 WERROR _spoolss_AddPrinter(pipes_struct *p,
7316 struct spoolss_AddPrinter *r)
7318 struct spoolss_AddPrinterEx a;
7319 struct spoolss_UserLevelCtr userlevel_ctr;
7321 ZERO_STRUCT(userlevel_ctr);
7323 userlevel_ctr.level = 1;
7325 a.in.server = r->in.server;
7326 a.in.info_ctr = r->in.info_ctr;
7327 a.in.devmode_ctr = r->in.devmode_ctr;
7328 a.in.secdesc_ctr = r->in.secdesc_ctr;
7329 a.in.userlevel_ctr = &userlevel_ctr;
7330 a.out.handle = r->out.handle;
7332 return _spoolss_AddPrinterEx(p, &a);
7335 /****************************************************************
7336 _spoolss_AddPrinterDriverEx
7337 ****************************************************************/
7339 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7340 struct spoolss_AddPrinterDriverEx *r)
7342 WERROR err = WERR_OK;
7343 const char *driver_name = NULL;
7348 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7349 fn = "_spoolss_AddPrinterDriver";
7351 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7352 fn = "_spoolss_AddPrinterDriverEx";
7355 return WERR_INVALID_PARAM;
7359 * we only support the semantics of AddPrinterDriver()
7360 * i.e. only copy files that are newer than existing ones
7363 if (r->in.flags == 0) {
7364 return WERR_INVALID_PARAM;
7367 if (r->in.flags != APD_COPY_NEW_FILES) {
7368 return WERR_ACCESS_DENIED;
7372 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7373 /* Clever hack from Martin Zielinski <mz@seh.de>
7374 * to allow downgrade from level 8 (Vista).
7376 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7377 r->in.info_ctr->level));
7378 return WERR_UNKNOWN_LEVEL;
7381 DEBUG(5,("Cleaning driver's information\n"));
7382 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7383 if (!W_ERROR_IS_OK(err))
7386 DEBUG(5,("Moving driver to final destination\n"));
7387 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7392 err = winreg_add_driver(p->mem_ctx, p->server_info,
7393 r->in.info_ctr, &driver_name, &version);
7394 if (!W_ERROR_IS_OK(err)) {
7399 * I think this is where he DrvUpgradePrinter() hook would be
7400 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7401 * server. Right now, we just need to send ourselves a message
7402 * to update each printer bound to this driver. --jerry
7405 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7406 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7414 /****************************************************************
7415 _spoolss_AddPrinterDriver
7416 ****************************************************************/
7418 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7419 struct spoolss_AddPrinterDriver *r)
7421 struct spoolss_AddPrinterDriverEx a;
7423 switch (r->in.info_ctr->level) {
7430 return WERR_UNKNOWN_LEVEL;
7433 a.in.servername = r->in.servername;
7434 a.in.info_ctr = r->in.info_ctr;
7435 a.in.flags = APD_COPY_NEW_FILES;
7437 return _spoolss_AddPrinterDriverEx(p, &a);
7440 /****************************************************************************
7441 ****************************************************************************/
7443 struct _spoolss_paths {
7449 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7451 static const struct _spoolss_paths spoolss_paths[]= {
7452 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7453 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7456 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7457 const char *servername,
7458 const char *environment,
7462 const char *pservername = NULL;
7463 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7464 const char *short_archi;
7468 /* environment may be empty */
7469 if (environment && strlen(environment)) {
7470 long_archi = environment;
7473 /* servername may be empty */
7474 if (servername && strlen(servername)) {
7475 pservername = canon_servername(servername);
7477 if (!is_myname_or_ipaddr(pservername)) {
7478 return WERR_INVALID_PARAM;
7482 if (!(short_archi = get_short_archi(long_archi))) {
7483 return WERR_INVALID_ENVIRONMENT;
7486 switch (component) {
7487 case SPOOLSS_PRTPROCS_PATH:
7488 case SPOOLSS_DRIVER_PATH:
7490 *path = talloc_asprintf(mem_ctx,
7493 spoolss_paths[component].share,
7496 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7497 SPOOLSS_DEFAULT_SERVER_PATH,
7498 spoolss_paths[component].dir,
7503 return WERR_INVALID_PARAM;
7513 /****************************************************************************
7514 ****************************************************************************/
7516 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7517 const char *servername,
7518 const char *environment,
7519 struct spoolss_DriverDirectoryInfo1 *r)
7524 werr = compose_spoolss_server_path(mem_ctx,
7527 SPOOLSS_DRIVER_PATH,
7529 if (!W_ERROR_IS_OK(werr)) {
7533 DEBUG(4,("printer driver directory: [%s]\n", path));
7535 r->directory_name = path;
7540 /****************************************************************
7541 _spoolss_GetPrinterDriverDirectory
7542 ****************************************************************/
7544 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7545 struct spoolss_GetPrinterDriverDirectory *r)
7549 /* that's an [in out] buffer */
7551 if (!r->in.buffer && (r->in.offered != 0)) {
7552 return WERR_INVALID_PARAM;
7555 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7560 /* r->in.level is ignored */
7562 werror = getprinterdriverdir_level_1(p->mem_ctx,
7565 &r->out.info->info1);
7566 if (!W_ERROR_IS_OK(werror)) {
7567 TALLOC_FREE(r->out.info);
7571 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7572 r->out.info, r->in.level);
7573 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7575 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7578 /****************************************************************
7579 _spoolss_EnumPrinterData
7580 ****************************************************************/
7582 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7583 struct spoolss_EnumPrinterData *r)
7586 struct spoolss_EnumPrinterDataEx r2;
7588 struct spoolss_PrinterEnumValues *info, *val = NULL;
7591 r2.in.handle = r->in.handle;
7592 r2.in.key_name = "PrinterDriverData";
7594 r2.out.count = &count;
7595 r2.out.info = &info;
7596 r2.out.needed = &needed;
7598 result = _spoolss_EnumPrinterDataEx(p, &r2);
7599 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7600 r2.in.offered = needed;
7601 result = _spoolss_EnumPrinterDataEx(p, &r2);
7603 if (!W_ERROR_IS_OK(result)) {
7608 * The NT machine wants to know the biggest size of value and data
7610 * cf: MSDN EnumPrinterData remark section
7613 if (!r->in.value_offered && !r->in.data_offered) {
7614 uint32_t biggest_valuesize = 0;
7615 uint32_t biggest_datasize = 0;
7618 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7620 for (i=0; i<count; i++) {
7622 name_length = strlen(info[i].value_name);
7623 if (strlen(info[i].value_name) > biggest_valuesize) {
7624 biggest_valuesize = name_length;
7627 if (info[i].data_length > biggest_datasize) {
7628 biggest_datasize = info[i].data_length;
7631 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7635 /* the value is an UNICODE string but real_value_size is the length
7636 in bytes including the trailing 0 */
7638 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7639 *r->out.data_needed = biggest_datasize;
7641 DEBUG(6,("final values: [%d], [%d]\n",
7642 *r->out.value_needed, *r->out.data_needed));
7647 if (r->in.enum_index < count) {
7648 val = &info[r->in.enum_index];
7652 /* out_value should default to "" or else NT4 has
7653 problems unmarshalling the response */
7655 if (r->in.value_offered) {
7656 *r->out.value_needed = 1;
7657 r->out.value_name = talloc_strdup(r, "");
7658 if (!r->out.value_name) {
7662 r->out.value_name = NULL;
7663 *r->out.value_needed = 0;
7666 /* the data is counted in bytes */
7668 *r->out.data_needed = r->in.data_offered;
7670 result = WERR_NO_MORE_ITEMS;
7674 * - counted in bytes in the request
7675 * - counted in UNICODE chars in the max reply
7676 * - counted in bytes in the real size
7678 * take a pause *before* coding not *during* coding
7682 if (r->in.value_offered) {
7683 r->out.value_name = talloc_strdup(r, val->value_name);
7684 if (!r->out.value_name) {
7687 *r->out.value_needed = val->value_name_len;
7689 r->out.value_name = NULL;
7690 *r->out.value_needed = 0;
7695 *r->out.type = val->type;
7697 /* data - counted in bytes */
7700 * See the section "Dynamically Typed Query Parameters"
7704 if (r->out.data && val->data && val->data->data &&
7705 val->data_length && r->in.data_offered) {
7706 memcpy(r->out.data, val->data->data,
7707 MIN(val->data_length,r->in.data_offered));
7710 *r->out.data_needed = val->data_length;
7718 /****************************************************************
7719 _spoolss_SetPrinterData
7720 ****************************************************************/
7722 WERROR _spoolss_SetPrinterData(pipes_struct *p,
7723 struct spoolss_SetPrinterData *r)
7725 struct spoolss_SetPrinterDataEx r2;
7727 r2.in.handle = r->in.handle;
7728 r2.in.key_name = "PrinterDriverData";
7729 r2.in.value_name = r->in.value_name;
7730 r2.in.type = r->in.type;
7731 r2.in.data = r->in.data;
7732 r2.in.offered = r->in.offered;
7734 return _spoolss_SetPrinterDataEx(p, &r2);
7737 /****************************************************************
7738 _spoolss_ResetPrinter
7739 ****************************************************************/
7741 WERROR _spoolss_ResetPrinter(pipes_struct *p,
7742 struct spoolss_ResetPrinter *r)
7744 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7747 DEBUG(5,("_spoolss_ResetPrinter\n"));
7750 * All we do is to check to see if the handle and queue is valid.
7751 * This call really doesn't mean anything to us because we only
7752 * support RAW printing. --jerry
7756 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7757 OUR_HANDLE(r->in.handle)));
7761 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7765 /* blindly return success */
7769 /****************************************************************
7770 _spoolss_DeletePrinterData
7771 ****************************************************************/
7773 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7774 struct spoolss_DeletePrinterData *r)
7776 struct spoolss_DeletePrinterDataEx r2;
7778 r2.in.handle = r->in.handle;
7779 r2.in.key_name = "PrinterDriverData";
7780 r2.in.value_name = r->in.value_name;
7782 return _spoolss_DeletePrinterDataEx(p, &r2);
7785 /****************************************************************
7787 ****************************************************************/
7789 WERROR _spoolss_AddForm(pipes_struct *p,
7790 struct spoolss_AddForm *r)
7792 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7794 WERROR status = WERR_OK;
7795 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7797 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7799 DEBUG(5,("_spoolss_AddForm\n"));
7802 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7803 OUR_HANDLE(r->in.handle)));
7807 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7808 and not a printer admin, then fail */
7810 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7811 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7812 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7813 p->server_info->info3->base.domain.string,
7815 p->server_info->ptok,
7816 lp_printer_admin(snum))) {
7817 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7818 return WERR_ACCESS_DENIED;
7821 switch (form->flags) {
7822 case SPOOLSS_FORM_USER:
7823 case SPOOLSS_FORM_BUILTIN:
7824 case SPOOLSS_FORM_PRINTER:
7827 return WERR_INVALID_PARAM;
7830 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7831 if (!W_ERROR_IS_OK(status)) {
7836 * ChangeID must always be set if this is a printer
7838 if (Printer->printer_type == SPLHND_PRINTER) {
7839 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7843 status = winreg_printer_update_changeid(p->mem_ctx,
7845 lp_const_servicename(snum));
7846 if (!W_ERROR_IS_OK(status)) {
7854 /****************************************************************
7856 ****************************************************************/
7858 WERROR _spoolss_DeleteForm(pipes_struct *p,
7859 struct spoolss_DeleteForm *r)
7861 const char *form_name = r->in.form_name;
7862 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7864 WERROR status = WERR_OK;
7865 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7867 DEBUG(5,("_spoolss_DeleteForm\n"));
7870 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7871 OUR_HANDLE(r->in.handle)));
7875 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7876 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7877 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7878 p->server_info->info3->base.domain.string,
7880 p->server_info->ptok,
7881 lp_printer_admin(snum))) {
7882 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7883 return WERR_ACCESS_DENIED;
7886 status = winreg_printer_deleteform1(p->mem_ctx,
7889 if (!W_ERROR_IS_OK(status)) {
7894 * ChangeID must always be set if this is a printer
7896 if (Printer->printer_type == SPLHND_PRINTER) {
7897 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7901 status = winreg_printer_update_changeid(p->mem_ctx,
7903 lp_const_servicename(snum));
7904 if (!W_ERROR_IS_OK(status)) {
7912 /****************************************************************
7914 ****************************************************************/
7916 WERROR _spoolss_SetForm(pipes_struct *p,
7917 struct spoolss_SetForm *r)
7919 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7920 const char *form_name = r->in.form_name;
7922 WERROR status = WERR_OK;
7923 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7925 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7927 DEBUG(5,("_spoolss_SetForm\n"));
7930 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7931 OUR_HANDLE(r->in.handle)));
7935 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7936 and not a printer admin, then fail */
7938 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7939 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7940 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7941 p->server_info->info3->base.domain.string,
7943 p->server_info->ptok,
7944 lp_printer_admin(snum))) {
7945 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7946 return WERR_ACCESS_DENIED;
7949 status = winreg_printer_setform1(p->mem_ctx,
7953 if (!W_ERROR_IS_OK(status)) {
7958 * ChangeID must always be set if this is a printer
7960 if (Printer->printer_type == SPLHND_PRINTER) {
7961 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7965 status = winreg_printer_update_changeid(p->mem_ctx,
7967 lp_const_servicename(snum));
7968 if (!W_ERROR_IS_OK(status)) {
7976 /****************************************************************************
7977 fill_print_processor1
7978 ****************************************************************************/
7980 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
7981 struct spoolss_PrintProcessorInfo1 *r,
7982 const char *print_processor_name)
7984 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
7985 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
7990 /****************************************************************************
7991 enumprintprocessors level 1.
7992 ****************************************************************************/
7994 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
7995 union spoolss_PrintProcessorInfo **info_p,
7998 union spoolss_PrintProcessorInfo *info;
8001 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8002 W_ERROR_HAVE_NO_MEMORY(info);
8006 result = fill_print_processor1(info, &info[0].info1, "winprint");
8007 if (!W_ERROR_IS_OK(result)) {
8012 if (!W_ERROR_IS_OK(result)) {
8023 /****************************************************************
8024 _spoolss_EnumPrintProcessors
8025 ****************************************************************/
8027 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8028 struct spoolss_EnumPrintProcessors *r)
8032 /* that's an [in out] buffer */
8034 if (!r->in.buffer && (r->in.offered != 0)) {
8035 return WERR_INVALID_PARAM;
8038 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8041 * Enumerate the print processors ...
8043 * Just reply with "winprint", to keep NT happy
8044 * and I can use my nice printer checker.
8049 *r->out.info = NULL;
8051 switch (r->in.level) {
8053 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8057 return WERR_UNKNOWN_LEVEL;
8060 if (!W_ERROR_IS_OK(result)) {
8064 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8065 spoolss_EnumPrintProcessors,
8066 *r->out.info, r->in.level,
8068 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8069 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8071 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8074 /****************************************************************************
8075 fill_printprocdatatype1
8076 ****************************************************************************/
8078 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8079 struct spoolss_PrintProcDataTypesInfo1 *r,
8080 const char *name_array)
8082 r->name_array = talloc_strdup(mem_ctx, name_array);
8083 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8088 /****************************************************************************
8089 enumprintprocdatatypes level 1.
8090 ****************************************************************************/
8092 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8093 union spoolss_PrintProcDataTypesInfo **info_p,
8097 union spoolss_PrintProcDataTypesInfo *info;
8099 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8100 W_ERROR_HAVE_NO_MEMORY(info);
8104 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8105 if (!W_ERROR_IS_OK(result)) {
8110 if (!W_ERROR_IS_OK(result)) {
8121 /****************************************************************
8122 _spoolss_EnumPrintProcDataTypes
8123 ****************************************************************/
8125 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8126 struct spoolss_EnumPrintProcDataTypes *r)
8130 /* that's an [in out] buffer */
8132 if (!r->in.buffer && (r->in.offered != 0)) {
8133 return WERR_INVALID_PARAM;
8136 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8140 *r->out.info = NULL;
8142 switch (r->in.level) {
8144 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8148 return WERR_UNKNOWN_LEVEL;
8151 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8152 spoolss_EnumPrintProcDataTypes,
8153 *r->out.info, r->in.level,
8155 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8156 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8158 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8161 /****************************************************************************
8163 ****************************************************************************/
8165 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8166 struct spoolss_MonitorInfo1 *r,
8167 const char *monitor_name)
8169 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8170 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8175 /****************************************************************************
8177 ****************************************************************************/
8179 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8180 struct spoolss_MonitorInfo2 *r,
8181 const char *monitor_name,
8182 const char *environment,
8183 const char *dll_name)
8185 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8186 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8187 r->environment = talloc_strdup(mem_ctx, environment);
8188 W_ERROR_HAVE_NO_MEMORY(r->environment);
8189 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8190 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8195 /****************************************************************************
8196 enumprintmonitors level 1.
8197 ****************************************************************************/
8199 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8200 union spoolss_MonitorInfo **info_p,
8203 union spoolss_MonitorInfo *info;
8204 WERROR result = WERR_OK;
8206 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8207 W_ERROR_HAVE_NO_MEMORY(info);
8211 result = fill_monitor_1(info, &info[0].info1,
8213 if (!W_ERROR_IS_OK(result)) {
8217 result = fill_monitor_1(info, &info[1].info1,
8219 if (!W_ERROR_IS_OK(result)) {
8224 if (!W_ERROR_IS_OK(result)) {
8235 /****************************************************************************
8236 enumprintmonitors level 2.
8237 ****************************************************************************/
8239 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8240 union spoolss_MonitorInfo **info_p,
8243 union spoolss_MonitorInfo *info;
8244 WERROR result = WERR_OK;
8246 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8247 W_ERROR_HAVE_NO_MEMORY(info);
8251 result = fill_monitor_2(info, &info[0].info2,
8253 "Windows NT X86", /* FIXME */
8255 if (!W_ERROR_IS_OK(result)) {
8259 result = fill_monitor_2(info, &info[1].info2,
8261 "Windows NT X86", /* FIXME */
8263 if (!W_ERROR_IS_OK(result)) {
8268 if (!W_ERROR_IS_OK(result)) {
8279 /****************************************************************
8280 _spoolss_EnumMonitors
8281 ****************************************************************/
8283 WERROR _spoolss_EnumMonitors(pipes_struct *p,
8284 struct spoolss_EnumMonitors *r)
8288 /* that's an [in out] buffer */
8290 if (!r->in.buffer && (r->in.offered != 0)) {
8291 return WERR_INVALID_PARAM;
8294 DEBUG(5,("_spoolss_EnumMonitors\n"));
8297 * Enumerate the print monitors ...
8299 * Just reply with "Local Port", to keep NT happy
8300 * and I can use my nice printer checker.
8305 *r->out.info = NULL;
8307 switch (r->in.level) {
8309 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8313 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8317 return WERR_UNKNOWN_LEVEL;
8320 if (!W_ERROR_IS_OK(result)) {
8324 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8325 spoolss_EnumMonitors,
8326 *r->out.info, r->in.level,
8328 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8329 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8331 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8334 /****************************************************************************
8335 ****************************************************************************/
8337 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8338 const print_queue_struct *queue,
8339 int count, int snum,
8340 struct spoolss_PrinterInfo2 *pinfo2,
8342 struct spoolss_JobInfo1 *r)
8347 for (i=0; i<count; i++) {
8348 if (queue[i].job == (int)jobid) {
8354 if (found == false) {
8355 /* NT treats not found as bad param... yet another bad choice */
8356 return WERR_INVALID_PARAM;
8359 return fill_job_info1(mem_ctx,
8367 /****************************************************************************
8368 ****************************************************************************/
8370 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8371 const print_queue_struct *queue,
8372 int count, int snum,
8373 struct spoolss_PrinterInfo2 *pinfo2,
8375 struct spoolss_JobInfo2 *r)
8379 struct spoolss_DeviceMode *devmode;
8382 for (i=0; i<count; i++) {
8383 if (queue[i].job == (int)jobid) {
8389 if (found == false) {
8390 /* NT treats not found as bad param... yet another bad
8392 return WERR_INVALID_PARAM;
8396 * if the print job does not have a DEVMODE associated with it,
8397 * just use the one for the printer. A NULL devicemode is not
8398 * a failure condition
8401 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8403 result = spoolss_create_default_devmode(mem_ctx,
8404 pinfo2->printername,
8406 if (!W_ERROR_IS_OK(result)) {
8407 DEBUG(3, ("Can't proceed w/o a devmode!"));
8412 return fill_job_info2(mem_ctx,
8421 /****************************************************************
8423 ****************************************************************/
8425 WERROR _spoolss_GetJob(pipes_struct *p,
8426 struct spoolss_GetJob *r)
8428 WERROR result = WERR_OK;
8429 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8432 print_queue_struct *queue = NULL;
8433 print_status_struct prt_status;
8435 /* that's an [in out] buffer */
8437 if (!r->in.buffer && (r->in.offered != 0)) {
8438 return WERR_INVALID_PARAM;
8441 DEBUG(5,("_spoolss_GetJob\n"));
8445 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8449 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8450 lp_servicename(snum), &pinfo2);
8451 if (!W_ERROR_IS_OK(result)) {
8455 count = print_queue_status(snum, &queue, &prt_status);
8457 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8458 count, prt_status.status, prt_status.message));
8460 switch (r->in.level) {
8462 result = getjob_level_1(p->mem_ctx,
8463 queue, count, snum, pinfo2,
8464 r->in.job_id, &r->out.info->info1);
8467 result = getjob_level_2(p->mem_ctx,
8468 queue, count, snum, pinfo2,
8469 r->in.job_id, &r->out.info->info2);
8472 result = WERR_UNKNOWN_LEVEL;
8477 TALLOC_FREE(pinfo2);
8479 if (!W_ERROR_IS_OK(result)) {
8480 TALLOC_FREE(r->out.info);
8484 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8486 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8488 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8491 /****************************************************************
8492 _spoolss_GetPrinterDataEx
8493 ****************************************************************/
8495 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8496 struct spoolss_GetPrinterDataEx *r)
8499 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8500 const char *printer;
8502 WERROR result = WERR_OK;
8504 enum winreg_Type val_type;
8509 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8511 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8512 r->in.key_name, r->in.value_name));
8514 /* in case of problem, return some default values */
8517 *r->out.type = REG_NONE;
8520 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8521 OUR_HANDLE(r->in.handle)));
8522 result = WERR_BADFID;
8526 /* Is the handle to a printer or to the server? */
8528 if (Printer->printer_type == SPLHND_SERVER) {
8530 union spoolss_PrinterData data;
8532 result = getprinterdata_printer_server(p->mem_ctx,
8536 if (!W_ERROR_IS_OK(result)) {
8540 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8541 *r->out.type, &data);
8542 if (!W_ERROR_IS_OK(result)) {
8546 *r->out.needed = blob.length;
8548 if (r->in.offered >= *r->out.needed) {
8549 memcpy(r->out.data, blob.data, blob.length);
8552 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8555 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8558 printer = lp_const_servicename(snum);
8560 /* check to see if the keyname is valid */
8561 if (!strlen(r->in.key_name)) {
8562 return WERR_INVALID_PARAM;
8565 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8566 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8567 strequal(r->in.value_name, "ChangeId")) {
8568 *r->out.type = REG_DWORD;
8570 if (r->in.offered >= *r->out.needed) {
8571 uint32_t changeid = 0;
8573 result = winreg_printer_get_changeid(p->mem_ctx,
8577 if (!W_ERROR_IS_OK(result)) {
8581 SIVAL(r->out.data, 0, changeid);
8587 result = winreg_get_printer_dataex(p->mem_ctx,
8595 if (!W_ERROR_IS_OK(result)) {
8599 *r->out.needed = val_size;
8600 *r->out.type = val_type;
8602 if (r->in.offered >= *r->out.needed) {
8603 memcpy(r->out.data, val_data, val_size);
8607 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8608 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8610 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8613 /****************************************************************
8614 _spoolss_SetPrinterDataEx
8615 ****************************************************************/
8617 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8618 struct spoolss_SetPrinterDataEx *r)
8620 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8622 WERROR result = WERR_OK;
8623 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8626 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8628 /* From MSDN documentation of SetPrinterDataEx: pass request to
8629 SetPrinterData if key is "PrinterDriverData" */
8632 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8633 OUR_HANDLE(r->in.handle)));
8637 if (Printer->printer_type == SPLHND_SERVER) {
8638 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8639 "Not implemented for server handles yet\n"));
8640 return WERR_INVALID_PARAM;
8643 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8648 * Access check : NT returns "access denied" if you make a
8649 * SetPrinterData call without the necessary privildge.
8650 * we were originally returning OK if nothing changed
8651 * which made Win2k issue **a lot** of SetPrinterData
8652 * when connecting to a printer --jerry
8655 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8656 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8657 "change denied by handle access permissions\n"));
8658 return WERR_ACCESS_DENIED;
8661 result = winreg_get_printer(Printer, p->server_info,
8662 Printer->servername,
8663 lp_servicename(snum),
8665 if (!W_ERROR_IS_OK(result)) {
8669 /* check for OID in valuename */
8671 oid_string = strchr(r->in.value_name, ',');
8677 /* save the registry data */
8679 result = winreg_set_printer_dataex(p->mem_ctx,
8688 if (W_ERROR_IS_OK(result)) {
8689 /* save the OID if one was specified */
8691 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8692 r->in.key_name, SPOOL_OID_KEY);
8694 result = WERR_NOMEM;
8699 * I'm not checking the status here on purpose. Don't know
8700 * if this is right, but I'm returning the status from the
8701 * previous set_printer_dataex() call. I have no idea if
8702 * this is right. --jerry
8704 winreg_set_printer_dataex(p->mem_ctx,
8710 (uint8_t *) oid_string,
8711 strlen(oid_string) + 1);
8714 result = winreg_printer_update_changeid(p->mem_ctx,
8716 lp_const_servicename(snum));
8721 talloc_free(pinfo2);
8725 /****************************************************************
8726 _spoolss_DeletePrinterDataEx
8727 ****************************************************************/
8729 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8730 struct spoolss_DeletePrinterDataEx *r)
8732 const char *printer;
8734 WERROR status = WERR_OK;
8735 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8737 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8740 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8741 "Invalid handle (%s:%u:%u).\n",
8742 OUR_HANDLE(r->in.handle)));
8746 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8747 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8748 "printer properties change denied by handle\n"));
8749 return WERR_ACCESS_DENIED;
8752 if (!r->in.value_name || !r->in.key_name) {
8756 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8759 printer = lp_const_servicename(snum);
8761 status = winreg_delete_printer_dataex(p->mem_ctx,
8766 if (W_ERROR_IS_OK(status)) {
8767 status = winreg_printer_update_changeid(p->mem_ctx,
8775 /****************************************************************
8776 _spoolss_EnumPrinterKey
8777 ****************************************************************/
8779 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
8780 struct spoolss_EnumPrinterKey *r)
8783 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8785 WERROR result = WERR_BADFILE;
8786 const char **array = NULL;
8789 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8792 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8793 OUR_HANDLE(r->in.handle)));
8797 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8801 result = winreg_enum_printer_key(p->mem_ctx,
8803 lp_const_servicename(snum),
8807 if (!W_ERROR_IS_OK(result)) {
8811 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8812 result = WERR_NOMEM;
8816 *r->out._ndr_size = r->in.offered / 2;
8817 *r->out.needed = blob.length;
8819 if (r->in.offered < *r->out.needed) {
8820 result = WERR_MORE_DATA;
8823 r->out.key_buffer->string_array = array;
8827 if (!W_ERROR_IS_OK(result)) {
8829 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8837 /****************************************************************
8838 _spoolss_DeletePrinterKey
8839 ****************************************************************/
8841 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
8842 struct spoolss_DeletePrinterKey *r)
8844 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8847 const char *printer;
8849 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8852 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8853 OUR_HANDLE(r->in.handle)));
8857 /* if keyname == NULL, return error */
8858 if ( !r->in.key_name )
8859 return WERR_INVALID_PARAM;
8861 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8865 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8866 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8867 "printer properties change denied by handle\n"));
8868 return WERR_ACCESS_DENIED;
8871 printer = lp_const_servicename(snum);
8873 /* delete the key and all subkeys */
8874 status = winreg_delete_printer_key(p->mem_ctx,
8878 if (W_ERROR_IS_OK(status)) {
8879 status = winreg_printer_update_changeid(p->mem_ctx,
8887 /****************************************************************
8888 _spoolss_EnumPrinterDataEx
8889 ****************************************************************/
8891 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
8892 struct spoolss_EnumPrinterDataEx *r)
8895 struct spoolss_PrinterEnumValues *info = NULL;
8896 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8900 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8904 *r->out.info = NULL;
8907 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8908 OUR_HANDLE(r->in.handle)));
8913 * first check for a keyname of NULL or "". Win2k seems to send
8914 * this a lot and we should send back WERR_INVALID_PARAM
8915 * no need to spend time looking up the printer in this case.
8919 if (!strlen(r->in.key_name)) {
8920 result = WERR_INVALID_PARAM;
8924 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8928 /* now look for a match on the key name */
8929 result = winreg_enum_printer_dataex(p->mem_ctx,
8931 lp_const_servicename(snum),
8935 if (!W_ERROR_IS_OK(result)) {
8939 #if 0 /* FIXME - gd */
8940 /* housekeeping information in the reply */
8942 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8943 * the hand marshalled container size is a multiple
8944 * of 4 bytes for RPC alignment.
8948 needed += 4-(needed % 4);
8951 *r->out.count = count;
8952 *r->out.info = info;
8955 if (!W_ERROR_IS_OK(result)) {
8959 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
8960 spoolss_EnumPrinterDataEx,
8963 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8964 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
8966 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8969 /****************************************************************************
8970 ****************************************************************************/
8972 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
8973 const char *servername,
8974 const char *environment,
8975 struct spoolss_PrintProcessorDirectoryInfo1 *r)
8980 werr = compose_spoolss_server_path(mem_ctx,
8983 SPOOLSS_PRTPROCS_PATH,
8985 if (!W_ERROR_IS_OK(werr)) {
8989 DEBUG(4,("print processor directory: [%s]\n", path));
8991 r->directory_name = path;
8996 /****************************************************************
8997 _spoolss_GetPrintProcessorDirectory
8998 ****************************************************************/
9000 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9001 struct spoolss_GetPrintProcessorDirectory *r)
9005 /* that's an [in out] buffer */
9007 if (!r->in.buffer && (r->in.offered != 0)) {
9008 return WERR_INVALID_PARAM;
9011 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9016 /* r->in.level is ignored */
9018 /* We always should reply with a local print processor directory so that
9019 * users are not forced to have a [prnproc$] share on the Samba spoolss
9020 * server - Guenther */
9022 result = getprintprocessordirectory_level_1(p->mem_ctx,
9023 NULL, /* r->in.server */
9025 &r->out.info->info1);
9026 if (!W_ERROR_IS_OK(result)) {
9027 TALLOC_FREE(r->out.info);
9031 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9032 r->out.info, r->in.level);
9033 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9035 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9038 /*******************************************************************
9039 ********************************************************************/
9041 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9042 const char *dllname)
9044 enum ndr_err_code ndr_err;
9045 struct spoolss_MonitorUi ui;
9047 ui.dll_name = dllname;
9049 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9050 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9051 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9052 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9054 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9057 /*******************************************************************
9058 Streams the monitor UI DLL name in UNICODE
9059 *******************************************************************/
9061 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9062 NT_USER_TOKEN *token, DATA_BLOB *in,
9063 DATA_BLOB *out, uint32_t *needed)
9065 const char *dllname = "tcpmonui.dll";
9067 *needed = (strlen(dllname)+1) * 2;
9069 if (out->length < *needed) {
9070 return WERR_INSUFFICIENT_BUFFER;
9073 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9080 /*******************************************************************
9081 ********************************************************************/
9083 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9084 struct spoolss_PortData1 *port1,
9085 const DATA_BLOB *buf)
9087 enum ndr_err_code ndr_err;
9088 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9089 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9090 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9091 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9093 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9096 /*******************************************************************
9097 ********************************************************************/
9099 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9100 struct spoolss_PortData2 *port2,
9101 const DATA_BLOB *buf)
9103 enum ndr_err_code ndr_err;
9104 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9105 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9106 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9107 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9109 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9112 /*******************************************************************
9113 Create a new TCP/IP port
9114 *******************************************************************/
9116 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9117 NT_USER_TOKEN *token, DATA_BLOB *in,
9118 DATA_BLOB *out, uint32_t *needed)
9120 struct spoolss_PortData1 port1;
9121 struct spoolss_PortData2 port2;
9122 char *device_uri = NULL;
9125 const char *portname;
9126 const char *hostaddress;
9128 uint32_t port_number;
9131 /* peek for spoolss_PortData version */
9133 if (!in || (in->length < (128 + 4))) {
9134 return WERR_GENERAL_FAILURE;
9137 version = IVAL(in->data, 128);
9143 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9147 portname = port1.portname;
9148 hostaddress = port1.hostaddress;
9149 queue = port1.queue;
9150 protocol = port1.protocol;
9151 port_number = port1.port_number;
9157 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9161 portname = port2.portname;
9162 hostaddress = port2.hostaddress;
9163 queue = port2.queue;
9164 protocol = port2.protocol;
9165 port_number = port2.port_number;
9169 DEBUG(1,("xcvtcp_addport: "
9170 "unknown version of port_data: %d\n", version));
9171 return WERR_UNKNOWN_PORT;
9174 /* create the device URI and call the add_port_hook() */
9177 case PROTOCOL_RAWTCP_TYPE:
9178 device_uri = talloc_asprintf(mem_ctx,
9179 "socket://%s:%d/", hostaddress,
9183 case PROTOCOL_LPR_TYPE:
9184 device_uri = talloc_asprintf(mem_ctx,
9185 "lpr://%s/%s", hostaddress, queue );
9189 return WERR_UNKNOWN_PORT;
9196 return add_port_hook(mem_ctx, token, portname, device_uri);
9199 /*******************************************************************
9200 *******************************************************************/
9202 struct xcv_api_table xcvtcp_cmds[] = {
9203 { "MonitorUI", xcvtcp_monitorui },
9204 { "AddPort", xcvtcp_addport},
9208 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9209 NT_USER_TOKEN *token, const char *command,
9216 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9218 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9219 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9220 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9223 return WERR_BADFUNC;
9226 /*******************************************************************
9227 *******************************************************************/
9228 #if 0 /* don't support management using the "Local Port" monitor */
9230 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9231 NT_USER_TOKEN *token, DATA_BLOB *in,
9232 DATA_BLOB *out, uint32_t *needed)
9234 const char *dllname = "localui.dll";
9236 *needed = (strlen(dllname)+1) * 2;
9238 if (out->length < *needed) {
9239 return WERR_INSUFFICIENT_BUFFER;
9242 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9249 /*******************************************************************
9250 *******************************************************************/
9252 struct xcv_api_table xcvlocal_cmds[] = {
9253 { "MonitorUI", xcvlocal_monitorui },
9257 struct xcv_api_table xcvlocal_cmds[] = {
9264 /*******************************************************************
9265 *******************************************************************/
9267 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9268 NT_USER_TOKEN *token, const char *command,
9269 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9274 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9276 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9277 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9278 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9280 return WERR_BADFUNC;
9283 /****************************************************************
9285 ****************************************************************/
9287 WERROR _spoolss_XcvData(pipes_struct *p,
9288 struct spoolss_XcvData *r)
9290 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9291 DATA_BLOB out_data = data_blob_null;
9295 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9296 OUR_HANDLE(r->in.handle)));
9300 /* Has to be a handle to the TCP/IP port monitor */
9302 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9303 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9307 /* requires administrative access to the server */
9309 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9310 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9311 return WERR_ACCESS_DENIED;
9314 /* Allocate the outgoing buffer */
9316 if (r->in.out_data_size) {
9317 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9318 if (out_data.data == NULL) {
9323 switch ( Printer->printer_type ) {
9324 case SPLHND_PORTMON_TCP:
9325 werror = process_xcvtcp_command(p->mem_ctx,
9326 p->server_info->ptok,
9327 r->in.function_name,
9328 &r->in.in_data, &out_data,
9331 case SPLHND_PORTMON_LOCAL:
9332 werror = process_xcvlocal_command(p->mem_ctx,
9333 p->server_info->ptok,
9334 r->in.function_name,
9335 &r->in.in_data, &out_data,
9339 werror = WERR_INVALID_PRINT_MONITOR;
9342 if (!W_ERROR_IS_OK(werror)) {
9346 *r->out.status_code = 0;
9348 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9349 memcpy(r->out.out_data, out_data.data,
9350 MIN(r->in.out_data_size, out_data.length));
9356 /****************************************************************
9357 _spoolss_AddPrintProcessor
9358 ****************************************************************/
9360 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9361 struct spoolss_AddPrintProcessor *r)
9363 /* for now, just indicate success and ignore the add. We'll
9364 automatically set the winprint processor for printer
9365 entries later. Used to debug the LexMark Optra S 1855 PCL
9371 /****************************************************************
9373 ****************************************************************/
9375 WERROR _spoolss_AddPort(pipes_struct *p,
9376 struct spoolss_AddPort *r)
9378 /* do what w2k3 does */
9380 return WERR_NOT_SUPPORTED;
9383 /****************************************************************
9384 _spoolss_GetPrinterDriver
9385 ****************************************************************/
9387 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9388 struct spoolss_GetPrinterDriver *r)
9390 p->rng_fault_state = true;
9391 return WERR_NOT_SUPPORTED;
9394 /****************************************************************
9395 _spoolss_ReadPrinter
9396 ****************************************************************/
9398 WERROR _spoolss_ReadPrinter(pipes_struct *p,
9399 struct spoolss_ReadPrinter *r)
9401 p->rng_fault_state = true;
9402 return WERR_NOT_SUPPORTED;
9405 /****************************************************************
9406 _spoolss_WaitForPrinterChange
9407 ****************************************************************/
9409 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9410 struct spoolss_WaitForPrinterChange *r)
9412 p->rng_fault_state = true;
9413 return WERR_NOT_SUPPORTED;
9416 /****************************************************************
9417 _spoolss_ConfigurePort
9418 ****************************************************************/
9420 WERROR _spoolss_ConfigurePort(pipes_struct *p,
9421 struct spoolss_ConfigurePort *r)
9423 p->rng_fault_state = true;
9424 return WERR_NOT_SUPPORTED;
9427 /****************************************************************
9429 ****************************************************************/
9431 WERROR _spoolss_DeletePort(pipes_struct *p,
9432 struct spoolss_DeletePort *r)
9434 p->rng_fault_state = true;
9435 return WERR_NOT_SUPPORTED;
9438 /****************************************************************
9439 _spoolss_CreatePrinterIC
9440 ****************************************************************/
9442 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9443 struct spoolss_CreatePrinterIC *r)
9445 p->rng_fault_state = true;
9446 return WERR_NOT_SUPPORTED;
9449 /****************************************************************
9450 _spoolss_PlayGDIScriptOnPrinterIC
9451 ****************************************************************/
9453 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9454 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9456 p->rng_fault_state = true;
9457 return WERR_NOT_SUPPORTED;
9460 /****************************************************************
9461 _spoolss_DeletePrinterIC
9462 ****************************************************************/
9464 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9465 struct spoolss_DeletePrinterIC *r)
9467 p->rng_fault_state = true;
9468 return WERR_NOT_SUPPORTED;
9471 /****************************************************************
9472 _spoolss_AddPrinterConnection
9473 ****************************************************************/
9475 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9476 struct spoolss_AddPrinterConnection *r)
9478 p->rng_fault_state = true;
9479 return WERR_NOT_SUPPORTED;
9482 /****************************************************************
9483 _spoolss_DeletePrinterConnection
9484 ****************************************************************/
9486 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9487 struct spoolss_DeletePrinterConnection *r)
9489 p->rng_fault_state = true;
9490 return WERR_NOT_SUPPORTED;
9493 /****************************************************************
9494 _spoolss_PrinterMessageBox
9495 ****************************************************************/
9497 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9498 struct spoolss_PrinterMessageBox *r)
9500 p->rng_fault_state = true;
9501 return WERR_NOT_SUPPORTED;
9504 /****************************************************************
9506 ****************************************************************/
9508 WERROR _spoolss_AddMonitor(pipes_struct *p,
9509 struct spoolss_AddMonitor *r)
9511 p->rng_fault_state = true;
9512 return WERR_NOT_SUPPORTED;
9515 /****************************************************************
9516 _spoolss_DeleteMonitor
9517 ****************************************************************/
9519 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9520 struct spoolss_DeleteMonitor *r)
9522 p->rng_fault_state = true;
9523 return WERR_NOT_SUPPORTED;
9526 /****************************************************************
9527 _spoolss_DeletePrintProcessor
9528 ****************************************************************/
9530 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9531 struct spoolss_DeletePrintProcessor *r)
9533 p->rng_fault_state = true;
9534 return WERR_NOT_SUPPORTED;
9537 /****************************************************************
9538 _spoolss_AddPrintProvidor
9539 ****************************************************************/
9541 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9542 struct spoolss_AddPrintProvidor *r)
9544 p->rng_fault_state = true;
9545 return WERR_NOT_SUPPORTED;
9548 /****************************************************************
9549 _spoolss_DeletePrintProvidor
9550 ****************************************************************/
9552 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9553 struct spoolss_DeletePrintProvidor *r)
9555 p->rng_fault_state = true;
9556 return WERR_NOT_SUPPORTED;
9559 /****************************************************************
9560 _spoolss_FindFirstPrinterChangeNotification
9561 ****************************************************************/
9563 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9564 struct spoolss_FindFirstPrinterChangeNotification *r)
9566 p->rng_fault_state = true;
9567 return WERR_NOT_SUPPORTED;
9570 /****************************************************************
9571 _spoolss_FindNextPrinterChangeNotification
9572 ****************************************************************/
9574 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9575 struct spoolss_FindNextPrinterChangeNotification *r)
9577 p->rng_fault_state = true;
9578 return WERR_NOT_SUPPORTED;
9581 /****************************************************************
9582 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9583 ****************************************************************/
9585 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9586 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9588 p->rng_fault_state = true;
9589 return WERR_NOT_SUPPORTED;
9592 /****************************************************************
9593 _spoolss_ReplyOpenPrinter
9594 ****************************************************************/
9596 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9597 struct spoolss_ReplyOpenPrinter *r)
9599 p->rng_fault_state = true;
9600 return WERR_NOT_SUPPORTED;
9603 /****************************************************************
9604 _spoolss_RouterReplyPrinter
9605 ****************************************************************/
9607 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9608 struct spoolss_RouterReplyPrinter *r)
9610 p->rng_fault_state = true;
9611 return WERR_NOT_SUPPORTED;
9614 /****************************************************************
9615 _spoolss_ReplyClosePrinter
9616 ****************************************************************/
9618 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9619 struct spoolss_ReplyClosePrinter *r)
9621 p->rng_fault_state = true;
9622 return WERR_NOT_SUPPORTED;
9625 /****************************************************************
9627 ****************************************************************/
9629 WERROR _spoolss_AddPortEx(pipes_struct *p,
9630 struct spoolss_AddPortEx *r)
9632 p->rng_fault_state = true;
9633 return WERR_NOT_SUPPORTED;
9636 /****************************************************************
9637 _spoolss_RouterFindFirstPrinterChangeNotification
9638 ****************************************************************/
9640 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9641 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9643 p->rng_fault_state = true;
9644 return WERR_NOT_SUPPORTED;
9647 /****************************************************************
9648 _spoolss_SpoolerInit
9649 ****************************************************************/
9651 WERROR _spoolss_SpoolerInit(pipes_struct *p,
9652 struct spoolss_SpoolerInit *r)
9654 p->rng_fault_state = true;
9655 return WERR_NOT_SUPPORTED;
9658 /****************************************************************
9659 _spoolss_ResetPrinterEx
9660 ****************************************************************/
9662 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
9663 struct spoolss_ResetPrinterEx *r)
9665 p->rng_fault_state = true;
9666 return WERR_NOT_SUPPORTED;
9669 /****************************************************************
9670 _spoolss_RouterReplyPrinterEx
9671 ****************************************************************/
9673 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
9674 struct spoolss_RouterReplyPrinterEx *r)
9676 p->rng_fault_state = true;
9677 return WERR_NOT_SUPPORTED;
9680 /****************************************************************
9682 ****************************************************************/
9684 WERROR _spoolss_44(pipes_struct *p,
9685 struct spoolss_44 *r)
9687 p->rng_fault_state = true;
9688 return WERR_NOT_SUPPORTED;
9691 /****************************************************************
9693 ****************************************************************/
9695 WERROR _spoolss_47(pipes_struct *p,
9696 struct spoolss_47 *r)
9698 p->rng_fault_state = true;
9699 return WERR_NOT_SUPPORTED;
9702 /****************************************************************
9704 ****************************************************************/
9706 WERROR _spoolss_4a(pipes_struct *p,
9707 struct spoolss_4a *r)
9709 p->rng_fault_state = true;
9710 return WERR_NOT_SUPPORTED;
9713 /****************************************************************
9715 ****************************************************************/
9717 WERROR _spoolss_4b(pipes_struct *p,
9718 struct spoolss_4b *r)
9720 p->rng_fault_state = true;
9721 return WERR_NOT_SUPPORTED;
9724 /****************************************************************
9726 ****************************************************************/
9728 WERROR _spoolss_4c(pipes_struct *p,
9729 struct spoolss_4c *r)
9731 p->rng_fault_state = true;
9732 return WERR_NOT_SUPPORTED;
9735 /****************************************************************
9737 ****************************************************************/
9739 WERROR _spoolss_53(pipes_struct *p,
9740 struct spoolss_53 *r)
9742 p->rng_fault_state = true;
9743 return WERR_NOT_SUPPORTED;
9746 /****************************************************************
9748 ****************************************************************/
9750 WERROR _spoolss_55(pipes_struct *p,
9751 struct spoolss_55 *r)
9753 p->rng_fault_state = true;
9754 return WERR_NOT_SUPPORTED;
9757 /****************************************************************
9759 ****************************************************************/
9761 WERROR _spoolss_56(pipes_struct *p,
9762 struct spoolss_56 *r)
9764 p->rng_fault_state = true;
9765 return WERR_NOT_SUPPORTED;
9768 /****************************************************************
9770 ****************************************************************/
9772 WERROR _spoolss_57(pipes_struct *p,
9773 struct spoolss_57 *r)
9775 p->rng_fault_state = true;
9776 return WERR_NOT_SUPPORTED;
9779 /****************************************************************
9781 ****************************************************************/
9783 WERROR _spoolss_5a(pipes_struct *p,
9784 struct spoolss_5a *r)
9786 p->rng_fault_state = true;
9787 return WERR_NOT_SUPPORTED;
9790 /****************************************************************
9792 ****************************************************************/
9794 WERROR _spoolss_5b(pipes_struct *p,
9795 struct spoolss_5b *r)
9797 p->rng_fault_state = true;
9798 return WERR_NOT_SUPPORTED;
9801 /****************************************************************
9803 ****************************************************************/
9805 WERROR _spoolss_5c(pipes_struct *p,
9806 struct spoolss_5c *r)
9808 p->rng_fault_state = true;
9809 return WERR_NOT_SUPPORTED;
9812 /****************************************************************
9814 ****************************************************************/
9816 WERROR _spoolss_5d(pipes_struct *p,
9817 struct spoolss_5d *r)
9819 p->rng_fault_state = true;
9820 return WERR_NOT_SUPPORTED;
9823 /****************************************************************
9825 ****************************************************************/
9827 WERROR _spoolss_5e(pipes_struct *p,
9828 struct spoolss_5e *r)
9830 p->rng_fault_state = true;
9831 return WERR_NOT_SUPPORTED;
9834 /****************************************************************
9836 ****************************************************************/
9838 WERROR _spoolss_5f(pipes_struct *p,
9839 struct spoolss_5f *r)
9841 p->rng_fault_state = true;
9842 return WERR_NOT_SUPPORTED;
9845 /****************************************************************
9847 ****************************************************************/
9849 WERROR _spoolss_60(pipes_struct *p,
9850 struct spoolss_60 *r)
9852 p->rng_fault_state = true;
9853 return WERR_NOT_SUPPORTED;
9856 /****************************************************************
9858 ****************************************************************/
9860 WERROR _spoolss_61(pipes_struct *p,
9861 struct spoolss_61 *r)
9863 p->rng_fault_state = true;
9864 return WERR_NOT_SUPPORTED;
9867 /****************************************************************
9869 ****************************************************************/
9871 WERROR _spoolss_62(pipes_struct *p,
9872 struct spoolss_62 *r)
9874 p->rng_fault_state = true;
9875 return WERR_NOT_SUPPORTED;
9878 /****************************************************************
9880 ****************************************************************/
9882 WERROR _spoolss_63(pipes_struct *p,
9883 struct spoolss_63 *r)
9885 p->rng_fault_state = true;
9886 return WERR_NOT_SUPPORTED;
9889 /****************************************************************
9891 ****************************************************************/
9893 WERROR _spoolss_64(pipes_struct *p,
9894 struct spoolss_64 *r)
9896 p->rng_fault_state = true;
9897 return WERR_NOT_SUPPORTED;
9900 /****************************************************************
9902 ****************************************************************/
9904 WERROR _spoolss_65(pipes_struct *p,
9905 struct spoolss_65 *r)
9907 p->rng_fault_state = true;
9908 return WERR_NOT_SUPPORTED;
9911 /****************************************************************
9912 _spoolss_GetCorePrinterDrivers
9913 ****************************************************************/
9915 WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
9916 struct spoolss_GetCorePrinterDrivers *r)
9918 p->rng_fault_state = true;
9919 return WERR_NOT_SUPPORTED;
9922 /****************************************************************
9924 ****************************************************************/
9926 WERROR _spoolss_67(pipes_struct *p,
9927 struct spoolss_67 *r)
9929 p->rng_fault_state = true;
9930 return WERR_NOT_SUPPORTED;
9933 /****************************************************************
9934 _spoolss_GetPrinterDriverPackagePath
9935 ****************************************************************/
9937 WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
9938 struct spoolss_GetPrinterDriverPackagePath *r)
9940 p->rng_fault_state = true;
9941 return WERR_NOT_SUPPORTED;
9944 /****************************************************************
9946 ****************************************************************/
9948 WERROR _spoolss_69(pipes_struct *p,
9949 struct spoolss_69 *r)
9951 p->rng_fault_state = true;
9952 return WERR_NOT_SUPPORTED;
9955 /****************************************************************
9957 ****************************************************************/
9959 WERROR _spoolss_6a(pipes_struct *p,
9960 struct spoolss_6a *r)
9962 p->rng_fault_state = true;
9963 return WERR_NOT_SUPPORTED;
9966 /****************************************************************
9968 ****************************************************************/
9970 WERROR _spoolss_6b(pipes_struct *p,
9971 struct spoolss_6b *r)
9973 p->rng_fault_state = true;
9974 return WERR_NOT_SUPPORTED;
9977 /****************************************************************
9979 ****************************************************************/
9981 WERROR _spoolss_6c(pipes_struct *p,
9982 struct spoolss_6c *r)
9984 p->rng_fault_state = true;
9985 return WERR_NOT_SUPPORTED;
9988 /****************************************************************
9990 ****************************************************************/
9992 WERROR _spoolss_6d(pipes_struct *p,
9993 struct spoolss_6d *r)
9995 p->rng_fault_state = true;
9996 return WERR_NOT_SUPPORTED;