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"
40 #include "include/printing.h"
42 /* macros stolen from s4 spoolss server */
43 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
44 ((info)?ndr_size_##fn(info, level, 0):0)
46 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
47 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
49 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
50 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
52 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
55 #define DBGC_CLASS DBGC_RPC_SRV
57 static Printer_entry *printers_list;
59 typedef struct _counter_printer_0 {
60 struct _counter_printer_0 *next;
61 struct _counter_printer_0 *prev;
67 static counter_printer_0 *counter_list;
69 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
70 static uint32_t smb_connections = 0;
73 /* Map generic permissions to printer object specific permissions */
75 const struct standard_mapping printer_std_mapping = {
82 /* Map generic permissions to print server object specific permissions */
84 const struct standard_mapping printserver_std_mapping = {
91 /* API table for Xcv Monitor functions */
93 struct xcv_api_table {
95 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
98 /********************************************************************
99 * Canonicalize servername.
100 ********************************************************************/
102 static const char *canon_servername(const char *servername)
104 const char *pservername = servername;
105 while (*pservername == '\\') {
111 /* translate between internal status numbers and NT status numbers */
112 static int nt_printj_status(int v)
118 return JOB_STATUS_PAUSED;
120 return JOB_STATUS_SPOOLING;
122 return JOB_STATUS_PRINTING;
124 return JOB_STATUS_ERROR;
126 return JOB_STATUS_DELETING;
128 return JOB_STATUS_OFFLINE;
130 return JOB_STATUS_PAPEROUT;
132 return JOB_STATUS_PRINTED;
134 return JOB_STATUS_DELETED;
136 return JOB_STATUS_BLOCKED_DEVQ;
137 case LPQ_USER_INTERVENTION:
138 return JOB_STATUS_USER_INTERVENTION;
143 static int nt_printq_status(int v)
147 return PRINTER_STATUS_PAUSED;
156 /***************************************************************************
157 Disconnect from the client
158 ****************************************************************************/
160 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
166 * Tell the specific printing tdb we no longer want messages for this printer
167 * by deregistering our PID.
170 if (!print_notify_deregister_pid(snum))
171 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
173 /* weird if the test succeds !!! */
174 if (smb_connections==0) {
175 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
179 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
182 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
183 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
184 win_errstr(result)));
186 /* if it's the last connection, deconnect the IPC$ share */
187 if (smb_connections==1) {
189 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
190 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
192 messaging_deregister(smbd_messaging_context(),
193 MSG_PRINTER_NOTIFY2, NULL);
195 /* Tell the connections db we're no longer interested in
196 * printer notify messages. */
198 serverid_register_msg_flags(
199 messaging_server_id(smbd_messaging_context()),
200 false, FLAG_MSG_PRINT_NOTIFY);
206 /****************************************************************************
207 Functions to free a printer entry datastruct.
208 ****************************************************************************/
210 static int printer_entry_destructor(Printer_entry *Printer)
212 if (Printer->notify.client_connected == true) {
215 if ( Printer->printer_type == SPLHND_SERVER) {
217 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
218 } else if (Printer->printer_type == SPLHND_PRINTER) {
219 snum = print_queue_snum(Printer->sharename);
221 srv_spoolss_replycloseprinter(snum,
222 &Printer->notify.client_hnd);
226 Printer->notify.flags=0;
227 Printer->notify.options=0;
228 Printer->notify.localmachine[0]='\0';
229 Printer->notify.printerlocal=0;
230 TALLOC_FREE(Printer->notify.option);
231 Printer->notify.client_connected = false;
233 TALLOC_FREE(Printer->devmode);
235 /* Remove from the internal list. */
236 DLIST_REMOVE(printers_list, Printer);
240 /****************************************************************************
241 find printer index by handle
242 ****************************************************************************/
244 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
245 struct policy_handle *hnd)
247 Printer_entry *find_printer = NULL;
249 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
250 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
257 /****************************************************************************
258 Close printer index by handle.
259 ****************************************************************************/
261 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
263 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
266 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
271 close_policy_hnd(p, hnd);
276 /****************************************************************************
277 Delete a printer given a handle.
278 ****************************************************************************/
280 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
282 char *cmd = lp_deleteprinter_cmd();
283 char *command = NULL;
285 SE_PRIV se_printop = SE_PRINT_OPERATOR;
286 bool is_print_op = false;
288 /* can't fail if we don't try */
293 command = talloc_asprintf(ctx,
300 is_print_op = user_has_privileges( token, &se_printop );
302 DEBUG(10,("Running [%s]\n", command));
304 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
309 if ( (ret = smbrun(command, NULL)) == 0 ) {
310 /* Tell everyone we updated smb.conf. */
311 message_send_all(smbd_messaging_context(),
312 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
318 /********** END SePrintOperatorPrivlege BLOCK **********/
320 DEBUGADD(10,("returned [%d]\n", ret));
322 TALLOC_FREE(command);
325 return WERR_BADFID; /* What to return here? */
327 /* go ahead and re-read the services immediately */
329 reload_services(false);
332 if ( lp_servicenumber( sharename ) > 0 )
333 return WERR_ACCESS_DENIED;
338 /****************************************************************************
339 Delete a printer given a handle.
340 ****************************************************************************/
342 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
344 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
348 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
354 * It turns out that Windows allows delete printer on a handle
355 * opened by an admin user, then used on a pipe handle created
356 * by an anonymous user..... but they're working on security.... riiight !
360 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
361 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
362 return WERR_ACCESS_DENIED;
365 /* this does not need a become root since the access check has been
366 done on the handle already */
368 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
369 Printer->sharename, "");
370 if (!W_ERROR_IS_OK(result)) {
371 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
375 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
376 Printer->sharename );
379 /****************************************************************************
380 Return the snum of a printer corresponding to an handle.
381 ****************************************************************************/
383 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
384 int *number, struct share_params **params)
386 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
389 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
394 switch (Printer->printer_type) {
396 DEBUG(4,("short name:%s\n", Printer->sharename));
397 *number = print_queue_snum(Printer->sharename);
398 return (*number != -1);
406 /****************************************************************************
407 Set printer handle type.
408 Check if it's \\server or \\server\printer
409 ****************************************************************************/
411 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
413 DEBUG(3,("Setting printer type=%s\n", handlename));
415 if ( strlen(handlename) < 3 ) {
416 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
420 /* it's a print server */
421 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
422 DEBUGADD(4,("Printer is a print server\n"));
423 Printer->printer_type = SPLHND_SERVER;
425 /* it's a printer (set_printer_hnd_name() will handle port monitors */
427 DEBUGADD(4,("Printer is a printer\n"));
428 Printer->printer_type = SPLHND_PRINTER;
434 /****************************************************************************
435 Set printer handle name.. Accept names like \\server, \\server\printer,
436 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
437 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
438 XcvDataPort() interface.
439 ****************************************************************************/
441 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
442 struct auth_serversupplied_info *server_info,
443 Printer_entry *Printer,
444 const char *handlename)
447 int n_services=lp_numservices();
449 const char *printername;
450 const char *servername;
453 struct spoolss_PrinterInfo2 *info2 = NULL;
456 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
457 (unsigned long)strlen(handlename)));
459 aprinter = CONST_DISCARD(char *, handlename);
460 if ( *handlename == '\\' ) {
461 servername = canon_servername(handlename);
462 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
466 if (!is_myname_or_ipaddr(servername)) {
470 fstrcpy(Printer->servername, servername);
473 if (Printer->printer_type == SPLHND_SERVER) {
477 if (Printer->printer_type != SPLHND_PRINTER) {
481 DEBUGADD(5, ("searching for [%s]\n", aprinter));
483 /* check for the Port Monitor Interface */
484 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
485 Printer->printer_type = SPLHND_PORTMON_TCP;
486 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
489 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
490 Printer->printer_type = SPLHND_PORTMON_LOCAL;
491 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
495 /* Search all sharenames first as this is easier than pulling
496 the printer_info_2 off of disk. Don't use find_service() since
497 that calls out to map_username() */
499 /* do another loop to look for printernames */
500 for (snum = 0; !found && snum < n_services; snum++) {
501 const char *printer = lp_const_servicename(snum);
503 /* no point going on if this is not a printer */
504 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
508 /* ignore [printers] share */
509 if (strequal(printer, "printers")) {
513 fstrcpy(sname, printer);
514 if (strequal(aprinter, printer)) {
519 /* no point looking up the printer object if
520 we aren't allowing printername != sharename */
521 if (lp_force_printername(snum)) {
525 result = winreg_get_printer(mem_ctx,
530 if ( !W_ERROR_IS_OK(result) ) {
531 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
532 sname, win_errstr(result)));
536 printername = strrchr(info2->printername, '\\');
537 if (printername == NULL) {
538 printername = info2->printername;
543 if (strequal(printername, aprinter)) {
548 DEBUGADD(10, ("printername: %s\n", printername));
554 DEBUGADD(4,("Printer not found\n"));
558 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
560 fstrcpy(Printer->sharename, sname);
565 /****************************************************************************
566 Find first available printer slot. creates a printer handle for you.
567 ****************************************************************************/
569 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
570 const char *name, uint32_t access_granted)
572 Printer_entry *new_printer;
574 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
576 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
577 if (new_printer == NULL) {
580 talloc_set_destructor(new_printer, printer_entry_destructor);
582 if (!create_policy_hnd(p, hnd, new_printer)) {
583 TALLOC_FREE(new_printer);
587 /* Add to the internal list. */
588 DLIST_ADD(printers_list, new_printer);
590 new_printer->notify.option=NULL;
592 if (!set_printer_hnd_printertype(new_printer, name)) {
593 close_printer_handle(p, hnd);
597 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
598 close_printer_handle(p, hnd);
602 new_printer->access_granted = access_granted;
604 DEBUG(5, ("%d printer handles active\n",
605 (int)num_pipe_handles(p)));
610 /***************************************************************************
611 check to see if the client motify handle is monitoring the notification
612 given by (notify_type, notify_field).
613 **************************************************************************/
615 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
616 uint16_t notify_field)
621 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
622 uint16_t notify_field)
624 struct spoolss_NotifyOption *option = p->notify.option;
628 * Flags should always be zero when the change notify
629 * is registered by the client's spooler. A user Win32 app
630 * might use the flags though instead of the NOTIFY_OPTION_INFO
639 return is_monitoring_event_flags(
640 p->notify.flags, notify_type, notify_field);
642 for (i = 0; i < option->count; i++) {
644 /* Check match for notify_type */
646 if (option->types[i].type != notify_type)
649 /* Check match for field */
651 for (j = 0; j < option->types[i].count; j++) {
652 if (option->types[i].fields[j].field == notify_field) {
658 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
659 p->servername, p->sharename, notify_type, notify_field));
664 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
665 _data->data.integer[0] = _integer; \
666 _data->data.integer[1] = 0;
669 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
670 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
671 if (!_data->data.string.string) {\
672 _data->data.string.size = 0; \
674 _data->data.string.size = strlen_m_term(_p) * 2;
676 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
677 _data->data.devmode.devmode = _devmode;
679 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
680 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
681 if (!_data->data.sd.sd) { \
682 _data->data.sd.sd_size = 0; \
684 _data->data.sd.sd_size = \
685 ndr_size_security_descriptor(_data->data.sd.sd, 0);
687 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
692 struct spoolss_Time st;
696 if (!init_systemtime(&st, t)) {
700 p = talloc_array(mem_ctx, char, len);
706 * Systemtime must be linearized as a set of UINT16's.
707 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
710 SSVAL(p, 0, st.year);
711 SSVAL(p, 2, st.month);
712 SSVAL(p, 4, st.day_of_week);
714 SSVAL(p, 8, st.hour);
715 SSVAL(p, 10, st.minute);
716 SSVAL(p, 12, st.second);
717 SSVAL(p, 14, st.millisecond);
723 /* Convert a notification message to a struct spoolss_Notify */
725 static void notify_one_value(struct spoolss_notify_msg *msg,
726 struct spoolss_Notify *data,
729 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
732 static void notify_string(struct spoolss_notify_msg *msg,
733 struct spoolss_Notify *data,
736 /* The length of the message includes the trailing \0 */
738 data->data.string.size = msg->len * 2;
739 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
740 if (!data->data.string.string) {
741 data->data.string.size = 0;
746 static void notify_system_time(struct spoolss_notify_msg *msg,
747 struct spoolss_Notify *data,
750 data->data.string.string = NULL;
751 data->data.string.size = 0;
753 if (msg->len != sizeof(time_t)) {
754 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
759 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
760 &data->data.string.string,
761 &data->data.string.size);
764 struct notify2_message_table {
766 void (*fn)(struct spoolss_notify_msg *msg,
767 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
770 static struct notify2_message_table printer_notify_table[] = {
771 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
772 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
773 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
774 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
775 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
776 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
777 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
778 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
779 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
780 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
781 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
782 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
783 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
784 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
785 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
786 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
787 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
788 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
789 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
792 static struct notify2_message_table job_notify_table[] = {
793 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
794 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
795 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
796 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
797 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
798 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
799 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
800 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
801 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
802 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
803 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
804 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
805 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
806 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
807 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
808 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
809 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
810 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
811 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
812 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
813 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
814 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
815 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
816 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
820 /***********************************************************************
821 Allocate talloc context for container object
822 **********************************************************************/
824 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
829 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
834 /***********************************************************************
835 release all allocated memory and zero out structure
836 **********************************************************************/
838 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
844 talloc_destroy(ctr->ctx);
851 /***********************************************************************
852 **********************************************************************/
854 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
862 /***********************************************************************
863 **********************************************************************/
865 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
867 if ( !ctr || !ctr->msg_groups )
870 if ( idx >= ctr->num_groups )
873 return &ctr->msg_groups[idx];
877 /***********************************************************************
878 How many groups of change messages do we have ?
879 **********************************************************************/
881 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
886 return ctr->num_groups;
889 /***********************************************************************
890 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
891 **********************************************************************/
893 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
895 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
896 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
897 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
903 /* loop over all groups looking for a matching printer name */
905 for ( i=0; i<ctr->num_groups; i++ ) {
906 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
910 /* add a new group? */
912 if ( i == ctr->num_groups ) {
915 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
916 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
919 ctr->msg_groups = groups;
921 /* clear the new entry and set the printer name */
923 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
924 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
927 /* add the change messages; 'i' is the correct index now regardless */
929 msg_grp = &ctr->msg_groups[i];
933 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
934 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
937 msg_grp->msgs = msg_list;
939 new_slot = msg_grp->num_msgs-1;
940 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
942 /* need to allocate own copy of data */
945 msg_grp->msgs[new_slot].notify.data = (char *)
946 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
948 return ctr->num_groups;
951 static void construct_info_data(struct spoolss_Notify *info_data,
952 enum spoolss_NotifyType type,
953 uint16_t field, int id);
955 /***********************************************************************
956 Send a change notication message on all handles which have a call
958 **********************************************************************/
960 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
963 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
964 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
965 SPOOLSS_NOTIFY_MSG *messages;
966 int sending_msg_count;
969 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
973 messages = msg_group->msgs;
976 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
980 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
982 /* loop over all printers */
984 for (p = printers_list; p; p = p->next) {
985 struct spoolss_Notify *notifies;
990 /* Is there notification on this handle? */
992 if ( !p->notify.client_connected )
995 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
997 /* For this printer? Print servers always receive
1000 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1001 ( !strequal(msg_group->printername, p->sharename) ) )
1004 DEBUG(10,("Our printer\n"));
1006 /* allocate the max entries possible */
1008 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1013 /* build the array of change notifications */
1015 sending_msg_count = 0;
1017 for ( i=0; i<msg_group->num_msgs; i++ ) {
1018 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1020 /* Are we monitoring this event? */
1022 if (!is_monitoring_event(p, msg->type, msg->field))
1025 sending_msg_count++;
1028 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1029 msg->type, msg->field, p->sharename));
1032 * if the is a printer notification handle and not a job notification
1033 * type, then set the id to 0. Other wise just use what was specified
1036 * When registering change notification on a print server handle
1037 * we always need to send back the id (snum) matching the printer
1038 * for which the change took place. For change notify registered
1039 * on a printer handle, this does not matter and the id should be 0.
1044 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1050 /* Convert unix jobid to smb jobid */
1052 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1053 id = sysjob_to_jobid(msg->id);
1056 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1061 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1064 case PRINTER_NOTIFY_TYPE:
1065 if ( printer_notify_table[msg->field].fn )
1066 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1069 case JOB_NOTIFY_TYPE:
1070 if ( job_notify_table[msg->field].fn )
1071 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1075 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1082 if ( sending_msg_count ) {
1085 union spoolss_ReplyPrinterInfo info;
1086 struct spoolss_NotifyInfo info0;
1087 uint32_t reply_result;
1089 info0.version = 0x2;
1090 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1091 info0.count = count;
1092 info0.notifies = notifies;
1094 info.info0 = &info0;
1096 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1097 &p->notify.client_hnd,
1098 p->notify.change, /* color */
1101 0, /* reply_type, must be 0 */
1104 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1105 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1106 notify_cli_pipe->srv_name_slash,
1109 switch (reply_result) {
1112 case PRINTER_NOTIFY_INFO_DISCARDED:
1113 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1114 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1123 DEBUG(8,("send_notify2_changes: Exit...\n"));
1127 /***********************************************************************
1128 **********************************************************************/
1130 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1133 uint32_t tv_sec, tv_usec;
1136 /* Unpack message */
1138 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1141 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1143 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1146 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1147 &msg->notify.value[0], &msg->notify.value[1]);
1149 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1150 &msg->len, &msg->notify.data);
1152 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1153 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1155 tv->tv_sec = tv_sec;
1156 tv->tv_usec = tv_usec;
1159 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1160 msg->notify.value[1]));
1162 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1167 /********************************************************************
1168 Receive a notify2 message list
1169 ********************************************************************/
1171 static void receive_notify2_message_list(struct messaging_context *msg,
1174 struct server_id server_id,
1177 size_t msg_count, i;
1178 char *buf = (char *)data->data;
1181 SPOOLSS_NOTIFY_MSG notify;
1182 SPOOLSS_NOTIFY_MSG_CTR messages;
1185 if (data->length < 4) {
1186 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1190 msg_count = IVAL(buf, 0);
1193 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1195 if (msg_count == 0) {
1196 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1200 /* initialize the container */
1202 ZERO_STRUCT( messages );
1203 notify_msg_ctr_init( &messages );
1206 * build message groups for each printer identified
1207 * in a change_notify msg. Remember that a PCN message
1208 * includes the handle returned for the srv_spoolss_replyopenprinter()
1209 * call. Therefore messages are grouped according to printer handle.
1212 for ( i=0; i<msg_count; i++ ) {
1213 struct timeval msg_tv;
1215 if (msg_ptr + 4 - buf > data->length) {
1216 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1220 msg_len = IVAL(msg_ptr,0);
1223 if (msg_ptr + msg_len - buf > data->length) {
1224 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1228 /* unpack messages */
1230 ZERO_STRUCT( notify );
1231 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1234 /* add to correct list in container */
1236 notify_msg_ctr_addmsg( &messages, ¬ify );
1238 /* free memory that might have been allocated by notify2_unpack_msg() */
1240 if ( notify.len != 0 )
1241 SAFE_FREE( notify.notify.data );
1244 /* process each group of messages */
1246 num_groups = notify_msg_ctr_numgroups( &messages );
1247 for ( i=0; i<num_groups; i++ )
1248 send_notify2_changes( &messages, i );
1253 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1254 (uint32_t)msg_count ));
1256 notify_msg_ctr_destroy( &messages );
1261 /********************************************************************
1262 Send a message to ourself about new driver being installed
1263 so we can upgrade the information for each printer bound to this
1265 ********************************************************************/
1267 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1269 int len = strlen(drivername);
1274 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1277 messaging_send_buf(smbd_messaging_context(),
1278 messaging_server_id(smbd_messaging_context()),
1279 MSG_PRINTER_DRVUPGRADE,
1280 (uint8_t *)drivername, len+1);
1285 /**********************************************************************
1286 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1287 over all printers, upgrading ones as necessary
1288 **********************************************************************/
1290 void do_drv_upgrade_printer(struct messaging_context *msg,
1293 struct server_id server_id,
1296 TALLOC_CTX *tmp_ctx;
1297 struct auth_serversupplied_info *server_info = NULL;
1298 struct spoolss_PrinterInfo2 *pinfo2;
1301 const char *drivername;
1303 int n_services = lp_numservices();
1306 tmp_ctx = talloc_new(NULL);
1307 if (!tmp_ctx) return;
1309 status = make_server_info_system(tmp_ctx, &server_info);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 DEBUG(0, ("do_drv_upgrade_printer: "
1312 "Could not create system server_info\n"));
1316 len = MIN(data->length,sizeof(drivername)-1);
1317 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1319 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1323 DEBUG(10, ("do_drv_upgrade_printer: "
1324 "Got message for new driver [%s]\n", drivername));
1326 /* Iterate the printer list */
1328 for (snum = 0; snum < n_services; snum++) {
1329 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1333 result = winreg_get_printer(tmp_ctx, server_info, NULL,
1334 lp_const_servicename(snum),
1337 if (!W_ERROR_IS_OK(result)) {
1341 if (!pinfo2->drivername) {
1345 if (strcmp(drivername, pinfo2->drivername) != 0) {
1349 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1351 /* all we care about currently is the change_id */
1352 result = winreg_printer_update_changeid(tmp_ctx,
1354 pinfo2->printername);
1356 if (!W_ERROR_IS_OK(result)) {
1357 DEBUG(3, ("do_drv_upgrade_printer: "
1358 "Failed to update changeid [%s]\n",
1359 win_errstr(result)));
1365 talloc_free(tmp_ctx);
1368 /********************************************************************
1369 Update the cache for all printq's with a registered client
1371 ********************************************************************/
1373 void update_monitored_printq_cache( void )
1375 Printer_entry *printer = printers_list;
1378 /* loop through all printers and update the cache where
1379 client_connected == true */
1382 if ( (printer->printer_type == SPLHND_PRINTER)
1383 && printer->notify.client_connected )
1385 snum = print_queue_snum(printer->sharename);
1386 print_queue_status( snum, NULL, NULL );
1389 printer = printer->next;
1395 /****************************************************************
1396 _spoolss_OpenPrinter
1397 ****************************************************************/
1399 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1400 struct spoolss_OpenPrinter *r)
1402 struct spoolss_OpenPrinterEx e;
1405 ZERO_STRUCT(e.in.userlevel);
1407 e.in.printername = r->in.printername;
1408 e.in.datatype = r->in.datatype;
1409 e.in.devmode_ctr = r->in.devmode_ctr;
1410 e.in.access_mask = r->in.access_mask;
1413 e.out.handle = r->out.handle;
1415 werr = _spoolss_OpenPrinterEx(p, &e);
1417 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1418 /* OpenPrinterEx returns this for a bad
1419 * printer name. We must return WERR_INVALID_PRINTER_NAME
1422 werr = WERR_INVALID_PRINTER_NAME;
1428 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1429 struct spoolss_DeviceMode *orig,
1430 struct spoolss_DeviceMode **dest)
1432 struct spoolss_DeviceMode *dm;
1434 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1439 /* copy all values, then duplicate strings and structs */
1442 dm->devicename = talloc_strdup(dm, orig->devicename);
1443 if (!dm->devicename) {
1446 dm->formname = talloc_strdup(dm, orig->formname);
1447 if (!dm->formname) {
1450 if (orig->driverextra_data.data) {
1451 dm->driverextra_data.data =
1452 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1453 orig->driverextra_data.length);
1454 if (!dm->driverextra_data.data) {
1463 /****************************************************************
1464 _spoolss_OpenPrinterEx
1465 ****************************************************************/
1467 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1468 struct spoolss_OpenPrinterEx *r)
1471 Printer_entry *Printer=NULL;
1473 if (!r->in.printername) {
1474 return WERR_INVALID_PARAM;
1477 /* some sanity check because you can open a printer or a print server */
1478 /* aka: \\server\printer or \\server */
1480 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1482 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1483 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1484 " for printer %s\n", r->in.printername));
1485 ZERO_STRUCTP(r->out.handle);
1486 return WERR_INVALID_PARAM;
1489 Printer = find_printer_index_by_hnd(p, r->out.handle);
1491 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1492 "handle we created for printer %s\n", r->in.printername));
1493 close_printer_handle(p, r->out.handle);
1494 ZERO_STRUCTP(r->out.handle);
1495 return WERR_INVALID_PARAM;
1499 * First case: the user is opening the print server:
1501 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1502 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1504 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1505 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1506 * or if the user is listed in the smb.conf printer admin parameter.
1508 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1509 * client view printer folder, but does not show the MSAPW.
1511 * Note: this test needs code to check access rights here too. Jeremy
1512 * could you look at this?
1514 * Second case: the user is opening a printer:
1515 * NT doesn't let us connect to a printer if the connecting user
1516 * doesn't have print permission.
1518 * Third case: user is opening a Port Monitor
1519 * access checks same as opening a handle to the print server.
1522 switch (Printer->printer_type )
1525 case SPLHND_PORTMON_TCP:
1526 case SPLHND_PORTMON_LOCAL:
1527 /* Printserver handles use global struct... */
1531 /* Map standard access rights to object specific access rights */
1533 se_map_standard(&r->in.access_mask,
1534 &printserver_std_mapping);
1536 /* Deny any object specific bits that don't apply to print
1537 servers (i.e printer and job specific bits) */
1539 r->in.access_mask &= SEC_MASK_SPECIFIC;
1541 if (r->in.access_mask &
1542 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1543 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1544 close_printer_handle(p, r->out.handle);
1545 ZERO_STRUCTP(r->out.handle);
1546 return WERR_ACCESS_DENIED;
1549 /* Allow admin access */
1551 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1553 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1555 if (!lp_ms_add_printer_wizard()) {
1556 close_printer_handle(p, r->out.handle);
1557 ZERO_STRUCTP(r->out.handle);
1558 return WERR_ACCESS_DENIED;
1561 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1562 and not a printer admin, then fail */
1564 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1565 !user_has_privileges(p->server_info->ptok,
1567 !token_contains_name_in_list(
1568 uidtoname(p->server_info->utok.uid),
1569 p->server_info->info3->base.domain.string,
1571 p->server_info->ptok,
1572 lp_printer_admin(snum))) {
1573 close_printer_handle(p, r->out.handle);
1574 ZERO_STRUCTP(r->out.handle);
1575 return WERR_ACCESS_DENIED;
1578 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1582 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1585 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1586 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1588 /* We fall through to return WERR_OK */
1591 case SPLHND_PRINTER:
1592 /* NT doesn't let us connect to a printer if the connecting user
1593 doesn't have print permission. */
1595 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1596 close_printer_handle(p, r->out.handle);
1597 ZERO_STRUCTP(r->out.handle);
1601 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1602 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1605 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1607 /* map an empty access mask to the minimum access mask */
1608 if (r->in.access_mask == 0x0)
1609 r->in.access_mask = PRINTER_ACCESS_USE;
1612 * If we are not serving the printer driver for this printer,
1613 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1614 * will keep NT clients happy --jerry
1617 if (lp_use_client_driver(snum)
1618 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1620 r->in.access_mask = PRINTER_ACCESS_USE;
1623 /* check smb.conf parameters and the the sec_desc */
1625 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1626 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1627 ZERO_STRUCTP(r->out.handle);
1628 return WERR_ACCESS_DENIED;
1631 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1632 p->server_info->ptok, snum) ||
1633 !print_access_check(p->server_info, snum,
1634 r->in.access_mask)) {
1635 DEBUG(3, ("access DENIED for printer open\n"));
1636 close_printer_handle(p, r->out.handle);
1637 ZERO_STRUCTP(r->out.handle);
1638 return WERR_ACCESS_DENIED;
1641 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1642 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1643 close_printer_handle(p, r->out.handle);
1644 ZERO_STRUCTP(r->out.handle);
1645 return WERR_ACCESS_DENIED;
1648 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1649 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1651 r->in.access_mask = PRINTER_ACCESS_USE;
1653 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1654 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1656 winreg_create_printer(p->mem_ctx,
1658 Printer->servername,
1659 lp_const_servicename(snum));
1664 /* sanity check to prevent programmer error */
1665 ZERO_STRUCTP(r->out.handle);
1669 Printer->access_granted = r->in.access_mask;
1672 * If the client sent a devmode in the OpenPrinter() call, then
1673 * save it here in case we get a job submission on this handle
1676 if ((Printer->printer_type != SPLHND_SERVER) &&
1677 r->in.devmode_ctr.devmode) {
1678 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1682 #if 0 /* JERRY -- I'm doubtful this is really effective */
1683 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1684 optimization in Windows 2000 clients --jerry */
1686 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1687 && (RA_WIN2K == get_remote_arch()) )
1689 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1690 sys_usleep( 500000 );
1697 /****************************************************************
1698 _spoolss_ClosePrinter
1699 ****************************************************************/
1701 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1702 struct spoolss_ClosePrinter *r)
1704 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1706 if (Printer && Printer->document_started) {
1707 struct spoolss_EndDocPrinter e;
1709 e.in.handle = r->in.handle;
1711 _spoolss_EndDocPrinter(p, &e);
1714 if (!close_printer_handle(p, r->in.handle))
1717 /* clear the returned printer handle. Observed behavior
1718 from Win2k server. Don't think this really matters.
1719 Previous code just copied the value of the closed
1722 ZERO_STRUCTP(r->out.handle);
1727 /****************************************************************
1728 _spoolss_DeletePrinter
1729 ****************************************************************/
1731 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1732 struct spoolss_DeletePrinter *r)
1734 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1738 if (Printer && Printer->document_started) {
1739 struct spoolss_EndDocPrinter e;
1741 e.in.handle = r->in.handle;
1743 _spoolss_EndDocPrinter(p, &e);
1746 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1747 winreg_delete_printer_key(p->mem_ctx,
1749 lp_const_servicename(snum),
1753 result = delete_printer_handle(p, r->in.handle);
1758 /*******************************************************************
1759 * static function to lookup the version id corresponding to an
1760 * long architecture string
1761 ******************************************************************/
1763 static const struct print_architecture_table_node archi_table[]= {
1765 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1766 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1767 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1768 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1769 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1770 {"Windows IA64", SPL_ARCH_IA64, 3 },
1771 {"Windows x64", SPL_ARCH_X64, 3 },
1775 static int get_version_id(const char *arch)
1779 for (i=0; archi_table[i].long_archi != NULL; i++)
1781 if (strcmp(arch, archi_table[i].long_archi) == 0)
1782 return (archi_table[i].version);
1788 /****************************************************************
1789 _spoolss_DeletePrinterDriver
1790 ****************************************************************/
1792 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1793 struct spoolss_DeletePrinterDriver *r)
1796 struct spoolss_DriverInfo8 *info = NULL;
1797 struct spoolss_DriverInfo8 *info_win2k = NULL;
1800 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1802 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1803 and not a printer admin, then fail */
1805 if ( (p->server_info->utok.uid != sec_initial_uid())
1806 && !user_has_privileges(p->server_info->ptok, &se_printop )
1807 && !token_contains_name_in_list(
1808 uidtoname(p->server_info->utok.uid),
1809 p->server_info->info3->base.domain.string,
1811 p->server_info->ptok,
1812 lp_printer_admin(-1)) )
1814 return WERR_ACCESS_DENIED;
1817 /* check that we have a valid driver name first */
1819 if ((version = get_version_id(r->in.architecture)) == -1)
1820 return WERR_INVALID_ENVIRONMENT;
1822 status = winreg_get_driver(p->mem_ctx, p->server_info,
1823 r->in.architecture, r->in.driver,
1825 if (!W_ERROR_IS_OK(status)) {
1826 /* try for Win2k driver if "Windows NT x86" */
1828 if ( version == 2 ) {
1831 status = winreg_get_driver(p->mem_ctx, p->server_info,
1835 if (!W_ERROR_IS_OK(status)) {
1836 status = WERR_UNKNOWN_PRINTER_DRIVER;
1840 /* otherwise it was a failure */
1842 status = WERR_UNKNOWN_PRINTER_DRIVER;
1848 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1849 status = WERR_PRINTER_DRIVER_IN_USE;
1854 status = winreg_get_driver(p->mem_ctx, p->server_info,
1856 r->in.driver, 3, &info_win2k);
1857 if (W_ERROR_IS_OK(status)) {
1858 /* if we get to here, we now have 2 driver info structures to remove */
1859 /* remove the Win2k driver first*/
1861 status = winreg_del_driver(p->mem_ctx,
1864 talloc_free(info_win2k);
1866 /* this should not have failed---if it did, report to client */
1867 if (!W_ERROR_IS_OK(status)) {
1873 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1881 /****************************************************************
1882 _spoolss_DeletePrinterDriverEx
1883 ****************************************************************/
1885 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1886 struct spoolss_DeletePrinterDriverEx *r)
1888 struct spoolss_DriverInfo8 *info = NULL;
1889 struct spoolss_DriverInfo8 *info_win2k = NULL;
1893 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1895 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1896 and not a printer admin, then fail */
1898 if ( (p->server_info->utok.uid != sec_initial_uid())
1899 && !user_has_privileges(p->server_info->ptok, &se_printop )
1900 && !token_contains_name_in_list(
1901 uidtoname(p->server_info->utok.uid),
1902 p->server_info->info3->base.domain.string,
1904 p->server_info->ptok, lp_printer_admin(-1)) )
1906 return WERR_ACCESS_DENIED;
1909 /* check that we have a valid driver name first */
1910 if ((version = get_version_id(r->in.architecture)) == -1) {
1911 /* this is what NT returns */
1912 return WERR_INVALID_ENVIRONMENT;
1915 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1916 version = r->in.version;
1918 status = winreg_get_driver(p->mem_ctx, p->server_info,
1919 r->in.architecture, r->in.driver,
1921 if (!W_ERROR_IS_OK(status)) {
1922 status = WERR_UNKNOWN_PRINTER_DRIVER;
1925 * if the client asked for a specific version,
1926 * or this is something other than Windows NT x86,
1930 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1933 /* try for Win2k driver if "Windows NT x86" */
1936 status = winreg_get_driver(info, p->server_info,
1940 if (!W_ERROR_IS_OK(status)) {
1941 status = WERR_UNKNOWN_PRINTER_DRIVER;
1946 if (printer_driver_in_use(info, p->server_info, info)) {
1947 status = WERR_PRINTER_DRIVER_IN_USE;
1952 * we have a couple of cases to consider.
1953 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1954 * then the delete should fail if **any** files overlap with
1956 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1957 * non-overlapping files
1958 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1959 * is set, the do not delete any files
1960 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1963 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1965 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1968 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1969 printer_driver_files_in_use(info, p->server_info, info)) {
1970 /* no idea of the correct error here */
1971 status = WERR_ACCESS_DENIED;
1976 /* also check for W32X86/3 if necessary; maybe we already have? */
1978 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1979 status = winreg_get_driver(info, p->server_info,
1981 r->in.driver, 3, &info_win2k);
1982 if (W_ERROR_IS_OK(status)) {
1985 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1986 printer_driver_files_in_use(info, p->server_info,
1988 /* no idea of the correct error here */
1989 talloc_free(info_win2k);
1990 status = WERR_ACCESS_DENIED;
1994 /* if we get to here, we now have 2 driver info structures to remove */
1995 /* remove the Win2k driver first*/
1997 status = winreg_del_driver(info, p->server_info,
2000 /* this should not have failed---if it did, report to client */
2002 if (!W_ERROR_IS_OK(status)) {
2007 * now delete any associated files if delete_files is
2008 * true. Even if this part failes, we return succes
2009 * because the driver doesn not exist any more
2012 delete_driver_files(p->server_info,
2018 status = winreg_del_driver(info, p->server_info, info, version);
2019 if (!W_ERROR_IS_OK(status)) {
2024 * now delete any associated files if delete_files is
2025 * true. Even if this part failes, we return succes
2026 * because the driver doesn not exist any more
2029 delete_driver_files(p->server_info, info);
2038 /********************************************************************
2039 GetPrinterData on a printer server Handle.
2040 ********************************************************************/
2042 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2044 enum winreg_Type *type,
2045 union spoolss_PrinterData *data)
2047 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2049 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2055 if (!StrCaseCmp(value, "BeepEnabled")) {
2061 if (!StrCaseCmp(value, "EventLog")) {
2063 /* formally was 0x1b */
2068 if (!StrCaseCmp(value, "NetPopup")) {
2074 if (!StrCaseCmp(value, "MajorVersion")) {
2077 /* Windows NT 4.0 seems to not allow uploading of drivers
2078 to a server that reports 0x3 as the MajorVersion.
2079 need to investigate more how Win2k gets around this .
2082 if (RA_WINNT == get_remote_arch()) {
2091 if (!StrCaseCmp(value, "MinorVersion")) {
2098 * uint32_t size = 0x114
2099 * uint32_t major = 5
2100 * uint32_t minor = [0|1]
2101 * uint32_t build = [2195|2600]
2102 * extra unicode string = e.g. "Service Pack 3"
2104 if (!StrCaseCmp(value, "OSVersion")) {
2106 enum ndr_err_code ndr_err;
2107 struct spoolss_OSVersion os;
2109 os.major = 5; /* Windows 2000 == 5.0 */
2111 os.build = 2195; /* build */
2112 os.extra_string = ""; /* leave extra string empty */
2114 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2115 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2116 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2117 return WERR_GENERAL_FAILURE;
2121 data->binary = blob;
2127 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2130 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2131 W_ERROR_HAVE_NO_MEMORY(data->string);
2136 if (!StrCaseCmp(value, "Architecture")) {
2138 data->string = talloc_strdup(mem_ctx,
2139 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2140 W_ERROR_HAVE_NO_MEMORY(data->string);
2145 if (!StrCaseCmp(value, "DsPresent")) {
2148 /* only show the publish check box if we are a
2149 member of a AD domain */
2151 if (lp_security() == SEC_ADS) {
2159 if (!StrCaseCmp(value, "DNSMachineName")) {
2160 const char *hostname = get_mydnsfullname();
2163 return WERR_BADFILE;
2167 data->string = talloc_strdup(mem_ctx, hostname);
2168 W_ERROR_HAVE_NO_MEMORY(data->string);
2175 return WERR_INVALID_PARAM;
2178 /****************************************************************
2179 _spoolss_GetPrinterData
2180 ****************************************************************/
2182 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2183 struct spoolss_GetPrinterData *r)
2185 struct spoolss_GetPrinterDataEx r2;
2187 r2.in.handle = r->in.handle;
2188 r2.in.key_name = "PrinterDriverData";
2189 r2.in.value_name = r->in.value_name;
2190 r2.in.offered = r->in.offered;
2191 r2.out.type = r->out.type;
2192 r2.out.data = r->out.data;
2193 r2.out.needed = r->out.needed;
2195 return _spoolss_GetPrinterDataEx(p, &r2);
2198 /*********************************************************
2199 Connect to the client machine.
2200 **********************************************************/
2202 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2203 struct sockaddr_storage *client_ss, const char *remote_machine)
2206 struct cli_state *the_cli;
2207 struct sockaddr_storage rm_addr;
2208 char addr[INET6_ADDRSTRLEN];
2210 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2211 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2213 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2214 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2217 print_sockaddr(addr, sizeof(addr), &rm_addr);
2219 rm_addr = *client_ss;
2220 print_sockaddr(addr, sizeof(addr), &rm_addr);
2221 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2225 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2226 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2231 /* setup the connection */
2232 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2233 &rm_addr, 0, "IPC$", "IPC",
2237 0, lp_client_signing(), NULL );
2239 if ( !NT_STATUS_IS_OK( ret ) ) {
2240 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2245 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2246 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2247 cli_shutdown(the_cli);
2252 * Ok - we have an anonymous connection to the IPC$ share.
2253 * Now start the NT Domain stuff :-).
2256 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2257 if (!NT_STATUS_IS_OK(ret)) {
2258 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2259 remote_machine, nt_errstr(ret)));
2260 cli_shutdown(the_cli);
2267 /***************************************************************************
2268 Connect to the client.
2269 ****************************************************************************/
2271 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2272 uint32_t localprinter, uint32_t type,
2273 struct policy_handle *handle,
2274 struct sockaddr_storage *client_ss)
2280 * If it's the first connection, contact the client
2281 * and connect to the IPC$ share anonymously
2283 if (smb_connections==0) {
2284 fstring unix_printer;
2286 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2288 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2291 messaging_register(smbd_messaging_context(), NULL,
2292 MSG_PRINTER_NOTIFY2,
2293 receive_notify2_message_list);
2294 /* Tell the connections db we're now interested in printer
2295 * notify messages. */
2296 serverid_register_msg_flags(
2297 messaging_server_id(smbd_messaging_context()),
2298 true, FLAG_MSG_PRINT_NOTIFY);
2302 * Tell the specific printing tdb we want messages for this printer
2303 * by registering our PID.
2306 if (!print_notify_register_pid(snum))
2307 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2311 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2319 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2320 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2321 win_errstr(result)));
2323 return (W_ERROR_IS_OK(result));
2326 /****************************************************************
2327 ****************************************************************/
2329 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2330 const struct spoolss_NotifyOption *r)
2332 struct spoolss_NotifyOption *option;
2339 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2346 if (!option->count) {
2350 option->types = talloc_zero_array(option,
2351 struct spoolss_NotifyOptionType, option->count);
2352 if (!option->types) {
2353 talloc_free(option);
2357 for (i=0; i < option->count; i++) {
2358 option->types[i] = r->types[i];
2360 if (option->types[i].count) {
2361 option->types[i].fields = talloc_zero_array(option,
2362 union spoolss_Field, option->types[i].count);
2363 if (!option->types[i].fields) {
2364 talloc_free(option);
2367 for (k=0; k<option->types[i].count; k++) {
2368 option->types[i].fields[k] =
2369 r->types[i].fields[k];
2377 /****************************************************************
2378 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2380 * before replying OK: status=0 a rpc call is made to the workstation
2381 * asking ReplyOpenPrinter
2383 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2384 * called from api_spoolss_rffpcnex
2385 ****************************************************************/
2387 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2388 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2391 struct spoolss_NotifyOption *option = r->in.notify_options;
2392 struct sockaddr_storage client_ss;
2394 /* store the notify value in the printer struct */
2396 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2399 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2400 "Invalid handle (%s:%u:%u).\n",
2401 OUR_HANDLE(r->in.handle)));
2405 Printer->notify.flags = r->in.flags;
2406 Printer->notify.options = r->in.options;
2407 Printer->notify.printerlocal = r->in.printer_local;
2409 TALLOC_FREE(Printer->notify.option);
2410 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2412 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2414 /* Connect to the client machine and send a ReplyOpenPrinter */
2416 if ( Printer->printer_type == SPLHND_SERVER)
2418 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2419 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2422 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2423 "client_address is %s\n", p->client_address));
2425 if (!interpret_string_addr(&client_ss, p->client_address,
2427 return WERR_SERVER_UNAVAILABLE;
2430 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2431 Printer->notify.printerlocal, 1,
2432 &Printer->notify.client_hnd, &client_ss))
2433 return WERR_SERVER_UNAVAILABLE;
2435 Printer->notify.client_connected = true;
2440 /*******************************************************************
2441 * fill a notify_info_data with the servername
2442 ********************************************************************/
2444 static void spoolss_notify_server_name(int snum,
2445 struct spoolss_Notify *data,
2446 print_queue_struct *queue,
2447 struct spoolss_PrinterInfo2 *pinfo2,
2448 TALLOC_CTX *mem_ctx)
2450 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2453 /*******************************************************************
2454 * fill a notify_info_data with the printername (not including the servername).
2455 ********************************************************************/
2457 static void spoolss_notify_printer_name(int snum,
2458 struct spoolss_Notify *data,
2459 print_queue_struct *queue,
2460 struct spoolss_PrinterInfo2 *pinfo2,
2461 TALLOC_CTX *mem_ctx)
2463 /* the notify name should not contain the \\server\ part */
2464 const char *p = strrchr(pinfo2->printername, '\\');
2467 p = pinfo2->printername;
2472 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2475 /*******************************************************************
2476 * fill a notify_info_data with the servicename
2477 ********************************************************************/
2479 static void spoolss_notify_share_name(int snum,
2480 struct spoolss_Notify *data,
2481 print_queue_struct *queue,
2482 struct spoolss_PrinterInfo2 *pinfo2,
2483 TALLOC_CTX *mem_ctx)
2485 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2488 /*******************************************************************
2489 * fill a notify_info_data with the port name
2490 ********************************************************************/
2492 static void spoolss_notify_port_name(int snum,
2493 struct spoolss_Notify *data,
2494 print_queue_struct *queue,
2495 struct spoolss_PrinterInfo2 *pinfo2,
2496 TALLOC_CTX *mem_ctx)
2498 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2501 /*******************************************************************
2502 * fill a notify_info_data with the printername
2503 * but it doesn't exist, have to see what to do
2504 ********************************************************************/
2506 static void spoolss_notify_driver_name(int snum,
2507 struct spoolss_Notify *data,
2508 print_queue_struct *queue,
2509 struct spoolss_PrinterInfo2 *pinfo2,
2510 TALLOC_CTX *mem_ctx)
2512 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2515 /*******************************************************************
2516 * fill a notify_info_data with the comment
2517 ********************************************************************/
2519 static void spoolss_notify_comment(int snum,
2520 struct spoolss_Notify *data,
2521 print_queue_struct *queue,
2522 struct spoolss_PrinterInfo2 *pinfo2,
2523 TALLOC_CTX *mem_ctx)
2527 if (*pinfo2->comment == '\0') {
2528 p = lp_comment(snum);
2530 p = pinfo2->comment;
2533 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2536 /*******************************************************************
2537 * fill a notify_info_data with the comment
2538 * location = "Room 1, floor 2, building 3"
2539 ********************************************************************/
2541 static void spoolss_notify_location(int snum,
2542 struct spoolss_Notify *data,
2543 print_queue_struct *queue,
2544 struct spoolss_PrinterInfo2 *pinfo2,
2545 TALLOC_CTX *mem_ctx)
2547 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2550 /*******************************************************************
2551 * fill a notify_info_data with the device mode
2552 * jfm:xxxx don't to it for know but that's a real problem !!!
2553 ********************************************************************/
2555 static void spoolss_notify_devmode(int snum,
2556 struct spoolss_Notify *data,
2557 print_queue_struct *queue,
2558 struct spoolss_PrinterInfo2 *pinfo2,
2559 TALLOC_CTX *mem_ctx)
2561 /* for a dummy implementation we have to zero the fields */
2562 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2565 /*******************************************************************
2566 * fill a notify_info_data with the separator file name
2567 ********************************************************************/
2569 static void spoolss_notify_sepfile(int snum,
2570 struct spoolss_Notify *data,
2571 print_queue_struct *queue,
2572 struct spoolss_PrinterInfo2 *pinfo2,
2573 TALLOC_CTX *mem_ctx)
2575 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2578 /*******************************************************************
2579 * fill a notify_info_data with the print processor
2580 * jfm:xxxx return always winprint to indicate we don't do anything to it
2581 ********************************************************************/
2583 static void spoolss_notify_print_processor(int snum,
2584 struct spoolss_Notify *data,
2585 print_queue_struct *queue,
2586 struct spoolss_PrinterInfo2 *pinfo2,
2587 TALLOC_CTX *mem_ctx)
2589 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2592 /*******************************************************************
2593 * fill a notify_info_data with the print processor options
2594 * jfm:xxxx send an empty string
2595 ********************************************************************/
2597 static void spoolss_notify_parameters(int snum,
2598 struct spoolss_Notify *data,
2599 print_queue_struct *queue,
2600 struct spoolss_PrinterInfo2 *pinfo2,
2601 TALLOC_CTX *mem_ctx)
2603 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2606 /*******************************************************************
2607 * fill a notify_info_data with the data type
2608 * jfm:xxxx always send RAW as data type
2609 ********************************************************************/
2611 static void spoolss_notify_datatype(int snum,
2612 struct spoolss_Notify *data,
2613 print_queue_struct *queue,
2614 struct spoolss_PrinterInfo2 *pinfo2,
2615 TALLOC_CTX *mem_ctx)
2617 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2620 /*******************************************************************
2621 * fill a notify_info_data with the security descriptor
2622 * jfm:xxxx send an null pointer to say no security desc
2623 * have to implement security before !
2624 ********************************************************************/
2626 static void spoolss_notify_security_desc(int snum,
2627 struct spoolss_Notify *data,
2628 print_queue_struct *queue,
2629 struct spoolss_PrinterInfo2 *pinfo2,
2630 TALLOC_CTX *mem_ctx)
2632 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2635 /*******************************************************************
2636 * fill a notify_info_data with the attributes
2637 * jfm:xxxx a samba printer is always shared
2638 ********************************************************************/
2640 static void spoolss_notify_attributes(int snum,
2641 struct spoolss_Notify *data,
2642 print_queue_struct *queue,
2643 struct spoolss_PrinterInfo2 *pinfo2,
2644 TALLOC_CTX *mem_ctx)
2646 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2649 /*******************************************************************
2650 * fill a notify_info_data with the priority
2651 ********************************************************************/
2653 static void spoolss_notify_priority(int snum,
2654 struct spoolss_Notify *data,
2655 print_queue_struct *queue,
2656 struct spoolss_PrinterInfo2 *pinfo2,
2657 TALLOC_CTX *mem_ctx)
2659 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2662 /*******************************************************************
2663 * fill a notify_info_data with the default priority
2664 ********************************************************************/
2666 static void spoolss_notify_default_priority(int snum,
2667 struct spoolss_Notify *data,
2668 print_queue_struct *queue,
2669 struct spoolss_PrinterInfo2 *pinfo2,
2670 TALLOC_CTX *mem_ctx)
2672 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2675 /*******************************************************************
2676 * fill a notify_info_data with the start time
2677 ********************************************************************/
2679 static void spoolss_notify_start_time(int snum,
2680 struct spoolss_Notify *data,
2681 print_queue_struct *queue,
2682 struct spoolss_PrinterInfo2 *pinfo2,
2683 TALLOC_CTX *mem_ctx)
2685 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2688 /*******************************************************************
2689 * fill a notify_info_data with the until time
2690 ********************************************************************/
2692 static void spoolss_notify_until_time(int snum,
2693 struct spoolss_Notify *data,
2694 print_queue_struct *queue,
2695 struct spoolss_PrinterInfo2 *pinfo2,
2696 TALLOC_CTX *mem_ctx)
2698 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2701 /*******************************************************************
2702 * fill a notify_info_data with the status
2703 ********************************************************************/
2705 static void spoolss_notify_status(int snum,
2706 struct spoolss_Notify *data,
2707 print_queue_struct *queue,
2708 struct spoolss_PrinterInfo2 *pinfo2,
2709 TALLOC_CTX *mem_ctx)
2711 print_status_struct status;
2713 print_queue_length(snum, &status);
2714 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2717 /*******************************************************************
2718 * fill a notify_info_data with the number of jobs queued
2719 ********************************************************************/
2721 static void spoolss_notify_cjobs(int snum,
2722 struct spoolss_Notify *data,
2723 print_queue_struct *queue,
2724 struct spoolss_PrinterInfo2 *pinfo2,
2725 TALLOC_CTX *mem_ctx)
2727 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2730 /*******************************************************************
2731 * fill a notify_info_data with the average ppm
2732 ********************************************************************/
2734 static void spoolss_notify_average_ppm(int snum,
2735 struct spoolss_Notify *data,
2736 print_queue_struct *queue,
2737 struct spoolss_PrinterInfo2 *pinfo2,
2738 TALLOC_CTX *mem_ctx)
2740 /* always respond 8 pages per minutes */
2741 /* a little hard ! */
2742 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2745 /*******************************************************************
2746 * fill a notify_info_data with username
2747 ********************************************************************/
2749 static void spoolss_notify_username(int snum,
2750 struct spoolss_Notify *data,
2751 print_queue_struct *queue,
2752 struct spoolss_PrinterInfo2 *pinfo2,
2753 TALLOC_CTX *mem_ctx)
2755 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2758 /*******************************************************************
2759 * fill a notify_info_data with job status
2760 ********************************************************************/
2762 static void spoolss_notify_job_status(int snum,
2763 struct spoolss_Notify *data,
2764 print_queue_struct *queue,
2765 struct spoolss_PrinterInfo2 *pinfo2,
2766 TALLOC_CTX *mem_ctx)
2768 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2771 /*******************************************************************
2772 * fill a notify_info_data with job name
2773 ********************************************************************/
2775 static void spoolss_notify_job_name(int snum,
2776 struct spoolss_Notify *data,
2777 print_queue_struct *queue,
2778 struct spoolss_PrinterInfo2 *pinfo2,
2779 TALLOC_CTX *mem_ctx)
2781 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2784 /*******************************************************************
2785 * fill a notify_info_data with job status
2786 ********************************************************************/
2788 static void spoolss_notify_job_status_string(int snum,
2789 struct spoolss_Notify *data,
2790 print_queue_struct *queue,
2791 struct spoolss_PrinterInfo2 *pinfo2,
2792 TALLOC_CTX *mem_ctx)
2795 * Now we're returning job status codes we just return a "" here. JRA.
2800 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2803 switch (queue->status) {
2808 p = ""; /* NT provides the paused string */
2817 #endif /* NO LONGER NEEDED. */
2819 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2822 /*******************************************************************
2823 * fill a notify_info_data with job time
2824 ********************************************************************/
2826 static void spoolss_notify_job_time(int snum,
2827 struct spoolss_Notify *data,
2828 print_queue_struct *queue,
2829 struct spoolss_PrinterInfo2 *pinfo2,
2830 TALLOC_CTX *mem_ctx)
2832 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2835 /*******************************************************************
2836 * fill a notify_info_data with job size
2837 ********************************************************************/
2839 static void spoolss_notify_job_size(int snum,
2840 struct spoolss_Notify *data,
2841 print_queue_struct *queue,
2842 struct spoolss_PrinterInfo2 *pinfo2,
2843 TALLOC_CTX *mem_ctx)
2845 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2848 /*******************************************************************
2849 * fill a notify_info_data with page info
2850 ********************************************************************/
2851 static void spoolss_notify_total_pages(int snum,
2852 struct spoolss_Notify *data,
2853 print_queue_struct *queue,
2854 struct spoolss_PrinterInfo2 *pinfo2,
2855 TALLOC_CTX *mem_ctx)
2857 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2860 /*******************************************************************
2861 * fill a notify_info_data with pages printed info.
2862 ********************************************************************/
2863 static void spoolss_notify_pages_printed(int snum,
2864 struct spoolss_Notify *data,
2865 print_queue_struct *queue,
2866 struct spoolss_PrinterInfo2 *pinfo2,
2867 TALLOC_CTX *mem_ctx)
2869 /* Add code when back-end tracks this */
2870 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2873 /*******************************************************************
2874 Fill a notify_info_data with job position.
2875 ********************************************************************/
2877 static void spoolss_notify_job_position(int snum,
2878 struct spoolss_Notify *data,
2879 print_queue_struct *queue,
2880 struct spoolss_PrinterInfo2 *pinfo2,
2881 TALLOC_CTX *mem_ctx)
2883 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2886 /*******************************************************************
2887 Fill a notify_info_data with submitted time.
2888 ********************************************************************/
2890 static void spoolss_notify_submitted_time(int snum,
2891 struct spoolss_Notify *data,
2892 print_queue_struct *queue,
2893 struct spoolss_PrinterInfo2 *pinfo2,
2894 TALLOC_CTX *mem_ctx)
2896 data->data.string.string = NULL;
2897 data->data.string.size = 0;
2899 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2900 &data->data.string.string,
2901 &data->data.string.size);
2905 struct s_notify_info_data_table
2907 enum spoolss_NotifyType type;
2910 enum spoolss_NotifyTable variable_type;
2911 void (*fn) (int snum, struct spoolss_Notify *data,
2912 print_queue_struct *queue,
2913 struct spoolss_PrinterInfo2 *pinfo2,
2914 TALLOC_CTX *mem_ctx);
2917 /* A table describing the various print notification constants and
2918 whether the notification data is a pointer to a variable sized
2919 buffer, a one value uint32_t or a two value uint32_t. */
2921 static const struct s_notify_info_data_table notify_info_data_table[] =
2923 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2924 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2925 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2926 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2927 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2928 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2929 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2930 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2931 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2932 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2933 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2934 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2935 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2936 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2937 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2938 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2939 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2940 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2941 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2942 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2943 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2949 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2950 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2951 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2952 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2953 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2954 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2955 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2956 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2957 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2958 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2959 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2960 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2961 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2962 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2963 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2964 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2965 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2966 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2967 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2968 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2969 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2970 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2971 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2974 /*******************************************************************
2975 Return the variable_type of info_data structure.
2976 ********************************************************************/
2978 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
2983 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
2984 if ( (notify_info_data_table[i].type == type) &&
2985 (notify_info_data_table[i].field == field) ) {
2986 return notify_info_data_table[i].variable_type;
2990 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
2995 /****************************************************************************
2996 ****************************************************************************/
2998 static bool search_notify(enum spoolss_NotifyType type,
3004 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3005 if (notify_info_data_table[i].type == type &&
3006 notify_info_data_table[i].field == field &&
3007 notify_info_data_table[i].fn != NULL) {
3016 /****************************************************************************
3017 ****************************************************************************/
3019 static void construct_info_data(struct spoolss_Notify *info_data,
3020 enum spoolss_NotifyType type,
3021 uint16_t field, int id)
3023 info_data->type = type;
3024 info_data->field.field = field;
3025 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3026 info_data->job_id = id;
3029 /*******************************************************************
3031 * fill a notify_info struct with info asked
3033 ********************************************************************/
3035 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3036 struct spoolss_NotifyInfo *info,
3037 struct spoolss_PrinterInfo2 *pinfo2,
3039 const struct spoolss_NotifyOptionType *option_type,
3041 TALLOC_CTX *mem_ctx)
3044 enum spoolss_NotifyType type;
3047 struct spoolss_Notify *current_data;
3048 print_queue_struct *queue=NULL;
3050 type = option_type->type;
3052 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3053 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3054 option_type->count, lp_servicename(snum)));
3056 for(field_num=0; field_num < option_type->count; field_num++) {
3057 field = option_type->fields[field_num].field;
3059 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3061 if (!search_notify(type, field, &j) )
3064 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3065 struct spoolss_Notify,
3067 if (info->notifies == NULL) {
3068 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3072 current_data = &info->notifies[info->count];
3074 construct_info_data(current_data, type, field, id);
3076 DEBUG(10, ("construct_notify_printer_info: "
3077 "calling [%s] snum=%d printername=[%s])\n",
3078 notify_info_data_table[j].name, snum,
3079 pinfo2->printername));
3081 notify_info_data_table[j].fn(snum, current_data, queue,
3090 /*******************************************************************
3092 * fill a notify_info struct with info asked
3094 ********************************************************************/
3096 static bool construct_notify_jobs_info(print_queue_struct *queue,
3097 struct spoolss_NotifyInfo *info,
3098 struct spoolss_PrinterInfo2 *pinfo2,
3100 const struct spoolss_NotifyOptionType *option_type,
3102 TALLOC_CTX *mem_ctx)
3105 enum spoolss_NotifyType type;
3107 struct spoolss_Notify *current_data;
3109 DEBUG(4,("construct_notify_jobs_info\n"));
3111 type = option_type->type;
3113 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3114 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3115 option_type->count));
3117 for(field_num=0; field_num<option_type->count; field_num++) {
3118 field = option_type->fields[field_num].field;
3120 if (!search_notify(type, field, &j) )
3123 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3124 struct spoolss_Notify,
3126 if (info->notifies == NULL) {
3127 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3131 current_data=&(info->notifies[info->count]);
3133 construct_info_data(current_data, type, field, id);
3134 notify_info_data_table[j].fn(snum, current_data, queue,
3143 * JFM: The enumeration is not that simple, it's even non obvious.
3145 * let's take an example: I want to monitor the PRINTER SERVER for
3146 * the printer's name and the number of jobs currently queued.
3147 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3148 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3150 * I have 3 printers on the back of my server.
3152 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3155 * 1 printer 1 name 1
3156 * 2 printer 1 cjob 1
3157 * 3 printer 2 name 2
3158 * 4 printer 2 cjob 2
3159 * 5 printer 3 name 3
3160 * 6 printer 3 name 3
3162 * that's the print server case, the printer case is even worse.
3165 /*******************************************************************
3167 * enumerate all printers on the printserver
3168 * fill a notify_info struct with info asked
3170 ********************************************************************/
3172 static WERROR printserver_notify_info(struct pipes_struct *p,
3173 struct policy_handle *hnd,
3174 struct spoolss_NotifyInfo *info,
3175 TALLOC_CTX *mem_ctx)
3178 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3179 int n_services=lp_numservices();
3181 struct spoolss_NotifyOption *option;
3182 struct spoolss_NotifyOptionType option_type;
3183 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3186 DEBUG(4,("printserver_notify_info\n"));
3191 option = Printer->notify.option;
3194 info->notifies = NULL;
3197 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3198 sending a ffpcn() request first */
3203 for (i=0; i<option->count; i++) {
3204 option_type = option->types[i];
3206 if (option_type.type != PRINTER_NOTIFY_TYPE)
3209 for (snum = 0; snum < n_services; snum++) {
3210 if (!lp_browseable(snum) ||
3211 !lp_snum_ok(snum) ||
3212 !lp_print_ok(snum)) {
3213 continue; /* skip */
3216 /* Maybe we should use the SYSTEM server_info here... */
3217 result = winreg_get_printer(mem_ctx, p->server_info,
3218 Printer->servername,
3219 lp_servicename(snum),
3221 if (!W_ERROR_IS_OK(result)) {
3222 DEBUG(4, ("printserver_notify_info: "
3223 "Failed to get printer [%s]\n",
3224 lp_servicename(snum)));
3229 construct_notify_printer_info(Printer, info,
3234 TALLOC_FREE(pinfo2);
3240 * Debugging information, don't delete.
3243 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3244 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3245 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3247 for (i=0; i<info->count; i++) {
3248 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3249 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3250 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3257 /*******************************************************************
3259 * fill a notify_info struct with info asked
3261 ********************************************************************/
3263 static WERROR printer_notify_info(struct pipes_struct *p,
3264 struct policy_handle *hnd,
3265 struct spoolss_NotifyInfo *info,
3266 TALLOC_CTX *mem_ctx)
3269 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3272 struct spoolss_NotifyOption *option;
3273 struct spoolss_NotifyOptionType option_type;
3275 print_queue_struct *queue=NULL;
3276 print_status_struct status;
3277 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3280 DEBUG(4,("printer_notify_info\n"));
3285 option = Printer->notify.option;
3289 info->notifies = NULL;
3292 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3293 sending a ffpcn() request first */
3298 get_printer_snum(p, hnd, &snum, NULL);
3300 /* Maybe we should use the SYSTEM server_info here... */
3301 result = winreg_get_printer(mem_ctx, p->server_info,
3302 Printer->servername,
3303 lp_servicename(snum), &pinfo2);
3304 if (!W_ERROR_IS_OK(result)) {
3308 for (i=0; i<option->count; i++) {
3309 option_type = option->types[i];
3311 switch (option_type.type) {
3312 case PRINTER_NOTIFY_TYPE:
3313 if (construct_notify_printer_info(Printer, info,
3321 case JOB_NOTIFY_TYPE:
3323 count = print_queue_status(snum, &queue, &status);
3325 for (j=0; j<count; j++) {
3326 construct_notify_jobs_info(&queue[j], info,
3339 * Debugging information, don't delete.
3342 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3343 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3344 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3346 for (i=0; i<info->count; i++) {
3347 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3348 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3349 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3353 talloc_free(pinfo2);
3357 /****************************************************************
3358 _spoolss_RouterRefreshPrinterChangeNotify
3359 ****************************************************************/
3361 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3362 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3364 struct spoolss_NotifyInfo *info;
3366 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3367 WERROR result = WERR_BADFID;
3369 /* we always have a spoolss_NotifyInfo struct */
3370 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3372 result = WERR_NOMEM;
3376 *r->out.info = info;
3379 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3380 "Invalid handle (%s:%u:%u).\n",
3381 OUR_HANDLE(r->in.handle)));
3385 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3388 * We are now using the change value, and
3389 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3390 * I don't have a global notification system, I'm sending back all the
3391 * informations even when _NOTHING_ has changed.
3394 /* We need to keep track of the change value to send back in
3395 RRPCN replies otherwise our updates are ignored. */
3397 Printer->notify.fnpcn = true;
3399 if (Printer->notify.client_connected) {
3400 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3401 "Saving change value in request [%x]\n",
3403 Printer->notify.change = r->in.change_low;
3406 /* just ignore the spoolss_NotifyOption */
3408 switch (Printer->printer_type) {
3410 result = printserver_notify_info(p, r->in.handle,
3414 case SPLHND_PRINTER:
3415 result = printer_notify_info(p, r->in.handle,
3420 Printer->notify.fnpcn = false;
3426 /********************************************************************
3427 * construct_printer_info_0
3428 * fill a printer_info_0 struct
3429 ********************************************************************/
3431 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3432 struct auth_serversupplied_info *server_info,
3433 struct spoolss_PrinterInfo2 *info2,
3434 struct spoolss_PrinterInfo0 *r,
3438 counter_printer_0 *session_counter;
3439 struct timeval setuptime;
3440 print_status_struct status;
3442 r->printername = talloc_strdup(mem_ctx, info2->printername);
3443 W_ERROR_HAVE_NO_MEMORY(r->printername);
3445 r->servername = talloc_strdup(mem_ctx, info2->servername);
3446 W_ERROR_HAVE_NO_MEMORY(r->servername);
3448 count = print_queue_length(snum, &status);
3450 /* check if we already have a counter for this printer */
3451 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3452 if (session_counter->snum == snum)
3456 /* it's the first time, add it to the list */
3457 if (session_counter == NULL) {
3458 session_counter = SMB_MALLOC_P(counter_printer_0);
3459 W_ERROR_HAVE_NO_MEMORY(session_counter);
3460 ZERO_STRUCTP(session_counter);
3461 session_counter->snum = snum;
3462 session_counter->counter = 0;
3463 DLIST_ADD(counter_list, session_counter);
3467 session_counter->counter++;
3473 get_startup_time(&setuptime);
3474 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3477 * the global_counter should be stored in a TDB as it's common to all the clients
3478 * and should be zeroed on samba startup
3480 r->global_counter = session_counter->counter;
3482 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3483 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3484 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3485 r->free_build = SPOOLSS_RELEASE_BUILD;
3487 r->max_spooling = 0;
3488 r->session_counter = session_counter->counter;
3489 r->num_error_out_of_paper = 0x0;
3490 r->num_error_not_ready = 0x0; /* number of print failure */
3492 r->number_of_processors = 0x1;
3493 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3494 r->high_part_total_bytes = 0x0;
3495 winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3496 r->last_error = WERR_OK;
3497 r->status = nt_printq_status(status.status);
3498 r->enumerate_network_printers = 0x0;
3499 r->c_setprinter = 0x0;
3500 r->processor_architecture = 0x0;
3501 r->processor_level = 0x6; /* 6 ???*/
3510 /********************************************************************
3511 * construct_printer_info1
3512 * fill a spoolss_PrinterInfo1 struct
3513 ********************************************************************/
3515 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3516 const struct spoolss_PrinterInfo2 *info2,
3518 struct spoolss_PrinterInfo1 *r,
3523 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3527 W_ERROR_HAVE_NO_MEMORY(r->description);
3529 if (info2->comment == NULL || info2->comment[0] == '\0') {
3530 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3532 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3534 W_ERROR_HAVE_NO_MEMORY(r->comment);
3536 r->name = talloc_strdup(mem_ctx, info2->printername);
3537 W_ERROR_HAVE_NO_MEMORY(r->name);
3542 /********************************************************************
3543 * construct_printer_info2
3544 * fill a spoolss_PrinterInfo2 struct
3545 ********************************************************************/
3547 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3548 const struct spoolss_PrinterInfo2 *info2,
3549 struct spoolss_PrinterInfo2 *r,
3553 print_status_struct status;
3555 count = print_queue_length(snum, &status);
3557 r->servername = talloc_strdup(mem_ctx, info2->servername);
3558 W_ERROR_HAVE_NO_MEMORY(r->servername);
3559 r->printername = talloc_strdup(mem_ctx, info2->printername);
3560 W_ERROR_HAVE_NO_MEMORY(r->printername);
3561 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3562 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3563 r->portname = talloc_strdup(mem_ctx, info2->portname);
3564 W_ERROR_HAVE_NO_MEMORY(r->portname);
3565 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3566 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3568 if (info2->comment[0] == '\0') {
3569 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3571 r->comment = talloc_strdup(mem_ctx, info2->comment);
3573 W_ERROR_HAVE_NO_MEMORY(r->comment);
3575 r->location = talloc_strdup(mem_ctx, info2->location);
3576 W_ERROR_HAVE_NO_MEMORY(r->location);
3577 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3578 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3579 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3580 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3581 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3582 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3583 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3584 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3586 r->attributes = info2->attributes;
3588 r->priority = info2->priority;
3589 r->defaultpriority = info2->defaultpriority;
3590 r->starttime = info2->starttime;
3591 r->untiltime = info2->untiltime;
3592 r->status = nt_printq_status(status.status);
3594 r->averageppm = info2->averageppm;
3596 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3598 DEBUG(8,("Returning NULL Devicemode!\n"));
3603 if (info2->secdesc != NULL) {
3604 /* don't use talloc_steal() here unless you do a deep steal of all
3605 the SEC_DESC members */
3607 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3613 /********************************************************************
3614 * construct_printer_info3
3615 * fill a spoolss_PrinterInfo3 struct
3616 ********************************************************************/
3618 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3619 const struct spoolss_PrinterInfo2 *info2,
3620 struct spoolss_PrinterInfo3 *r,
3623 /* These are the components of the SD we are returning. */
3625 if (info2->secdesc != NULL) {
3626 /* don't use talloc_steal() here unless you do a deep steal of all
3627 the SEC_DESC members */
3629 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3630 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3636 /********************************************************************
3637 * construct_printer_info4
3638 * fill a spoolss_PrinterInfo4 struct
3639 ********************************************************************/
3641 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3642 const struct spoolss_PrinterInfo2 *info2,
3643 struct spoolss_PrinterInfo4 *r,
3646 r->printername = talloc_strdup(mem_ctx, info2->printername);
3647 W_ERROR_HAVE_NO_MEMORY(r->printername);
3648 r->servername = talloc_strdup(mem_ctx, info2->servername);
3649 W_ERROR_HAVE_NO_MEMORY(r->servername);
3651 r->attributes = info2->attributes;
3656 /********************************************************************
3657 * construct_printer_info5
3658 * fill a spoolss_PrinterInfo5 struct
3659 ********************************************************************/
3661 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3662 const struct spoolss_PrinterInfo2 *info2,
3663 struct spoolss_PrinterInfo5 *r,
3666 r->printername = talloc_strdup(mem_ctx, info2->printername);
3667 W_ERROR_HAVE_NO_MEMORY(r->printername);
3668 r->portname = talloc_strdup(mem_ctx, info2->portname);
3669 W_ERROR_HAVE_NO_MEMORY(r->portname);
3671 r->attributes = info2->attributes;
3673 /* these two are not used by NT+ according to MSDN */
3674 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3675 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3680 /********************************************************************
3681 * construct_printer_info_6
3682 * fill a spoolss_PrinterInfo6 struct
3683 ********************************************************************/
3685 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3686 const struct spoolss_PrinterInfo2 *info2,
3687 struct spoolss_PrinterInfo6 *r,
3691 print_status_struct status;
3693 count = print_queue_length(snum, &status);
3695 r->status = nt_printq_status(status.status);
3700 /********************************************************************
3701 * construct_printer_info7
3702 * fill a spoolss_PrinterInfo7 struct
3703 ********************************************************************/
3705 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3706 Printer_entry *print_hnd,
3707 struct spoolss_PrinterInfo7 *r,
3710 struct auth_serversupplied_info *server_info;
3714 status = make_server_info_system(mem_ctx, &server_info);
3715 if (!NT_STATUS_IS_OK(status)) {
3716 DEBUG(0, ("construct_printer_info7: "
3717 "Could not create system server_info\n"));
3721 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3722 lp_servicename(snum), &guid, NULL)) {
3723 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3724 r->action = DSPRINT_PUBLISH;
3726 r->guid = talloc_strdup(mem_ctx, "");
3727 r->action = DSPRINT_UNPUBLISH;
3729 W_ERROR_HAVE_NO_MEMORY(r->guid);
3731 TALLOC_FREE(server_info);
3735 /********************************************************************
3736 * construct_printer_info8
3737 * fill a spoolss_PrinterInfo8 struct
3738 ********************************************************************/
3740 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3741 const struct spoolss_PrinterInfo2 *info2,
3742 struct spoolss_DeviceModeInfo *r,
3745 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3747 DEBUG(8,("Returning NULL Devicemode!\n"));
3754 /********************************************************************
3755 ********************************************************************/
3757 static bool snum_is_shared_printer(int snum)
3759 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3762 /********************************************************************
3763 Spoolss_enumprinters.
3764 ********************************************************************/
3766 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3767 struct auth_serversupplied_info *server_info,
3770 union spoolss_PrinterInfo **info_p,
3774 int n_services = lp_numservices();
3775 union spoolss_PrinterInfo *info = NULL;
3777 WERROR result = WERR_OK;
3782 for (snum = 0; snum < n_services; snum++) {
3784 const char *printer;
3785 struct spoolss_PrinterInfo2 *info2;
3787 if (!snum_is_shared_printer(snum)) {
3791 printer = lp_const_servicename(snum);
3793 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3796 result = winreg_create_printer(mem_ctx,
3800 if (!W_ERROR_IS_OK(result)) {
3804 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3805 union spoolss_PrinterInfo,
3808 result = WERR_NOMEM;
3812 result = winreg_get_printer(mem_ctx, server_info,
3813 NULL, printer, &info2);
3814 if (!W_ERROR_IS_OK(result)) {
3820 result = construct_printer_info0(info, server_info, info2,
3821 &info[count].info0, snum);
3824 result = construct_printer_info1(info, info2, flags,
3825 &info[count].info1, snum);
3828 result = construct_printer_info2(info, info2,
3829 &info[count].info2, snum);
3832 result = construct_printer_info4(info, info2,
3833 &info[count].info4, snum);
3836 result = construct_printer_info5(info, info2,
3837 &info[count].info5, snum);
3841 result = WERR_UNKNOWN_LEVEL;
3845 if (!W_ERROR_IS_OK(result)) {
3856 if (!W_ERROR_IS_OK(result)) {
3866 /********************************************************************
3867 * handle enumeration of printers at level 0
3868 ********************************************************************/
3870 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3871 struct auth_serversupplied_info *server_info,
3873 const char *servername,
3874 union spoolss_PrinterInfo **info,
3877 DEBUG(4,("enum_all_printers_info_0\n"));
3879 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3883 /********************************************************************
3884 ********************************************************************/
3886 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3887 struct auth_serversupplied_info *server_info,
3889 union spoolss_PrinterInfo **info,
3892 DEBUG(4,("enum_all_printers_info_1\n"));
3894 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3897 /********************************************************************
3898 enum_all_printers_info_1_local.
3899 *********************************************************************/
3901 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3902 struct auth_serversupplied_info *server_info,
3903 union spoolss_PrinterInfo **info,
3906 DEBUG(4,("enum_all_printers_info_1_local\n"));
3908 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3911 /********************************************************************
3912 enum_all_printers_info_1_name.
3913 *********************************************************************/
3915 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3916 struct auth_serversupplied_info *server_info,
3918 union spoolss_PrinterInfo **info,
3921 const char *s = name;
3923 DEBUG(4,("enum_all_printers_info_1_name\n"));
3925 if ((name[0] == '\\') && (name[1] == '\\')) {
3929 if (!is_myname_or_ipaddr(s)) {
3930 return WERR_INVALID_NAME;
3933 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3936 /********************************************************************
3937 enum_all_printers_info_1_network.
3938 *********************************************************************/
3940 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3941 struct auth_serversupplied_info *server_info,
3943 union spoolss_PrinterInfo **info,
3946 const char *s = name;
3948 DEBUG(4,("enum_all_printers_info_1_network\n"));
3950 /* If we respond to a enum_printers level 1 on our name with flags
3951 set to PRINTER_ENUM_REMOTE with a list of printers then these
3952 printers incorrectly appear in the APW browse list.
3953 Specifically the printers for the server appear at the workgroup
3954 level where all the other servers in the domain are
3955 listed. Windows responds to this call with a
3956 WERR_CAN_NOT_COMPLETE so we should do the same. */
3958 if (name[0] == '\\' && name[1] == '\\') {
3962 if (is_myname_or_ipaddr(s)) {
3963 return WERR_CAN_NOT_COMPLETE;
3966 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3969 /********************************************************************
3970 * api_spoolss_enumprinters
3972 * called from api_spoolss_enumprinters (see this to understand)
3973 ********************************************************************/
3975 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3976 struct auth_serversupplied_info *server_info,
3977 union spoolss_PrinterInfo **info,
3980 DEBUG(4,("enum_all_printers_info_2\n"));
3982 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
3985 /********************************************************************
3986 * handle enumeration of printers at level 1
3987 ********************************************************************/
3989 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
3990 struct auth_serversupplied_info *server_info,
3993 union spoolss_PrinterInfo **info,
3996 /* Not all the flags are equals */
3998 if (flags & PRINTER_ENUM_LOCAL) {
3999 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4002 if (flags & PRINTER_ENUM_NAME) {
4003 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4006 if (flags & PRINTER_ENUM_NETWORK) {
4007 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4010 return WERR_OK; /* NT4sp5 does that */
4013 /********************************************************************
4014 * handle enumeration of printers at level 2
4015 ********************************************************************/
4017 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4018 struct auth_serversupplied_info *server_info,
4020 const char *servername,
4021 union spoolss_PrinterInfo **info,
4024 if (flags & PRINTER_ENUM_LOCAL) {
4025 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4028 if (flags & PRINTER_ENUM_NAME) {
4029 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4030 return WERR_INVALID_NAME;
4033 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4036 if (flags & PRINTER_ENUM_REMOTE) {
4037 return WERR_UNKNOWN_LEVEL;
4043 /********************************************************************
4044 * handle enumeration of printers at level 4
4045 ********************************************************************/
4047 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4048 struct auth_serversupplied_info *server_info,
4050 const char *servername,
4051 union spoolss_PrinterInfo **info,
4054 DEBUG(4,("enum_all_printers_info_4\n"));
4056 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4060 /********************************************************************
4061 * handle enumeration of printers at level 5
4062 ********************************************************************/
4064 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4065 struct auth_serversupplied_info *server_info,
4067 const char *servername,
4068 union spoolss_PrinterInfo **info,
4071 DEBUG(4,("enum_all_printers_info_5\n"));
4073 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4076 /****************************************************************
4077 _spoolss_EnumPrinters
4078 ****************************************************************/
4080 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4081 struct spoolss_EnumPrinters *r)
4083 const char *name = NULL;
4086 /* that's an [in out] buffer */
4088 if (!r->in.buffer && (r->in.offered != 0)) {
4089 return WERR_INVALID_PARAM;
4092 DEBUG(4,("_spoolss_EnumPrinters\n"));
4096 *r->out.info = NULL;
4100 * flags==PRINTER_ENUM_NAME
4101 * if name=="" then enumerates all printers
4102 * if name!="" then enumerate the printer
4103 * flags==PRINTER_ENUM_REMOTE
4104 * name is NULL, enumerate printers
4105 * Level 2: name!="" enumerates printers, name can't be NULL
4106 * Level 3: doesn't exist
4107 * Level 4: does a local registry lookup
4108 * Level 5: same as Level 2
4112 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4113 W_ERROR_HAVE_NO_MEMORY(name);
4116 switch (r->in.level) {
4118 result = enumprinters_level0(p->mem_ctx, p->server_info,
4120 r->out.info, r->out.count);
4123 result = enumprinters_level1(p->mem_ctx, p->server_info,
4125 r->out.info, r->out.count);
4128 result = enumprinters_level2(p->mem_ctx, p->server_info,
4130 r->out.info, r->out.count);
4133 result = enumprinters_level4(p->mem_ctx, p->server_info,
4135 r->out.info, r->out.count);
4138 result = enumprinters_level5(p->mem_ctx, p->server_info,
4140 r->out.info, r->out.count);
4143 return WERR_UNKNOWN_LEVEL;
4146 if (!W_ERROR_IS_OK(result)) {
4150 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4151 spoolss_EnumPrinters,
4152 *r->out.info, r->in.level,
4154 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4155 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4157 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4160 /****************************************************************
4162 ****************************************************************/
4164 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4165 struct spoolss_GetPrinter *r)
4167 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4168 struct spoolss_PrinterInfo2 *info2 = NULL;
4169 WERROR result = WERR_OK;
4170 const char *servername = NULL;
4173 /* that's an [in out] buffer */
4175 if (!r->in.buffer && (r->in.offered != 0)) {
4176 return WERR_INVALID_PARAM;
4181 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4185 if (Printer != NULL || Printer->servername != NULL) {
4186 servername = Printer->servername;
4189 result = winreg_get_printer(p->mem_ctx,
4192 lp_const_servicename(snum),
4194 if (!W_ERROR_IS_OK(result)) {
4198 switch (r->in.level) {
4200 result = construct_printer_info0(p->mem_ctx, p->server_info,
4202 &r->out.info->info0, snum);
4205 result = construct_printer_info1(p->mem_ctx, info2,
4207 &r->out.info->info1, snum);
4210 result = construct_printer_info2(p->mem_ctx, info2,
4211 &r->out.info->info2, snum);
4214 result = construct_printer_info3(p->mem_ctx, info2,
4215 &r->out.info->info3, snum);
4218 result = construct_printer_info4(p->mem_ctx, info2,
4219 &r->out.info->info4, snum);
4222 result = construct_printer_info5(p->mem_ctx, info2,
4223 &r->out.info->info5, snum);
4226 result = construct_printer_info6(p->mem_ctx, info2,
4227 &r->out.info->info6, snum);
4230 result = construct_printer_info7(p->mem_ctx, Printer,
4231 &r->out.info->info7, snum);
4234 result = construct_printer_info8(p->mem_ctx, info2,
4235 &r->out.info->info8, snum);
4238 result = WERR_UNKNOWN_LEVEL;
4242 if (!W_ERROR_IS_OK(result)) {
4243 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4244 r->in.level, win_errstr(result)));
4245 TALLOC_FREE(r->out.info);
4249 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4250 r->out.info, r->in.level);
4251 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4253 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4256 /********************************************************************
4257 ********************************************************************/
4259 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4261 if (in && strlen(in)) { \
4262 out = talloc_strdup(mem_ctx, in); \
4264 out = talloc_strdup(mem_ctx, ""); \
4266 W_ERROR_HAVE_NO_MEMORY(out); \
4269 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4271 if (in && strlen(in)) { \
4272 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4274 out = talloc_strdup(mem_ctx, ""); \
4276 W_ERROR_HAVE_NO_MEMORY(out); \
4279 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4280 const char **string_array,
4281 const char ***presult,
4282 const char *cservername,
4286 int i, num_strings = 0;
4287 const char **array = NULL;
4289 if (string_array == NULL) {
4290 return WERR_INVALID_PARAMETER;;
4293 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4294 const char *str = NULL;
4296 if (cservername == NULL || arch == NULL) {
4297 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4299 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4302 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4309 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4310 &array, &num_strings);
4320 /********************************************************************
4321 * fill a spoolss_DriverInfo1 struct
4322 ********************************************************************/
4324 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4325 struct spoolss_DriverInfo1 *r,
4326 const struct spoolss_DriverInfo8 *driver,
4327 const char *servername)
4329 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4330 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4335 /********************************************************************
4336 * fill a spoolss_DriverInfo2 struct
4337 ********************************************************************/
4339 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4340 struct spoolss_DriverInfo2 *r,
4341 const struct spoolss_DriverInfo8 *driver,
4342 const char *servername)
4345 const char *cservername = canon_servername(servername);
4347 r->version = driver->version;
4349 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4350 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4351 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4352 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4354 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4355 driver->architecture,
4357 driver->driver_path,
4360 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4361 driver->architecture,
4366 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4367 driver->architecture,
4369 driver->config_file,
4375 /********************************************************************
4376 * fill a spoolss_DriverInfo3 struct
4377 ********************************************************************/
4379 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4380 struct spoolss_DriverInfo3 *r,
4381 const struct spoolss_DriverInfo8 *driver,
4382 const char *servername)
4384 const char *cservername = canon_servername(servername);
4386 r->version = driver->version;
4388 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4389 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4390 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4391 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4393 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4394 driver->architecture,
4396 driver->driver_path,
4399 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4400 driver->architecture,
4405 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4406 driver->architecture,
4408 driver->config_file,
4411 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4412 driver->architecture,
4417 FILL_DRIVER_STRING(mem_ctx,
4418 driver->monitor_name,
4421 FILL_DRIVER_STRING(mem_ctx,
4422 driver->default_datatype,
4423 r->default_datatype);
4425 return string_array_from_driver_info(mem_ctx,
4426 driver->dependent_files,
4427 &r->dependent_files,
4429 driver->architecture,
4433 /********************************************************************
4434 * fill a spoolss_DriverInfo4 struct
4435 ********************************************************************/
4437 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4438 struct spoolss_DriverInfo4 *r,
4439 const struct spoolss_DriverInfo8 *driver,
4440 const char *servername)
4442 const char *cservername = canon_servername(servername);
4445 r->version = driver->version;
4447 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4448 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4449 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4450 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4452 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4453 driver->architecture,
4455 driver->driver_path,
4458 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4459 driver->architecture,
4464 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4465 driver->architecture,
4467 driver->config_file,
4470 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4471 driver->architecture,
4476 result = string_array_from_driver_info(mem_ctx,
4477 driver->dependent_files,
4478 &r->dependent_files,
4480 driver->architecture,
4482 if (!W_ERROR_IS_OK(result)) {
4486 FILL_DRIVER_STRING(mem_ctx,
4487 driver->monitor_name,
4490 FILL_DRIVER_STRING(mem_ctx,
4491 driver->default_datatype,
4492 r->default_datatype);
4495 result = string_array_from_driver_info(mem_ctx,
4496 driver->previous_names,
4503 /********************************************************************
4504 * fill a spoolss_DriverInfo5 struct
4505 ********************************************************************/
4507 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4508 struct spoolss_DriverInfo5 *r,
4509 const struct spoolss_DriverInfo8 *driver,
4510 const char *servername)
4512 const char *cservername = canon_servername(servername);
4514 r->version = driver->version;
4516 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4517 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4518 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4519 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4521 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4522 driver->architecture,
4524 driver->driver_path,
4527 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4528 driver->architecture,
4533 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4534 driver->architecture,
4536 driver->config_file,
4539 r->driver_attributes = 0;
4540 r->config_version = 0;
4541 r->driver_version = 0;
4545 /********************************************************************
4546 * fill a spoolss_DriverInfo6 struct
4547 ********************************************************************/
4549 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4550 struct spoolss_DriverInfo6 *r,
4551 const struct spoolss_DriverInfo8 *driver,
4552 const char *servername)
4554 const char *cservername = canon_servername(servername);
4557 r->version = driver->version;
4559 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4560 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4561 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4562 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4564 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4565 driver->architecture,
4567 driver->driver_path,
4570 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4571 driver->architecture,
4576 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4577 driver->architecture,
4579 driver->config_file,
4582 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4583 driver->architecture,
4588 FILL_DRIVER_STRING(mem_ctx,
4589 driver->monitor_name,
4592 FILL_DRIVER_STRING(mem_ctx,
4593 driver->default_datatype,
4594 r->default_datatype);
4596 result = string_array_from_driver_info(mem_ctx,
4597 driver->dependent_files,
4598 &r->dependent_files,
4600 driver->architecture,
4602 if (!W_ERROR_IS_OK(result)) {
4606 result = string_array_from_driver_info(mem_ctx,
4607 driver->previous_names,
4610 if (!W_ERROR_IS_OK(result)) {
4614 r->driver_date = driver->driver_date;
4615 r->driver_version = driver->driver_version;
4617 FILL_DRIVER_STRING(mem_ctx,
4618 driver->manufacturer_name,
4619 r->manufacturer_name);
4620 FILL_DRIVER_STRING(mem_ctx,
4621 driver->manufacturer_url,
4622 r->manufacturer_url);
4623 FILL_DRIVER_STRING(mem_ctx,
4624 driver->hardware_id,
4626 FILL_DRIVER_STRING(mem_ctx,
4633 /********************************************************************
4634 * fill a spoolss_DriverInfo8 struct
4635 ********************************************************************/
4637 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4638 struct spoolss_DriverInfo8 *r,
4639 const struct spoolss_DriverInfo8 *driver,
4640 const char *servername)
4642 const char *cservername = canon_servername(servername);
4645 r->version = driver->version;
4647 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4648 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4649 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4650 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4652 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4653 driver->architecture,
4655 driver->driver_path,
4658 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4659 driver->architecture,
4664 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4665 driver->architecture,
4667 driver->config_file,
4670 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4671 driver->architecture,
4676 FILL_DRIVER_STRING(mem_ctx,
4677 driver->monitor_name,
4680 FILL_DRIVER_STRING(mem_ctx,
4681 driver->default_datatype,
4682 r->default_datatype);
4684 result = string_array_from_driver_info(mem_ctx,
4685 driver->dependent_files,
4686 &r->dependent_files,
4688 driver->architecture,
4690 if (!W_ERROR_IS_OK(result)) {
4694 result = string_array_from_driver_info(mem_ctx,
4695 driver->previous_names,
4698 if (!W_ERROR_IS_OK(result)) {
4702 r->driver_date = driver->driver_date;
4703 r->driver_version = driver->driver_version;
4705 FILL_DRIVER_STRING(mem_ctx,
4706 driver->manufacturer_name,
4707 r->manufacturer_name);
4708 FILL_DRIVER_STRING(mem_ctx,
4709 driver->manufacturer_url,
4710 r->manufacturer_url);
4711 FILL_DRIVER_STRING(mem_ctx,
4712 driver->hardware_id,
4714 FILL_DRIVER_STRING(mem_ctx,
4718 FILL_DRIVER_STRING(mem_ctx,
4719 driver->print_processor,
4720 r->print_processor);
4721 FILL_DRIVER_STRING(mem_ctx,
4722 driver->vendor_setup,
4725 result = string_array_from_driver_info(mem_ctx,
4726 driver->color_profiles,
4729 if (!W_ERROR_IS_OK(result)) {
4733 FILL_DRIVER_STRING(mem_ctx,
4737 r->printer_driver_attributes = driver->printer_driver_attributes;
4739 result = string_array_from_driver_info(mem_ctx,
4740 driver->core_driver_dependencies,
4741 &r->core_driver_dependencies,
4743 if (!W_ERROR_IS_OK(result)) {
4747 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4748 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4753 #if 0 /* disabled until marshalling issues are resolved - gd */
4754 /********************************************************************
4755 ********************************************************************/
4757 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4758 struct spoolss_DriverFileInfo *r,
4759 const char *cservername,
4760 const char *file_name,
4761 enum spoolss_DriverFileType file_type,
4762 uint32_t file_version)
4764 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4765 cservername, file_name);
4766 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4767 r->file_type = file_type;
4768 r->file_version = file_version;
4773 /********************************************************************
4774 ********************************************************************/
4776 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4777 const struct spoolss_DriverInfo8 *driver,
4778 const char *cservername,
4779 struct spoolss_DriverFileInfo **info_p,
4782 struct spoolss_DriverFileInfo *info = NULL;
4790 if (strlen(driver->driver_path)) {
4791 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4792 struct spoolss_DriverFileInfo,
4794 W_ERROR_HAVE_NO_MEMORY(info);
4795 result = fill_spoolss_DriverFileInfo(info,
4798 driver->driver_path,
4799 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4801 W_ERROR_NOT_OK_RETURN(result);
4805 if (strlen(driver->config_file)) {
4806 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4807 struct spoolss_DriverFileInfo,
4809 W_ERROR_HAVE_NO_MEMORY(info);
4810 result = fill_spoolss_DriverFileInfo(info,
4813 driver->config_file,
4814 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4816 W_ERROR_NOT_OK_RETURN(result);
4820 if (strlen(driver->data_file)) {
4821 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4822 struct spoolss_DriverFileInfo,
4824 W_ERROR_HAVE_NO_MEMORY(info);
4825 result = fill_spoolss_DriverFileInfo(info,
4829 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4831 W_ERROR_NOT_OK_RETURN(result);
4835 if (strlen(driver->help_file)) {
4836 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4837 struct spoolss_DriverFileInfo,
4839 W_ERROR_HAVE_NO_MEMORY(info);
4840 result = fill_spoolss_DriverFileInfo(info,
4844 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4846 W_ERROR_NOT_OK_RETURN(result);
4850 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4851 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4852 struct spoolss_DriverFileInfo,
4854 W_ERROR_HAVE_NO_MEMORY(info);
4855 result = fill_spoolss_DriverFileInfo(info,
4858 driver->dependent_files[i],
4859 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4861 W_ERROR_NOT_OK_RETURN(result);
4871 /********************************************************************
4872 * fill a spoolss_DriverInfo101 struct
4873 ********************************************************************/
4875 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4876 struct spoolss_DriverInfo101 *r,
4877 const struct spoolss_DriverInfo8 *driver,
4878 const char *servername)
4880 const char *cservername = canon_servername(servername);
4883 r->version = driver->version;
4885 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4886 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4887 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4888 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4890 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4894 if (!W_ERROR_IS_OK(result)) {
4898 FILL_DRIVER_STRING(mem_ctx,
4899 driver->monitor_name,
4902 FILL_DRIVER_STRING(mem_ctx,
4903 driver->default_datatype,
4904 r->default_datatype);
4906 result = string_array_from_driver_info(mem_ctx,
4907 driver->previous_names,
4910 if (!W_ERROR_IS_OK(result)) {
4914 r->driver_date = driver->driver_date;
4915 r->driver_version = driver->driver_version;
4917 FILL_DRIVER_STRING(mem_ctx,
4918 driver->manufacturer_name,
4919 r->manufacturer_name);
4920 FILL_DRIVER_STRING(mem_ctx,
4921 driver->manufacturer_url,
4922 r->manufacturer_url);
4923 FILL_DRIVER_STRING(mem_ctx,
4924 driver->hardware_id,
4926 FILL_DRIVER_STRING(mem_ctx,
4933 /********************************************************************
4934 ********************************************************************/
4936 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4937 struct auth_serversupplied_info *server_info,
4939 union spoolss_DriverInfo *r,
4941 const char *servername,
4942 const char *architecture,
4945 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4946 struct spoolss_DriverInfo8 *driver;
4949 result = winreg_get_printer(mem_ctx,
4952 lp_const_servicename(snum),
4955 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4956 win_errstr(result)));
4958 if (!W_ERROR_IS_OK(result)) {
4959 return WERR_INVALID_PRINTER_NAME;
4962 result = winreg_get_driver(mem_ctx, server_info, architecture,
4963 pinfo2->drivername, version, &driver);
4965 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4966 win_errstr(result)));
4968 if (!W_ERROR_IS_OK(result)) {
4970 * Is this a W2k client ?
4974 talloc_free(pinfo2);
4975 return WERR_UNKNOWN_PRINTER_DRIVER;
4978 /* Yes - try again with a WinNT driver. */
4980 result = winreg_get_driver(mem_ctx, server_info, architecture,
4983 DEBUG(8,("construct_printer_driver_level: status: %s\n",
4984 win_errstr(result)));
4985 if (!W_ERROR_IS_OK(result)) {
4986 talloc_free(pinfo2);
4987 return WERR_UNKNOWN_PRINTER_DRIVER;
4993 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
4996 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
4999 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5002 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5005 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5008 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5011 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5013 #if 0 /* disabled until marshalling issues are resolved - gd */
5015 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5019 result = WERR_UNKNOWN_LEVEL;
5023 talloc_free(pinfo2);
5024 talloc_free(driver);
5029 /****************************************************************
5030 _spoolss_GetPrinterDriver2
5031 ****************************************************************/
5033 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5034 struct spoolss_GetPrinterDriver2 *r)
5036 Printer_entry *printer;
5041 /* that's an [in out] buffer */
5043 if (!r->in.buffer && (r->in.offered != 0)) {
5044 return WERR_INVALID_PARAM;
5047 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5049 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5050 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5051 return WERR_INVALID_PRINTER_NAME;
5055 *r->out.server_major_version = 0;
5056 *r->out.server_minor_version = 0;
5058 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5062 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5063 r->in.level, r->out.info,
5064 snum, printer->servername,
5066 r->in.client_major_version);
5067 if (!W_ERROR_IS_OK(result)) {
5068 TALLOC_FREE(r->out.info);
5072 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5073 r->out.info, r->in.level);
5074 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5076 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5080 /****************************************************************
5081 _spoolss_StartPagePrinter
5082 ****************************************************************/
5084 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5085 struct spoolss_StartPagePrinter *r)
5087 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5090 DEBUG(3,("_spoolss_StartPagePrinter: "
5091 "Error in startpageprinter printer handle\n"));
5095 Printer->page_started = true;
5099 /****************************************************************
5100 _spoolss_EndPagePrinter
5101 ****************************************************************/
5103 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5104 struct spoolss_EndPagePrinter *r)
5108 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5111 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5112 OUR_HANDLE(r->in.handle)));
5116 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5119 Printer->page_started = false;
5120 print_job_endpage(snum, Printer->jobid);
5125 /****************************************************************
5126 _spoolss_StartDocPrinter
5127 ****************************************************************/
5129 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5130 struct spoolss_StartDocPrinter *r)
5132 struct spoolss_DocumentInfo1 *info_1;
5134 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5138 DEBUG(2,("_spoolss_StartDocPrinter: "
5139 "Invalid handle (%s:%u:%u)\n",
5140 OUR_HANDLE(r->in.handle)));
5144 if (Printer->jobid) {
5145 DEBUG(2, ("_spoolss_StartDocPrinter: "
5146 "StartDocPrinter called twice! "
5147 "(existing jobid = %d)\n", Printer->jobid));
5148 return WERR_INVALID_HANDLE;
5151 if (r->in.level != 1) {
5152 return WERR_UNKNOWN_LEVEL;
5155 info_1 = r->in.info.info1;
5158 * a nice thing with NT is it doesn't listen to what you tell it.
5159 * when asked to send _only_ RAW datas, it tries to send datas
5162 * So I add checks like in NT Server ...
5165 if (info_1->datatype) {
5166 if (strcmp(info_1->datatype, "RAW") != 0) {
5168 return WERR_INVALID_DATATYPE;
5172 /* get the share number of the printer */
5173 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5177 werr = print_job_start(p->server_info, snum,
5178 info_1->document_name, info_1->output_file,
5179 Printer->devmode, &Printer->jobid);
5181 /* An error occured in print_job_start() so return an appropriate
5184 if (!W_ERROR_IS_OK(werr)) {
5188 Printer->document_started = true;
5189 *r->out.job_id = Printer->jobid;
5194 /****************************************************************
5195 _spoolss_EndDocPrinter
5196 ****************************************************************/
5198 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5199 struct spoolss_EndDocPrinter *r)
5201 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5206 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5207 OUR_HANDLE(r->in.handle)));
5211 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5215 Printer->document_started = false;
5216 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5217 if (!NT_STATUS_IS_OK(status)) {
5218 DEBUG(2, ("_spoolss_EndDocPrinter: "
5219 "print_job_end failed [%s]\n",
5220 nt_errstr(status)));
5224 return ntstatus_to_werror(status);
5227 /****************************************************************
5228 _spoolss_WritePrinter
5229 ****************************************************************/
5231 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5232 struct spoolss_WritePrinter *r)
5234 ssize_t buffer_written;
5236 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5239 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5240 OUR_HANDLE(r->in.handle)));
5241 *r->out.num_written = r->in._data_size;
5245 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5248 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5249 buffer_written = print_job_write(snum, Printer->jobid,
5250 (const char *)r->in.data.data,
5252 (size_t)r->in._data_size);
5253 if (buffer_written == (ssize_t)-1) {
5254 *r->out.num_written = 0;
5255 if (errno == ENOSPC)
5256 return WERR_NO_SPOOL_SPACE;
5258 return WERR_ACCESS_DENIED;
5261 *r->out.num_written = r->in._data_size;
5266 /********************************************************************
5267 * api_spoolss_getprinter
5268 * called from the spoolss dispatcher
5270 ********************************************************************/
5272 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5273 struct pipes_struct *p)
5276 WERROR errcode = WERR_BADFUNC;
5277 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5280 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5281 OUR_HANDLE(handle)));
5285 if (!get_printer_snum(p, handle, &snum, NULL))
5289 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5290 errcode = print_queue_pause(p->server_info, snum);
5292 case SPOOLSS_PRINTER_CONTROL_RESUME:
5293 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5294 errcode = print_queue_resume(p->server_info, snum);
5296 case SPOOLSS_PRINTER_CONTROL_PURGE:
5297 errcode = print_queue_purge(p->server_info, snum);
5300 return WERR_UNKNOWN_LEVEL;
5307 /****************************************************************
5308 _spoolss_AbortPrinter
5309 * From MSDN: "Deletes printer's spool file if printer is configured
5311 ****************************************************************/
5313 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5314 struct spoolss_AbortPrinter *r)
5316 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5318 WERROR errcode = WERR_OK;
5321 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5322 OUR_HANDLE(r->in.handle)));
5326 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5329 if (!Printer->document_started) {
5330 return WERR_SPL_NO_STARTDOC;
5333 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5338 /********************************************************************
5339 * called by spoolss_api_setprinter
5340 * when updating a printer description
5341 ********************************************************************/
5343 static WERROR update_printer_sec(struct policy_handle *handle,
5344 struct pipes_struct *p,
5345 struct sec_desc_buf *secdesc_ctr)
5347 struct spoolss_security_descriptor *new_secdesc = NULL;
5348 struct spoolss_security_descriptor *old_secdesc = NULL;
5349 const char *printer;
5353 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5355 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5356 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5357 OUR_HANDLE(handle)));
5359 result = WERR_BADFID;
5363 if (secdesc_ctr == NULL) {
5364 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5365 result = WERR_INVALID_PARAM;
5368 printer = lp_const_servicename(snum);
5370 /* Check the user has permissions to change the security
5371 descriptor. By experimentation with two NT machines, the user
5372 requires Full Access to the printer to change security
5375 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5376 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5377 result = WERR_ACCESS_DENIED;
5381 /* NT seems to like setting the security descriptor even though
5382 nothing may have actually changed. */
5383 result = winreg_get_printer_secdesc(p->mem_ctx,
5387 if (!W_ERROR_IS_OK(result)) {
5388 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5389 result = WERR_BADFID;
5393 if (DEBUGLEVEL >= 10) {
5394 struct security_acl *the_acl;
5397 the_acl = old_secdesc->dacl;
5398 DEBUG(10, ("old_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 the_acl = secdesc_ctr->sd->dacl;
5410 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5411 printer, the_acl->num_aces));
5413 for (i = 0; i < the_acl->num_aces; i++) {
5414 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5415 &the_acl->aces[i].trustee),
5416 the_acl->aces[i].access_mask));
5419 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5423 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5424 if (new_secdesc == NULL) {
5425 result = WERR_NOMEM;
5429 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5434 result = winreg_set_printer_secdesc(p->mem_ctx,
5443 /********************************************************************
5444 Canonicalize printer info from a client
5445 ********************************************************************/
5447 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5448 struct spoolss_SetPrinterInfo2 *info2,
5451 fstring printername;
5454 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5455 "portname=%s drivername=%s comment=%s location=%s\n",
5456 info2->servername, info2->printername, info2->sharename,
5457 info2->portname, info2->drivername, info2->comment,
5460 /* we force some elements to "correct" values */
5461 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5462 if (info2->servername == NULL) {
5465 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5466 if (info2->sharename == NULL) {
5470 /* check to see if we allow printername != sharename */
5471 if (lp_force_printername(snum)) {
5472 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5473 global_myname(), info2->sharename);
5475 /* make sure printername is in \\server\printername format */
5476 fstrcpy(printername, info2->printername);
5478 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5479 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5483 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5484 global_myname(), p);
5486 if (info2->printername == NULL) {
5490 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5491 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5496 /****************************************************************************
5497 ****************************************************************************/
5499 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5501 char *cmd = lp_addport_cmd();
5502 char *command = NULL;
5504 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5505 bool is_print_op = false;
5508 return WERR_ACCESS_DENIED;
5511 command = talloc_asprintf(ctx,
5512 "%s \"%s\" \"%s\"", cmd, portname, uri );
5518 is_print_op = user_has_privileges( token, &se_printop );
5520 DEBUG(10,("Running [%s]\n", command));
5522 /********* BEGIN SePrintOperatorPrivilege **********/
5527 ret = smbrun(command, NULL);
5532 /********* END SePrintOperatorPrivilege **********/
5534 DEBUGADD(10,("returned [%d]\n", ret));
5536 TALLOC_FREE(command);
5539 return WERR_ACCESS_DENIED;
5545 /****************************************************************************
5546 ****************************************************************************/
5548 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5549 struct spoolss_SetPrinterInfo2 *info2,
5550 const char *remote_machine)
5552 char *cmd = lp_addprinter_cmd();
5554 char *command = NULL;
5558 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5559 bool is_print_op = false;
5561 if (!remote_machine) {
5565 command = talloc_asprintf(ctx,
5566 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5567 cmd, info2->printername, info2->sharename,
5568 info2->portname, info2->drivername,
5569 info2->location, info2->comment, remote_machine);
5575 is_print_op = user_has_privileges( token, &se_printop );
5577 DEBUG(10,("Running [%s]\n", command));
5579 /********* BEGIN SePrintOperatorPrivilege **********/
5584 if ( (ret = smbrun(command, &fd)) == 0 ) {
5585 /* Tell everyone we updated smb.conf. */
5586 message_send_all(smbd_messaging_context(),
5587 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5593 /********* END SePrintOperatorPrivilege **********/
5595 DEBUGADD(10,("returned [%d]\n", ret));
5597 TALLOC_FREE(command);
5605 /* reload our services immediately */
5607 reload_services(false);
5611 /* Get lines and convert them back to dos-codepage */
5612 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5613 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5616 /* Set the portname to what the script says the portname should be. */
5617 /* but don't require anything to be return from the script exit a good error code */
5620 /* Set the portname to what the script says the portname should be. */
5621 info2->portname = talloc_strdup(ctx, qlines[0]);
5622 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5625 TALLOC_FREE(qlines);
5629 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5630 struct auth_serversupplied_info *server_info,
5632 struct spoolss_SetPrinterInfo2 *printer,
5633 struct spoolss_PrinterInfo2 *old_printer)
5635 bool force_update = (old_printer == NULL);
5636 const char *dnsdomname;
5637 const char *longname;
5638 const char *uncname;
5639 const char *spooling;
5641 WERROR result = WERR_OK;
5643 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5644 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5645 winreg_set_printer_dataex(mem_ctx,
5648 SPOOL_DSSPOOLER_KEY,
5649 SPOOL_REG_DRIVERNAME,
5654 if (!force_update) {
5655 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5656 printer->drivername));
5658 notify_printer_driver(snum, printer->drivername);
5662 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5663 push_reg_sz(mem_ctx, &buffer, printer->comment);
5664 winreg_set_printer_dataex(mem_ctx,
5667 SPOOL_DSSPOOLER_KEY,
5668 SPOOL_REG_DESCRIPTION,
5673 if (!force_update) {
5674 notify_printer_comment(snum, printer->comment);
5678 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5679 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5680 winreg_set_printer_dataex(mem_ctx,
5683 SPOOL_DSSPOOLER_KEY,
5684 SPOOL_REG_PRINTSHARENAME,
5689 if (!force_update) {
5690 notify_printer_sharename(snum, printer->sharename);
5694 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5697 p = strrchr(printer->printername, '\\' );
5701 p = printer->printername;
5704 push_reg_sz(mem_ctx, &buffer, p);
5705 winreg_set_printer_dataex(mem_ctx,
5708 SPOOL_DSSPOOLER_KEY,
5709 SPOOL_REG_PRINTERNAME,
5714 if (!force_update) {
5715 notify_printer_printername(snum, p);
5719 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5720 push_reg_sz(mem_ctx, &buffer, printer->portname);
5721 winreg_set_printer_dataex(mem_ctx,
5724 SPOOL_DSSPOOLER_KEY,
5730 if (!force_update) {
5731 notify_printer_port(snum, printer->portname);
5735 if (force_update || !strequal(printer->location, old_printer->location)) {
5736 push_reg_sz(mem_ctx, &buffer, printer->location);
5737 winreg_set_printer_dataex(mem_ctx,
5740 SPOOL_DSSPOOLER_KEY,
5746 if (!force_update) {
5747 notify_printer_location(snum, printer->location);
5751 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5752 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5753 winreg_set_printer_dataex(mem_ctx,
5756 SPOOL_DSSPOOLER_KEY,
5757 SPOOL_REG_PRINTSEPARATORFILE,
5762 if (!force_update) {
5763 notify_printer_location(snum, printer->location);
5767 if (force_update || printer->starttime != old_printer->starttime) {
5768 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5769 SIVAL(buffer.data, 0, printer->starttime);
5770 winreg_set_printer_dataex(mem_ctx,
5773 SPOOL_DSSPOOLER_KEY,
5774 SPOOL_REG_PRINTSTARTTIME,
5780 if (force_update || printer->untiltime != old_printer->untiltime) {
5781 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5782 SIVAL(buffer.data, 0, printer->untiltime);
5783 winreg_set_printer_dataex(mem_ctx,
5786 SPOOL_DSSPOOLER_KEY,
5787 SPOOL_REG_PRINTENDTIME,
5793 if (force_update || printer->priority != old_printer->priority) {
5794 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5795 SIVAL(buffer.data, 0, printer->priority);
5796 winreg_set_printer_dataex(mem_ctx,
5799 SPOOL_DSSPOOLER_KEY,
5806 if (force_update || printer->attributes != old_printer->attributes) {
5807 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5808 SIVAL(buffer.data, 0, (printer->attributes &
5809 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5810 winreg_set_printer_dataex(mem_ctx,
5813 SPOOL_DSSPOOLER_KEY,
5814 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5819 switch (printer->attributes & 0x3) {
5821 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5824 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5827 spooling = SPOOL_REGVAL_PRINTDIRECT;
5830 spooling = "unknown";
5832 push_reg_sz(mem_ctx, &buffer, spooling);
5833 winreg_set_printer_dataex(mem_ctx,
5836 SPOOL_DSSPOOLER_KEY,
5837 SPOOL_REG_PRINTSPOOLING,
5843 push_reg_sz(mem_ctx, &buffer, global_myname());
5844 winreg_set_printer_dataex(mem_ctx,
5847 SPOOL_DSSPOOLER_KEY,
5848 SPOOL_REG_SHORTSERVERNAME,
5853 dnsdomname = get_mydnsfullname();
5854 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5855 longname = talloc_strdup(mem_ctx, dnsdomname);
5857 longname = talloc_strdup(mem_ctx, global_myname());
5859 if (longname == NULL) {
5860 result = WERR_NOMEM;
5864 push_reg_sz(mem_ctx, &buffer, longname);
5865 winreg_set_printer_dataex(mem_ctx,
5868 SPOOL_DSSPOOLER_KEY,
5869 SPOOL_REG_SERVERNAME,
5874 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5875 global_myname(), printer->sharename);
5876 push_reg_sz(mem_ctx, &buffer, uncname);
5877 winreg_set_printer_dataex(mem_ctx,
5880 SPOOL_DSSPOOLER_KEY,
5890 /********************************************************************
5891 * Called by spoolss_api_setprinter
5892 * when updating a printer description.
5893 ********************************************************************/
5895 static WERROR update_printer(struct pipes_struct *p,
5896 struct policy_handle *handle,
5897 struct spoolss_SetPrinterInfoCtr *info_ctr,
5898 struct spoolss_DeviceMode *devmode)
5900 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5901 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5902 struct spoolss_PrinterInfo2 *old_printer;
5903 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5904 const char *servername = NULL;
5906 WERROR result = WERR_OK;
5907 TALLOC_CTX *tmp_ctx;
5909 DEBUG(8,("update_printer\n"));
5911 tmp_ctx = talloc_new(p->mem_ctx);
5912 if (tmp_ctx == NULL) {
5917 result = WERR_BADFID;
5921 if (!get_printer_snum(p, handle, &snum, NULL)) {
5922 result = WERR_BADFID;
5926 if (Printer != NULL || Printer->servername != NULL) {
5927 servername = Printer->servername;
5930 result = winreg_get_printer(tmp_ctx,
5933 lp_const_servicename(snum),
5935 if (!W_ERROR_IS_OK(result)) {
5936 result = WERR_BADFID;
5940 /* Do sanity check on the requested changes for Samba */
5941 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5942 result = WERR_INVALID_PARAM;
5946 /* FIXME!!! If the driver has changed we really should verify that
5947 it is installed before doing much else --jerry */
5949 /* Check calling user has permission to update printer description */
5950 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5951 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5952 result = WERR_ACCESS_DENIED;
5956 /* Call addprinter hook */
5957 /* Check changes to see if this is really needed */
5959 if (*lp_addprinter_cmd() &&
5960 (!strequal(printer->drivername, old_printer->drivername) ||
5961 !strequal(printer->comment, old_printer->comment) ||
5962 !strequal(printer->portname, old_printer->portname) ||
5963 !strequal(printer->location, old_printer->location)) )
5965 /* add_printer_hook() will call reload_services() */
5966 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5967 printer, p->client_address) ) {
5968 result = WERR_ACCESS_DENIED;
5973 update_dsspooler(tmp_ctx,
5979 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
5981 if (devmode == NULL) {
5982 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
5984 result = winreg_update_printer(tmp_ctx,
5993 talloc_free(tmp_ctx);
5998 /****************************************************************************
5999 ****************************************************************************/
6000 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6001 struct policy_handle *handle,
6002 struct spoolss_SetPrinterInfo7 *info7)
6005 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6008 Printer_entry *Printer;
6010 if ( lp_security() != SEC_ADS ) {
6011 return WERR_UNKNOWN_LEVEL;
6014 Printer = find_printer_index_by_hnd(p, handle);
6016 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6021 if (!get_printer_snum(p, handle, &snum, NULL))
6024 result = winreg_get_printer(p->mem_ctx, p->server_info,
6025 Printer->servername,
6026 lp_servicename(snum), &pinfo2);
6027 if (!W_ERROR_IS_OK(result)) {
6031 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6033 TALLOC_FREE(pinfo2);
6036 return WERR_UNKNOWN_LEVEL;
6040 /********************************************************************
6041 ********************************************************************/
6043 static WERROR update_printer_devmode(struct pipes_struct *p,
6044 struct policy_handle *handle,
6045 struct spoolss_DeviceMode *devmode)
6048 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6049 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6051 DEBUG(8,("update_printer_devmode\n"));
6057 if (!get_printer_snum(p, handle, &snum, NULL)) {
6061 /* Check calling user has permission to update printer description */
6062 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6063 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6064 return WERR_ACCESS_DENIED;
6067 return winreg_update_printer(p->mem_ctx,
6069 lp_const_servicename(snum),
6077 /****************************************************************
6079 ****************************************************************/
6081 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6082 struct spoolss_SetPrinter *r)
6086 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6089 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6090 OUR_HANDLE(r->in.handle)));
6094 /* check the level */
6095 switch (r->in.info_ctr->level) {
6097 return control_printer(r->in.handle, r->in.command, p);
6099 result = update_printer(p, r->in.handle,
6101 r->in.devmode_ctr->devmode);
6102 if (!W_ERROR_IS_OK(result))
6104 if (r->in.secdesc_ctr->sd)
6105 result = update_printer_sec(r->in.handle, p,
6109 return update_printer_sec(r->in.handle, p,
6112 return publish_or_unpublish_printer(p, r->in.handle,
6113 r->in.info_ctr->info.info7);
6115 return update_printer_devmode(p, r->in.handle,
6116 r->in.devmode_ctr->devmode);
6118 return WERR_UNKNOWN_LEVEL;
6122 /****************************************************************
6123 _spoolss_FindClosePrinterNotify
6124 ****************************************************************/
6126 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6127 struct spoolss_FindClosePrinterNotify *r)
6129 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6132 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6133 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6137 if (Printer->notify.client_connected == true) {
6140 if ( Printer->printer_type == SPLHND_SERVER)
6142 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6143 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6146 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6149 Printer->notify.flags=0;
6150 Printer->notify.options=0;
6151 Printer->notify.localmachine[0]='\0';
6152 Printer->notify.printerlocal=0;
6153 TALLOC_FREE(Printer->notify.option);
6154 Printer->notify.client_connected = false;
6159 /****************************************************************
6161 ****************************************************************/
6163 WERROR _spoolss_AddJob(struct pipes_struct *p,
6164 struct spoolss_AddJob *r)
6166 if (!r->in.buffer && (r->in.offered != 0)) {
6167 return WERR_INVALID_PARAM;
6170 /* this is what a NT server returns for AddJob. AddJob must fail on
6171 * non-local printers */
6173 if (r->in.level != 1) {
6174 return WERR_UNKNOWN_LEVEL;
6177 return WERR_INVALID_PARAM;
6180 /****************************************************************************
6182 ****************************************************************************/
6184 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6185 struct spoolss_JobInfo1 *r,
6186 const print_queue_struct *queue,
6187 int position, int snum,
6188 struct spoolss_PrinterInfo2 *pinfo2)
6192 t = gmtime(&queue->time);
6194 r->job_id = queue->job;
6196 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6197 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6198 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6199 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6200 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6201 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6202 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6203 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6204 r->data_type = talloc_strdup(mem_ctx, "RAW");
6205 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6206 r->text_status = talloc_strdup(mem_ctx, "");
6207 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6209 r->status = nt_printj_status(queue->status);
6210 r->priority = queue->priority;
6211 r->position = position;
6212 r->total_pages = queue->page_count;
6213 r->pages_printed = 0; /* ??? */
6215 init_systemtime(&r->submitted, t);
6220 /****************************************************************************
6222 ****************************************************************************/
6224 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6225 struct spoolss_JobInfo2 *r,
6226 const print_queue_struct *queue,
6227 int position, int snum,
6228 struct spoolss_PrinterInfo2 *pinfo2,
6229 struct spoolss_DeviceMode *devmode)
6233 t = gmtime(&queue->time);
6235 r->job_id = queue->job;
6237 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6238 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6239 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6240 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6241 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6242 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6243 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6244 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6245 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6246 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6247 r->data_type = talloc_strdup(mem_ctx, "RAW");
6248 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6249 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6250 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6251 r->parameters = talloc_strdup(mem_ctx, "");
6252 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6253 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6254 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6256 r->devmode = devmode;
6258 r->text_status = talloc_strdup(mem_ctx, "");
6259 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6263 r->status = nt_printj_status(queue->status);
6264 r->priority = queue->priority;
6265 r->position = position;
6268 r->total_pages = queue->page_count;
6269 r->size = queue->size;
6270 init_systemtime(&r->submitted, t);
6272 r->pages_printed = 0; /* ??? */
6277 /****************************************************************************
6279 ****************************************************************************/
6281 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6282 struct spoolss_JobInfo3 *r,
6283 const print_queue_struct *queue,
6284 const print_queue_struct *next_queue,
6285 int position, int snum,
6286 struct spoolss_PrinterInfo2 *pinfo2)
6288 r->job_id = queue->job;
6291 r->next_job_id = next_queue->job;
6298 /****************************************************************************
6299 Enumjobs at level 1.
6300 ****************************************************************************/
6302 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6303 const print_queue_struct *queue,
6304 uint32_t num_queues, int snum,
6305 struct spoolss_PrinterInfo2 *pinfo2,
6306 union spoolss_JobInfo **info_p,
6309 union spoolss_JobInfo *info;
6311 WERROR result = WERR_OK;
6313 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6314 W_ERROR_HAVE_NO_MEMORY(info);
6316 *count = num_queues;
6318 for (i=0; i<*count; i++) {
6319 result = fill_job_info1(info,
6325 if (!W_ERROR_IS_OK(result)) {
6331 if (!W_ERROR_IS_OK(result)) {
6342 /****************************************************************************
6343 Enumjobs at level 2.
6344 ****************************************************************************/
6346 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6347 const print_queue_struct *queue,
6348 uint32_t num_queues, int snum,
6349 struct spoolss_PrinterInfo2 *pinfo2,
6350 union spoolss_JobInfo **info_p,
6353 union spoolss_JobInfo *info;
6355 WERROR result = WERR_OK;
6357 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6358 W_ERROR_HAVE_NO_MEMORY(info);
6360 *count = num_queues;
6362 for (i=0; i<*count; i++) {
6363 struct spoolss_DeviceMode *devmode;
6365 result = spoolss_create_default_devmode(info,
6366 pinfo2->printername,
6368 if (!W_ERROR_IS_OK(result)) {
6369 DEBUG(3, ("Can't proceed w/o a devmode!"));
6373 result = fill_job_info2(info,
6380 if (!W_ERROR_IS_OK(result)) {
6386 if (!W_ERROR_IS_OK(result)) {
6397 /****************************************************************************
6398 Enumjobs at level 3.
6399 ****************************************************************************/
6401 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6402 const print_queue_struct *queue,
6403 uint32_t num_queues, int snum,
6404 struct spoolss_PrinterInfo2 *pinfo2,
6405 union spoolss_JobInfo **info_p,
6408 union spoolss_JobInfo *info;
6410 WERROR result = WERR_OK;
6412 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6413 W_ERROR_HAVE_NO_MEMORY(info);
6415 *count = num_queues;
6417 for (i=0; i<*count; i++) {
6418 const print_queue_struct *next_queue = NULL;
6421 next_queue = &queue[i+1];
6424 result = fill_job_info3(info,
6431 if (!W_ERROR_IS_OK(result)) {
6437 if (!W_ERROR_IS_OK(result)) {
6448 /****************************************************************
6450 ****************************************************************/
6452 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6453 struct spoolss_EnumJobs *r)
6456 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6458 print_status_struct prt_status;
6459 print_queue_struct *queue = NULL;
6462 /* that's an [in out] buffer */
6464 if (!r->in.buffer && (r->in.offered != 0)) {
6465 return WERR_INVALID_PARAM;
6468 DEBUG(4,("_spoolss_EnumJobs\n"));
6472 *r->out.info = NULL;
6474 /* lookup the printer snum and tdb entry */
6476 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6480 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6481 lp_servicename(snum), &pinfo2);
6482 if (!W_ERROR_IS_OK(result)) {
6486 count = print_queue_status(snum, &queue, &prt_status);
6487 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6488 count, prt_status.status, prt_status.message));
6492 TALLOC_FREE(pinfo2);
6496 switch (r->in.level) {
6498 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6499 pinfo2, r->out.info, r->out.count);
6502 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6503 pinfo2, r->out.info, r->out.count);
6506 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6507 pinfo2, r->out.info, r->out.count);
6510 result = WERR_UNKNOWN_LEVEL;
6515 TALLOC_FREE(pinfo2);
6517 if (!W_ERROR_IS_OK(result)) {
6521 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6523 *r->out.info, r->in.level,
6525 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6526 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6528 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6531 /****************************************************************
6532 _spoolss_ScheduleJob
6533 ****************************************************************/
6535 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6536 struct spoolss_ScheduleJob *r)
6541 /****************************************************************
6542 ****************************************************************/
6544 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6545 const char *printer_name,
6547 struct spoolss_SetJobInfo1 *r)
6551 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6555 if (strequal(old_doc_name, r->document_name)) {
6559 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6566 /****************************************************************
6568 ****************************************************************/
6570 WERROR _spoolss_SetJob(struct pipes_struct *p,
6571 struct spoolss_SetJob *r)
6574 WERROR errcode = WERR_BADFUNC;
6576 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6580 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6581 return WERR_INVALID_PRINTER_NAME;
6584 switch (r->in.command) {
6585 case SPOOLSS_JOB_CONTROL_CANCEL:
6586 case SPOOLSS_JOB_CONTROL_DELETE:
6587 errcode = print_job_delete(p->server_info,
6588 snum, r->in.job_id);
6589 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6593 case SPOOLSS_JOB_CONTROL_PAUSE:
6594 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6598 case SPOOLSS_JOB_CONTROL_RESTART:
6599 case SPOOLSS_JOB_CONTROL_RESUME:
6600 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6608 return WERR_UNKNOWN_LEVEL;
6611 if (!W_ERROR_IS_OK(errcode)) {
6615 if (r->in.ctr == NULL) {
6619 switch (r->in.ctr->level) {
6621 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6623 r->in.ctr->info.info1);
6629 return WERR_UNKNOWN_LEVEL;
6635 /****************************************************************************
6636 Enumerates all printer drivers by level and architecture.
6637 ****************************************************************************/
6639 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6640 struct auth_serversupplied_info *server_info,
6641 const char *servername,
6642 const char *architecture,
6644 union spoolss_DriverInfo **info_p,
6649 struct spoolss_DriverInfo8 *driver;
6650 union spoolss_DriverInfo *info = NULL;
6652 WERROR result = WERR_OK;
6653 uint32_t num_drivers;
6654 const char **drivers;
6659 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6660 result = winreg_get_driver_list(mem_ctx, server_info,
6661 architecture, version,
6662 &num_drivers, &drivers);
6663 if (!W_ERROR_IS_OK(result)) {
6666 DEBUG(4, ("we have:[%d] drivers in environment"
6667 " [%s] and version [%d]\n",
6668 num_drivers, architecture, version));
6670 if (num_drivers != 0) {
6671 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6672 union spoolss_DriverInfo,
6673 count + num_drivers);
6675 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6676 "failed to enlarge driver info buffer!\n"));
6677 result = WERR_NOMEM;
6682 for (i = 0; i < num_drivers; i++) {
6683 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6685 result = winreg_get_driver(mem_ctx, server_info,
6686 architecture, drivers[i],
6688 if (!W_ERROR_IS_OK(result)) {
6694 result = fill_printer_driver_info1(info, &info[count+i].info1,
6695 driver, servername);
6698 result = fill_printer_driver_info2(info, &info[count+i].info2,
6699 driver, servername);
6702 result = fill_printer_driver_info3(info, &info[count+i].info3,
6703 driver, servername);
6706 result = fill_printer_driver_info4(info, &info[count+i].info4,
6707 driver, servername);
6710 result = fill_printer_driver_info5(info, &info[count+i].info5,
6711 driver, servername);
6714 result = fill_printer_driver_info6(info, &info[count+i].info6,
6715 driver, servername);
6718 result = fill_printer_driver_info8(info, &info[count+i].info8,
6719 driver, servername);
6722 result = WERR_UNKNOWN_LEVEL;
6726 TALLOC_FREE(driver);
6728 if (!W_ERROR_IS_OK(result)) {
6733 count += num_drivers;
6734 TALLOC_FREE(drivers);
6738 TALLOC_FREE(drivers);
6740 if (!W_ERROR_IS_OK(result)) {
6751 /****************************************************************************
6752 Enumerates all printer drivers by level.
6753 ****************************************************************************/
6755 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6756 struct auth_serversupplied_info *server_info,
6757 const char *servername,
6758 const char *architecture,
6760 union spoolss_DriverInfo **info_p,
6764 WERROR result = WERR_OK;
6766 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6768 for (a=0; archi_table[a].long_archi != NULL; a++) {
6770 union spoolss_DriverInfo *info = NULL;
6773 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6776 archi_table[a].long_archi,
6780 if (!W_ERROR_IS_OK(result)) {
6784 for (i=0; i < count; i++) {
6785 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6786 info[i], info_p, count_p);
6793 return enumprinterdrivers_level_by_architecture(mem_ctx,
6802 /****************************************************************
6803 _spoolss_EnumPrinterDrivers
6804 ****************************************************************/
6806 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6807 struct spoolss_EnumPrinterDrivers *r)
6809 const char *cservername;
6812 /* that's an [in out] buffer */
6814 if (!r->in.buffer && (r->in.offered != 0)) {
6815 return WERR_INVALID_PARAM;
6818 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6822 *r->out.info = NULL;
6824 cservername = canon_servername(r->in.server);
6826 if (!is_myname_or_ipaddr(cservername)) {
6827 return WERR_UNKNOWN_PRINTER_DRIVER;
6830 result = enumprinterdrivers_level(p->mem_ctx,
6837 if (!W_ERROR_IS_OK(result)) {
6841 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6842 spoolss_EnumPrinterDrivers,
6843 *r->out.info, r->in.level,
6845 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6846 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6848 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6851 /****************************************************************
6853 ****************************************************************/
6855 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6856 struct spoolss_EnumForms *r)
6862 *r->out.info = NULL;
6864 /* that's an [in out] buffer */
6866 if (!r->in.buffer && (r->in.offered != 0) ) {
6867 return WERR_INVALID_PARAM;
6870 DEBUG(4,("_spoolss_EnumForms\n"));
6871 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6872 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6874 switch (r->in.level) {
6876 result = winreg_printer_enumforms1(p->mem_ctx,
6882 result = WERR_UNKNOWN_LEVEL;
6886 if (!W_ERROR_IS_OK(result)) {
6890 if (*r->out.count == 0) {
6891 return WERR_NO_MORE_ITEMS;
6894 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6896 *r->out.info, r->in.level,
6898 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6899 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6901 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6904 /****************************************************************
6906 ****************************************************************/
6908 WERROR _spoolss_GetForm(struct pipes_struct *p,
6909 struct spoolss_GetForm *r)
6913 /* that's an [in out] buffer */
6915 if (!r->in.buffer && (r->in.offered != 0)) {
6916 return WERR_INVALID_PARAM;
6919 DEBUG(4,("_spoolss_GetForm\n"));
6920 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6921 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6923 switch (r->in.level) {
6925 result = winreg_printer_getform1(p->mem_ctx,
6928 &r->out.info->info1);
6931 result = WERR_UNKNOWN_LEVEL;
6935 if (!W_ERROR_IS_OK(result)) {
6936 TALLOC_FREE(r->out.info);
6940 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6941 r->out.info, r->in.level);
6942 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6944 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6947 /****************************************************************************
6948 ****************************************************************************/
6950 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6951 struct spoolss_PortInfo1 *r,
6954 r->port_name = talloc_strdup(mem_ctx, name);
6955 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6960 /****************************************************************************
6961 TODO: This probably needs distinguish between TCP/IP and Local ports
6963 ****************************************************************************/
6965 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6966 struct spoolss_PortInfo2 *r,
6969 r->port_name = talloc_strdup(mem_ctx, name);
6970 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6972 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6973 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6975 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6976 W_ERROR_HAVE_NO_MEMORY(r->description);
6978 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6985 /****************************************************************************
6986 wrapper around the enumer ports command
6987 ****************************************************************************/
6989 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6991 char *cmd = lp_enumports_cmd();
6992 char **qlines = NULL;
6993 char *command = NULL;
7001 /* if no hook then just fill in the default port */
7004 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7007 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7008 TALLOC_FREE(qlines);
7015 /* we have a valid enumport command */
7017 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7022 DEBUG(10,("Running [%s]\n", command));
7023 ret = smbrun(command, &fd);
7024 DEBUG(10,("Returned [%d]\n", ret));
7025 TALLOC_FREE(command);
7030 return WERR_ACCESS_DENIED;
7034 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7035 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7045 /****************************************************************************
7047 ****************************************************************************/
7049 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7050 union spoolss_PortInfo **info_p,
7053 union spoolss_PortInfo *info = NULL;
7055 WERROR result = WERR_OK;
7056 char **qlines = NULL;
7059 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7060 if (!W_ERROR_IS_OK(result)) {
7065 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7067 DEBUG(10,("Returning WERR_NOMEM\n"));
7068 result = WERR_NOMEM;
7072 for (i=0; i<numlines; i++) {
7073 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7074 result = fill_port_1(info, &info[i].info1, qlines[i]);
7075 if (!W_ERROR_IS_OK(result)) {
7080 TALLOC_FREE(qlines);
7083 if (!W_ERROR_IS_OK(result)) {
7085 TALLOC_FREE(qlines);
7097 /****************************************************************************
7099 ****************************************************************************/
7101 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7102 union spoolss_PortInfo **info_p,
7105 union spoolss_PortInfo *info = NULL;
7107 WERROR result = WERR_OK;
7108 char **qlines = NULL;
7111 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7112 if (!W_ERROR_IS_OK(result)) {
7117 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7119 DEBUG(10,("Returning WERR_NOMEM\n"));
7120 result = WERR_NOMEM;
7124 for (i=0; i<numlines; i++) {
7125 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7126 result = fill_port_2(info, &info[i].info2, qlines[i]);
7127 if (!W_ERROR_IS_OK(result)) {
7132 TALLOC_FREE(qlines);
7135 if (!W_ERROR_IS_OK(result)) {
7137 TALLOC_FREE(qlines);
7149 /****************************************************************
7151 ****************************************************************/
7153 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7154 struct spoolss_EnumPorts *r)
7158 /* that's an [in out] buffer */
7160 if (!r->in.buffer && (r->in.offered != 0)) {
7161 return WERR_INVALID_PARAM;
7164 DEBUG(4,("_spoolss_EnumPorts\n"));
7168 *r->out.info = NULL;
7170 switch (r->in.level) {
7172 result = enumports_level_1(p->mem_ctx, r->out.info,
7176 result = enumports_level_2(p->mem_ctx, r->out.info,
7180 return WERR_UNKNOWN_LEVEL;
7183 if (!W_ERROR_IS_OK(result)) {
7187 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7189 *r->out.info, r->in.level,
7191 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7192 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7194 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7197 /****************************************************************************
7198 ****************************************************************************/
7200 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7202 struct spoolss_SetPrinterInfoCtr *info_ctr,
7203 struct spoolss_DeviceMode *devmode,
7204 struct security_descriptor *secdesc,
7205 struct spoolss_UserLevelCtr *user_ctr,
7206 struct policy_handle *handle)
7208 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7209 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7211 WERROR err = WERR_OK;
7213 /* samba does not have a concept of local, non-shared printers yet, so
7214 * make sure we always setup sharename - gd */
7215 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7216 (info2->printername != NULL && info2->printername[0] != '\0')) {
7217 DEBUG(5, ("spoolss_addprinterex_level_2: "
7218 "no sharename has been set, setting printername %s as sharename\n",
7219 info2->printername));
7220 info2->sharename = info2->printername;
7223 /* check to see if the printer already exists */
7224 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7225 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7227 return WERR_PRINTER_ALREADY_EXISTS;
7230 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7231 if ((snum = print_queue_snum(info2->printername)) != -1) {
7232 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7233 info2->printername));
7234 return WERR_PRINTER_ALREADY_EXISTS;
7238 /* validate printer info struct */
7239 if (!info2->printername || strlen(info2->printername) == 0) {
7240 return WERR_INVALID_PRINTER_NAME;
7242 if (!info2->portname || strlen(info2->portname) == 0) {
7243 return WERR_UNKNOWN_PORT;
7245 if (!info2->drivername || strlen(info2->drivername) == 0) {
7246 return WERR_UNKNOWN_PRINTER_DRIVER;
7248 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7249 return WERR_UNKNOWN_PRINTPROCESSOR;
7252 /* FIXME!!! smbd should check to see if the driver is installed before
7253 trying to add a printer like this --jerry */
7255 if (*lp_addprinter_cmd() ) {
7256 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7257 info2, p->client_address) ) {
7258 return WERR_ACCESS_DENIED;
7261 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7262 "smb.conf parameter \"addprinter command\" is defined. This"
7263 "parameter must exist for this call to succeed\n",
7264 info2->sharename ));
7267 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7268 return WERR_ACCESS_DENIED;
7271 /* you must be a printer admin to add a new printer */
7272 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7273 return WERR_ACCESS_DENIED;
7277 * Do sanity check on the requested changes for Samba.
7280 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7281 return WERR_INVALID_PARAM;
7284 if (devmode == NULL) {
7285 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7288 update_dsspooler(p->mem_ctx,
7294 err = winreg_update_printer(p->mem_ctx,
7301 if (!W_ERROR_IS_OK(err)) {
7305 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7306 /* Handle open failed - remove addition. */
7307 ZERO_STRUCTP(handle);
7308 return WERR_ACCESS_DENIED;
7314 /****************************************************************
7315 _spoolss_AddPrinterEx
7316 ****************************************************************/
7318 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7319 struct spoolss_AddPrinterEx *r)
7321 switch (r->in.info_ctr->level) {
7323 /* we don't handle yet */
7324 /* but I know what to do ... */
7325 return WERR_UNKNOWN_LEVEL;
7327 return spoolss_addprinterex_level_2(p, r->in.server,
7329 r->in.devmode_ctr->devmode,
7330 r->in.secdesc_ctr->sd,
7331 r->in.userlevel_ctr,
7334 return WERR_UNKNOWN_LEVEL;
7338 /****************************************************************
7340 ****************************************************************/
7342 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7343 struct spoolss_AddPrinter *r)
7345 struct spoolss_AddPrinterEx a;
7346 struct spoolss_UserLevelCtr userlevel_ctr;
7348 ZERO_STRUCT(userlevel_ctr);
7350 userlevel_ctr.level = 1;
7352 a.in.server = r->in.server;
7353 a.in.info_ctr = r->in.info_ctr;
7354 a.in.devmode_ctr = r->in.devmode_ctr;
7355 a.in.secdesc_ctr = r->in.secdesc_ctr;
7356 a.in.userlevel_ctr = &userlevel_ctr;
7357 a.out.handle = r->out.handle;
7359 return _spoolss_AddPrinterEx(p, &a);
7362 /****************************************************************
7363 _spoolss_AddPrinterDriverEx
7364 ****************************************************************/
7366 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7367 struct spoolss_AddPrinterDriverEx *r)
7369 WERROR err = WERR_OK;
7370 const char *driver_name = NULL;
7375 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7376 fn = "_spoolss_AddPrinterDriver";
7378 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7379 fn = "_spoolss_AddPrinterDriverEx";
7382 return WERR_INVALID_PARAM;
7386 * we only support the semantics of AddPrinterDriver()
7387 * i.e. only copy files that are newer than existing ones
7390 if (r->in.flags == 0) {
7391 return WERR_INVALID_PARAM;
7394 if (r->in.flags != APD_COPY_NEW_FILES) {
7395 return WERR_ACCESS_DENIED;
7399 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7400 /* Clever hack from Martin Zielinski <mz@seh.de>
7401 * to allow downgrade from level 8 (Vista).
7403 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7404 r->in.info_ctr->level));
7405 return WERR_UNKNOWN_LEVEL;
7408 DEBUG(5,("Cleaning driver's information\n"));
7409 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7410 if (!W_ERROR_IS_OK(err))
7413 DEBUG(5,("Moving driver to final destination\n"));
7414 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7419 err = winreg_add_driver(p->mem_ctx, p->server_info,
7420 r->in.info_ctr, &driver_name, &version);
7421 if (!W_ERROR_IS_OK(err)) {
7426 * I think this is where he DrvUpgradePrinter() hook would be
7427 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7428 * server. Right now, we just need to send ourselves a message
7429 * to update each printer bound to this driver. --jerry
7432 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7433 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7441 /****************************************************************
7442 _spoolss_AddPrinterDriver
7443 ****************************************************************/
7445 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7446 struct spoolss_AddPrinterDriver *r)
7448 struct spoolss_AddPrinterDriverEx a;
7450 switch (r->in.info_ctr->level) {
7457 return WERR_UNKNOWN_LEVEL;
7460 a.in.servername = r->in.servername;
7461 a.in.info_ctr = r->in.info_ctr;
7462 a.in.flags = APD_COPY_NEW_FILES;
7464 return _spoolss_AddPrinterDriverEx(p, &a);
7467 /****************************************************************************
7468 ****************************************************************************/
7470 struct _spoolss_paths {
7476 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7478 static const struct _spoolss_paths spoolss_paths[]= {
7479 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7480 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7483 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7484 const char *servername,
7485 const char *environment,
7489 const char *pservername = NULL;
7490 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7491 const char *short_archi;
7495 /* environment may be empty */
7496 if (environment && strlen(environment)) {
7497 long_archi = environment;
7500 /* servername may be empty */
7501 if (servername && strlen(servername)) {
7502 pservername = canon_servername(servername);
7504 if (!is_myname_or_ipaddr(pservername)) {
7505 return WERR_INVALID_PARAM;
7509 if (!(short_archi = get_short_archi(long_archi))) {
7510 return WERR_INVALID_ENVIRONMENT;
7513 switch (component) {
7514 case SPOOLSS_PRTPROCS_PATH:
7515 case SPOOLSS_DRIVER_PATH:
7517 *path = talloc_asprintf(mem_ctx,
7520 spoolss_paths[component].share,
7523 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7524 SPOOLSS_DEFAULT_SERVER_PATH,
7525 spoolss_paths[component].dir,
7530 return WERR_INVALID_PARAM;
7540 /****************************************************************************
7541 ****************************************************************************/
7543 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7544 const char *servername,
7545 const char *environment,
7546 struct spoolss_DriverDirectoryInfo1 *r)
7551 werr = compose_spoolss_server_path(mem_ctx,
7554 SPOOLSS_DRIVER_PATH,
7556 if (!W_ERROR_IS_OK(werr)) {
7560 DEBUG(4,("printer driver directory: [%s]\n", path));
7562 r->directory_name = path;
7567 /****************************************************************
7568 _spoolss_GetPrinterDriverDirectory
7569 ****************************************************************/
7571 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7572 struct spoolss_GetPrinterDriverDirectory *r)
7576 /* that's an [in out] buffer */
7578 if (!r->in.buffer && (r->in.offered != 0)) {
7579 return WERR_INVALID_PARAM;
7582 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7587 /* r->in.level is ignored */
7589 werror = getprinterdriverdir_level_1(p->mem_ctx,
7592 &r->out.info->info1);
7593 if (!W_ERROR_IS_OK(werror)) {
7594 TALLOC_FREE(r->out.info);
7598 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7599 r->out.info, r->in.level);
7600 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7602 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7605 /****************************************************************
7606 _spoolss_EnumPrinterData
7607 ****************************************************************/
7609 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7610 struct spoolss_EnumPrinterData *r)
7613 struct spoolss_EnumPrinterDataEx r2;
7615 struct spoolss_PrinterEnumValues *info, *val = NULL;
7618 r2.in.handle = r->in.handle;
7619 r2.in.key_name = "PrinterDriverData";
7621 r2.out.count = &count;
7622 r2.out.info = &info;
7623 r2.out.needed = &needed;
7625 result = _spoolss_EnumPrinterDataEx(p, &r2);
7626 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7627 r2.in.offered = needed;
7628 result = _spoolss_EnumPrinterDataEx(p, &r2);
7630 if (!W_ERROR_IS_OK(result)) {
7635 * The NT machine wants to know the biggest size of value and data
7637 * cf: MSDN EnumPrinterData remark section
7640 if (!r->in.value_offered && !r->in.data_offered) {
7641 uint32_t biggest_valuesize = 0;
7642 uint32_t biggest_datasize = 0;
7645 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7647 for (i=0; i<count; i++) {
7649 name_length = strlen(info[i].value_name);
7650 if (strlen(info[i].value_name) > biggest_valuesize) {
7651 biggest_valuesize = name_length;
7654 if (info[i].data_length > biggest_datasize) {
7655 biggest_datasize = info[i].data_length;
7658 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7662 /* the value is an UNICODE string but real_value_size is the length
7663 in bytes including the trailing 0 */
7665 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7666 *r->out.data_needed = biggest_datasize;
7668 DEBUG(6,("final values: [%d], [%d]\n",
7669 *r->out.value_needed, *r->out.data_needed));
7674 if (r->in.enum_index < count) {
7675 val = &info[r->in.enum_index];
7679 /* out_value should default to "" or else NT4 has
7680 problems unmarshalling the response */
7682 if (r->in.value_offered) {
7683 *r->out.value_needed = 1;
7684 r->out.value_name = talloc_strdup(r, "");
7685 if (!r->out.value_name) {
7689 r->out.value_name = NULL;
7690 *r->out.value_needed = 0;
7693 /* the data is counted in bytes */
7695 *r->out.data_needed = r->in.data_offered;
7697 result = WERR_NO_MORE_ITEMS;
7701 * - counted in bytes in the request
7702 * - counted in UNICODE chars in the max reply
7703 * - counted in bytes in the real size
7705 * take a pause *before* coding not *during* coding
7709 if (r->in.value_offered) {
7710 r->out.value_name = talloc_strdup(r, val->value_name);
7711 if (!r->out.value_name) {
7714 *r->out.value_needed = val->value_name_len;
7716 r->out.value_name = NULL;
7717 *r->out.value_needed = 0;
7722 *r->out.type = val->type;
7724 /* data - counted in bytes */
7727 * See the section "Dynamically Typed Query Parameters"
7731 if (r->out.data && val->data && val->data->data &&
7732 val->data_length && r->in.data_offered) {
7733 memcpy(r->out.data, val->data->data,
7734 MIN(val->data_length,r->in.data_offered));
7737 *r->out.data_needed = val->data_length;
7745 /****************************************************************
7746 _spoolss_SetPrinterData
7747 ****************************************************************/
7749 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7750 struct spoolss_SetPrinterData *r)
7752 struct spoolss_SetPrinterDataEx r2;
7754 r2.in.handle = r->in.handle;
7755 r2.in.key_name = "PrinterDriverData";
7756 r2.in.value_name = r->in.value_name;
7757 r2.in.type = r->in.type;
7758 r2.in.data = r->in.data;
7759 r2.in.offered = r->in.offered;
7761 return _spoolss_SetPrinterDataEx(p, &r2);
7764 /****************************************************************
7765 _spoolss_ResetPrinter
7766 ****************************************************************/
7768 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7769 struct spoolss_ResetPrinter *r)
7771 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7774 DEBUG(5,("_spoolss_ResetPrinter\n"));
7777 * All we do is to check to see if the handle and queue is valid.
7778 * This call really doesn't mean anything to us because we only
7779 * support RAW printing. --jerry
7783 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7784 OUR_HANDLE(r->in.handle)));
7788 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7792 /* blindly return success */
7796 /****************************************************************
7797 _spoolss_DeletePrinterData
7798 ****************************************************************/
7800 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7801 struct spoolss_DeletePrinterData *r)
7803 struct spoolss_DeletePrinterDataEx r2;
7805 r2.in.handle = r->in.handle;
7806 r2.in.key_name = "PrinterDriverData";
7807 r2.in.value_name = r->in.value_name;
7809 return _spoolss_DeletePrinterDataEx(p, &r2);
7812 /****************************************************************
7814 ****************************************************************/
7816 WERROR _spoolss_AddForm(struct pipes_struct *p,
7817 struct spoolss_AddForm *r)
7819 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7821 WERROR status = WERR_OK;
7822 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7824 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7826 DEBUG(5,("_spoolss_AddForm\n"));
7829 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7830 OUR_HANDLE(r->in.handle)));
7834 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7835 and not a printer admin, then fail */
7837 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7838 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7839 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7840 p->server_info->info3->base.domain.string,
7842 p->server_info->ptok,
7843 lp_printer_admin(snum))) {
7844 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7845 return WERR_ACCESS_DENIED;
7848 switch (form->flags) {
7849 case SPOOLSS_FORM_USER:
7850 case SPOOLSS_FORM_BUILTIN:
7851 case SPOOLSS_FORM_PRINTER:
7854 return WERR_INVALID_PARAM;
7857 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7858 if (!W_ERROR_IS_OK(status)) {
7863 * ChangeID must always be set if this is a printer
7865 if (Printer->printer_type == SPLHND_PRINTER) {
7866 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7870 status = winreg_printer_update_changeid(p->mem_ctx,
7872 lp_const_servicename(snum));
7873 if (!W_ERROR_IS_OK(status)) {
7881 /****************************************************************
7883 ****************************************************************/
7885 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7886 struct spoolss_DeleteForm *r)
7888 const char *form_name = r->in.form_name;
7889 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7891 WERROR status = WERR_OK;
7892 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7894 DEBUG(5,("_spoolss_DeleteForm\n"));
7897 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7898 OUR_HANDLE(r->in.handle)));
7902 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7903 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7904 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7905 p->server_info->info3->base.domain.string,
7907 p->server_info->ptok,
7908 lp_printer_admin(snum))) {
7909 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7910 return WERR_ACCESS_DENIED;
7913 status = winreg_printer_deleteform1(p->mem_ctx,
7916 if (!W_ERROR_IS_OK(status)) {
7921 * ChangeID must always be set if this is a printer
7923 if (Printer->printer_type == SPLHND_PRINTER) {
7924 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7928 status = winreg_printer_update_changeid(p->mem_ctx,
7930 lp_const_servicename(snum));
7931 if (!W_ERROR_IS_OK(status)) {
7939 /****************************************************************
7941 ****************************************************************/
7943 WERROR _spoolss_SetForm(struct pipes_struct *p,
7944 struct spoolss_SetForm *r)
7946 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7947 const char *form_name = r->in.form_name;
7949 WERROR status = WERR_OK;
7950 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7952 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7954 DEBUG(5,("_spoolss_SetForm\n"));
7957 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7958 OUR_HANDLE(r->in.handle)));
7962 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7963 and not a printer admin, then fail */
7965 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7966 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7967 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7968 p->server_info->info3->base.domain.string,
7970 p->server_info->ptok,
7971 lp_printer_admin(snum))) {
7972 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7973 return WERR_ACCESS_DENIED;
7976 status = winreg_printer_setform1(p->mem_ctx,
7980 if (!W_ERROR_IS_OK(status)) {
7985 * ChangeID must always be set if this is a printer
7987 if (Printer->printer_type == SPLHND_PRINTER) {
7988 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7992 status = winreg_printer_update_changeid(p->mem_ctx,
7994 lp_const_servicename(snum));
7995 if (!W_ERROR_IS_OK(status)) {
8003 /****************************************************************************
8004 fill_print_processor1
8005 ****************************************************************************/
8007 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8008 struct spoolss_PrintProcessorInfo1 *r,
8009 const char *print_processor_name)
8011 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8012 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8017 /****************************************************************************
8018 enumprintprocessors level 1.
8019 ****************************************************************************/
8021 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8022 union spoolss_PrintProcessorInfo **info_p,
8025 union spoolss_PrintProcessorInfo *info;
8028 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8029 W_ERROR_HAVE_NO_MEMORY(info);
8033 result = fill_print_processor1(info, &info[0].info1, "winprint");
8034 if (!W_ERROR_IS_OK(result)) {
8039 if (!W_ERROR_IS_OK(result)) {
8050 /****************************************************************
8051 _spoolss_EnumPrintProcessors
8052 ****************************************************************/
8054 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8055 struct spoolss_EnumPrintProcessors *r)
8059 /* that's an [in out] buffer */
8061 if (!r->in.buffer && (r->in.offered != 0)) {
8062 return WERR_INVALID_PARAM;
8065 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8068 * Enumerate the print processors ...
8070 * Just reply with "winprint", to keep NT happy
8071 * and I can use my nice printer checker.
8076 *r->out.info = NULL;
8078 switch (r->in.level) {
8080 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8084 return WERR_UNKNOWN_LEVEL;
8087 if (!W_ERROR_IS_OK(result)) {
8091 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8092 spoolss_EnumPrintProcessors,
8093 *r->out.info, r->in.level,
8095 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8096 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8098 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8101 /****************************************************************************
8102 fill_printprocdatatype1
8103 ****************************************************************************/
8105 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8106 struct spoolss_PrintProcDataTypesInfo1 *r,
8107 const char *name_array)
8109 r->name_array = talloc_strdup(mem_ctx, name_array);
8110 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8115 /****************************************************************************
8116 enumprintprocdatatypes level 1.
8117 ****************************************************************************/
8119 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8120 union spoolss_PrintProcDataTypesInfo **info_p,
8124 union spoolss_PrintProcDataTypesInfo *info;
8126 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8127 W_ERROR_HAVE_NO_MEMORY(info);
8131 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8132 if (!W_ERROR_IS_OK(result)) {
8137 if (!W_ERROR_IS_OK(result)) {
8148 /****************************************************************
8149 _spoolss_EnumPrintProcDataTypes
8150 ****************************************************************/
8152 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8153 struct spoolss_EnumPrintProcDataTypes *r)
8157 /* that's an [in out] buffer */
8159 if (!r->in.buffer && (r->in.offered != 0)) {
8160 return WERR_INVALID_PARAM;
8163 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8167 *r->out.info = NULL;
8169 switch (r->in.level) {
8171 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8175 return WERR_UNKNOWN_LEVEL;
8178 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8179 spoolss_EnumPrintProcDataTypes,
8180 *r->out.info, r->in.level,
8182 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8183 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8185 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8188 /****************************************************************************
8190 ****************************************************************************/
8192 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8193 struct spoolss_MonitorInfo1 *r,
8194 const char *monitor_name)
8196 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8197 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8202 /****************************************************************************
8204 ****************************************************************************/
8206 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8207 struct spoolss_MonitorInfo2 *r,
8208 const char *monitor_name,
8209 const char *environment,
8210 const char *dll_name)
8212 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8213 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8214 r->environment = talloc_strdup(mem_ctx, environment);
8215 W_ERROR_HAVE_NO_MEMORY(r->environment);
8216 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8217 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8222 /****************************************************************************
8223 enumprintmonitors level 1.
8224 ****************************************************************************/
8226 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8227 union spoolss_MonitorInfo **info_p,
8230 union spoolss_MonitorInfo *info;
8231 WERROR result = WERR_OK;
8233 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8234 W_ERROR_HAVE_NO_MEMORY(info);
8238 result = fill_monitor_1(info, &info[0].info1,
8240 if (!W_ERROR_IS_OK(result)) {
8244 result = fill_monitor_1(info, &info[1].info1,
8246 if (!W_ERROR_IS_OK(result)) {
8251 if (!W_ERROR_IS_OK(result)) {
8262 /****************************************************************************
8263 enumprintmonitors level 2.
8264 ****************************************************************************/
8266 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8267 union spoolss_MonitorInfo **info_p,
8270 union spoolss_MonitorInfo *info;
8271 WERROR result = WERR_OK;
8273 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8274 W_ERROR_HAVE_NO_MEMORY(info);
8278 result = fill_monitor_2(info, &info[0].info2,
8280 "Windows NT X86", /* FIXME */
8282 if (!W_ERROR_IS_OK(result)) {
8286 result = fill_monitor_2(info, &info[1].info2,
8288 "Windows NT X86", /* FIXME */
8290 if (!W_ERROR_IS_OK(result)) {
8295 if (!W_ERROR_IS_OK(result)) {
8306 /****************************************************************
8307 _spoolss_EnumMonitors
8308 ****************************************************************/
8310 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8311 struct spoolss_EnumMonitors *r)
8315 /* that's an [in out] buffer */
8317 if (!r->in.buffer && (r->in.offered != 0)) {
8318 return WERR_INVALID_PARAM;
8321 DEBUG(5,("_spoolss_EnumMonitors\n"));
8324 * Enumerate the print monitors ...
8326 * Just reply with "Local Port", to keep NT happy
8327 * and I can use my nice printer checker.
8332 *r->out.info = NULL;
8334 switch (r->in.level) {
8336 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8340 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8344 return WERR_UNKNOWN_LEVEL;
8347 if (!W_ERROR_IS_OK(result)) {
8351 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8352 spoolss_EnumMonitors,
8353 *r->out.info, r->in.level,
8355 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8356 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8358 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8361 /****************************************************************************
8362 ****************************************************************************/
8364 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8365 const print_queue_struct *queue,
8366 int count, int snum,
8367 struct spoolss_PrinterInfo2 *pinfo2,
8369 struct spoolss_JobInfo1 *r)
8374 for (i=0; i<count; i++) {
8375 if (queue[i].job == (int)jobid) {
8381 if (found == false) {
8382 /* NT treats not found as bad param... yet another bad choice */
8383 return WERR_INVALID_PARAM;
8386 return fill_job_info1(mem_ctx,
8394 /****************************************************************************
8395 ****************************************************************************/
8397 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8398 const print_queue_struct *queue,
8399 int count, int snum,
8400 struct spoolss_PrinterInfo2 *pinfo2,
8402 struct spoolss_JobInfo2 *r)
8406 struct spoolss_DeviceMode *devmode;
8409 for (i=0; i<count; i++) {
8410 if (queue[i].job == (int)jobid) {
8416 if (found == false) {
8417 /* NT treats not found as bad param... yet another bad
8419 return WERR_INVALID_PARAM;
8423 * if the print job does not have a DEVMODE associated with it,
8424 * just use the one for the printer. A NULL devicemode is not
8425 * a failure condition
8428 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8430 result = spoolss_create_default_devmode(mem_ctx,
8431 pinfo2->printername,
8433 if (!W_ERROR_IS_OK(result)) {
8434 DEBUG(3, ("Can't proceed w/o a devmode!"));
8439 return fill_job_info2(mem_ctx,
8448 /****************************************************************
8450 ****************************************************************/
8452 WERROR _spoolss_GetJob(struct pipes_struct *p,
8453 struct spoolss_GetJob *r)
8455 WERROR result = WERR_OK;
8456 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8459 print_queue_struct *queue = NULL;
8460 print_status_struct prt_status;
8462 /* that's an [in out] buffer */
8464 if (!r->in.buffer && (r->in.offered != 0)) {
8465 return WERR_INVALID_PARAM;
8468 DEBUG(5,("_spoolss_GetJob\n"));
8472 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8476 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8477 lp_servicename(snum), &pinfo2);
8478 if (!W_ERROR_IS_OK(result)) {
8482 count = print_queue_status(snum, &queue, &prt_status);
8484 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8485 count, prt_status.status, prt_status.message));
8487 switch (r->in.level) {
8489 result = getjob_level_1(p->mem_ctx,
8490 queue, count, snum, pinfo2,
8491 r->in.job_id, &r->out.info->info1);
8494 result = getjob_level_2(p->mem_ctx,
8495 queue, count, snum, pinfo2,
8496 r->in.job_id, &r->out.info->info2);
8499 result = WERR_UNKNOWN_LEVEL;
8504 TALLOC_FREE(pinfo2);
8506 if (!W_ERROR_IS_OK(result)) {
8507 TALLOC_FREE(r->out.info);
8511 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8513 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8515 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8518 /****************************************************************
8519 _spoolss_GetPrinterDataEx
8520 ****************************************************************/
8522 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8523 struct spoolss_GetPrinterDataEx *r)
8526 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8527 const char *printer;
8529 WERROR result = WERR_OK;
8531 enum winreg_Type val_type;
8536 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8538 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8539 r->in.key_name, r->in.value_name));
8541 /* in case of problem, return some default values */
8544 *r->out.type = REG_NONE;
8547 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8548 OUR_HANDLE(r->in.handle)));
8549 result = WERR_BADFID;
8553 /* Is the handle to a printer or to the server? */
8555 if (Printer->printer_type == SPLHND_SERVER) {
8557 union spoolss_PrinterData data;
8559 result = getprinterdata_printer_server(p->mem_ctx,
8563 if (!W_ERROR_IS_OK(result)) {
8567 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8568 *r->out.type, &data);
8569 if (!W_ERROR_IS_OK(result)) {
8573 *r->out.needed = blob.length;
8575 if (r->in.offered >= *r->out.needed) {
8576 memcpy(r->out.data, blob.data, blob.length);
8579 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8582 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8585 printer = lp_const_servicename(snum);
8587 /* check to see if the keyname is valid */
8588 if (!strlen(r->in.key_name)) {
8589 return WERR_INVALID_PARAM;
8592 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8593 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8594 strequal(r->in.value_name, "ChangeId")) {
8595 *r->out.type = REG_DWORD;
8597 if (r->in.offered >= *r->out.needed) {
8598 uint32_t changeid = 0;
8600 result = winreg_printer_get_changeid(p->mem_ctx,
8604 if (!W_ERROR_IS_OK(result)) {
8608 SIVAL(r->out.data, 0, changeid);
8614 result = winreg_get_printer_dataex(p->mem_ctx,
8622 if (!W_ERROR_IS_OK(result)) {
8626 *r->out.needed = val_size;
8627 *r->out.type = val_type;
8629 if (r->in.offered >= *r->out.needed) {
8630 memcpy(r->out.data, val_data, val_size);
8634 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8635 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8637 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8640 /****************************************************************
8641 _spoolss_SetPrinterDataEx
8642 ****************************************************************/
8644 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8645 struct spoolss_SetPrinterDataEx *r)
8647 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8649 WERROR result = WERR_OK;
8650 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8653 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8655 /* From MSDN documentation of SetPrinterDataEx: pass request to
8656 SetPrinterData if key is "PrinterDriverData" */
8659 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8660 OUR_HANDLE(r->in.handle)));
8664 if (Printer->printer_type == SPLHND_SERVER) {
8665 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8666 "Not implemented for server handles yet\n"));
8667 return WERR_INVALID_PARAM;
8670 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8675 * Access check : NT returns "access denied" if you make a
8676 * SetPrinterData call without the necessary privildge.
8677 * we were originally returning OK if nothing changed
8678 * which made Win2k issue **a lot** of SetPrinterData
8679 * when connecting to a printer --jerry
8682 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8683 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8684 "change denied by handle access permissions\n"));
8685 return WERR_ACCESS_DENIED;
8688 result = winreg_get_printer(Printer, p->server_info,
8689 Printer->servername,
8690 lp_servicename(snum),
8692 if (!W_ERROR_IS_OK(result)) {
8696 /* check for OID in valuename */
8698 oid_string = strchr(r->in.value_name, ',');
8704 /* save the registry data */
8706 result = winreg_set_printer_dataex(p->mem_ctx,
8715 if (W_ERROR_IS_OK(result)) {
8716 /* save the OID if one was specified */
8718 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8719 r->in.key_name, SPOOL_OID_KEY);
8721 result = WERR_NOMEM;
8726 * I'm not checking the status here on purpose. Don't know
8727 * if this is right, but I'm returning the status from the
8728 * previous set_printer_dataex() call. I have no idea if
8729 * this is right. --jerry
8731 winreg_set_printer_dataex(p->mem_ctx,
8737 (uint8_t *) oid_string,
8738 strlen(oid_string) + 1);
8741 result = winreg_printer_update_changeid(p->mem_ctx,
8743 lp_const_servicename(snum));
8748 talloc_free(pinfo2);
8752 /****************************************************************
8753 _spoolss_DeletePrinterDataEx
8754 ****************************************************************/
8756 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8757 struct spoolss_DeletePrinterDataEx *r)
8759 const char *printer;
8761 WERROR status = WERR_OK;
8762 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8764 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8767 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8768 "Invalid handle (%s:%u:%u).\n",
8769 OUR_HANDLE(r->in.handle)));
8773 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8774 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8775 "printer properties change denied by handle\n"));
8776 return WERR_ACCESS_DENIED;
8779 if (!r->in.value_name || !r->in.key_name) {
8783 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8786 printer = lp_const_servicename(snum);
8788 status = winreg_delete_printer_dataex(p->mem_ctx,
8793 if (W_ERROR_IS_OK(status)) {
8794 status = winreg_printer_update_changeid(p->mem_ctx,
8802 /****************************************************************
8803 _spoolss_EnumPrinterKey
8804 ****************************************************************/
8806 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8807 struct spoolss_EnumPrinterKey *r)
8810 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8812 WERROR result = WERR_BADFILE;
8813 const char **array = NULL;
8816 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8819 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8820 OUR_HANDLE(r->in.handle)));
8824 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8828 result = winreg_enum_printer_key(p->mem_ctx,
8830 lp_const_servicename(snum),
8834 if (!W_ERROR_IS_OK(result)) {
8838 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8839 result = WERR_NOMEM;
8843 *r->out._ndr_size = r->in.offered / 2;
8844 *r->out.needed = blob.length;
8846 if (r->in.offered < *r->out.needed) {
8847 result = WERR_MORE_DATA;
8850 r->out.key_buffer->string_array = array;
8854 if (!W_ERROR_IS_OK(result)) {
8856 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8864 /****************************************************************
8865 _spoolss_DeletePrinterKey
8866 ****************************************************************/
8868 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8869 struct spoolss_DeletePrinterKey *r)
8871 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8874 const char *printer;
8876 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8879 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8880 OUR_HANDLE(r->in.handle)));
8884 /* if keyname == NULL, return error */
8885 if ( !r->in.key_name )
8886 return WERR_INVALID_PARAM;
8888 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8892 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8893 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8894 "printer properties change denied by handle\n"));
8895 return WERR_ACCESS_DENIED;
8898 printer = lp_const_servicename(snum);
8900 /* delete the key and all subkeys */
8901 status = winreg_delete_printer_key(p->mem_ctx,
8905 if (W_ERROR_IS_OK(status)) {
8906 status = winreg_printer_update_changeid(p->mem_ctx,
8914 /****************************************************************
8915 _spoolss_EnumPrinterDataEx
8916 ****************************************************************/
8918 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8919 struct spoolss_EnumPrinterDataEx *r)
8922 struct spoolss_PrinterEnumValues *info = NULL;
8923 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8927 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8931 *r->out.info = NULL;
8934 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8935 OUR_HANDLE(r->in.handle)));
8940 * first check for a keyname of NULL or "". Win2k seems to send
8941 * this a lot and we should send back WERR_INVALID_PARAM
8942 * no need to spend time looking up the printer in this case.
8946 if (!strlen(r->in.key_name)) {
8947 result = WERR_INVALID_PARAM;
8951 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8955 /* now look for a match on the key name */
8956 result = winreg_enum_printer_dataex(p->mem_ctx,
8958 lp_const_servicename(snum),
8962 if (!W_ERROR_IS_OK(result)) {
8966 #if 0 /* FIXME - gd */
8967 /* housekeeping information in the reply */
8969 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8970 * the hand marshalled container size is a multiple
8971 * of 4 bytes for RPC alignment.
8975 needed += 4-(needed % 4);
8978 *r->out.count = count;
8979 *r->out.info = info;
8982 if (!W_ERROR_IS_OK(result)) {
8986 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
8987 spoolss_EnumPrinterDataEx,
8990 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8991 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
8993 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8996 /****************************************************************************
8997 ****************************************************************************/
8999 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9000 const char *servername,
9001 const char *environment,
9002 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9007 werr = compose_spoolss_server_path(mem_ctx,
9010 SPOOLSS_PRTPROCS_PATH,
9012 if (!W_ERROR_IS_OK(werr)) {
9016 DEBUG(4,("print processor directory: [%s]\n", path));
9018 r->directory_name = path;
9023 /****************************************************************
9024 _spoolss_GetPrintProcessorDirectory
9025 ****************************************************************/
9027 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9028 struct spoolss_GetPrintProcessorDirectory *r)
9032 /* that's an [in out] buffer */
9034 if (!r->in.buffer && (r->in.offered != 0)) {
9035 return WERR_INVALID_PARAM;
9038 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9043 /* r->in.level is ignored */
9045 /* We always should reply with a local print processor directory so that
9046 * users are not forced to have a [prnproc$] share on the Samba spoolss
9047 * server - Guenther */
9049 result = getprintprocessordirectory_level_1(p->mem_ctx,
9050 NULL, /* r->in.server */
9052 &r->out.info->info1);
9053 if (!W_ERROR_IS_OK(result)) {
9054 TALLOC_FREE(r->out.info);
9058 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9059 r->out.info, r->in.level);
9060 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9062 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9065 /*******************************************************************
9066 ********************************************************************/
9068 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9069 const char *dllname)
9071 enum ndr_err_code ndr_err;
9072 struct spoolss_MonitorUi ui;
9074 ui.dll_name = dllname;
9076 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9077 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9078 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9079 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9081 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9084 /*******************************************************************
9085 Streams the monitor UI DLL name in UNICODE
9086 *******************************************************************/
9088 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9089 NT_USER_TOKEN *token, DATA_BLOB *in,
9090 DATA_BLOB *out, uint32_t *needed)
9092 const char *dllname = "tcpmonui.dll";
9094 *needed = (strlen(dllname)+1) * 2;
9096 if (out->length < *needed) {
9097 return WERR_INSUFFICIENT_BUFFER;
9100 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9107 /*******************************************************************
9108 ********************************************************************/
9110 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9111 struct spoolss_PortData1 *port1,
9112 const DATA_BLOB *buf)
9114 enum ndr_err_code ndr_err;
9115 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9116 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9117 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9118 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9120 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9123 /*******************************************************************
9124 ********************************************************************/
9126 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9127 struct spoolss_PortData2 *port2,
9128 const DATA_BLOB *buf)
9130 enum ndr_err_code ndr_err;
9131 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9132 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9133 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9134 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9136 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9139 /*******************************************************************
9140 Create a new TCP/IP port
9141 *******************************************************************/
9143 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9144 NT_USER_TOKEN *token, DATA_BLOB *in,
9145 DATA_BLOB *out, uint32_t *needed)
9147 struct spoolss_PortData1 port1;
9148 struct spoolss_PortData2 port2;
9149 char *device_uri = NULL;
9152 const char *portname;
9153 const char *hostaddress;
9155 uint32_t port_number;
9158 /* peek for spoolss_PortData version */
9160 if (!in || (in->length < (128 + 4))) {
9161 return WERR_GENERAL_FAILURE;
9164 version = IVAL(in->data, 128);
9170 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9174 portname = port1.portname;
9175 hostaddress = port1.hostaddress;
9176 queue = port1.queue;
9177 protocol = port1.protocol;
9178 port_number = port1.port_number;
9184 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9188 portname = port2.portname;
9189 hostaddress = port2.hostaddress;
9190 queue = port2.queue;
9191 protocol = port2.protocol;
9192 port_number = port2.port_number;
9196 DEBUG(1,("xcvtcp_addport: "
9197 "unknown version of port_data: %d\n", version));
9198 return WERR_UNKNOWN_PORT;
9201 /* create the device URI and call the add_port_hook() */
9204 case PROTOCOL_RAWTCP_TYPE:
9205 device_uri = talloc_asprintf(mem_ctx,
9206 "socket://%s:%d/", hostaddress,
9210 case PROTOCOL_LPR_TYPE:
9211 device_uri = talloc_asprintf(mem_ctx,
9212 "lpr://%s/%s", hostaddress, queue );
9216 return WERR_UNKNOWN_PORT;
9223 return add_port_hook(mem_ctx, token, portname, device_uri);
9226 /*******************************************************************
9227 *******************************************************************/
9229 struct xcv_api_table xcvtcp_cmds[] = {
9230 { "MonitorUI", xcvtcp_monitorui },
9231 { "AddPort", xcvtcp_addport},
9235 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9236 NT_USER_TOKEN *token, const char *command,
9243 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9245 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9246 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9247 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9250 return WERR_BADFUNC;
9253 /*******************************************************************
9254 *******************************************************************/
9255 #if 0 /* don't support management using the "Local Port" monitor */
9257 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9258 NT_USER_TOKEN *token, DATA_BLOB *in,
9259 DATA_BLOB *out, uint32_t *needed)
9261 const char *dllname = "localui.dll";
9263 *needed = (strlen(dllname)+1) * 2;
9265 if (out->length < *needed) {
9266 return WERR_INSUFFICIENT_BUFFER;
9269 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9276 /*******************************************************************
9277 *******************************************************************/
9279 struct xcv_api_table xcvlocal_cmds[] = {
9280 { "MonitorUI", xcvlocal_monitorui },
9284 struct xcv_api_table xcvlocal_cmds[] = {
9291 /*******************************************************************
9292 *******************************************************************/
9294 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9295 NT_USER_TOKEN *token, const char *command,
9296 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9301 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9303 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9304 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9305 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9307 return WERR_BADFUNC;
9310 /****************************************************************
9312 ****************************************************************/
9314 WERROR _spoolss_XcvData(struct pipes_struct *p,
9315 struct spoolss_XcvData *r)
9317 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9318 DATA_BLOB out_data = data_blob_null;
9322 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9323 OUR_HANDLE(r->in.handle)));
9327 /* Has to be a handle to the TCP/IP port monitor */
9329 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9330 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9334 /* requires administrative access to the server */
9336 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9337 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9338 return WERR_ACCESS_DENIED;
9341 /* Allocate the outgoing buffer */
9343 if (r->in.out_data_size) {
9344 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9345 if (out_data.data == NULL) {
9350 switch ( Printer->printer_type ) {
9351 case SPLHND_PORTMON_TCP:
9352 werror = process_xcvtcp_command(p->mem_ctx,
9353 p->server_info->ptok,
9354 r->in.function_name,
9355 &r->in.in_data, &out_data,
9358 case SPLHND_PORTMON_LOCAL:
9359 werror = process_xcvlocal_command(p->mem_ctx,
9360 p->server_info->ptok,
9361 r->in.function_name,
9362 &r->in.in_data, &out_data,
9366 werror = WERR_INVALID_PRINT_MONITOR;
9369 if (!W_ERROR_IS_OK(werror)) {
9373 *r->out.status_code = 0;
9375 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9376 memcpy(r->out.out_data, out_data.data,
9377 MIN(r->in.out_data_size, out_data.length));
9383 /****************************************************************
9384 _spoolss_AddPrintProcessor
9385 ****************************************************************/
9387 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9388 struct spoolss_AddPrintProcessor *r)
9390 /* for now, just indicate success and ignore the add. We'll
9391 automatically set the winprint processor for printer
9392 entries later. Used to debug the LexMark Optra S 1855 PCL
9398 /****************************************************************
9400 ****************************************************************/
9402 WERROR _spoolss_AddPort(struct pipes_struct *p,
9403 struct spoolss_AddPort *r)
9405 /* do what w2k3 does */
9407 return WERR_NOT_SUPPORTED;
9410 /****************************************************************
9411 _spoolss_GetPrinterDriver
9412 ****************************************************************/
9414 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9415 struct spoolss_GetPrinterDriver *r)
9417 p->rng_fault_state = true;
9418 return WERR_NOT_SUPPORTED;
9421 /****************************************************************
9422 _spoolss_ReadPrinter
9423 ****************************************************************/
9425 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9426 struct spoolss_ReadPrinter *r)
9428 p->rng_fault_state = true;
9429 return WERR_NOT_SUPPORTED;
9432 /****************************************************************
9433 _spoolss_WaitForPrinterChange
9434 ****************************************************************/
9436 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9437 struct spoolss_WaitForPrinterChange *r)
9439 p->rng_fault_state = true;
9440 return WERR_NOT_SUPPORTED;
9443 /****************************************************************
9444 _spoolss_ConfigurePort
9445 ****************************************************************/
9447 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9448 struct spoolss_ConfigurePort *r)
9450 p->rng_fault_state = true;
9451 return WERR_NOT_SUPPORTED;
9454 /****************************************************************
9456 ****************************************************************/
9458 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9459 struct spoolss_DeletePort *r)
9461 p->rng_fault_state = true;
9462 return WERR_NOT_SUPPORTED;
9465 /****************************************************************
9466 _spoolss_CreatePrinterIC
9467 ****************************************************************/
9469 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9470 struct spoolss_CreatePrinterIC *r)
9472 p->rng_fault_state = true;
9473 return WERR_NOT_SUPPORTED;
9476 /****************************************************************
9477 _spoolss_PlayGDIScriptOnPrinterIC
9478 ****************************************************************/
9480 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9481 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9483 p->rng_fault_state = true;
9484 return WERR_NOT_SUPPORTED;
9487 /****************************************************************
9488 _spoolss_DeletePrinterIC
9489 ****************************************************************/
9491 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9492 struct spoolss_DeletePrinterIC *r)
9494 p->rng_fault_state = true;
9495 return WERR_NOT_SUPPORTED;
9498 /****************************************************************
9499 _spoolss_AddPrinterConnection
9500 ****************************************************************/
9502 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9503 struct spoolss_AddPrinterConnection *r)
9505 p->rng_fault_state = true;
9506 return WERR_NOT_SUPPORTED;
9509 /****************************************************************
9510 _spoolss_DeletePrinterConnection
9511 ****************************************************************/
9513 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9514 struct spoolss_DeletePrinterConnection *r)
9516 p->rng_fault_state = true;
9517 return WERR_NOT_SUPPORTED;
9520 /****************************************************************
9521 _spoolss_PrinterMessageBox
9522 ****************************************************************/
9524 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9525 struct spoolss_PrinterMessageBox *r)
9527 p->rng_fault_state = true;
9528 return WERR_NOT_SUPPORTED;
9531 /****************************************************************
9533 ****************************************************************/
9535 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9536 struct spoolss_AddMonitor *r)
9538 p->rng_fault_state = true;
9539 return WERR_NOT_SUPPORTED;
9542 /****************************************************************
9543 _spoolss_DeleteMonitor
9544 ****************************************************************/
9546 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9547 struct spoolss_DeleteMonitor *r)
9549 p->rng_fault_state = true;
9550 return WERR_NOT_SUPPORTED;
9553 /****************************************************************
9554 _spoolss_DeletePrintProcessor
9555 ****************************************************************/
9557 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9558 struct spoolss_DeletePrintProcessor *r)
9560 p->rng_fault_state = true;
9561 return WERR_NOT_SUPPORTED;
9564 /****************************************************************
9565 _spoolss_AddPrintProvidor
9566 ****************************************************************/
9568 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9569 struct spoolss_AddPrintProvidor *r)
9571 p->rng_fault_state = true;
9572 return WERR_NOT_SUPPORTED;
9575 /****************************************************************
9576 _spoolss_DeletePrintProvidor
9577 ****************************************************************/
9579 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9580 struct spoolss_DeletePrintProvidor *r)
9582 p->rng_fault_state = true;
9583 return WERR_NOT_SUPPORTED;
9586 /****************************************************************
9587 _spoolss_FindFirstPrinterChangeNotification
9588 ****************************************************************/
9590 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9591 struct spoolss_FindFirstPrinterChangeNotification *r)
9593 p->rng_fault_state = true;
9594 return WERR_NOT_SUPPORTED;
9597 /****************************************************************
9598 _spoolss_FindNextPrinterChangeNotification
9599 ****************************************************************/
9601 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9602 struct spoolss_FindNextPrinterChangeNotification *r)
9604 p->rng_fault_state = true;
9605 return WERR_NOT_SUPPORTED;
9608 /****************************************************************
9609 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9610 ****************************************************************/
9612 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9613 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9615 p->rng_fault_state = true;
9616 return WERR_NOT_SUPPORTED;
9619 /****************************************************************
9620 _spoolss_ReplyOpenPrinter
9621 ****************************************************************/
9623 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9624 struct spoolss_ReplyOpenPrinter *r)
9626 p->rng_fault_state = true;
9627 return WERR_NOT_SUPPORTED;
9630 /****************************************************************
9631 _spoolss_RouterReplyPrinter
9632 ****************************************************************/
9634 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9635 struct spoolss_RouterReplyPrinter *r)
9637 p->rng_fault_state = true;
9638 return WERR_NOT_SUPPORTED;
9641 /****************************************************************
9642 _spoolss_ReplyClosePrinter
9643 ****************************************************************/
9645 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9646 struct spoolss_ReplyClosePrinter *r)
9648 p->rng_fault_state = true;
9649 return WERR_NOT_SUPPORTED;
9652 /****************************************************************
9654 ****************************************************************/
9656 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9657 struct spoolss_AddPortEx *r)
9659 p->rng_fault_state = true;
9660 return WERR_NOT_SUPPORTED;
9663 /****************************************************************
9664 _spoolss_RouterFindFirstPrinterChangeNotification
9665 ****************************************************************/
9667 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9668 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9670 p->rng_fault_state = true;
9671 return WERR_NOT_SUPPORTED;
9674 /****************************************************************
9675 _spoolss_SpoolerInit
9676 ****************************************************************/
9678 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9679 struct spoolss_SpoolerInit *r)
9681 p->rng_fault_state = true;
9682 return WERR_NOT_SUPPORTED;
9685 /****************************************************************
9686 _spoolss_ResetPrinterEx
9687 ****************************************************************/
9689 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9690 struct spoolss_ResetPrinterEx *r)
9692 p->rng_fault_state = true;
9693 return WERR_NOT_SUPPORTED;
9696 /****************************************************************
9697 _spoolss_RouterReplyPrinterEx
9698 ****************************************************************/
9700 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9701 struct spoolss_RouterReplyPrinterEx *r)
9703 p->rng_fault_state = true;
9704 return WERR_NOT_SUPPORTED;
9707 /****************************************************************
9709 ****************************************************************/
9711 WERROR _spoolss_44(struct pipes_struct *p,
9712 struct spoolss_44 *r)
9714 p->rng_fault_state = true;
9715 return WERR_NOT_SUPPORTED;
9718 /****************************************************************
9720 ****************************************************************/
9722 WERROR _spoolss_47(struct pipes_struct *p,
9723 struct spoolss_47 *r)
9725 p->rng_fault_state = true;
9726 return WERR_NOT_SUPPORTED;
9729 /****************************************************************
9731 ****************************************************************/
9733 WERROR _spoolss_4a(struct pipes_struct *p,
9734 struct spoolss_4a *r)
9736 p->rng_fault_state = true;
9737 return WERR_NOT_SUPPORTED;
9740 /****************************************************************
9742 ****************************************************************/
9744 WERROR _spoolss_4b(struct pipes_struct *p,
9745 struct spoolss_4b *r)
9747 p->rng_fault_state = true;
9748 return WERR_NOT_SUPPORTED;
9751 /****************************************************************
9753 ****************************************************************/
9755 WERROR _spoolss_4c(struct pipes_struct *p,
9756 struct spoolss_4c *r)
9758 p->rng_fault_state = true;
9759 return WERR_NOT_SUPPORTED;
9762 /****************************************************************
9764 ****************************************************************/
9766 WERROR _spoolss_53(struct pipes_struct *p,
9767 struct spoolss_53 *r)
9769 p->rng_fault_state = true;
9770 return WERR_NOT_SUPPORTED;
9773 /****************************************************************
9775 ****************************************************************/
9777 WERROR _spoolss_55(struct pipes_struct *p,
9778 struct spoolss_55 *r)
9780 p->rng_fault_state = true;
9781 return WERR_NOT_SUPPORTED;
9784 /****************************************************************
9786 ****************************************************************/
9788 WERROR _spoolss_56(struct pipes_struct *p,
9789 struct spoolss_56 *r)
9791 p->rng_fault_state = true;
9792 return WERR_NOT_SUPPORTED;
9795 /****************************************************************
9797 ****************************************************************/
9799 WERROR _spoolss_57(struct pipes_struct *p,
9800 struct spoolss_57 *r)
9802 p->rng_fault_state = true;
9803 return WERR_NOT_SUPPORTED;
9806 /****************************************************************
9808 ****************************************************************/
9810 WERROR _spoolss_5a(struct pipes_struct *p,
9811 struct spoolss_5a *r)
9813 p->rng_fault_state = true;
9814 return WERR_NOT_SUPPORTED;
9817 /****************************************************************
9819 ****************************************************************/
9821 WERROR _spoolss_5b(struct pipes_struct *p,
9822 struct spoolss_5b *r)
9824 p->rng_fault_state = true;
9825 return WERR_NOT_SUPPORTED;
9828 /****************************************************************
9830 ****************************************************************/
9832 WERROR _spoolss_5c(struct pipes_struct *p,
9833 struct spoolss_5c *r)
9835 p->rng_fault_state = true;
9836 return WERR_NOT_SUPPORTED;
9839 /****************************************************************
9841 ****************************************************************/
9843 WERROR _spoolss_5d(struct pipes_struct *p,
9844 struct spoolss_5d *r)
9846 p->rng_fault_state = true;
9847 return WERR_NOT_SUPPORTED;
9850 /****************************************************************
9852 ****************************************************************/
9854 WERROR _spoolss_5e(struct pipes_struct *p,
9855 struct spoolss_5e *r)
9857 p->rng_fault_state = true;
9858 return WERR_NOT_SUPPORTED;
9861 /****************************************************************
9863 ****************************************************************/
9865 WERROR _spoolss_5f(struct pipes_struct *p,
9866 struct spoolss_5f *r)
9868 p->rng_fault_state = true;
9869 return WERR_NOT_SUPPORTED;
9872 /****************************************************************
9874 ****************************************************************/
9876 WERROR _spoolss_60(struct pipes_struct *p,
9877 struct spoolss_60 *r)
9879 p->rng_fault_state = true;
9880 return WERR_NOT_SUPPORTED;
9883 /****************************************************************
9885 ****************************************************************/
9887 WERROR _spoolss_61(struct pipes_struct *p,
9888 struct spoolss_61 *r)
9890 p->rng_fault_state = true;
9891 return WERR_NOT_SUPPORTED;
9894 /****************************************************************
9896 ****************************************************************/
9898 WERROR _spoolss_62(struct pipes_struct *p,
9899 struct spoolss_62 *r)
9901 p->rng_fault_state = true;
9902 return WERR_NOT_SUPPORTED;
9905 /****************************************************************
9907 ****************************************************************/
9909 WERROR _spoolss_63(struct pipes_struct *p,
9910 struct spoolss_63 *r)
9912 p->rng_fault_state = true;
9913 return WERR_NOT_SUPPORTED;
9916 /****************************************************************
9918 ****************************************************************/
9920 WERROR _spoolss_64(struct pipes_struct *p,
9921 struct spoolss_64 *r)
9923 p->rng_fault_state = true;
9924 return WERR_NOT_SUPPORTED;
9927 /****************************************************************
9929 ****************************************************************/
9931 WERROR _spoolss_65(struct pipes_struct *p,
9932 struct spoolss_65 *r)
9934 p->rng_fault_state = true;
9935 return WERR_NOT_SUPPORTED;
9938 /****************************************************************
9939 _spoolss_GetCorePrinterDrivers
9940 ****************************************************************/
9942 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9943 struct spoolss_GetCorePrinterDrivers *r)
9945 p->rng_fault_state = true;
9946 return WERR_NOT_SUPPORTED;
9949 /****************************************************************
9951 ****************************************************************/
9953 WERROR _spoolss_67(struct pipes_struct *p,
9954 struct spoolss_67 *r)
9956 p->rng_fault_state = true;
9957 return WERR_NOT_SUPPORTED;
9960 /****************************************************************
9961 _spoolss_GetPrinterDriverPackagePath
9962 ****************************************************************/
9964 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
9965 struct spoolss_GetPrinterDriverPackagePath *r)
9967 p->rng_fault_state = true;
9968 return WERR_NOT_SUPPORTED;
9971 /****************************************************************
9973 ****************************************************************/
9975 WERROR _spoolss_69(struct pipes_struct *p,
9976 struct spoolss_69 *r)
9978 p->rng_fault_state = true;
9979 return WERR_NOT_SUPPORTED;
9982 /****************************************************************
9984 ****************************************************************/
9986 WERROR _spoolss_6a(struct pipes_struct *p,
9987 struct spoolss_6a *r)
9989 p->rng_fault_state = true;
9990 return WERR_NOT_SUPPORTED;
9993 /****************************************************************
9995 ****************************************************************/
9997 WERROR _spoolss_6b(struct pipes_struct *p,
9998 struct spoolss_6b *r)
10000 p->rng_fault_state = true;
10001 return WERR_NOT_SUPPORTED;
10004 /****************************************************************
10006 ****************************************************************/
10008 WERROR _spoolss_6c(struct pipes_struct *p,
10009 struct spoolss_6c *r)
10011 p->rng_fault_state = true;
10012 return WERR_NOT_SUPPORTED;
10015 /****************************************************************
10017 ****************************************************************/
10019 WERROR _spoolss_6d(struct pipes_struct *p,
10020 struct spoolss_6d *r)
10022 p->rng_fault_state = true;
10023 return WERR_NOT_SUPPORTED;