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);
5127 DEBUG(2,("_spoolss_StartDocPrinter: "
5128 "Invalid handle (%s:%u:%u)\n",
5129 OUR_HANDLE(r->in.handle)));
5133 if (Printer->jobid) {
5134 DEBUG(2, ("_spoolss_StartDocPrinter: "
5135 "StartDocPrinter called twice! "
5136 "(existing jobid = %d)\n", Printer->jobid));
5137 return WERR_INVALID_HANDLE;
5140 if (r->in.level != 1) {
5141 return WERR_UNKNOWN_LEVEL;
5144 info_1 = r->in.info.info1;
5147 * a nice thing with NT is it doesn't listen to what you tell it.
5148 * when asked to send _only_ RAW datas, it tries to send datas
5151 * So I add checks like in NT Server ...
5154 if (info_1->datatype) {
5155 if (strcmp(info_1->datatype, "RAW") != 0) {
5157 return WERR_INVALID_DATATYPE;
5161 /* get the share number of the printer */
5162 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5166 werr = print_job_start(p->server_info, snum,
5167 info_1->document_name, info_1->output_file,
5168 Printer->devmode, &Printer->jobid);
5170 /* An error occured in print_job_start() so return an appropriate
5173 if (!W_ERROR_IS_OK(werr)) {
5177 Printer->document_started = true;
5178 *r->out.job_id = Printer->jobid;
5183 /****************************************************************
5184 _spoolss_EndDocPrinter
5185 ****************************************************************/
5187 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5188 struct spoolss_EndDocPrinter *r)
5190 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5195 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5196 OUR_HANDLE(r->in.handle)));
5200 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5204 Printer->document_started = false;
5205 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5206 if (!NT_STATUS_IS_OK(status)) {
5207 DEBUG(2, ("_spoolss_EndDocPrinter: "
5208 "print_job_end failed [%s]\n",
5209 nt_errstr(status)));
5213 return ntstatus_to_werror(status);
5216 /****************************************************************
5217 _spoolss_WritePrinter
5218 ****************************************************************/
5220 WERROR _spoolss_WritePrinter(pipes_struct *p,
5221 struct spoolss_WritePrinter *r)
5223 ssize_t buffer_written;
5225 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5228 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5229 OUR_HANDLE(r->in.handle)));
5230 *r->out.num_written = r->in._data_size;
5234 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5237 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5238 buffer_written = print_job_write(snum, Printer->jobid,
5239 (const char *)r->in.data.data,
5241 (size_t)r->in._data_size);
5242 if (buffer_written == (ssize_t)-1) {
5243 *r->out.num_written = 0;
5244 if (errno == ENOSPC)
5245 return WERR_NO_SPOOL_SPACE;
5247 return WERR_ACCESS_DENIED;
5250 *r->out.num_written = r->in._data_size;
5255 /********************************************************************
5256 * api_spoolss_getprinter
5257 * called from the spoolss dispatcher
5259 ********************************************************************/
5261 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5265 WERROR errcode = WERR_BADFUNC;
5266 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5269 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5270 OUR_HANDLE(handle)));
5274 if (!get_printer_snum(p, handle, &snum, NULL))
5278 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5279 errcode = print_queue_pause(p->server_info, snum);
5281 case SPOOLSS_PRINTER_CONTROL_RESUME:
5282 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5283 errcode = print_queue_resume(p->server_info, snum);
5285 case SPOOLSS_PRINTER_CONTROL_PURGE:
5286 errcode = print_queue_purge(p->server_info, snum);
5289 return WERR_UNKNOWN_LEVEL;
5296 /****************************************************************
5297 _spoolss_AbortPrinter
5298 * From MSDN: "Deletes printer's spool file if printer is configured
5300 ****************************************************************/
5302 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5303 struct spoolss_AbortPrinter *r)
5305 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5307 WERROR errcode = WERR_OK;
5310 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5311 OUR_HANDLE(r->in.handle)));
5315 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5318 if (!Printer->document_started) {
5319 return WERR_SPL_NO_STARTDOC;
5322 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5327 /********************************************************************
5328 * called by spoolss_api_setprinter
5329 * when updating a printer description
5330 ********************************************************************/
5332 static WERROR update_printer_sec(struct policy_handle *handle,
5333 pipes_struct *p, struct sec_desc_buf *secdesc_ctr)
5335 struct spoolss_security_descriptor *new_secdesc = NULL;
5336 struct spoolss_security_descriptor *old_secdesc = NULL;
5337 const char *printer;
5341 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5343 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5344 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5345 OUR_HANDLE(handle)));
5347 result = WERR_BADFID;
5351 if (secdesc_ctr == NULL) {
5352 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5353 result = WERR_INVALID_PARAM;
5356 printer = lp_const_servicename(snum);
5358 /* Check the user has permissions to change the security
5359 descriptor. By experimentation with two NT machines, the user
5360 requires Full Access to the printer to change security
5363 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5364 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5365 result = WERR_ACCESS_DENIED;
5369 /* NT seems to like setting the security descriptor even though
5370 nothing may have actually changed. */
5371 result = winreg_get_printer_secdesc(p->mem_ctx,
5375 if (!W_ERROR_IS_OK(result)) {
5376 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5377 result = WERR_BADFID;
5381 if (DEBUGLEVEL >= 10) {
5382 struct security_acl *the_acl;
5385 the_acl = secdesc_ctr->sd->dacl;
5386 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5387 printer, the_acl->num_aces));
5389 for (i = 0; i < the_acl->num_aces; i++) {
5390 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5391 &the_acl->aces[i].trustee),
5392 the_acl->aces[i].access_mask));
5395 the_acl = secdesc_ctr->sd->dacl;
5398 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5399 printer, the_acl->num_aces));
5401 for (i = 0; i < the_acl->num_aces; i++) {
5402 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5403 &the_acl->aces[i].trustee),
5404 the_acl->aces[i].access_mask));
5407 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5411 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5412 if (new_secdesc == NULL) {
5413 result = WERR_NOMEM;
5417 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5422 result = winreg_set_printer_secdesc(p->mem_ctx,
5431 /********************************************************************
5432 Canonicalize printer info from a client
5433 ********************************************************************/
5435 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5436 struct spoolss_SetPrinterInfo2 *info2,
5439 fstring printername;
5442 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5443 "portname=%s drivername=%s comment=%s location=%s\n",
5444 info2->servername, info2->printername, info2->sharename,
5445 info2->portname, info2->drivername, info2->comment,
5448 /* we force some elements to "correct" values */
5449 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5450 if (info2->servername == NULL) {
5453 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5454 if (info2->sharename == NULL) {
5458 /* check to see if we allow printername != sharename */
5459 if (lp_force_printername(snum)) {
5460 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5461 global_myname(), info2->sharename);
5463 /* make sure printername is in \\server\printername format */
5464 fstrcpy(printername, info2->printername);
5466 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5467 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5471 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5472 global_myname(), p);
5474 if (info2->printername == NULL) {
5478 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5479 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5484 /****************************************************************************
5485 ****************************************************************************/
5487 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5489 char *cmd = lp_addport_cmd();
5490 char *command = NULL;
5492 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5493 bool is_print_op = false;
5496 return WERR_ACCESS_DENIED;
5499 command = talloc_asprintf(ctx,
5500 "%s \"%s\" \"%s\"", cmd, portname, uri );
5506 is_print_op = user_has_privileges( token, &se_printop );
5508 DEBUG(10,("Running [%s]\n", command));
5510 /********* BEGIN SePrintOperatorPrivilege **********/
5515 ret = smbrun(command, NULL);
5520 /********* END SePrintOperatorPrivilege **********/
5522 DEBUGADD(10,("returned [%d]\n", ret));
5524 TALLOC_FREE(command);
5527 return WERR_ACCESS_DENIED;
5533 /****************************************************************************
5534 ****************************************************************************/
5536 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5537 struct spoolss_SetPrinterInfo2 *info2)
5539 char *cmd = lp_addprinter_cmd();
5541 char *command = NULL;
5545 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5546 bool is_print_op = false;
5547 char *remote_machine = talloc_strdup(ctx, "%m");
5549 if (!remote_machine) {
5552 remote_machine = talloc_sub_basic(ctx,
5553 current_user_info.smb_name,
5554 current_user_info.domain,
5556 if (!remote_machine) {
5560 command = talloc_asprintf(ctx,
5561 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5562 cmd, info2->printername, info2->sharename,
5563 info2->portname, info2->drivername,
5564 info2->location, info2->comment, remote_machine);
5570 is_print_op = user_has_privileges( token, &se_printop );
5572 DEBUG(10,("Running [%s]\n", command));
5574 /********* BEGIN SePrintOperatorPrivilege **********/
5579 if ( (ret = smbrun(command, &fd)) == 0 ) {
5580 /* Tell everyone we updated smb.conf. */
5581 message_send_all(smbd_messaging_context(),
5582 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5588 /********* END SePrintOperatorPrivilege **********/
5590 DEBUGADD(10,("returned [%d]\n", ret));
5592 TALLOC_FREE(command);
5593 TALLOC_FREE(remote_machine);
5601 /* reload our services immediately */
5603 reload_services(false);
5607 /* Get lines and convert them back to dos-codepage */
5608 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5609 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5612 /* Set the portname to what the script says the portname should be. */
5613 /* but don't require anything to be return from the script exit a good error code */
5616 /* Set the portname to what the script says the portname should be. */
5617 info2->portname = talloc_strdup(ctx, qlines[0]);
5618 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5621 TALLOC_FREE(qlines);
5625 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5626 struct auth_serversupplied_info *server_info,
5628 struct spoolss_SetPrinterInfo2 *printer,
5629 struct spoolss_PrinterInfo2 *old_printer)
5631 bool force_update = (old_printer == NULL);
5632 const char *dnsdomname;
5633 const char *longname;
5634 const char *uncname;
5635 const char *spooling;
5637 WERROR result = WERR_OK;
5639 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5640 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5641 winreg_set_printer_dataex(mem_ctx,
5644 SPOOL_DSSPOOLER_KEY,
5645 SPOOL_REG_DRIVERNAME,
5650 if (!force_update) {
5651 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5652 printer->drivername));
5654 notify_printer_driver(snum, printer->drivername);
5658 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5659 push_reg_sz(mem_ctx, &buffer, printer->comment);
5660 winreg_set_printer_dataex(mem_ctx,
5663 SPOOL_DSSPOOLER_KEY,
5664 SPOOL_REG_DESCRIPTION,
5669 if (!force_update) {
5670 notify_printer_comment(snum, printer->comment);
5674 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5675 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5676 winreg_set_printer_dataex(mem_ctx,
5679 SPOOL_DSSPOOLER_KEY,
5680 SPOOL_REG_PRINTSHARENAME,
5685 if (!force_update) {
5686 notify_printer_sharename(snum, printer->sharename);
5690 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5693 p = strrchr(printer->printername, '\\' );
5697 p = printer->printername;
5700 push_reg_sz(mem_ctx, &buffer, p);
5701 winreg_set_printer_dataex(mem_ctx,
5704 SPOOL_DSSPOOLER_KEY,
5705 SPOOL_REG_PRINTERNAME,
5710 if (!force_update) {
5711 notify_printer_printername(snum, p);
5715 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5716 push_reg_sz(mem_ctx, &buffer, printer->portname);
5717 winreg_set_printer_dataex(mem_ctx,
5720 SPOOL_DSSPOOLER_KEY,
5726 if (!force_update) {
5727 notify_printer_port(snum, printer->portname);
5731 if (force_update || !strequal(printer->location, old_printer->location)) {
5732 push_reg_sz(mem_ctx, &buffer, printer->location);
5733 winreg_set_printer_dataex(mem_ctx,
5736 SPOOL_DSSPOOLER_KEY,
5742 if (!force_update) {
5743 notify_printer_location(snum, printer->location);
5747 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5748 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5749 winreg_set_printer_dataex(mem_ctx,
5752 SPOOL_DSSPOOLER_KEY,
5753 SPOOL_REG_PRINTSEPARATORFILE,
5758 if (!force_update) {
5759 notify_printer_location(snum, printer->location);
5763 if (force_update || printer->starttime != old_printer->starttime) {
5764 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5765 SIVAL(buffer.data, 0, printer->starttime);
5766 winreg_set_printer_dataex(mem_ctx,
5769 SPOOL_DSSPOOLER_KEY,
5770 SPOOL_REG_PRINTSTARTTIME,
5776 if (force_update || printer->untiltime != old_printer->untiltime) {
5777 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5778 SIVAL(buffer.data, 0, printer->untiltime);
5779 winreg_set_printer_dataex(mem_ctx,
5782 SPOOL_DSSPOOLER_KEY,
5783 SPOOL_REG_PRINTENDTIME,
5789 if (force_update || printer->priority != old_printer->priority) {
5790 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5791 SIVAL(buffer.data, 0, printer->priority);
5792 winreg_set_printer_dataex(mem_ctx,
5795 SPOOL_DSSPOOLER_KEY,
5802 if (force_update || printer->attributes != old_printer->attributes) {
5803 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5804 SIVAL(buffer.data, 0, (printer->attributes &
5805 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5806 winreg_set_printer_dataex(mem_ctx,
5809 SPOOL_DSSPOOLER_KEY,
5810 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5815 switch (printer->attributes & 0x3) {
5817 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5820 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5823 spooling = SPOOL_REGVAL_PRINTDIRECT;
5826 spooling = "unknown";
5828 push_reg_sz(mem_ctx, &buffer, spooling);
5829 winreg_set_printer_dataex(mem_ctx,
5832 SPOOL_DSSPOOLER_KEY,
5833 SPOOL_REG_PRINTSPOOLING,
5839 push_reg_sz(mem_ctx, &buffer, global_myname());
5840 winreg_set_printer_dataex(mem_ctx,
5843 SPOOL_DSSPOOLER_KEY,
5844 SPOOL_REG_SHORTSERVERNAME,
5849 dnsdomname = get_mydnsfullname();
5850 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5851 longname = talloc_strdup(mem_ctx, dnsdomname);
5853 longname = talloc_strdup(mem_ctx, global_myname());
5855 if (longname == NULL) {
5856 result = WERR_NOMEM;
5860 push_reg_sz(mem_ctx, &buffer, longname);
5861 winreg_set_printer_dataex(mem_ctx,
5864 SPOOL_DSSPOOLER_KEY,
5865 SPOOL_REG_SERVERNAME,
5870 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5871 global_myname(), printer->sharename);
5872 push_reg_sz(mem_ctx, &buffer, uncname);
5873 winreg_set_printer_dataex(mem_ctx,
5876 SPOOL_DSSPOOLER_KEY,
5886 /********************************************************************
5887 * Called by spoolss_api_setprinter
5888 * when updating a printer description.
5889 ********************************************************************/
5891 static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5892 struct spoolss_SetPrinterInfoCtr *info_ctr,
5893 struct spoolss_DeviceMode *devmode)
5895 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5896 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5897 struct spoolss_PrinterInfo2 *old_printer;
5898 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5899 const char *servername = NULL;
5901 WERROR result = WERR_OK;
5902 TALLOC_CTX *tmp_ctx;
5904 DEBUG(8,("update_printer\n"));
5906 tmp_ctx = talloc_new(p->mem_ctx);
5907 if (tmp_ctx == NULL) {
5912 result = WERR_BADFID;
5916 if (!get_printer_snum(p, handle, &snum, NULL)) {
5917 result = WERR_BADFID;
5921 if (Printer != NULL || Printer->servername != NULL) {
5922 servername = Printer->servername;
5925 result = winreg_get_printer(tmp_ctx,
5928 lp_const_servicename(snum),
5930 if (!W_ERROR_IS_OK(result)) {
5931 result = WERR_BADFID;
5935 /* Do sanity check on the requested changes for Samba */
5936 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5937 result = WERR_INVALID_PARAM;
5941 /* FIXME!!! If the driver has changed we really should verify that
5942 it is installed before doing much else --jerry */
5944 /* Check calling user has permission to update printer description */
5945 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5946 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5947 result = WERR_ACCESS_DENIED;
5951 /* Call addprinter hook */
5952 /* Check changes to see if this is really needed */
5954 if (*lp_addprinter_cmd() &&
5955 (!strequal(printer->drivername, old_printer->drivername) ||
5956 !strequal(printer->comment, old_printer->comment) ||
5957 !strequal(printer->portname, old_printer->portname) ||
5958 !strequal(printer->location, old_printer->location)) )
5960 /* add_printer_hook() will call reload_services() */
5961 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5963 result = WERR_ACCESS_DENIED;
5968 update_dsspooler(tmp_ctx,
5974 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
5976 if (devmode == NULL) {
5977 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
5979 result = winreg_update_printer(tmp_ctx,
5988 talloc_free(tmp_ctx);
5993 /****************************************************************************
5994 ****************************************************************************/
5995 static WERROR publish_or_unpublish_printer(pipes_struct *p,
5996 struct policy_handle *handle,
5997 struct spoolss_SetPrinterInfo7 *info7)
6000 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6003 Printer_entry *Printer;
6005 if ( lp_security() != SEC_ADS ) {
6006 return WERR_UNKNOWN_LEVEL;
6009 Printer = find_printer_index_by_hnd(p, handle);
6011 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6016 if (!get_printer_snum(p, handle, &snum, NULL))
6019 result = winreg_get_printer(p->mem_ctx, p->server_info,
6020 Printer->servername,
6021 lp_servicename(snum), &pinfo2);
6022 if (!W_ERROR_IS_OK(result)) {
6026 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6028 TALLOC_FREE(pinfo2);
6031 return WERR_UNKNOWN_LEVEL;
6035 /********************************************************************
6036 ********************************************************************/
6038 static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
6039 struct spoolss_DeviceMode *devmode)
6042 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6043 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6045 DEBUG(8,("update_printer_devmode\n"));
6051 if (!get_printer_snum(p, handle, &snum, NULL)) {
6055 /* Check calling user has permission to update printer description */
6056 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6057 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6058 return WERR_ACCESS_DENIED;
6061 return winreg_update_printer(p->mem_ctx,
6063 lp_const_servicename(snum),
6071 /****************************************************************
6073 ****************************************************************/
6075 WERROR _spoolss_SetPrinter(pipes_struct *p,
6076 struct spoolss_SetPrinter *r)
6080 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6083 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6084 OUR_HANDLE(r->in.handle)));
6088 /* check the level */
6089 switch (r->in.info_ctr->level) {
6091 return control_printer(r->in.handle, r->in.command, p);
6093 result = update_printer(p, r->in.handle,
6095 r->in.devmode_ctr->devmode);
6096 if (!W_ERROR_IS_OK(result))
6098 if (r->in.secdesc_ctr->sd)
6099 result = update_printer_sec(r->in.handle, p,
6103 return update_printer_sec(r->in.handle, p,
6106 return publish_or_unpublish_printer(p, r->in.handle,
6107 r->in.info_ctr->info.info7);
6109 return update_printer_devmode(p, r->in.handle,
6110 r->in.devmode_ctr->devmode);
6112 return WERR_UNKNOWN_LEVEL;
6116 /****************************************************************
6117 _spoolss_FindClosePrinterNotify
6118 ****************************************************************/
6120 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6121 struct spoolss_FindClosePrinterNotify *r)
6123 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6126 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6127 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6131 if (Printer->notify.client_connected == true) {
6134 if ( Printer->printer_type == SPLHND_SERVER)
6136 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6137 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6140 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6143 Printer->notify.flags=0;
6144 Printer->notify.options=0;
6145 Printer->notify.localmachine[0]='\0';
6146 Printer->notify.printerlocal=0;
6147 TALLOC_FREE(Printer->notify.option);
6148 Printer->notify.client_connected = false;
6153 /****************************************************************
6155 ****************************************************************/
6157 WERROR _spoolss_AddJob(pipes_struct *p,
6158 struct spoolss_AddJob *r)
6160 if (!r->in.buffer && (r->in.offered != 0)) {
6161 return WERR_INVALID_PARAM;
6164 /* this is what a NT server returns for AddJob. AddJob must fail on
6165 * non-local printers */
6167 if (r->in.level != 1) {
6168 return WERR_UNKNOWN_LEVEL;
6171 return WERR_INVALID_PARAM;
6174 /****************************************************************************
6176 ****************************************************************************/
6178 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6179 struct spoolss_JobInfo1 *r,
6180 const print_queue_struct *queue,
6181 int position, int snum,
6182 struct spoolss_PrinterInfo2 *pinfo2)
6186 t = gmtime(&queue->time);
6188 r->job_id = queue->job;
6190 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6191 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6192 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6193 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6194 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6195 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6196 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6197 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6198 r->data_type = talloc_strdup(mem_ctx, "RAW");
6199 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6200 r->text_status = talloc_strdup(mem_ctx, "");
6201 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6203 r->status = nt_printj_status(queue->status);
6204 r->priority = queue->priority;
6205 r->position = position;
6206 r->total_pages = queue->page_count;
6207 r->pages_printed = 0; /* ??? */
6209 init_systemtime(&r->submitted, t);
6214 /****************************************************************************
6216 ****************************************************************************/
6218 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6219 struct spoolss_JobInfo2 *r,
6220 const print_queue_struct *queue,
6221 int position, int snum,
6222 struct spoolss_PrinterInfo2 *pinfo2,
6223 struct spoolss_DeviceMode *devmode)
6227 t = gmtime(&queue->time);
6229 r->job_id = queue->job;
6231 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6232 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6233 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6234 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6235 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6236 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6237 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6238 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6239 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6240 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6241 r->data_type = talloc_strdup(mem_ctx, "RAW");
6242 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6243 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6244 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6245 r->parameters = talloc_strdup(mem_ctx, "");
6246 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6247 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6248 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6250 r->devmode = devmode;
6252 r->text_status = talloc_strdup(mem_ctx, "");
6253 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6257 r->status = nt_printj_status(queue->status);
6258 r->priority = queue->priority;
6259 r->position = position;
6262 r->total_pages = queue->page_count;
6263 r->size = queue->size;
6264 init_systemtime(&r->submitted, t);
6266 r->pages_printed = 0; /* ??? */
6271 /****************************************************************************
6273 ****************************************************************************/
6275 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6276 struct spoolss_JobInfo3 *r,
6277 const print_queue_struct *queue,
6278 const print_queue_struct *next_queue,
6279 int position, int snum,
6280 struct spoolss_PrinterInfo2 *pinfo2)
6282 r->job_id = queue->job;
6285 r->next_job_id = next_queue->job;
6292 /****************************************************************************
6293 Enumjobs at level 1.
6294 ****************************************************************************/
6296 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6297 const print_queue_struct *queue,
6298 uint32_t num_queues, int snum,
6299 struct spoolss_PrinterInfo2 *pinfo2,
6300 union spoolss_JobInfo **info_p,
6303 union spoolss_JobInfo *info;
6305 WERROR result = WERR_OK;
6307 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6308 W_ERROR_HAVE_NO_MEMORY(info);
6310 *count = num_queues;
6312 for (i=0; i<*count; i++) {
6313 result = fill_job_info1(info,
6319 if (!W_ERROR_IS_OK(result)) {
6325 if (!W_ERROR_IS_OK(result)) {
6336 /****************************************************************************
6337 Enumjobs at level 2.
6338 ****************************************************************************/
6340 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6341 const print_queue_struct *queue,
6342 uint32_t num_queues, int snum,
6343 struct spoolss_PrinterInfo2 *pinfo2,
6344 union spoolss_JobInfo **info_p,
6347 union spoolss_JobInfo *info;
6349 WERROR result = WERR_OK;
6351 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6352 W_ERROR_HAVE_NO_MEMORY(info);
6354 *count = num_queues;
6356 for (i=0; i<*count; i++) {
6357 struct spoolss_DeviceMode *devmode;
6359 result = spoolss_create_default_devmode(info,
6360 pinfo2->printername,
6362 if (!W_ERROR_IS_OK(result)) {
6363 DEBUG(3, ("Can't proceed w/o a devmode!"));
6367 result = fill_job_info2(info,
6374 if (!W_ERROR_IS_OK(result)) {
6380 if (!W_ERROR_IS_OK(result)) {
6391 /****************************************************************************
6392 Enumjobs at level 3.
6393 ****************************************************************************/
6395 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6396 const print_queue_struct *queue,
6397 uint32_t num_queues, int snum,
6398 struct spoolss_PrinterInfo2 *pinfo2,
6399 union spoolss_JobInfo **info_p,
6402 union spoolss_JobInfo *info;
6404 WERROR result = WERR_OK;
6406 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6407 W_ERROR_HAVE_NO_MEMORY(info);
6409 *count = num_queues;
6411 for (i=0; i<*count; i++) {
6412 const print_queue_struct *next_queue = NULL;
6415 next_queue = &queue[i+1];
6418 result = fill_job_info3(info,
6425 if (!W_ERROR_IS_OK(result)) {
6431 if (!W_ERROR_IS_OK(result)) {
6442 /****************************************************************
6444 ****************************************************************/
6446 WERROR _spoolss_EnumJobs(pipes_struct *p,
6447 struct spoolss_EnumJobs *r)
6450 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6452 print_status_struct prt_status;
6453 print_queue_struct *queue = NULL;
6456 /* that's an [in out] buffer */
6458 if (!r->in.buffer && (r->in.offered != 0)) {
6459 return WERR_INVALID_PARAM;
6462 DEBUG(4,("_spoolss_EnumJobs\n"));
6466 *r->out.info = NULL;
6468 /* lookup the printer snum and tdb entry */
6470 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6474 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6475 lp_servicename(snum), &pinfo2);
6476 if (!W_ERROR_IS_OK(result)) {
6480 count = print_queue_status(snum, &queue, &prt_status);
6481 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6482 count, prt_status.status, prt_status.message));
6486 TALLOC_FREE(pinfo2);
6490 switch (r->in.level) {
6492 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6493 pinfo2, r->out.info, r->out.count);
6496 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6497 pinfo2, r->out.info, r->out.count);
6500 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6501 pinfo2, r->out.info, r->out.count);
6504 result = WERR_UNKNOWN_LEVEL;
6509 TALLOC_FREE(pinfo2);
6511 if (!W_ERROR_IS_OK(result)) {
6515 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6517 *r->out.info, r->in.level,
6519 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6520 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6522 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6525 /****************************************************************
6526 _spoolss_ScheduleJob
6527 ****************************************************************/
6529 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6530 struct spoolss_ScheduleJob *r)
6535 /****************************************************************
6536 ****************************************************************/
6538 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6539 const char *printer_name,
6541 struct spoolss_SetJobInfo1 *r)
6545 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6549 if (strequal(old_doc_name, r->document_name)) {
6553 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6560 /****************************************************************
6562 ****************************************************************/
6564 WERROR _spoolss_SetJob(pipes_struct *p,
6565 struct spoolss_SetJob *r)
6568 WERROR errcode = WERR_BADFUNC;
6570 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6574 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6575 return WERR_INVALID_PRINTER_NAME;
6578 switch (r->in.command) {
6579 case SPOOLSS_JOB_CONTROL_CANCEL:
6580 case SPOOLSS_JOB_CONTROL_DELETE:
6581 errcode = print_job_delete(p->server_info,
6582 snum, r->in.job_id);
6583 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6587 case SPOOLSS_JOB_CONTROL_PAUSE:
6588 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6592 case SPOOLSS_JOB_CONTROL_RESTART:
6593 case SPOOLSS_JOB_CONTROL_RESUME:
6594 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6602 return WERR_UNKNOWN_LEVEL;
6605 if (!W_ERROR_IS_OK(errcode)) {
6609 if (r->in.ctr == NULL) {
6613 switch (r->in.ctr->level) {
6615 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6617 r->in.ctr->info.info1);
6623 return WERR_UNKNOWN_LEVEL;
6629 /****************************************************************************
6630 Enumerates all printer drivers by level and architecture.
6631 ****************************************************************************/
6633 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6634 struct auth_serversupplied_info *server_info,
6635 const char *servername,
6636 const char *architecture,
6638 union spoolss_DriverInfo **info_p,
6643 struct spoolss_DriverInfo8 *driver;
6644 union spoolss_DriverInfo *info = NULL;
6646 WERROR result = WERR_OK;
6647 uint32_t num_drivers;
6648 const char **drivers;
6653 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6654 result = winreg_get_driver_list(mem_ctx, server_info,
6655 architecture, version,
6656 &num_drivers, &drivers);
6657 if (!W_ERROR_IS_OK(result)) {
6660 DEBUG(4, ("we have:[%d] drivers in environment"
6661 " [%s] and version [%d]\n",
6662 num_drivers, architecture, version));
6664 if (num_drivers != 0) {
6665 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6666 union spoolss_DriverInfo,
6667 count + num_drivers);
6669 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6670 "failed to enlarge driver info buffer!\n"));
6671 result = WERR_NOMEM;
6676 for (i = 0; i < num_drivers; i++) {
6677 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6679 result = winreg_get_driver(mem_ctx, server_info,
6680 architecture, drivers[i],
6682 if (!W_ERROR_IS_OK(result)) {
6688 result = fill_printer_driver_info1(info, &info[count+i].info1,
6689 driver, servername);
6692 result = fill_printer_driver_info2(info, &info[count+i].info2,
6693 driver, servername);
6696 result = fill_printer_driver_info3(info, &info[count+i].info3,
6697 driver, servername);
6700 result = fill_printer_driver_info4(info, &info[count+i].info4,
6701 driver, servername);
6704 result = fill_printer_driver_info5(info, &info[count+i].info5,
6705 driver, servername);
6708 result = fill_printer_driver_info6(info, &info[count+i].info6,
6709 driver, servername);
6712 result = fill_printer_driver_info8(info, &info[count+i].info8,
6713 driver, servername);
6716 result = WERR_UNKNOWN_LEVEL;
6720 TALLOC_FREE(driver);
6722 if (!W_ERROR_IS_OK(result)) {
6727 count += num_drivers;
6728 TALLOC_FREE(drivers);
6732 TALLOC_FREE(drivers);
6734 if (!W_ERROR_IS_OK(result)) {
6745 /****************************************************************************
6746 Enumerates all printer drivers by level.
6747 ****************************************************************************/
6749 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6750 struct auth_serversupplied_info *server_info,
6751 const char *servername,
6752 const char *architecture,
6754 union spoolss_DriverInfo **info_p,
6758 WERROR result = WERR_OK;
6760 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6762 for (a=0; archi_table[a].long_archi != NULL; a++) {
6764 union spoolss_DriverInfo *info = NULL;
6767 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6770 archi_table[a].long_archi,
6774 if (!W_ERROR_IS_OK(result)) {
6778 for (i=0; i < count; i++) {
6779 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6780 info[i], info_p, count_p);
6787 return enumprinterdrivers_level_by_architecture(mem_ctx,
6796 /****************************************************************
6797 _spoolss_EnumPrinterDrivers
6798 ****************************************************************/
6800 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6801 struct spoolss_EnumPrinterDrivers *r)
6803 const char *cservername;
6806 /* that's an [in out] buffer */
6808 if (!r->in.buffer && (r->in.offered != 0)) {
6809 return WERR_INVALID_PARAM;
6812 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6816 *r->out.info = NULL;
6818 cservername = canon_servername(r->in.server);
6820 if (!is_myname_or_ipaddr(cservername)) {
6821 return WERR_UNKNOWN_PRINTER_DRIVER;
6824 result = enumprinterdrivers_level(p->mem_ctx,
6831 if (!W_ERROR_IS_OK(result)) {
6835 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6836 spoolss_EnumPrinterDrivers,
6837 *r->out.info, r->in.level,
6839 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6840 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6842 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6845 /****************************************************************
6847 ****************************************************************/
6849 WERROR _spoolss_EnumForms(pipes_struct *p,
6850 struct spoolss_EnumForms *r)
6856 *r->out.info = NULL;
6858 /* that's an [in out] buffer */
6860 if (!r->in.buffer && (r->in.offered != 0) ) {
6861 return WERR_INVALID_PARAM;
6864 DEBUG(4,("_spoolss_EnumForms\n"));
6865 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6866 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6868 switch (r->in.level) {
6870 result = winreg_printer_enumforms1(p->mem_ctx,
6876 result = WERR_UNKNOWN_LEVEL;
6880 if (!W_ERROR_IS_OK(result)) {
6884 if (*r->out.count == 0) {
6885 return WERR_NO_MORE_ITEMS;
6888 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6890 *r->out.info, r->in.level,
6892 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6893 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6895 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6898 /****************************************************************
6900 ****************************************************************/
6902 WERROR _spoolss_GetForm(pipes_struct *p,
6903 struct spoolss_GetForm *r)
6907 /* that's an [in out] buffer */
6909 if (!r->in.buffer && (r->in.offered != 0)) {
6910 return WERR_INVALID_PARAM;
6913 DEBUG(4,("_spoolss_GetForm\n"));
6914 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6915 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6917 switch (r->in.level) {
6919 result = winreg_printer_getform1(p->mem_ctx,
6922 &r->out.info->info1);
6925 result = WERR_UNKNOWN_LEVEL;
6929 if (!W_ERROR_IS_OK(result)) {
6930 TALLOC_FREE(r->out.info);
6934 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6935 r->out.info, r->in.level);
6936 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6938 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6941 /****************************************************************************
6942 ****************************************************************************/
6944 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6945 struct spoolss_PortInfo1 *r,
6948 r->port_name = talloc_strdup(mem_ctx, name);
6949 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6954 /****************************************************************************
6955 TODO: This probably needs distinguish between TCP/IP and Local ports
6957 ****************************************************************************/
6959 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6960 struct spoolss_PortInfo2 *r,
6963 r->port_name = talloc_strdup(mem_ctx, name);
6964 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6966 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6967 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6969 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6970 W_ERROR_HAVE_NO_MEMORY(r->description);
6972 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6979 /****************************************************************************
6980 wrapper around the enumer ports command
6981 ****************************************************************************/
6983 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6985 char *cmd = lp_enumports_cmd();
6986 char **qlines = NULL;
6987 char *command = NULL;
6995 /* if no hook then just fill in the default port */
6998 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7001 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7002 TALLOC_FREE(qlines);
7009 /* we have a valid enumport command */
7011 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7016 DEBUG(10,("Running [%s]\n", command));
7017 ret = smbrun(command, &fd);
7018 DEBUG(10,("Returned [%d]\n", ret));
7019 TALLOC_FREE(command);
7024 return WERR_ACCESS_DENIED;
7028 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7029 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7039 /****************************************************************************
7041 ****************************************************************************/
7043 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7044 union spoolss_PortInfo **info_p,
7047 union spoolss_PortInfo *info = NULL;
7049 WERROR result = WERR_OK;
7050 char **qlines = NULL;
7053 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7054 if (!W_ERROR_IS_OK(result)) {
7059 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7061 DEBUG(10,("Returning WERR_NOMEM\n"));
7062 result = WERR_NOMEM;
7066 for (i=0; i<numlines; i++) {
7067 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7068 result = fill_port_1(info, &info[i].info1, qlines[i]);
7069 if (!W_ERROR_IS_OK(result)) {
7074 TALLOC_FREE(qlines);
7077 if (!W_ERROR_IS_OK(result)) {
7079 TALLOC_FREE(qlines);
7091 /****************************************************************************
7093 ****************************************************************************/
7095 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7096 union spoolss_PortInfo **info_p,
7099 union spoolss_PortInfo *info = NULL;
7101 WERROR result = WERR_OK;
7102 char **qlines = NULL;
7105 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7106 if (!W_ERROR_IS_OK(result)) {
7111 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7113 DEBUG(10,("Returning WERR_NOMEM\n"));
7114 result = WERR_NOMEM;
7118 for (i=0; i<numlines; i++) {
7119 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7120 result = fill_port_2(info, &info[i].info2, qlines[i]);
7121 if (!W_ERROR_IS_OK(result)) {
7126 TALLOC_FREE(qlines);
7129 if (!W_ERROR_IS_OK(result)) {
7131 TALLOC_FREE(qlines);
7143 /****************************************************************
7145 ****************************************************************/
7147 WERROR _spoolss_EnumPorts(pipes_struct *p,
7148 struct spoolss_EnumPorts *r)
7152 /* that's an [in out] buffer */
7154 if (!r->in.buffer && (r->in.offered != 0)) {
7155 return WERR_INVALID_PARAM;
7158 DEBUG(4,("_spoolss_EnumPorts\n"));
7162 *r->out.info = NULL;
7164 switch (r->in.level) {
7166 result = enumports_level_1(p->mem_ctx, r->out.info,
7170 result = enumports_level_2(p->mem_ctx, r->out.info,
7174 return WERR_UNKNOWN_LEVEL;
7177 if (!W_ERROR_IS_OK(result)) {
7181 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7183 *r->out.info, r->in.level,
7185 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7186 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7188 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7191 /****************************************************************************
7192 ****************************************************************************/
7194 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7196 struct spoolss_SetPrinterInfoCtr *info_ctr,
7197 struct spoolss_DeviceMode *devmode,
7198 struct security_descriptor *secdesc,
7199 struct spoolss_UserLevelCtr *user_ctr,
7200 struct policy_handle *handle)
7202 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7203 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7205 WERROR err = WERR_OK;
7207 /* samba does not have a concept of local, non-shared printers yet, so
7208 * make sure we always setup sharename - gd */
7209 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7210 (info2->printername != NULL && info2->printername[0] != '\0')) {
7211 DEBUG(5, ("spoolss_addprinterex_level_2: "
7212 "no sharename has been set, setting printername %s as sharename\n",
7213 info2->printername));
7214 info2->sharename = info2->printername;
7217 /* check to see if the printer already exists */
7218 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7219 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7221 return WERR_PRINTER_ALREADY_EXISTS;
7224 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7225 if ((snum = print_queue_snum(info2->printername)) != -1) {
7226 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7227 info2->printername));
7228 return WERR_PRINTER_ALREADY_EXISTS;
7232 /* validate printer info struct */
7233 if (!info2->printername || strlen(info2->printername) == 0) {
7234 return WERR_INVALID_PRINTER_NAME;
7236 if (!info2->portname || strlen(info2->portname) == 0) {
7237 return WERR_UNKNOWN_PORT;
7239 if (!info2->drivername || strlen(info2->drivername) == 0) {
7240 return WERR_UNKNOWN_PRINTER_DRIVER;
7242 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7243 return WERR_UNKNOWN_PRINTPROCESSOR;
7246 /* FIXME!!! smbd should check to see if the driver is installed before
7247 trying to add a printer like this --jerry */
7249 if (*lp_addprinter_cmd() ) {
7250 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7252 return WERR_ACCESS_DENIED;
7255 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7256 "smb.conf parameter \"addprinter command\" is defined. This"
7257 "parameter must exist for this call to succeed\n",
7258 info2->sharename ));
7261 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7262 return WERR_ACCESS_DENIED;
7265 /* you must be a printer admin to add a new printer */
7266 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7267 return WERR_ACCESS_DENIED;
7271 * Do sanity check on the requested changes for Samba.
7274 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7275 return WERR_INVALID_PARAM;
7278 if (devmode == NULL) {
7279 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7282 update_dsspooler(p->mem_ctx,
7288 err = winreg_update_printer(p->mem_ctx,
7295 if (!W_ERROR_IS_OK(err)) {
7299 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7300 /* Handle open failed - remove addition. */
7301 ZERO_STRUCTP(handle);
7302 return WERR_ACCESS_DENIED;
7308 /****************************************************************
7309 _spoolss_AddPrinterEx
7310 ****************************************************************/
7312 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7313 struct spoolss_AddPrinterEx *r)
7315 switch (r->in.info_ctr->level) {
7317 /* we don't handle yet */
7318 /* but I know what to do ... */
7319 return WERR_UNKNOWN_LEVEL;
7321 return spoolss_addprinterex_level_2(p, r->in.server,
7323 r->in.devmode_ctr->devmode,
7324 r->in.secdesc_ctr->sd,
7325 r->in.userlevel_ctr,
7328 return WERR_UNKNOWN_LEVEL;
7332 /****************************************************************
7334 ****************************************************************/
7336 WERROR _spoolss_AddPrinter(pipes_struct *p,
7337 struct spoolss_AddPrinter *r)
7339 struct spoolss_AddPrinterEx a;
7340 struct spoolss_UserLevelCtr userlevel_ctr;
7342 ZERO_STRUCT(userlevel_ctr);
7344 userlevel_ctr.level = 1;
7346 a.in.server = r->in.server;
7347 a.in.info_ctr = r->in.info_ctr;
7348 a.in.devmode_ctr = r->in.devmode_ctr;
7349 a.in.secdesc_ctr = r->in.secdesc_ctr;
7350 a.in.userlevel_ctr = &userlevel_ctr;
7351 a.out.handle = r->out.handle;
7353 return _spoolss_AddPrinterEx(p, &a);
7356 /****************************************************************
7357 _spoolss_AddPrinterDriverEx
7358 ****************************************************************/
7360 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7361 struct spoolss_AddPrinterDriverEx *r)
7363 WERROR err = WERR_OK;
7364 const char *driver_name = NULL;
7369 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7370 fn = "_spoolss_AddPrinterDriver";
7372 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7373 fn = "_spoolss_AddPrinterDriverEx";
7376 return WERR_INVALID_PARAM;
7380 * we only support the semantics of AddPrinterDriver()
7381 * i.e. only copy files that are newer than existing ones
7384 if (r->in.flags == 0) {
7385 return WERR_INVALID_PARAM;
7388 if (r->in.flags != APD_COPY_NEW_FILES) {
7389 return WERR_ACCESS_DENIED;
7393 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7394 /* Clever hack from Martin Zielinski <mz@seh.de>
7395 * to allow downgrade from level 8 (Vista).
7397 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7398 r->in.info_ctr->level));
7399 return WERR_UNKNOWN_LEVEL;
7402 DEBUG(5,("Cleaning driver's information\n"));
7403 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7404 if (!W_ERROR_IS_OK(err))
7407 DEBUG(5,("Moving driver to final destination\n"));
7408 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7413 err = winreg_add_driver(p->mem_ctx, p->server_info,
7414 r->in.info_ctr, &driver_name, &version);
7415 if (!W_ERROR_IS_OK(err)) {
7420 * I think this is where he DrvUpgradePrinter() hook would be
7421 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7422 * server. Right now, we just need to send ourselves a message
7423 * to update each printer bound to this driver. --jerry
7426 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7427 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7435 /****************************************************************
7436 _spoolss_AddPrinterDriver
7437 ****************************************************************/
7439 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7440 struct spoolss_AddPrinterDriver *r)
7442 struct spoolss_AddPrinterDriverEx a;
7444 switch (r->in.info_ctr->level) {
7451 return WERR_UNKNOWN_LEVEL;
7454 a.in.servername = r->in.servername;
7455 a.in.info_ctr = r->in.info_ctr;
7456 a.in.flags = APD_COPY_NEW_FILES;
7458 return _spoolss_AddPrinterDriverEx(p, &a);
7461 /****************************************************************************
7462 ****************************************************************************/
7464 struct _spoolss_paths {
7470 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7472 static const struct _spoolss_paths spoolss_paths[]= {
7473 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7474 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7477 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7478 const char *servername,
7479 const char *environment,
7483 const char *pservername = NULL;
7484 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7485 const char *short_archi;
7489 /* environment may be empty */
7490 if (environment && strlen(environment)) {
7491 long_archi = environment;
7494 /* servername may be empty */
7495 if (servername && strlen(servername)) {
7496 pservername = canon_servername(servername);
7498 if (!is_myname_or_ipaddr(pservername)) {
7499 return WERR_INVALID_PARAM;
7503 if (!(short_archi = get_short_archi(long_archi))) {
7504 return WERR_INVALID_ENVIRONMENT;
7507 switch (component) {
7508 case SPOOLSS_PRTPROCS_PATH:
7509 case SPOOLSS_DRIVER_PATH:
7511 *path = talloc_asprintf(mem_ctx,
7514 spoolss_paths[component].share,
7517 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7518 SPOOLSS_DEFAULT_SERVER_PATH,
7519 spoolss_paths[component].dir,
7524 return WERR_INVALID_PARAM;
7534 /****************************************************************************
7535 ****************************************************************************/
7537 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7538 const char *servername,
7539 const char *environment,
7540 struct spoolss_DriverDirectoryInfo1 *r)
7545 werr = compose_spoolss_server_path(mem_ctx,
7548 SPOOLSS_DRIVER_PATH,
7550 if (!W_ERROR_IS_OK(werr)) {
7554 DEBUG(4,("printer driver directory: [%s]\n", path));
7556 r->directory_name = path;
7561 /****************************************************************
7562 _spoolss_GetPrinterDriverDirectory
7563 ****************************************************************/
7565 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7566 struct spoolss_GetPrinterDriverDirectory *r)
7570 /* that's an [in out] buffer */
7572 if (!r->in.buffer && (r->in.offered != 0)) {
7573 return WERR_INVALID_PARAM;
7576 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7581 /* r->in.level is ignored */
7583 werror = getprinterdriverdir_level_1(p->mem_ctx,
7586 &r->out.info->info1);
7587 if (!W_ERROR_IS_OK(werror)) {
7588 TALLOC_FREE(r->out.info);
7592 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7593 r->out.info, r->in.level);
7594 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7596 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7599 /****************************************************************
7600 _spoolss_EnumPrinterData
7601 ****************************************************************/
7603 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7604 struct spoolss_EnumPrinterData *r)
7607 struct spoolss_EnumPrinterDataEx r2;
7609 struct spoolss_PrinterEnumValues *info, *val = NULL;
7612 r2.in.handle = r->in.handle;
7613 r2.in.key_name = "PrinterDriverData";
7615 r2.out.count = &count;
7616 r2.out.info = &info;
7617 r2.out.needed = &needed;
7619 result = _spoolss_EnumPrinterDataEx(p, &r2);
7620 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7621 r2.in.offered = needed;
7622 result = _spoolss_EnumPrinterDataEx(p, &r2);
7624 if (!W_ERROR_IS_OK(result)) {
7629 * The NT machine wants to know the biggest size of value and data
7631 * cf: MSDN EnumPrinterData remark section
7634 if (!r->in.value_offered && !r->in.data_offered) {
7635 uint32_t biggest_valuesize = 0;
7636 uint32_t biggest_datasize = 0;
7639 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7641 for (i=0; i<count; i++) {
7643 name_length = strlen(info[i].value_name);
7644 if (strlen(info[i].value_name) > biggest_valuesize) {
7645 biggest_valuesize = name_length;
7648 if (info[i].data_length > biggest_datasize) {
7649 biggest_datasize = info[i].data_length;
7652 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7656 /* the value is an UNICODE string but real_value_size is the length
7657 in bytes including the trailing 0 */
7659 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7660 *r->out.data_needed = biggest_datasize;
7662 DEBUG(6,("final values: [%d], [%d]\n",
7663 *r->out.value_needed, *r->out.data_needed));
7668 if (r->in.enum_index < count) {
7669 val = &info[r->in.enum_index];
7673 /* out_value should default to "" or else NT4 has
7674 problems unmarshalling the response */
7676 if (r->in.value_offered) {
7677 *r->out.value_needed = 1;
7678 r->out.value_name = talloc_strdup(r, "");
7679 if (!r->out.value_name) {
7683 r->out.value_name = NULL;
7684 *r->out.value_needed = 0;
7687 /* the data is counted in bytes */
7689 *r->out.data_needed = r->in.data_offered;
7691 result = WERR_NO_MORE_ITEMS;
7695 * - counted in bytes in the request
7696 * - counted in UNICODE chars in the max reply
7697 * - counted in bytes in the real size
7699 * take a pause *before* coding not *during* coding
7703 if (r->in.value_offered) {
7704 r->out.value_name = talloc_strdup(r, val->value_name);
7705 if (!r->out.value_name) {
7708 *r->out.value_needed = val->value_name_len;
7710 r->out.value_name = NULL;
7711 *r->out.value_needed = 0;
7716 *r->out.type = val->type;
7718 /* data - counted in bytes */
7721 * See the section "Dynamically Typed Query Parameters"
7725 if (r->out.data && val->data && val->data->data &&
7726 val->data_length && r->in.data_offered) {
7727 memcpy(r->out.data, val->data->data,
7728 MIN(val->data_length,r->in.data_offered));
7731 *r->out.data_needed = val->data_length;
7739 /****************************************************************
7740 _spoolss_SetPrinterData
7741 ****************************************************************/
7743 WERROR _spoolss_SetPrinterData(pipes_struct *p,
7744 struct spoolss_SetPrinterData *r)
7746 struct spoolss_SetPrinterDataEx r2;
7748 r2.in.handle = r->in.handle;
7749 r2.in.key_name = "PrinterDriverData";
7750 r2.in.value_name = r->in.value_name;
7751 r2.in.type = r->in.type;
7752 r2.in.data = r->in.data;
7753 r2.in.offered = r->in.offered;
7755 return _spoolss_SetPrinterDataEx(p, &r2);
7758 /****************************************************************
7759 _spoolss_ResetPrinter
7760 ****************************************************************/
7762 WERROR _spoolss_ResetPrinter(pipes_struct *p,
7763 struct spoolss_ResetPrinter *r)
7765 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7768 DEBUG(5,("_spoolss_ResetPrinter\n"));
7771 * All we do is to check to see if the handle and queue is valid.
7772 * This call really doesn't mean anything to us because we only
7773 * support RAW printing. --jerry
7777 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7778 OUR_HANDLE(r->in.handle)));
7782 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7786 /* blindly return success */
7790 /****************************************************************
7791 _spoolss_DeletePrinterData
7792 ****************************************************************/
7794 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7795 struct spoolss_DeletePrinterData *r)
7797 struct spoolss_DeletePrinterDataEx r2;
7799 r2.in.handle = r->in.handle;
7800 r2.in.key_name = "PrinterDriverData";
7801 r2.in.value_name = r->in.value_name;
7803 return _spoolss_DeletePrinterDataEx(p, &r2);
7806 /****************************************************************
7808 ****************************************************************/
7810 WERROR _spoolss_AddForm(pipes_struct *p,
7811 struct spoolss_AddForm *r)
7813 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7815 WERROR status = WERR_OK;
7816 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7818 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7820 DEBUG(5,("_spoolss_AddForm\n"));
7823 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7824 OUR_HANDLE(r->in.handle)));
7828 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7829 and not a printer admin, then fail */
7831 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7832 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7833 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7834 p->server_info->info3->base.domain.string,
7836 p->server_info->ptok,
7837 lp_printer_admin(snum))) {
7838 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7839 return WERR_ACCESS_DENIED;
7842 switch (form->flags) {
7843 case SPOOLSS_FORM_USER:
7844 case SPOOLSS_FORM_BUILTIN:
7845 case SPOOLSS_FORM_PRINTER:
7848 return WERR_INVALID_PARAM;
7851 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7852 if (!W_ERROR_IS_OK(status)) {
7857 * ChangeID must always be set if this is a printer
7859 if (Printer->printer_type == SPLHND_PRINTER) {
7860 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7864 status = winreg_printer_update_changeid(p->mem_ctx,
7866 lp_const_servicename(snum));
7867 if (!W_ERROR_IS_OK(status)) {
7875 /****************************************************************
7877 ****************************************************************/
7879 WERROR _spoolss_DeleteForm(pipes_struct *p,
7880 struct spoolss_DeleteForm *r)
7882 const char *form_name = r->in.form_name;
7883 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7885 WERROR status = WERR_OK;
7886 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7888 DEBUG(5,("_spoolss_DeleteForm\n"));
7891 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7892 OUR_HANDLE(r->in.handle)));
7896 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7897 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7898 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7899 p->server_info->info3->base.domain.string,
7901 p->server_info->ptok,
7902 lp_printer_admin(snum))) {
7903 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7904 return WERR_ACCESS_DENIED;
7907 status = winreg_printer_deleteform1(p->mem_ctx,
7910 if (!W_ERROR_IS_OK(status)) {
7915 * ChangeID must always be set if this is a printer
7917 if (Printer->printer_type == SPLHND_PRINTER) {
7918 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7922 status = winreg_printer_update_changeid(p->mem_ctx,
7924 lp_const_servicename(snum));
7925 if (!W_ERROR_IS_OK(status)) {
7933 /****************************************************************
7935 ****************************************************************/
7937 WERROR _spoolss_SetForm(pipes_struct *p,
7938 struct spoolss_SetForm *r)
7940 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7941 const char *form_name = r->in.form_name;
7943 WERROR status = WERR_OK;
7944 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7946 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7948 DEBUG(5,("_spoolss_SetForm\n"));
7951 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7952 OUR_HANDLE(r->in.handle)));
7956 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7957 and not a printer admin, then fail */
7959 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7960 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7961 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7962 p->server_info->info3->base.domain.string,
7964 p->server_info->ptok,
7965 lp_printer_admin(snum))) {
7966 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7967 return WERR_ACCESS_DENIED;
7970 status = winreg_printer_setform1(p->mem_ctx,
7974 if (!W_ERROR_IS_OK(status)) {
7979 * ChangeID must always be set if this is a printer
7981 if (Printer->printer_type == SPLHND_PRINTER) {
7982 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7986 status = winreg_printer_update_changeid(p->mem_ctx,
7988 lp_const_servicename(snum));
7989 if (!W_ERROR_IS_OK(status)) {
7997 /****************************************************************************
7998 fill_print_processor1
7999 ****************************************************************************/
8001 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8002 struct spoolss_PrintProcessorInfo1 *r,
8003 const char *print_processor_name)
8005 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8006 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8011 /****************************************************************************
8012 enumprintprocessors level 1.
8013 ****************************************************************************/
8015 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8016 union spoolss_PrintProcessorInfo **info_p,
8019 union spoolss_PrintProcessorInfo *info;
8022 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8023 W_ERROR_HAVE_NO_MEMORY(info);
8027 result = fill_print_processor1(info, &info[0].info1, "winprint");
8028 if (!W_ERROR_IS_OK(result)) {
8033 if (!W_ERROR_IS_OK(result)) {
8044 /****************************************************************
8045 _spoolss_EnumPrintProcessors
8046 ****************************************************************/
8048 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8049 struct spoolss_EnumPrintProcessors *r)
8053 /* that's an [in out] buffer */
8055 if (!r->in.buffer && (r->in.offered != 0)) {
8056 return WERR_INVALID_PARAM;
8059 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8062 * Enumerate the print processors ...
8064 * Just reply with "winprint", to keep NT happy
8065 * and I can use my nice printer checker.
8070 *r->out.info = NULL;
8072 switch (r->in.level) {
8074 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8078 return WERR_UNKNOWN_LEVEL;
8081 if (!W_ERROR_IS_OK(result)) {
8085 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8086 spoolss_EnumPrintProcessors,
8087 *r->out.info, r->in.level,
8089 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8090 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8092 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8095 /****************************************************************************
8096 fill_printprocdatatype1
8097 ****************************************************************************/
8099 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8100 struct spoolss_PrintProcDataTypesInfo1 *r,
8101 const char *name_array)
8103 r->name_array = talloc_strdup(mem_ctx, name_array);
8104 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8109 /****************************************************************************
8110 enumprintprocdatatypes level 1.
8111 ****************************************************************************/
8113 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8114 union spoolss_PrintProcDataTypesInfo **info_p,
8118 union spoolss_PrintProcDataTypesInfo *info;
8120 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8121 W_ERROR_HAVE_NO_MEMORY(info);
8125 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8126 if (!W_ERROR_IS_OK(result)) {
8131 if (!W_ERROR_IS_OK(result)) {
8142 /****************************************************************
8143 _spoolss_EnumPrintProcDataTypes
8144 ****************************************************************/
8146 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8147 struct spoolss_EnumPrintProcDataTypes *r)
8151 /* that's an [in out] buffer */
8153 if (!r->in.buffer && (r->in.offered != 0)) {
8154 return WERR_INVALID_PARAM;
8157 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8161 *r->out.info = NULL;
8163 switch (r->in.level) {
8165 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8169 return WERR_UNKNOWN_LEVEL;
8172 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8173 spoolss_EnumPrintProcDataTypes,
8174 *r->out.info, r->in.level,
8176 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8177 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8179 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8182 /****************************************************************************
8184 ****************************************************************************/
8186 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8187 struct spoolss_MonitorInfo1 *r,
8188 const char *monitor_name)
8190 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8191 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8196 /****************************************************************************
8198 ****************************************************************************/
8200 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8201 struct spoolss_MonitorInfo2 *r,
8202 const char *monitor_name,
8203 const char *environment,
8204 const char *dll_name)
8206 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8207 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8208 r->environment = talloc_strdup(mem_ctx, environment);
8209 W_ERROR_HAVE_NO_MEMORY(r->environment);
8210 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8211 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8216 /****************************************************************************
8217 enumprintmonitors level 1.
8218 ****************************************************************************/
8220 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8221 union spoolss_MonitorInfo **info_p,
8224 union spoolss_MonitorInfo *info;
8225 WERROR result = WERR_OK;
8227 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8228 W_ERROR_HAVE_NO_MEMORY(info);
8232 result = fill_monitor_1(info, &info[0].info1,
8234 if (!W_ERROR_IS_OK(result)) {
8238 result = fill_monitor_1(info, &info[1].info1,
8240 if (!W_ERROR_IS_OK(result)) {
8245 if (!W_ERROR_IS_OK(result)) {
8256 /****************************************************************************
8257 enumprintmonitors level 2.
8258 ****************************************************************************/
8260 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8261 union spoolss_MonitorInfo **info_p,
8264 union spoolss_MonitorInfo *info;
8265 WERROR result = WERR_OK;
8267 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8268 W_ERROR_HAVE_NO_MEMORY(info);
8272 result = fill_monitor_2(info, &info[0].info2,
8274 "Windows NT X86", /* FIXME */
8276 if (!W_ERROR_IS_OK(result)) {
8280 result = fill_monitor_2(info, &info[1].info2,
8282 "Windows NT X86", /* FIXME */
8284 if (!W_ERROR_IS_OK(result)) {
8289 if (!W_ERROR_IS_OK(result)) {
8300 /****************************************************************
8301 _spoolss_EnumMonitors
8302 ****************************************************************/
8304 WERROR _spoolss_EnumMonitors(pipes_struct *p,
8305 struct spoolss_EnumMonitors *r)
8309 /* that's an [in out] buffer */
8311 if (!r->in.buffer && (r->in.offered != 0)) {
8312 return WERR_INVALID_PARAM;
8315 DEBUG(5,("_spoolss_EnumMonitors\n"));
8318 * Enumerate the print monitors ...
8320 * Just reply with "Local Port", to keep NT happy
8321 * and I can use my nice printer checker.
8326 *r->out.info = NULL;
8328 switch (r->in.level) {
8330 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8334 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8338 return WERR_UNKNOWN_LEVEL;
8341 if (!W_ERROR_IS_OK(result)) {
8345 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8346 spoolss_EnumMonitors,
8347 *r->out.info, r->in.level,
8349 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8350 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8352 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8355 /****************************************************************************
8356 ****************************************************************************/
8358 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8359 const print_queue_struct *queue,
8360 int count, int snum,
8361 struct spoolss_PrinterInfo2 *pinfo2,
8363 struct spoolss_JobInfo1 *r)
8368 for (i=0; i<count; i++) {
8369 if (queue[i].job == (int)jobid) {
8375 if (found == false) {
8376 /* NT treats not found as bad param... yet another bad choice */
8377 return WERR_INVALID_PARAM;
8380 return fill_job_info1(mem_ctx,
8388 /****************************************************************************
8389 ****************************************************************************/
8391 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8392 const print_queue_struct *queue,
8393 int count, int snum,
8394 struct spoolss_PrinterInfo2 *pinfo2,
8396 struct spoolss_JobInfo2 *r)
8400 struct spoolss_DeviceMode *devmode;
8403 for (i=0; i<count; i++) {
8404 if (queue[i].job == (int)jobid) {
8410 if (found == false) {
8411 /* NT treats not found as bad param... yet another bad
8413 return WERR_INVALID_PARAM;
8417 * if the print job does not have a DEVMODE associated with it,
8418 * just use the one for the printer. A NULL devicemode is not
8419 * a failure condition
8422 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8424 result = spoolss_create_default_devmode(mem_ctx,
8425 pinfo2->printername,
8427 if (!W_ERROR_IS_OK(result)) {
8428 DEBUG(3, ("Can't proceed w/o a devmode!"));
8433 return fill_job_info2(mem_ctx,
8442 /****************************************************************
8444 ****************************************************************/
8446 WERROR _spoolss_GetJob(pipes_struct *p,
8447 struct spoolss_GetJob *r)
8449 WERROR result = WERR_OK;
8450 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8453 print_queue_struct *queue = NULL;
8454 print_status_struct prt_status;
8456 /* that's an [in out] buffer */
8458 if (!r->in.buffer && (r->in.offered != 0)) {
8459 return WERR_INVALID_PARAM;
8462 DEBUG(5,("_spoolss_GetJob\n"));
8466 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8470 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8471 lp_servicename(snum), &pinfo2);
8472 if (!W_ERROR_IS_OK(result)) {
8476 count = print_queue_status(snum, &queue, &prt_status);
8478 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8479 count, prt_status.status, prt_status.message));
8481 switch (r->in.level) {
8483 result = getjob_level_1(p->mem_ctx,
8484 queue, count, snum, pinfo2,
8485 r->in.job_id, &r->out.info->info1);
8488 result = getjob_level_2(p->mem_ctx,
8489 queue, count, snum, pinfo2,
8490 r->in.job_id, &r->out.info->info2);
8493 result = WERR_UNKNOWN_LEVEL;
8498 TALLOC_FREE(pinfo2);
8500 if (!W_ERROR_IS_OK(result)) {
8501 TALLOC_FREE(r->out.info);
8505 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8507 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8509 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8512 /****************************************************************
8513 _spoolss_GetPrinterDataEx
8514 ****************************************************************/
8516 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8517 struct spoolss_GetPrinterDataEx *r)
8520 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8521 const char *printer;
8523 WERROR result = WERR_OK;
8525 enum winreg_Type val_type;
8530 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8532 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8533 r->in.key_name, r->in.value_name));
8535 /* in case of problem, return some default values */
8538 *r->out.type = REG_NONE;
8541 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8542 OUR_HANDLE(r->in.handle)));
8543 result = WERR_BADFID;
8547 /* Is the handle to a printer or to the server? */
8549 if (Printer->printer_type == SPLHND_SERVER) {
8551 union spoolss_PrinterData data;
8553 result = getprinterdata_printer_server(p->mem_ctx,
8557 if (!W_ERROR_IS_OK(result)) {
8561 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8562 *r->out.type, &data);
8563 if (!W_ERROR_IS_OK(result)) {
8567 *r->out.needed = blob.length;
8569 if (r->in.offered >= *r->out.needed) {
8570 memcpy(r->out.data, blob.data, blob.length);
8573 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8576 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8579 printer = lp_const_servicename(snum);
8581 /* check to see if the keyname is valid */
8582 if (!strlen(r->in.key_name)) {
8583 return WERR_INVALID_PARAM;
8586 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8587 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8588 strequal(r->in.value_name, "ChangeId")) {
8589 *r->out.type = REG_DWORD;
8591 if (r->in.offered >= *r->out.needed) {
8592 uint32_t changeid = 0;
8594 result = winreg_printer_get_changeid(p->mem_ctx,
8598 if (!W_ERROR_IS_OK(result)) {
8602 SIVAL(r->out.data, 0, changeid);
8608 result = winreg_get_printer_dataex(p->mem_ctx,
8616 if (!W_ERROR_IS_OK(result)) {
8620 *r->out.needed = val_size;
8621 *r->out.type = val_type;
8623 if (r->in.offered >= *r->out.needed) {
8624 memcpy(r->out.data, val_data, val_size);
8628 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8629 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8631 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8634 /****************************************************************
8635 _spoolss_SetPrinterDataEx
8636 ****************************************************************/
8638 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8639 struct spoolss_SetPrinterDataEx *r)
8641 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8643 WERROR result = WERR_OK;
8644 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8647 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8649 /* From MSDN documentation of SetPrinterDataEx: pass request to
8650 SetPrinterData if key is "PrinterDriverData" */
8653 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8654 OUR_HANDLE(r->in.handle)));
8658 if (Printer->printer_type == SPLHND_SERVER) {
8659 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8660 "Not implemented for server handles yet\n"));
8661 return WERR_INVALID_PARAM;
8664 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8669 * Access check : NT returns "access denied" if you make a
8670 * SetPrinterData call without the necessary privildge.
8671 * we were originally returning OK if nothing changed
8672 * which made Win2k issue **a lot** of SetPrinterData
8673 * when connecting to a printer --jerry
8676 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8677 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8678 "change denied by handle access permissions\n"));
8679 return WERR_ACCESS_DENIED;
8682 result = winreg_get_printer(Printer, p->server_info,
8683 Printer->servername,
8684 lp_servicename(snum),
8686 if (!W_ERROR_IS_OK(result)) {
8690 /* check for OID in valuename */
8692 oid_string = strchr(r->in.value_name, ',');
8698 /* save the registry data */
8700 result = winreg_set_printer_dataex(p->mem_ctx,
8709 if (W_ERROR_IS_OK(result)) {
8710 /* save the OID if one was specified */
8712 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8713 r->in.key_name, SPOOL_OID_KEY);
8715 result = WERR_NOMEM;
8720 * I'm not checking the status here on purpose. Don't know
8721 * if this is right, but I'm returning the status from the
8722 * previous set_printer_dataex() call. I have no idea if
8723 * this is right. --jerry
8725 winreg_set_printer_dataex(p->mem_ctx,
8731 (uint8_t *) oid_string,
8732 strlen(oid_string) + 1);
8735 result = winreg_printer_update_changeid(p->mem_ctx,
8737 lp_const_servicename(snum));
8742 talloc_free(pinfo2);
8746 /****************************************************************
8747 _spoolss_DeletePrinterDataEx
8748 ****************************************************************/
8750 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8751 struct spoolss_DeletePrinterDataEx *r)
8753 const char *printer;
8755 WERROR status = WERR_OK;
8756 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8758 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8761 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8762 "Invalid handle (%s:%u:%u).\n",
8763 OUR_HANDLE(r->in.handle)));
8767 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8768 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8769 "printer properties change denied by handle\n"));
8770 return WERR_ACCESS_DENIED;
8773 if (!r->in.value_name || !r->in.key_name) {
8777 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8780 printer = lp_const_servicename(snum);
8782 status = winreg_delete_printer_dataex(p->mem_ctx,
8787 if (W_ERROR_IS_OK(status)) {
8788 status = winreg_printer_update_changeid(p->mem_ctx,
8796 /****************************************************************
8797 _spoolss_EnumPrinterKey
8798 ****************************************************************/
8800 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
8801 struct spoolss_EnumPrinterKey *r)
8804 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8806 WERROR result = WERR_BADFILE;
8807 const char **array = NULL;
8810 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8813 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8814 OUR_HANDLE(r->in.handle)));
8818 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8822 result = winreg_enum_printer_key(p->mem_ctx,
8824 lp_const_servicename(snum),
8828 if (!W_ERROR_IS_OK(result)) {
8832 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8833 result = WERR_NOMEM;
8837 *r->out._ndr_size = r->in.offered / 2;
8838 *r->out.needed = blob.length;
8840 if (r->in.offered < *r->out.needed) {
8841 result = WERR_MORE_DATA;
8844 r->out.key_buffer->string_array = array;
8848 if (!W_ERROR_IS_OK(result)) {
8850 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8858 /****************************************************************
8859 _spoolss_DeletePrinterKey
8860 ****************************************************************/
8862 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
8863 struct spoolss_DeletePrinterKey *r)
8865 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8868 const char *printer;
8870 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8873 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8874 OUR_HANDLE(r->in.handle)));
8878 /* if keyname == NULL, return error */
8879 if ( !r->in.key_name )
8880 return WERR_INVALID_PARAM;
8882 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8886 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8887 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8888 "printer properties change denied by handle\n"));
8889 return WERR_ACCESS_DENIED;
8892 printer = lp_const_servicename(snum);
8894 /* delete the key and all subkeys */
8895 status = winreg_delete_printer_key(p->mem_ctx,
8899 if (W_ERROR_IS_OK(status)) {
8900 status = winreg_printer_update_changeid(p->mem_ctx,
8908 /****************************************************************
8909 _spoolss_EnumPrinterDataEx
8910 ****************************************************************/
8912 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
8913 struct spoolss_EnumPrinterDataEx *r)
8916 struct spoolss_PrinterEnumValues *info = NULL;
8917 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8921 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8925 *r->out.info = NULL;
8928 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8929 OUR_HANDLE(r->in.handle)));
8934 * first check for a keyname of NULL or "". Win2k seems to send
8935 * this a lot and we should send back WERR_INVALID_PARAM
8936 * no need to spend time looking up the printer in this case.
8940 if (!strlen(r->in.key_name)) {
8941 result = WERR_INVALID_PARAM;
8945 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8949 /* now look for a match on the key name */
8950 result = winreg_enum_printer_dataex(p->mem_ctx,
8952 lp_const_servicename(snum),
8956 if (!W_ERROR_IS_OK(result)) {
8960 #if 0 /* FIXME - gd */
8961 /* housekeeping information in the reply */
8963 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8964 * the hand marshalled container size is a multiple
8965 * of 4 bytes for RPC alignment.
8969 needed += 4-(needed % 4);
8972 *r->out.count = count;
8973 *r->out.info = info;
8976 if (!W_ERROR_IS_OK(result)) {
8980 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
8981 spoolss_EnumPrinterDataEx,
8984 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8985 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
8987 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8990 /****************************************************************************
8991 ****************************************************************************/
8993 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
8994 const char *servername,
8995 const char *environment,
8996 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9001 werr = compose_spoolss_server_path(mem_ctx,
9004 SPOOLSS_PRTPROCS_PATH,
9006 if (!W_ERROR_IS_OK(werr)) {
9010 DEBUG(4,("print processor directory: [%s]\n", path));
9012 r->directory_name = path;
9017 /****************************************************************
9018 _spoolss_GetPrintProcessorDirectory
9019 ****************************************************************/
9021 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9022 struct spoolss_GetPrintProcessorDirectory *r)
9026 /* that's an [in out] buffer */
9028 if (!r->in.buffer && (r->in.offered != 0)) {
9029 return WERR_INVALID_PARAM;
9032 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9037 /* r->in.level is ignored */
9039 /* We always should reply with a local print processor directory so that
9040 * users are not forced to have a [prnproc$] share on the Samba spoolss
9041 * server - Guenther */
9043 result = getprintprocessordirectory_level_1(p->mem_ctx,
9044 NULL, /* r->in.server */
9046 &r->out.info->info1);
9047 if (!W_ERROR_IS_OK(result)) {
9048 TALLOC_FREE(r->out.info);
9052 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9053 r->out.info, r->in.level);
9054 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9056 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9059 /*******************************************************************
9060 ********************************************************************/
9062 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9063 const char *dllname)
9065 enum ndr_err_code ndr_err;
9066 struct spoolss_MonitorUi ui;
9068 ui.dll_name = dllname;
9070 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9071 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9072 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9073 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9075 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9078 /*******************************************************************
9079 Streams the monitor UI DLL name in UNICODE
9080 *******************************************************************/
9082 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9083 NT_USER_TOKEN *token, DATA_BLOB *in,
9084 DATA_BLOB *out, uint32_t *needed)
9086 const char *dllname = "tcpmonui.dll";
9088 *needed = (strlen(dllname)+1) * 2;
9090 if (out->length < *needed) {
9091 return WERR_INSUFFICIENT_BUFFER;
9094 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9101 /*******************************************************************
9102 ********************************************************************/
9104 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9105 struct spoolss_PortData1 *port1,
9106 const DATA_BLOB *buf)
9108 enum ndr_err_code ndr_err;
9109 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9110 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9111 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9112 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9114 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9117 /*******************************************************************
9118 ********************************************************************/
9120 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9121 struct spoolss_PortData2 *port2,
9122 const DATA_BLOB *buf)
9124 enum ndr_err_code ndr_err;
9125 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9126 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9127 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9128 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9130 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9133 /*******************************************************************
9134 Create a new TCP/IP port
9135 *******************************************************************/
9137 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9138 NT_USER_TOKEN *token, DATA_BLOB *in,
9139 DATA_BLOB *out, uint32_t *needed)
9141 struct spoolss_PortData1 port1;
9142 struct spoolss_PortData2 port2;
9143 char *device_uri = NULL;
9146 const char *portname;
9147 const char *hostaddress;
9149 uint32_t port_number;
9152 /* peek for spoolss_PortData version */
9154 if (!in || (in->length < (128 + 4))) {
9155 return WERR_GENERAL_FAILURE;
9158 version = IVAL(in->data, 128);
9164 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9168 portname = port1.portname;
9169 hostaddress = port1.hostaddress;
9170 queue = port1.queue;
9171 protocol = port1.protocol;
9172 port_number = port1.port_number;
9178 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9182 portname = port2.portname;
9183 hostaddress = port2.hostaddress;
9184 queue = port2.queue;
9185 protocol = port2.protocol;
9186 port_number = port2.port_number;
9190 DEBUG(1,("xcvtcp_addport: "
9191 "unknown version of port_data: %d\n", version));
9192 return WERR_UNKNOWN_PORT;
9195 /* create the device URI and call the add_port_hook() */
9198 case PROTOCOL_RAWTCP_TYPE:
9199 device_uri = talloc_asprintf(mem_ctx,
9200 "socket://%s:%d/", hostaddress,
9204 case PROTOCOL_LPR_TYPE:
9205 device_uri = talloc_asprintf(mem_ctx,
9206 "lpr://%s/%s", hostaddress, queue );
9210 return WERR_UNKNOWN_PORT;
9217 return add_port_hook(mem_ctx, token, portname, device_uri);
9220 /*******************************************************************
9221 *******************************************************************/
9223 struct xcv_api_table xcvtcp_cmds[] = {
9224 { "MonitorUI", xcvtcp_monitorui },
9225 { "AddPort", xcvtcp_addport},
9229 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9230 NT_USER_TOKEN *token, const char *command,
9237 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9239 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9240 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9241 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9244 return WERR_BADFUNC;
9247 /*******************************************************************
9248 *******************************************************************/
9249 #if 0 /* don't support management using the "Local Port" monitor */
9251 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9252 NT_USER_TOKEN *token, DATA_BLOB *in,
9253 DATA_BLOB *out, uint32_t *needed)
9255 const char *dllname = "localui.dll";
9257 *needed = (strlen(dllname)+1) * 2;
9259 if (out->length < *needed) {
9260 return WERR_INSUFFICIENT_BUFFER;
9263 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9270 /*******************************************************************
9271 *******************************************************************/
9273 struct xcv_api_table xcvlocal_cmds[] = {
9274 { "MonitorUI", xcvlocal_monitorui },
9278 struct xcv_api_table xcvlocal_cmds[] = {
9285 /*******************************************************************
9286 *******************************************************************/
9288 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9289 NT_USER_TOKEN *token, const char *command,
9290 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9295 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9297 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9298 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9299 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9301 return WERR_BADFUNC;
9304 /****************************************************************
9306 ****************************************************************/
9308 WERROR _spoolss_XcvData(pipes_struct *p,
9309 struct spoolss_XcvData *r)
9311 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9312 DATA_BLOB out_data = data_blob_null;
9316 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9317 OUR_HANDLE(r->in.handle)));
9321 /* Has to be a handle to the TCP/IP port monitor */
9323 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9324 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9328 /* requires administrative access to the server */
9330 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9331 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9332 return WERR_ACCESS_DENIED;
9335 /* Allocate the outgoing buffer */
9337 if (r->in.out_data_size) {
9338 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9339 if (out_data.data == NULL) {
9344 switch ( Printer->printer_type ) {
9345 case SPLHND_PORTMON_TCP:
9346 werror = process_xcvtcp_command(p->mem_ctx,
9347 p->server_info->ptok,
9348 r->in.function_name,
9349 &r->in.in_data, &out_data,
9352 case SPLHND_PORTMON_LOCAL:
9353 werror = process_xcvlocal_command(p->mem_ctx,
9354 p->server_info->ptok,
9355 r->in.function_name,
9356 &r->in.in_data, &out_data,
9360 werror = WERR_INVALID_PRINT_MONITOR;
9363 if (!W_ERROR_IS_OK(werror)) {
9367 *r->out.status_code = 0;
9369 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9370 memcpy(r->out.out_data, out_data.data,
9371 MIN(r->in.out_data_size, out_data.length));
9377 /****************************************************************
9378 _spoolss_AddPrintProcessor
9379 ****************************************************************/
9381 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9382 struct spoolss_AddPrintProcessor *r)
9384 /* for now, just indicate success and ignore the add. We'll
9385 automatically set the winprint processor for printer
9386 entries later. Used to debug the LexMark Optra S 1855 PCL
9392 /****************************************************************
9394 ****************************************************************/
9396 WERROR _spoolss_AddPort(pipes_struct *p,
9397 struct spoolss_AddPort *r)
9399 /* do what w2k3 does */
9401 return WERR_NOT_SUPPORTED;
9404 /****************************************************************
9405 _spoolss_GetPrinterDriver
9406 ****************************************************************/
9408 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9409 struct spoolss_GetPrinterDriver *r)
9411 p->rng_fault_state = true;
9412 return WERR_NOT_SUPPORTED;
9415 /****************************************************************
9416 _spoolss_ReadPrinter
9417 ****************************************************************/
9419 WERROR _spoolss_ReadPrinter(pipes_struct *p,
9420 struct spoolss_ReadPrinter *r)
9422 p->rng_fault_state = true;
9423 return WERR_NOT_SUPPORTED;
9426 /****************************************************************
9427 _spoolss_WaitForPrinterChange
9428 ****************************************************************/
9430 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9431 struct spoolss_WaitForPrinterChange *r)
9433 p->rng_fault_state = true;
9434 return WERR_NOT_SUPPORTED;
9437 /****************************************************************
9438 _spoolss_ConfigurePort
9439 ****************************************************************/
9441 WERROR _spoolss_ConfigurePort(pipes_struct *p,
9442 struct spoolss_ConfigurePort *r)
9444 p->rng_fault_state = true;
9445 return WERR_NOT_SUPPORTED;
9448 /****************************************************************
9450 ****************************************************************/
9452 WERROR _spoolss_DeletePort(pipes_struct *p,
9453 struct spoolss_DeletePort *r)
9455 p->rng_fault_state = true;
9456 return WERR_NOT_SUPPORTED;
9459 /****************************************************************
9460 _spoolss_CreatePrinterIC
9461 ****************************************************************/
9463 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9464 struct spoolss_CreatePrinterIC *r)
9466 p->rng_fault_state = true;
9467 return WERR_NOT_SUPPORTED;
9470 /****************************************************************
9471 _spoolss_PlayGDIScriptOnPrinterIC
9472 ****************************************************************/
9474 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9475 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9477 p->rng_fault_state = true;
9478 return WERR_NOT_SUPPORTED;
9481 /****************************************************************
9482 _spoolss_DeletePrinterIC
9483 ****************************************************************/
9485 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9486 struct spoolss_DeletePrinterIC *r)
9488 p->rng_fault_state = true;
9489 return WERR_NOT_SUPPORTED;
9492 /****************************************************************
9493 _spoolss_AddPrinterConnection
9494 ****************************************************************/
9496 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9497 struct spoolss_AddPrinterConnection *r)
9499 p->rng_fault_state = true;
9500 return WERR_NOT_SUPPORTED;
9503 /****************************************************************
9504 _spoolss_DeletePrinterConnection
9505 ****************************************************************/
9507 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9508 struct spoolss_DeletePrinterConnection *r)
9510 p->rng_fault_state = true;
9511 return WERR_NOT_SUPPORTED;
9514 /****************************************************************
9515 _spoolss_PrinterMessageBox
9516 ****************************************************************/
9518 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9519 struct spoolss_PrinterMessageBox *r)
9521 p->rng_fault_state = true;
9522 return WERR_NOT_SUPPORTED;
9525 /****************************************************************
9527 ****************************************************************/
9529 WERROR _spoolss_AddMonitor(pipes_struct *p,
9530 struct spoolss_AddMonitor *r)
9532 p->rng_fault_state = true;
9533 return WERR_NOT_SUPPORTED;
9536 /****************************************************************
9537 _spoolss_DeleteMonitor
9538 ****************************************************************/
9540 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9541 struct spoolss_DeleteMonitor *r)
9543 p->rng_fault_state = true;
9544 return WERR_NOT_SUPPORTED;
9547 /****************************************************************
9548 _spoolss_DeletePrintProcessor
9549 ****************************************************************/
9551 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9552 struct spoolss_DeletePrintProcessor *r)
9554 p->rng_fault_state = true;
9555 return WERR_NOT_SUPPORTED;
9558 /****************************************************************
9559 _spoolss_AddPrintProvidor
9560 ****************************************************************/
9562 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9563 struct spoolss_AddPrintProvidor *r)
9565 p->rng_fault_state = true;
9566 return WERR_NOT_SUPPORTED;
9569 /****************************************************************
9570 _spoolss_DeletePrintProvidor
9571 ****************************************************************/
9573 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9574 struct spoolss_DeletePrintProvidor *r)
9576 p->rng_fault_state = true;
9577 return WERR_NOT_SUPPORTED;
9580 /****************************************************************
9581 _spoolss_FindFirstPrinterChangeNotification
9582 ****************************************************************/
9584 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9585 struct spoolss_FindFirstPrinterChangeNotification *r)
9587 p->rng_fault_state = true;
9588 return WERR_NOT_SUPPORTED;
9591 /****************************************************************
9592 _spoolss_FindNextPrinterChangeNotification
9593 ****************************************************************/
9595 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9596 struct spoolss_FindNextPrinterChangeNotification *r)
9598 p->rng_fault_state = true;
9599 return WERR_NOT_SUPPORTED;
9602 /****************************************************************
9603 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9604 ****************************************************************/
9606 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9607 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9609 p->rng_fault_state = true;
9610 return WERR_NOT_SUPPORTED;
9613 /****************************************************************
9614 _spoolss_ReplyOpenPrinter
9615 ****************************************************************/
9617 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9618 struct spoolss_ReplyOpenPrinter *r)
9620 p->rng_fault_state = true;
9621 return WERR_NOT_SUPPORTED;
9624 /****************************************************************
9625 _spoolss_RouterReplyPrinter
9626 ****************************************************************/
9628 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9629 struct spoolss_RouterReplyPrinter *r)
9631 p->rng_fault_state = true;
9632 return WERR_NOT_SUPPORTED;
9635 /****************************************************************
9636 _spoolss_ReplyClosePrinter
9637 ****************************************************************/
9639 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9640 struct spoolss_ReplyClosePrinter *r)
9642 p->rng_fault_state = true;
9643 return WERR_NOT_SUPPORTED;
9646 /****************************************************************
9648 ****************************************************************/
9650 WERROR _spoolss_AddPortEx(pipes_struct *p,
9651 struct spoolss_AddPortEx *r)
9653 p->rng_fault_state = true;
9654 return WERR_NOT_SUPPORTED;
9657 /****************************************************************
9658 _spoolss_RouterFindFirstPrinterChangeNotification
9659 ****************************************************************/
9661 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9662 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9664 p->rng_fault_state = true;
9665 return WERR_NOT_SUPPORTED;
9668 /****************************************************************
9669 _spoolss_SpoolerInit
9670 ****************************************************************/
9672 WERROR _spoolss_SpoolerInit(pipes_struct *p,
9673 struct spoolss_SpoolerInit *r)
9675 p->rng_fault_state = true;
9676 return WERR_NOT_SUPPORTED;
9679 /****************************************************************
9680 _spoolss_ResetPrinterEx
9681 ****************************************************************/
9683 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
9684 struct spoolss_ResetPrinterEx *r)
9686 p->rng_fault_state = true;
9687 return WERR_NOT_SUPPORTED;
9690 /****************************************************************
9691 _spoolss_RouterReplyPrinterEx
9692 ****************************************************************/
9694 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
9695 struct spoolss_RouterReplyPrinterEx *r)
9697 p->rng_fault_state = true;
9698 return WERR_NOT_SUPPORTED;
9701 /****************************************************************
9703 ****************************************************************/
9705 WERROR _spoolss_44(pipes_struct *p,
9706 struct spoolss_44 *r)
9708 p->rng_fault_state = true;
9709 return WERR_NOT_SUPPORTED;
9712 /****************************************************************
9714 ****************************************************************/
9716 WERROR _spoolss_47(pipes_struct *p,
9717 struct spoolss_47 *r)
9719 p->rng_fault_state = true;
9720 return WERR_NOT_SUPPORTED;
9723 /****************************************************************
9725 ****************************************************************/
9727 WERROR _spoolss_4a(pipes_struct *p,
9728 struct spoolss_4a *r)
9730 p->rng_fault_state = true;
9731 return WERR_NOT_SUPPORTED;
9734 /****************************************************************
9736 ****************************************************************/
9738 WERROR _spoolss_4b(pipes_struct *p,
9739 struct spoolss_4b *r)
9741 p->rng_fault_state = true;
9742 return WERR_NOT_SUPPORTED;
9745 /****************************************************************
9747 ****************************************************************/
9749 WERROR _spoolss_4c(pipes_struct *p,
9750 struct spoolss_4c *r)
9752 p->rng_fault_state = true;
9753 return WERR_NOT_SUPPORTED;
9756 /****************************************************************
9758 ****************************************************************/
9760 WERROR _spoolss_53(pipes_struct *p,
9761 struct spoolss_53 *r)
9763 p->rng_fault_state = true;
9764 return WERR_NOT_SUPPORTED;
9767 /****************************************************************
9769 ****************************************************************/
9771 WERROR _spoolss_55(pipes_struct *p,
9772 struct spoolss_55 *r)
9774 p->rng_fault_state = true;
9775 return WERR_NOT_SUPPORTED;
9778 /****************************************************************
9780 ****************************************************************/
9782 WERROR _spoolss_56(pipes_struct *p,
9783 struct spoolss_56 *r)
9785 p->rng_fault_state = true;
9786 return WERR_NOT_SUPPORTED;
9789 /****************************************************************
9791 ****************************************************************/
9793 WERROR _spoolss_57(pipes_struct *p,
9794 struct spoolss_57 *r)
9796 p->rng_fault_state = true;
9797 return WERR_NOT_SUPPORTED;
9800 /****************************************************************
9802 ****************************************************************/
9804 WERROR _spoolss_5a(pipes_struct *p,
9805 struct spoolss_5a *r)
9807 p->rng_fault_state = true;
9808 return WERR_NOT_SUPPORTED;
9811 /****************************************************************
9813 ****************************************************************/
9815 WERROR _spoolss_5b(pipes_struct *p,
9816 struct spoolss_5b *r)
9818 p->rng_fault_state = true;
9819 return WERR_NOT_SUPPORTED;
9822 /****************************************************************
9824 ****************************************************************/
9826 WERROR _spoolss_5c(pipes_struct *p,
9827 struct spoolss_5c *r)
9829 p->rng_fault_state = true;
9830 return WERR_NOT_SUPPORTED;
9833 /****************************************************************
9835 ****************************************************************/
9837 WERROR _spoolss_5d(pipes_struct *p,
9838 struct spoolss_5d *r)
9840 p->rng_fault_state = true;
9841 return WERR_NOT_SUPPORTED;
9844 /****************************************************************
9846 ****************************************************************/
9848 WERROR _spoolss_5e(pipes_struct *p,
9849 struct spoolss_5e *r)
9851 p->rng_fault_state = true;
9852 return WERR_NOT_SUPPORTED;
9855 /****************************************************************
9857 ****************************************************************/
9859 WERROR _spoolss_5f(pipes_struct *p,
9860 struct spoolss_5f *r)
9862 p->rng_fault_state = true;
9863 return WERR_NOT_SUPPORTED;
9866 /****************************************************************
9868 ****************************************************************/
9870 WERROR _spoolss_60(pipes_struct *p,
9871 struct spoolss_60 *r)
9873 p->rng_fault_state = true;
9874 return WERR_NOT_SUPPORTED;
9877 /****************************************************************
9879 ****************************************************************/
9881 WERROR _spoolss_61(pipes_struct *p,
9882 struct spoolss_61 *r)
9884 p->rng_fault_state = true;
9885 return WERR_NOT_SUPPORTED;
9888 /****************************************************************
9890 ****************************************************************/
9892 WERROR _spoolss_62(pipes_struct *p,
9893 struct spoolss_62 *r)
9895 p->rng_fault_state = true;
9896 return WERR_NOT_SUPPORTED;
9899 /****************************************************************
9901 ****************************************************************/
9903 WERROR _spoolss_63(pipes_struct *p,
9904 struct spoolss_63 *r)
9906 p->rng_fault_state = true;
9907 return WERR_NOT_SUPPORTED;
9910 /****************************************************************
9912 ****************************************************************/
9914 WERROR _spoolss_64(pipes_struct *p,
9915 struct spoolss_64 *r)
9917 p->rng_fault_state = true;
9918 return WERR_NOT_SUPPORTED;
9921 /****************************************************************
9923 ****************************************************************/
9925 WERROR _spoolss_65(pipes_struct *p,
9926 struct spoolss_65 *r)
9928 p->rng_fault_state = true;
9929 return WERR_NOT_SUPPORTED;
9932 /****************************************************************
9933 _spoolss_GetCorePrinterDrivers
9934 ****************************************************************/
9936 WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
9937 struct spoolss_GetCorePrinterDrivers *r)
9939 p->rng_fault_state = true;
9940 return WERR_NOT_SUPPORTED;
9943 /****************************************************************
9945 ****************************************************************/
9947 WERROR _spoolss_67(pipes_struct *p,
9948 struct spoolss_67 *r)
9950 p->rng_fault_state = true;
9951 return WERR_NOT_SUPPORTED;
9954 /****************************************************************
9955 _spoolss_GetPrinterDriverPackagePath
9956 ****************************************************************/
9958 WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
9959 struct spoolss_GetPrinterDriverPackagePath *r)
9961 p->rng_fault_state = true;
9962 return WERR_NOT_SUPPORTED;
9965 /****************************************************************
9967 ****************************************************************/
9969 WERROR _spoolss_69(pipes_struct *p,
9970 struct spoolss_69 *r)
9972 p->rng_fault_state = true;
9973 return WERR_NOT_SUPPORTED;
9976 /****************************************************************
9978 ****************************************************************/
9980 WERROR _spoolss_6a(pipes_struct *p,
9981 struct spoolss_6a *r)
9983 p->rng_fault_state = true;
9984 return WERR_NOT_SUPPORTED;
9987 /****************************************************************
9989 ****************************************************************/
9991 WERROR _spoolss_6b(pipes_struct *p,
9992 struct spoolss_6b *r)
9994 p->rng_fault_state = true;
9995 return WERR_NOT_SUPPORTED;
9998 /****************************************************************
10000 ****************************************************************/
10002 WERROR _spoolss_6c(pipes_struct *p,
10003 struct spoolss_6c *r)
10005 p->rng_fault_state = true;
10006 return WERR_NOT_SUPPORTED;
10009 /****************************************************************
10011 ****************************************************************/
10013 WERROR _spoolss_6d(pipes_struct *p,
10014 struct spoolss_6d *r)
10016 p->rng_fault_state = true;
10017 return WERR_NOT_SUPPORTED;