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 #include "../librpc/gen_ndr/netlogon.h"
44 /* macros stolen from s4 spoolss server */
45 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
46 ((info)?ndr_size_##fn(info, level, 0):0)
48 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
49 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
51 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
52 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
54 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
57 #define DBGC_CLASS DBGC_RPC_SRV
59 static Printer_entry *printers_list;
61 typedef struct _counter_printer_0 {
62 struct _counter_printer_0 *next;
63 struct _counter_printer_0 *prev;
69 static counter_printer_0 *counter_list;
71 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
72 static uint32_t smb_connections = 0;
75 /* Map generic permissions to printer object specific permissions */
77 const struct standard_mapping printer_std_mapping = {
84 /* Map generic permissions to print server object specific permissions */
86 const struct standard_mapping printserver_std_mapping = {
93 /* API table for Xcv Monitor functions */
95 struct xcv_api_table {
97 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
100 /********************************************************************
101 * Canonicalize servername.
102 ********************************************************************/
104 static const char *canon_servername(const char *servername)
106 const char *pservername = servername;
107 while (*pservername == '\\') {
113 /* translate between internal status numbers and NT status numbers */
114 static int nt_printj_status(int v)
120 return JOB_STATUS_PAUSED;
122 return JOB_STATUS_SPOOLING;
124 return JOB_STATUS_PRINTING;
126 return JOB_STATUS_ERROR;
128 return JOB_STATUS_DELETING;
130 return JOB_STATUS_OFFLINE;
132 return JOB_STATUS_PAPEROUT;
134 return JOB_STATUS_PRINTED;
136 return JOB_STATUS_DELETED;
138 return JOB_STATUS_BLOCKED_DEVQ;
139 case LPQ_USER_INTERVENTION:
140 return JOB_STATUS_USER_INTERVENTION;
145 static int nt_printq_status(int v)
149 return PRINTER_STATUS_PAUSED;
158 /***************************************************************************
159 Disconnect from the client
160 ****************************************************************************/
162 static void srv_spoolss_replycloseprinter(
163 int snum, struct policy_handle *handle,
164 struct messaging_context *msg_ctx)
170 * Tell the specific printing tdb we no longer want messages for this printer
171 * by deregistering our PID.
174 if (!print_notify_deregister_pid(snum))
175 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
177 /* weird if the test succeeds !!! */
178 if (smb_connections==0) {
179 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
183 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
186 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
187 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
188 win_errstr(result)));
190 /* if it's the last connection, deconnect the IPC$ share */
191 if (smb_connections==1) {
193 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
195 * The above call shuts down the pipe also.
197 notify_cli_pipe = NULL;
199 if (msg_ctx != NULL) {
200 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
204 * Tell the serverid.tdb we're no longer
205 * interested in printer notify messages.
208 serverid_register_msg_flags(
209 messaging_server_id(msg_ctx),
210 false, FLAG_MSG_PRINT_NOTIFY);
217 /****************************************************************************
218 Functions to free a printer entry datastruct.
219 ****************************************************************************/
221 static int printer_entry_destructor(Printer_entry *Printer)
223 if (Printer->notify.client_connected == true) {
226 if ( Printer->printer_type == SPLHND_SERVER) {
228 srv_spoolss_replycloseprinter(
229 snum, &Printer->notify.client_hnd,
230 Printer->notify.msg_ctx);
231 } else if (Printer->printer_type == SPLHND_PRINTER) {
232 snum = print_queue_snum(Printer->sharename);
234 srv_spoolss_replycloseprinter(
235 snum, &Printer->notify.client_hnd,
236 Printer->notify.msg_ctx);
240 Printer->notify.flags=0;
241 Printer->notify.options=0;
242 Printer->notify.localmachine[0]='\0';
243 Printer->notify.printerlocal=0;
244 TALLOC_FREE(Printer->notify.option);
245 Printer->notify.client_connected = false;
247 TALLOC_FREE(Printer->devmode);
249 /* Remove from the internal list. */
250 DLIST_REMOVE(printers_list, Printer);
254 /****************************************************************************
255 find printer index by handle
256 ****************************************************************************/
258 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
259 struct policy_handle *hnd)
261 Printer_entry *find_printer = NULL;
263 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
264 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
271 /****************************************************************************
272 Close printer index by handle.
273 ****************************************************************************/
275 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
277 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
280 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
285 close_policy_hnd(p, hnd);
290 /****************************************************************************
291 Delete a printer given a handle.
292 ****************************************************************************/
294 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
295 const char *sharename,
296 struct messaging_context *msg_ctx)
298 char *cmd = lp_deleteprinter_cmd();
299 char *command = NULL;
301 SE_PRIV se_printop = SE_PRINT_OPERATOR;
302 bool is_print_op = false;
304 /* can't fail if we don't try */
309 command = talloc_asprintf(ctx,
316 is_print_op = user_has_privileges( token, &se_printop );
318 DEBUG(10,("Running [%s]\n", command));
320 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
325 if ( (ret = smbrun(command, NULL)) == 0 ) {
326 /* Tell everyone we updated smb.conf. */
327 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
333 /********** END SePrintOperatorPrivlege BLOCK **********/
335 DEBUGADD(10,("returned [%d]\n", ret));
337 TALLOC_FREE(command);
340 return WERR_BADFID; /* What to return here? */
342 /* go ahead and re-read the services immediately */
344 reload_services(false);
347 if ( lp_servicenumber( sharename ) > 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
363 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
369 * It turns out that Windows allows delete printer on a handle
370 * opened by an admin user, then used on a pipe handle created
371 * by an anonymous user..... but they're working on security.... riiight !
375 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
376 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
377 return WERR_ACCESS_DENIED;
380 /* this does not need a become root since the access check has been
381 done on the handle already */
383 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
384 Printer->sharename, "");
385 if (!W_ERROR_IS_OK(result)) {
386 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
390 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
391 Printer->sharename, p->msg_ctx);
394 /****************************************************************************
395 Return the snum of a printer corresponding to an handle.
396 ****************************************************************************/
398 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
399 int *number, struct share_params **params)
401 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
404 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
409 switch (Printer->printer_type) {
411 DEBUG(4,("short name:%s\n", Printer->sharename));
412 *number = print_queue_snum(Printer->sharename);
413 return (*number != -1);
421 /****************************************************************************
422 Set printer handle type.
423 Check if it's \\server or \\server\printer
424 ****************************************************************************/
426 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
428 DEBUG(3,("Setting printer type=%s\n", handlename));
430 if ( strlen(handlename) < 3 ) {
431 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
435 /* it's a print server */
436 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
437 DEBUGADD(4,("Printer is a print server\n"));
438 Printer->printer_type = SPLHND_SERVER;
440 /* it's a printer (set_printer_hnd_name() will handle port monitors */
442 DEBUGADD(4,("Printer is a printer\n"));
443 Printer->printer_type = SPLHND_PRINTER;
449 /****************************************************************************
450 Set printer handle name.. Accept names like \\server, \\server\printer,
451 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
452 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
453 XcvDataPort() interface.
454 ****************************************************************************/
456 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
457 struct auth_serversupplied_info *server_info,
458 Printer_entry *Printer,
459 const char *handlename)
462 int n_services=lp_numservices();
464 const char *printername;
465 const char *servername = NULL;
468 struct spoolss_PrinterInfo2 *info2 = NULL;
471 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
472 (unsigned long)strlen(handlename)));
474 aprinter = CONST_DISCARD(char *, handlename);
475 if ( *handlename == '\\' ) {
476 servername = canon_servername(handlename);
477 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
481 if (!is_myname_or_ipaddr(servername)) {
485 fstrcpy(Printer->servername, servername);
488 if (Printer->printer_type == SPLHND_SERVER) {
492 if (Printer->printer_type != SPLHND_PRINTER) {
496 DEBUGADD(5, ("searching for [%s]\n", aprinter));
498 /* check for the Port Monitor Interface */
499 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
500 Printer->printer_type = SPLHND_PORTMON_TCP;
501 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
504 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
505 Printer->printer_type = SPLHND_PORTMON_LOCAL;
506 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
510 /* Search all sharenames first as this is easier than pulling
511 the printer_info_2 off of disk. Don't use find_service() since
512 that calls out to map_username() */
514 /* do another loop to look for printernames */
515 for (snum = 0; !found && snum < n_services; snum++) {
516 const char *printer = lp_const_servicename(snum);
518 /* no point going on if this is not a printer */
519 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
523 /* ignore [printers] share */
524 if (strequal(printer, "printers")) {
528 fstrcpy(sname, printer);
529 if (strequal(aprinter, printer)) {
534 /* no point looking up the printer object if
535 we aren't allowing printername != sharename */
536 if (lp_force_printername(snum)) {
540 result = winreg_get_printer(mem_ctx,
545 if ( !W_ERROR_IS_OK(result) ) {
546 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
547 sname, win_errstr(result)));
551 printername = strrchr(info2->printername, '\\');
552 if (printername == NULL) {
553 printername = info2->printername;
558 if (strequal(printername, aprinter)) {
563 DEBUGADD(10, ("printername: %s\n", printername));
569 DEBUGADD(4,("Printer not found\n"));
573 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
575 fstrcpy(Printer->sharename, sname);
580 /****************************************************************************
581 Find first available printer slot. creates a printer handle for you.
582 ****************************************************************************/
584 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
585 const char *name, uint32_t access_granted)
587 Printer_entry *new_printer;
589 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
591 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
592 if (new_printer == NULL) {
595 talloc_set_destructor(new_printer, printer_entry_destructor);
597 if (!create_policy_hnd(p, hnd, new_printer)) {
598 TALLOC_FREE(new_printer);
602 /* Add to the internal list. */
603 DLIST_ADD(printers_list, new_printer);
605 new_printer->notify.option=NULL;
607 if (!set_printer_hnd_printertype(new_printer, name)) {
608 close_printer_handle(p, hnd);
612 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
613 close_printer_handle(p, hnd);
617 new_printer->access_granted = access_granted;
619 DEBUG(5, ("%d printer handles active\n",
620 (int)num_pipe_handles(p)));
625 /***************************************************************************
626 check to see if the client motify handle is monitoring the notification
627 given by (notify_type, notify_field).
628 **************************************************************************/
630 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
631 uint16_t notify_field)
636 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
637 uint16_t notify_field)
639 struct spoolss_NotifyOption *option = p->notify.option;
643 * Flags should always be zero when the change notify
644 * is registered by the client's spooler. A user Win32 app
645 * might use the flags though instead of the NOTIFY_OPTION_INFO
654 return is_monitoring_event_flags(
655 p->notify.flags, notify_type, notify_field);
657 for (i = 0; i < option->count; i++) {
659 /* Check match for notify_type */
661 if (option->types[i].type != notify_type)
664 /* Check match for field */
666 for (j = 0; j < option->types[i].count; j++) {
667 if (option->types[i].fields[j].field == notify_field) {
673 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
674 p->servername, p->sharename, notify_type, notify_field));
679 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
680 _data->data.integer[0] = _integer; \
681 _data->data.integer[1] = 0;
684 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
685 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
686 if (!_data->data.string.string) {\
687 _data->data.string.size = 0; \
689 _data->data.string.size = strlen_m_term(_p) * 2;
691 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
692 _data->data.devmode.devmode = _devmode;
694 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
695 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
696 if (!_data->data.sd.sd) { \
697 _data->data.sd.sd_size = 0; \
699 _data->data.sd.sd_size = \
700 ndr_size_security_descriptor(_data->data.sd.sd, 0);
702 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
707 struct spoolss_Time st;
711 if (!init_systemtime(&st, t)) {
715 p = talloc_array(mem_ctx, char, len);
721 * Systemtime must be linearized as a set of UINT16's.
722 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
725 SSVAL(p, 0, st.year);
726 SSVAL(p, 2, st.month);
727 SSVAL(p, 4, st.day_of_week);
729 SSVAL(p, 8, st.hour);
730 SSVAL(p, 10, st.minute);
731 SSVAL(p, 12, st.second);
732 SSVAL(p, 14, st.millisecond);
738 /* Convert a notification message to a struct spoolss_Notify */
740 static void notify_one_value(struct spoolss_notify_msg *msg,
741 struct spoolss_Notify *data,
744 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
747 static void notify_string(struct spoolss_notify_msg *msg,
748 struct spoolss_Notify *data,
751 /* The length of the message includes the trailing \0 */
753 data->data.string.size = msg->len * 2;
754 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
755 if (!data->data.string.string) {
756 data->data.string.size = 0;
761 static void notify_system_time(struct spoolss_notify_msg *msg,
762 struct spoolss_Notify *data,
765 data->data.string.string = NULL;
766 data->data.string.size = 0;
768 if (msg->len != sizeof(time_t)) {
769 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
774 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
775 &data->data.string.string,
776 &data->data.string.size);
779 struct notify2_message_table {
781 void (*fn)(struct spoolss_notify_msg *msg,
782 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
785 static struct notify2_message_table printer_notify_table[] = {
786 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
787 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
788 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
789 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
790 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
791 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
792 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
793 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
794 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
795 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
796 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
797 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
798 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
799 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
800 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
801 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
802 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
803 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
804 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
807 static struct notify2_message_table job_notify_table[] = {
808 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
809 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
810 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
811 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
812 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
813 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
814 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
815 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
816 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
817 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
818 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
819 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
820 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
821 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
822 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
823 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
824 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
825 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
826 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
827 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
828 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
829 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
830 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
831 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
835 /***********************************************************************
836 Allocate talloc context for container object
837 **********************************************************************/
839 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
844 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
849 /***********************************************************************
850 release all allocated memory and zero out structure
851 **********************************************************************/
853 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
859 talloc_destroy(ctr->ctx);
866 /***********************************************************************
867 **********************************************************************/
869 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
877 /***********************************************************************
878 **********************************************************************/
880 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
882 if ( !ctr || !ctr->msg_groups )
885 if ( idx >= ctr->num_groups )
888 return &ctr->msg_groups[idx];
892 /***********************************************************************
893 How many groups of change messages do we have ?
894 **********************************************************************/
896 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
901 return ctr->num_groups;
904 /***********************************************************************
905 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
906 **********************************************************************/
908 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
910 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
911 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
912 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
918 /* loop over all groups looking for a matching printer name */
920 for ( i=0; i<ctr->num_groups; i++ ) {
921 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
925 /* add a new group? */
927 if ( i == ctr->num_groups ) {
930 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
931 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
934 ctr->msg_groups = groups;
936 /* clear the new entry and set the printer name */
938 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
939 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
942 /* add the change messages; 'i' is the correct index now regardless */
944 msg_grp = &ctr->msg_groups[i];
948 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
949 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
952 msg_grp->msgs = msg_list;
954 new_slot = msg_grp->num_msgs-1;
955 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
957 /* need to allocate own copy of data */
960 msg_grp->msgs[new_slot].notify.data = (char *)
961 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
963 return ctr->num_groups;
966 static void construct_info_data(struct spoolss_Notify *info_data,
967 enum spoolss_NotifyType type,
968 uint16_t field, int id);
970 /***********************************************************************
971 Send a change notication message on all handles which have a call
973 **********************************************************************/
975 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
978 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
979 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
980 SPOOLSS_NOTIFY_MSG *messages;
981 int sending_msg_count;
984 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
988 messages = msg_group->msgs;
991 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
995 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
997 /* loop over all printers */
999 for (p = printers_list; p; p = p->next) {
1000 struct spoolss_Notify *notifies;
1005 /* Is there notification on this handle? */
1007 if ( !p->notify.client_connected )
1010 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1012 /* For this printer? Print servers always receive
1015 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1016 ( !strequal(msg_group->printername, p->sharename) ) )
1019 DEBUG(10,("Our printer\n"));
1021 /* allocate the max entries possible */
1023 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1028 /* build the array of change notifications */
1030 sending_msg_count = 0;
1032 for ( i=0; i<msg_group->num_msgs; i++ ) {
1033 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1035 /* Are we monitoring this event? */
1037 if (!is_monitoring_event(p, msg->type, msg->field))
1040 sending_msg_count++;
1043 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1044 msg->type, msg->field, p->sharename));
1047 * if the is a printer notification handle and not a job notification
1048 * type, then set the id to 0. Other wise just use what was specified
1051 * When registering change notification on a print server handle
1052 * we always need to send back the id (snum) matching the printer
1053 * for which the change took place. For change notify registered
1054 * on a printer handle, this does not matter and the id should be 0.
1059 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1065 /* Convert unix jobid to smb jobid */
1067 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1068 id = sysjob_to_jobid(msg->id);
1071 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1076 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1079 case PRINTER_NOTIFY_TYPE:
1080 if ( printer_notify_table[msg->field].fn )
1081 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1084 case JOB_NOTIFY_TYPE:
1085 if ( job_notify_table[msg->field].fn )
1086 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1090 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1097 if ( sending_msg_count ) {
1100 union spoolss_ReplyPrinterInfo info;
1101 struct spoolss_NotifyInfo info0;
1102 uint32_t reply_result;
1104 info0.version = 0x2;
1105 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1106 info0.count = count;
1107 info0.notifies = notifies;
1109 info.info0 = &info0;
1111 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1112 &p->notify.client_hnd,
1113 p->notify.change, /* color */
1116 0, /* reply_type, must be 0 */
1119 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1120 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1121 notify_cli_pipe->srv_name_slash,
1124 switch (reply_result) {
1127 case PRINTER_NOTIFY_INFO_DISCARDED:
1128 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1129 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1138 DEBUG(8,("send_notify2_changes: Exit...\n"));
1142 /***********************************************************************
1143 **********************************************************************/
1145 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1148 uint32_t tv_sec, tv_usec;
1151 /* Unpack message */
1153 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1156 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1158 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1161 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1162 &msg->notify.value[0], &msg->notify.value[1]);
1164 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1165 &msg->len, &msg->notify.data);
1167 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1168 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1170 tv->tv_sec = tv_sec;
1171 tv->tv_usec = tv_usec;
1174 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1175 msg->notify.value[1]));
1177 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1182 /********************************************************************
1183 Receive a notify2 message list
1184 ********************************************************************/
1186 static void receive_notify2_message_list(struct messaging_context *msg,
1189 struct server_id server_id,
1192 size_t msg_count, i;
1193 char *buf = (char *)data->data;
1196 SPOOLSS_NOTIFY_MSG notify;
1197 SPOOLSS_NOTIFY_MSG_CTR messages;
1200 if (data->length < 4) {
1201 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1205 msg_count = IVAL(buf, 0);
1208 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1210 if (msg_count == 0) {
1211 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1215 /* initialize the container */
1217 ZERO_STRUCT( messages );
1218 notify_msg_ctr_init( &messages );
1221 * build message groups for each printer identified
1222 * in a change_notify msg. Remember that a PCN message
1223 * includes the handle returned for the srv_spoolss_replyopenprinter()
1224 * call. Therefore messages are grouped according to printer handle.
1227 for ( i=0; i<msg_count; i++ ) {
1228 struct timeval msg_tv;
1230 if (msg_ptr + 4 - buf > data->length) {
1231 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1235 msg_len = IVAL(msg_ptr,0);
1238 if (msg_ptr + msg_len - buf > data->length) {
1239 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1243 /* unpack messages */
1245 ZERO_STRUCT( notify );
1246 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1249 /* add to correct list in container */
1251 notify_msg_ctr_addmsg( &messages, ¬ify );
1253 /* free memory that might have been allocated by notify2_unpack_msg() */
1255 if ( notify.len != 0 )
1256 SAFE_FREE( notify.notify.data );
1259 /* process each group of messages */
1261 num_groups = notify_msg_ctr_numgroups( &messages );
1262 for ( i=0; i<num_groups; i++ )
1263 send_notify2_changes( &messages, i );
1268 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1269 (uint32_t)msg_count ));
1271 notify_msg_ctr_destroy( &messages );
1276 /********************************************************************
1277 Send a message to ourself about new driver being installed
1278 so we can upgrade the information for each printer bound to this
1280 ********************************************************************/
1282 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1283 struct messaging_context *msg_ctx)
1285 int len = strlen(drivername);
1290 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1293 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1294 MSG_PRINTER_DRVUPGRADE,
1295 (uint8_t *)drivername, len+1);
1300 /**********************************************************************
1301 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1302 over all printers, upgrading ones as necessary
1303 **********************************************************************/
1305 void do_drv_upgrade_printer(struct messaging_context *msg,
1308 struct server_id server_id,
1311 TALLOC_CTX *tmp_ctx;
1312 struct auth_serversupplied_info *server_info = NULL;
1313 struct spoolss_PrinterInfo2 *pinfo2;
1316 const char *drivername;
1318 int n_services = lp_numservices();
1321 tmp_ctx = talloc_new(NULL);
1322 if (!tmp_ctx) return;
1324 status = make_server_info_system(tmp_ctx, &server_info);
1325 if (!NT_STATUS_IS_OK(status)) {
1326 DEBUG(0, ("do_drv_upgrade_printer: "
1327 "Could not create system server_info\n"));
1331 len = MIN(data->length,sizeof(drivername)-1);
1332 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1334 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1338 DEBUG(10, ("do_drv_upgrade_printer: "
1339 "Got message for new driver [%s]\n", drivername));
1341 /* Iterate the printer list */
1343 for (snum = 0; snum < n_services; snum++) {
1344 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1348 result = winreg_get_printer(tmp_ctx, server_info, NULL,
1349 lp_const_servicename(snum),
1352 if (!W_ERROR_IS_OK(result)) {
1356 if (!pinfo2->drivername) {
1360 if (strcmp(drivername, pinfo2->drivername) != 0) {
1364 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1366 /* all we care about currently is the change_id */
1367 result = winreg_printer_update_changeid(tmp_ctx,
1369 pinfo2->printername);
1371 if (!W_ERROR_IS_OK(result)) {
1372 DEBUG(3, ("do_drv_upgrade_printer: "
1373 "Failed to update changeid [%s]\n",
1374 win_errstr(result)));
1380 talloc_free(tmp_ctx);
1383 /********************************************************************
1384 Update the cache for all printq's with a registered client
1386 ********************************************************************/
1388 void update_monitored_printq_cache( void )
1390 Printer_entry *printer = printers_list;
1393 /* loop through all printers and update the cache where
1394 client_connected == true */
1397 if ( (printer->printer_type == SPLHND_PRINTER)
1398 && printer->notify.client_connected )
1400 snum = print_queue_snum(printer->sharename);
1401 print_queue_status( snum, NULL, NULL );
1404 printer = printer->next;
1410 /****************************************************************
1411 _spoolss_OpenPrinter
1412 ****************************************************************/
1414 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1415 struct spoolss_OpenPrinter *r)
1417 struct spoolss_OpenPrinterEx e;
1420 ZERO_STRUCT(e.in.userlevel);
1422 e.in.printername = r->in.printername;
1423 e.in.datatype = r->in.datatype;
1424 e.in.devmode_ctr = r->in.devmode_ctr;
1425 e.in.access_mask = r->in.access_mask;
1428 e.out.handle = r->out.handle;
1430 werr = _spoolss_OpenPrinterEx(p, &e);
1432 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1433 /* OpenPrinterEx returns this for a bad
1434 * printer name. We must return WERR_INVALID_PRINTER_NAME
1437 werr = WERR_INVALID_PRINTER_NAME;
1443 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1444 struct spoolss_DeviceMode *orig,
1445 struct spoolss_DeviceMode **dest)
1447 struct spoolss_DeviceMode *dm;
1449 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1454 /* copy all values, then duplicate strings and structs */
1457 dm->devicename = talloc_strdup(dm, orig->devicename);
1458 if (!dm->devicename) {
1461 dm->formname = talloc_strdup(dm, orig->formname);
1462 if (!dm->formname) {
1465 if (orig->driverextra_data.data) {
1466 dm->driverextra_data.data =
1467 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1468 orig->driverextra_data.length);
1469 if (!dm->driverextra_data.data) {
1478 /****************************************************************
1479 _spoolss_OpenPrinterEx
1480 ****************************************************************/
1482 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1483 struct spoolss_OpenPrinterEx *r)
1486 Printer_entry *Printer=NULL;
1488 if (!r->in.printername) {
1489 return WERR_INVALID_PARAM;
1492 /* some sanity check because you can open a printer or a print server */
1493 /* aka: \\server\printer or \\server */
1495 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1497 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1498 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1499 " for printer %s\n", r->in.printername));
1500 ZERO_STRUCTP(r->out.handle);
1501 return WERR_INVALID_PARAM;
1504 Printer = find_printer_index_by_hnd(p, r->out.handle);
1506 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1507 "handle we created for printer %s\n", r->in.printername));
1508 close_printer_handle(p, r->out.handle);
1509 ZERO_STRUCTP(r->out.handle);
1510 return WERR_INVALID_PARAM;
1514 * First case: the user is opening the print server:
1516 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1517 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1519 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1520 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1521 * or if the user is listed in the smb.conf printer admin parameter.
1523 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1524 * client view printer folder, but does not show the MSAPW.
1526 * Note: this test needs code to check access rights here too. Jeremy
1527 * could you look at this?
1529 * Second case: the user is opening a printer:
1530 * NT doesn't let us connect to a printer if the connecting user
1531 * doesn't have print permission.
1533 * Third case: user is opening a Port Monitor
1534 * access checks same as opening a handle to the print server.
1537 switch (Printer->printer_type )
1540 case SPLHND_PORTMON_TCP:
1541 case SPLHND_PORTMON_LOCAL:
1542 /* Printserver handles use global struct... */
1546 /* Map standard access rights to object specific access rights */
1548 se_map_standard(&r->in.access_mask,
1549 &printserver_std_mapping);
1551 /* Deny any object specific bits that don't apply to print
1552 servers (i.e printer and job specific bits) */
1554 r->in.access_mask &= SEC_MASK_SPECIFIC;
1556 if (r->in.access_mask &
1557 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1558 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1559 close_printer_handle(p, r->out.handle);
1560 ZERO_STRUCTP(r->out.handle);
1561 return WERR_ACCESS_DENIED;
1564 /* Allow admin access */
1566 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1568 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1570 if (!lp_ms_add_printer_wizard()) {
1571 close_printer_handle(p, r->out.handle);
1572 ZERO_STRUCTP(r->out.handle);
1573 return WERR_ACCESS_DENIED;
1576 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1577 and not a printer admin, then fail */
1579 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1580 !user_has_privileges(p->server_info->ptok,
1582 !token_contains_name_in_list(
1583 uidtoname(p->server_info->utok.uid),
1584 p->server_info->info3->base.domain.string,
1586 p->server_info->ptok,
1587 lp_printer_admin(snum))) {
1588 close_printer_handle(p, r->out.handle);
1589 ZERO_STRUCTP(r->out.handle);
1590 return WERR_ACCESS_DENIED;
1593 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1597 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1600 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1601 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1603 /* We fall through to return WERR_OK */
1606 case SPLHND_PRINTER:
1607 /* NT doesn't let us connect to a printer if the connecting user
1608 doesn't have print permission. */
1610 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1611 close_printer_handle(p, r->out.handle);
1612 ZERO_STRUCTP(r->out.handle);
1616 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1617 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1620 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1622 /* map an empty access mask to the minimum access mask */
1623 if (r->in.access_mask == 0x0)
1624 r->in.access_mask = PRINTER_ACCESS_USE;
1627 * If we are not serving the printer driver for this printer,
1628 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1629 * will keep NT clients happy --jerry
1632 if (lp_use_client_driver(snum)
1633 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1635 r->in.access_mask = PRINTER_ACCESS_USE;
1638 /* check smb.conf parameters and the the sec_desc */
1640 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1641 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1642 ZERO_STRUCTP(r->out.handle);
1643 return WERR_ACCESS_DENIED;
1646 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1647 p->server_info->ptok, snum) ||
1648 !print_access_check(p->server_info, snum,
1649 r->in.access_mask)) {
1650 DEBUG(3, ("access DENIED for printer open\n"));
1651 close_printer_handle(p, r->out.handle);
1652 ZERO_STRUCTP(r->out.handle);
1653 return WERR_ACCESS_DENIED;
1656 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1657 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1658 close_printer_handle(p, r->out.handle);
1659 ZERO_STRUCTP(r->out.handle);
1660 return WERR_ACCESS_DENIED;
1663 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1664 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1666 r->in.access_mask = PRINTER_ACCESS_USE;
1668 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1669 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1671 winreg_create_printer(p->mem_ctx,
1674 Printer->servername,
1675 lp_const_servicename(snum));
1680 /* sanity check to prevent programmer error */
1681 ZERO_STRUCTP(r->out.handle);
1685 Printer->access_granted = r->in.access_mask;
1688 * If the client sent a devmode in the OpenPrinter() call, then
1689 * save it here in case we get a job submission on this handle
1692 if ((Printer->printer_type != SPLHND_SERVER) &&
1693 r->in.devmode_ctr.devmode) {
1694 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1698 #if 0 /* JERRY -- I'm doubtful this is really effective */
1699 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1700 optimization in Windows 2000 clients --jerry */
1702 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1703 && (RA_WIN2K == get_remote_arch()) )
1705 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1706 sys_usleep( 500000 );
1713 /****************************************************************
1714 _spoolss_ClosePrinter
1715 ****************************************************************/
1717 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1718 struct spoolss_ClosePrinter *r)
1720 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1722 if (Printer && Printer->document_started) {
1723 struct spoolss_EndDocPrinter e;
1725 e.in.handle = r->in.handle;
1727 _spoolss_EndDocPrinter(p, &e);
1730 if (!close_printer_handle(p, r->in.handle))
1733 /* clear the returned printer handle. Observed behavior
1734 from Win2k server. Don't think this really matters.
1735 Previous code just copied the value of the closed
1738 ZERO_STRUCTP(r->out.handle);
1743 /****************************************************************
1744 _spoolss_DeletePrinter
1745 ****************************************************************/
1747 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1748 struct spoolss_DeletePrinter *r)
1750 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1754 if (Printer && Printer->document_started) {
1755 struct spoolss_EndDocPrinter e;
1757 e.in.handle = r->in.handle;
1759 _spoolss_EndDocPrinter(p, &e);
1762 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1763 winreg_delete_printer_key(p->mem_ctx,
1765 lp_const_servicename(snum),
1769 result = delete_printer_handle(p, r->in.handle);
1774 /*******************************************************************
1775 * static function to lookup the version id corresponding to an
1776 * long architecture string
1777 ******************************************************************/
1779 static const struct print_architecture_table_node archi_table[]= {
1781 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1782 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1783 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1784 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1785 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1786 {"Windows IA64", SPL_ARCH_IA64, 3 },
1787 {"Windows x64", SPL_ARCH_X64, 3 },
1791 static int get_version_id(const char *arch)
1795 for (i=0; archi_table[i].long_archi != NULL; i++)
1797 if (strcmp(arch, archi_table[i].long_archi) == 0)
1798 return (archi_table[i].version);
1804 /****************************************************************
1805 _spoolss_DeletePrinterDriver
1806 ****************************************************************/
1808 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1809 struct spoolss_DeletePrinterDriver *r)
1812 struct spoolss_DriverInfo8 *info = NULL;
1813 struct spoolss_DriverInfo8 *info_win2k = NULL;
1816 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1818 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1819 and not a printer admin, then fail */
1821 if ( (p->server_info->utok.uid != sec_initial_uid())
1822 && !user_has_privileges(p->server_info->ptok, &se_printop )
1823 && !token_contains_name_in_list(
1824 uidtoname(p->server_info->utok.uid),
1825 p->server_info->info3->base.domain.string,
1827 p->server_info->ptok,
1828 lp_printer_admin(-1)) )
1830 return WERR_ACCESS_DENIED;
1833 /* check that we have a valid driver name first */
1835 if ((version = get_version_id(r->in.architecture)) == -1)
1836 return WERR_INVALID_ENVIRONMENT;
1838 status = winreg_get_driver(p->mem_ctx, p->server_info,
1839 r->in.architecture, r->in.driver,
1841 if (!W_ERROR_IS_OK(status)) {
1842 /* try for Win2k driver if "Windows NT x86" */
1844 if ( version == 2 ) {
1847 status = winreg_get_driver(p->mem_ctx, p->server_info,
1851 if (!W_ERROR_IS_OK(status)) {
1852 status = WERR_UNKNOWN_PRINTER_DRIVER;
1856 /* otherwise it was a failure */
1858 status = WERR_UNKNOWN_PRINTER_DRIVER;
1864 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1865 status = WERR_PRINTER_DRIVER_IN_USE;
1870 status = winreg_get_driver(p->mem_ctx, p->server_info,
1872 r->in.driver, 3, &info_win2k);
1873 if (W_ERROR_IS_OK(status)) {
1874 /* if we get to here, we now have 2 driver info structures to remove */
1875 /* remove the Win2k driver first*/
1877 status = winreg_del_driver(p->mem_ctx,
1880 talloc_free(info_win2k);
1882 /* this should not have failed---if it did, report to client */
1883 if (!W_ERROR_IS_OK(status)) {
1889 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1897 /****************************************************************
1898 _spoolss_DeletePrinterDriverEx
1899 ****************************************************************/
1901 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1902 struct spoolss_DeletePrinterDriverEx *r)
1904 struct spoolss_DriverInfo8 *info = NULL;
1905 struct spoolss_DriverInfo8 *info_win2k = NULL;
1909 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1911 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1912 and not a printer admin, then fail */
1914 if ( (p->server_info->utok.uid != sec_initial_uid())
1915 && !user_has_privileges(p->server_info->ptok, &se_printop )
1916 && !token_contains_name_in_list(
1917 uidtoname(p->server_info->utok.uid),
1918 p->server_info->info3->base.domain.string,
1920 p->server_info->ptok, lp_printer_admin(-1)) )
1922 return WERR_ACCESS_DENIED;
1925 /* check that we have a valid driver name first */
1926 if ((version = get_version_id(r->in.architecture)) == -1) {
1927 /* this is what NT returns */
1928 return WERR_INVALID_ENVIRONMENT;
1931 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1932 version = r->in.version;
1934 status = winreg_get_driver(p->mem_ctx, p->server_info,
1935 r->in.architecture, r->in.driver,
1937 if (!W_ERROR_IS_OK(status)) {
1938 status = WERR_UNKNOWN_PRINTER_DRIVER;
1941 * if the client asked for a specific version,
1942 * or this is something other than Windows NT x86,
1946 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1949 /* try for Win2k driver if "Windows NT x86" */
1952 status = winreg_get_driver(info, p->server_info,
1956 if (!W_ERROR_IS_OK(status)) {
1957 status = WERR_UNKNOWN_PRINTER_DRIVER;
1962 if (printer_driver_in_use(info, p->server_info, info)) {
1963 status = WERR_PRINTER_DRIVER_IN_USE;
1968 * we have a couple of cases to consider.
1969 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1970 * then the delete should fail if **any** files overlap with
1972 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1973 * non-overlapping files
1974 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1975 * is set, the do not delete any files
1976 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1979 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1981 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1984 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1985 printer_driver_files_in_use(info, p->server_info, info)) {
1986 /* no idea of the correct error here */
1987 status = WERR_ACCESS_DENIED;
1992 /* also check for W32X86/3 if necessary; maybe we already have? */
1994 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1995 status = winreg_get_driver(info, p->server_info,
1997 r->in.driver, 3, &info_win2k);
1998 if (W_ERROR_IS_OK(status)) {
2001 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2002 printer_driver_files_in_use(info, p->server_info,
2004 /* no idea of the correct error here */
2005 talloc_free(info_win2k);
2006 status = WERR_ACCESS_DENIED;
2010 /* if we get to here, we now have 2 driver info structures to remove */
2011 /* remove the Win2k driver first*/
2013 status = winreg_del_driver(info, p->server_info,
2016 /* this should not have failed---if it did, report to client */
2018 if (!W_ERROR_IS_OK(status)) {
2023 * now delete any associated files if delete_files is
2024 * true. Even if this part failes, we return succes
2025 * because the driver doesn not exist any more
2028 delete_driver_files(p->server_info,
2034 status = winreg_del_driver(info, p->server_info, info, version);
2035 if (!W_ERROR_IS_OK(status)) {
2040 * now delete any associated files if delete_files is
2041 * true. Even if this part failes, we return succes
2042 * because the driver doesn not exist any more
2045 delete_driver_files(p->server_info, info);
2054 /********************************************************************
2055 GetPrinterData on a printer server Handle.
2056 ********************************************************************/
2058 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2060 enum winreg_Type *type,
2061 union spoolss_PrinterData *data)
2063 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2065 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2071 if (!StrCaseCmp(value, "BeepEnabled")) {
2077 if (!StrCaseCmp(value, "EventLog")) {
2079 /* formally was 0x1b */
2084 if (!StrCaseCmp(value, "NetPopup")) {
2090 if (!StrCaseCmp(value, "MajorVersion")) {
2093 /* Windows NT 4.0 seems to not allow uploading of drivers
2094 to a server that reports 0x3 as the MajorVersion.
2095 need to investigate more how Win2k gets around this .
2098 if (RA_WINNT == get_remote_arch()) {
2107 if (!StrCaseCmp(value, "MinorVersion")) {
2114 * uint32_t size = 0x114
2115 * uint32_t major = 5
2116 * uint32_t minor = [0|1]
2117 * uint32_t build = [2195|2600]
2118 * extra unicode string = e.g. "Service Pack 3"
2120 if (!StrCaseCmp(value, "OSVersion")) {
2122 enum ndr_err_code ndr_err;
2123 struct spoolss_OSVersion os;
2125 os.major = 5; /* Windows 2000 == 5.0 */
2127 os.build = 2195; /* build */
2128 os.extra_string = ""; /* leave extra string empty */
2130 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2131 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2132 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2133 return WERR_GENERAL_FAILURE;
2137 data->binary = blob;
2143 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2146 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2147 W_ERROR_HAVE_NO_MEMORY(data->string);
2152 if (!StrCaseCmp(value, "Architecture")) {
2154 data->string = talloc_strdup(mem_ctx,
2155 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2156 W_ERROR_HAVE_NO_MEMORY(data->string);
2161 if (!StrCaseCmp(value, "DsPresent")) {
2164 /* only show the publish check box if we are a
2165 member of a AD domain */
2167 if (lp_security() == SEC_ADS) {
2175 if (!StrCaseCmp(value, "DNSMachineName")) {
2176 const char *hostname = get_mydnsfullname();
2179 return WERR_BADFILE;
2183 data->string = talloc_strdup(mem_ctx, hostname);
2184 W_ERROR_HAVE_NO_MEMORY(data->string);
2191 return WERR_INVALID_PARAM;
2194 /****************************************************************
2195 _spoolss_GetPrinterData
2196 ****************************************************************/
2198 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2199 struct spoolss_GetPrinterData *r)
2201 struct spoolss_GetPrinterDataEx r2;
2203 r2.in.handle = r->in.handle;
2204 r2.in.key_name = "PrinterDriverData";
2205 r2.in.value_name = r->in.value_name;
2206 r2.in.offered = r->in.offered;
2207 r2.out.type = r->out.type;
2208 r2.out.data = r->out.data;
2209 r2.out.needed = r->out.needed;
2211 return _spoolss_GetPrinterDataEx(p, &r2);
2214 /*********************************************************
2215 Connect to the client machine.
2216 **********************************************************/
2218 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2219 struct sockaddr_storage *client_ss, const char *remote_machine)
2222 struct cli_state *the_cli;
2223 struct sockaddr_storage rm_addr;
2224 char addr[INET6_ADDRSTRLEN];
2226 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2227 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2229 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2230 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2233 print_sockaddr(addr, sizeof(addr), &rm_addr);
2235 rm_addr = *client_ss;
2236 print_sockaddr(addr, sizeof(addr), &rm_addr);
2237 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2241 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2242 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2247 /* setup the connection */
2248 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2249 &rm_addr, 0, "IPC$", "IPC",
2253 0, lp_client_signing(), NULL );
2255 if ( !NT_STATUS_IS_OK( ret ) ) {
2256 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2261 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2262 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2263 cli_shutdown(the_cli);
2268 * Ok - we have an anonymous connection to the IPC$ share.
2269 * Now start the NT Domain stuff :-).
2272 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2273 if (!NT_STATUS_IS_OK(ret)) {
2274 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2275 remote_machine, nt_errstr(ret)));
2276 cli_shutdown(the_cli);
2283 /***************************************************************************
2284 Connect to the client.
2285 ****************************************************************************/
2287 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2288 uint32_t localprinter, uint32_t type,
2289 struct policy_handle *handle,
2290 struct sockaddr_storage *client_ss,
2291 struct messaging_context *msg_ctx)
2297 * If it's the first connection, contact the client
2298 * and connect to the IPC$ share anonymously
2300 if (smb_connections==0) {
2301 fstring unix_printer;
2303 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2305 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2308 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2309 receive_notify2_message_list);
2310 /* Tell the connections db we're now interested in printer
2311 * notify messages. */
2312 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2313 true, FLAG_MSG_PRINT_NOTIFY);
2317 * Tell the specific printing tdb we want messages for this printer
2318 * by registering our PID.
2321 if (!print_notify_register_pid(snum))
2322 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2326 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2334 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2335 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2336 win_errstr(result)));
2338 return (W_ERROR_IS_OK(result));
2341 /****************************************************************
2342 ****************************************************************/
2344 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2345 const struct spoolss_NotifyOption *r)
2347 struct spoolss_NotifyOption *option;
2354 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2361 if (!option->count) {
2365 option->types = talloc_zero_array(option,
2366 struct spoolss_NotifyOptionType, option->count);
2367 if (!option->types) {
2368 talloc_free(option);
2372 for (i=0; i < option->count; i++) {
2373 option->types[i] = r->types[i];
2375 if (option->types[i].count) {
2376 option->types[i].fields = talloc_zero_array(option,
2377 union spoolss_Field, option->types[i].count);
2378 if (!option->types[i].fields) {
2379 talloc_free(option);
2382 for (k=0; k<option->types[i].count; k++) {
2383 option->types[i].fields[k] =
2384 r->types[i].fields[k];
2392 /****************************************************************
2393 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2395 * before replying OK: status=0 a rpc call is made to the workstation
2396 * asking ReplyOpenPrinter
2398 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2399 * called from api_spoolss_rffpcnex
2400 ****************************************************************/
2402 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2403 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2406 struct spoolss_NotifyOption *option = r->in.notify_options;
2407 struct sockaddr_storage client_ss;
2409 /* store the notify value in the printer struct */
2411 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2414 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2415 "Invalid handle (%s:%u:%u).\n",
2416 OUR_HANDLE(r->in.handle)));
2420 Printer->notify.flags = r->in.flags;
2421 Printer->notify.options = r->in.options;
2422 Printer->notify.printerlocal = r->in.printer_local;
2423 Printer->notify.msg_ctx = p->msg_ctx;
2425 TALLOC_FREE(Printer->notify.option);
2426 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2428 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2430 /* Connect to the client machine and send a ReplyOpenPrinter */
2432 if ( Printer->printer_type == SPLHND_SERVER)
2434 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2435 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2438 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2439 "client_address is %s\n", p->client_address));
2441 if (!interpret_string_addr(&client_ss, p->client_address,
2443 return WERR_SERVER_UNAVAILABLE;
2446 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2447 Printer->notify.printerlocal, 1,
2448 &Printer->notify.client_hnd,
2449 &client_ss, p->msg_ctx))
2450 return WERR_SERVER_UNAVAILABLE;
2452 Printer->notify.client_connected = true;
2457 /*******************************************************************
2458 * fill a notify_info_data with the servername
2459 ********************************************************************/
2461 static void spoolss_notify_server_name(int snum,
2462 struct spoolss_Notify *data,
2463 print_queue_struct *queue,
2464 struct spoolss_PrinterInfo2 *pinfo2,
2465 TALLOC_CTX *mem_ctx)
2467 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2470 /*******************************************************************
2471 * fill a notify_info_data with the printername (not including the servername).
2472 ********************************************************************/
2474 static void spoolss_notify_printer_name(int snum,
2475 struct spoolss_Notify *data,
2476 print_queue_struct *queue,
2477 struct spoolss_PrinterInfo2 *pinfo2,
2478 TALLOC_CTX *mem_ctx)
2480 /* the notify name should not contain the \\server\ part */
2481 const char *p = strrchr(pinfo2->printername, '\\');
2484 p = pinfo2->printername;
2489 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2492 /*******************************************************************
2493 * fill a notify_info_data with the servicename
2494 ********************************************************************/
2496 static void spoolss_notify_share_name(int snum,
2497 struct spoolss_Notify *data,
2498 print_queue_struct *queue,
2499 struct spoolss_PrinterInfo2 *pinfo2,
2500 TALLOC_CTX *mem_ctx)
2502 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2505 /*******************************************************************
2506 * fill a notify_info_data with the port name
2507 ********************************************************************/
2509 static void spoolss_notify_port_name(int snum,
2510 struct spoolss_Notify *data,
2511 print_queue_struct *queue,
2512 struct spoolss_PrinterInfo2 *pinfo2,
2513 TALLOC_CTX *mem_ctx)
2515 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2518 /*******************************************************************
2519 * fill a notify_info_data with the printername
2520 * but it doesn't exist, have to see what to do
2521 ********************************************************************/
2523 static void spoolss_notify_driver_name(int snum,
2524 struct spoolss_Notify *data,
2525 print_queue_struct *queue,
2526 struct spoolss_PrinterInfo2 *pinfo2,
2527 TALLOC_CTX *mem_ctx)
2529 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2532 /*******************************************************************
2533 * fill a notify_info_data with the comment
2534 ********************************************************************/
2536 static void spoolss_notify_comment(int snum,
2537 struct spoolss_Notify *data,
2538 print_queue_struct *queue,
2539 struct spoolss_PrinterInfo2 *pinfo2,
2540 TALLOC_CTX *mem_ctx)
2544 if (*pinfo2->comment == '\0') {
2545 p = lp_comment(snum);
2547 p = pinfo2->comment;
2550 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2553 /*******************************************************************
2554 * fill a notify_info_data with the comment
2555 * location = "Room 1, floor 2, building 3"
2556 ********************************************************************/
2558 static void spoolss_notify_location(int snum,
2559 struct spoolss_Notify *data,
2560 print_queue_struct *queue,
2561 struct spoolss_PrinterInfo2 *pinfo2,
2562 TALLOC_CTX *mem_ctx)
2564 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2567 /*******************************************************************
2568 * fill a notify_info_data with the device mode
2569 * jfm:xxxx don't to it for know but that's a real problem !!!
2570 ********************************************************************/
2572 static void spoolss_notify_devmode(int snum,
2573 struct spoolss_Notify *data,
2574 print_queue_struct *queue,
2575 struct spoolss_PrinterInfo2 *pinfo2,
2576 TALLOC_CTX *mem_ctx)
2578 /* for a dummy implementation we have to zero the fields */
2579 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2582 /*******************************************************************
2583 * fill a notify_info_data with the separator file name
2584 ********************************************************************/
2586 static void spoolss_notify_sepfile(int snum,
2587 struct spoolss_Notify *data,
2588 print_queue_struct *queue,
2589 struct spoolss_PrinterInfo2 *pinfo2,
2590 TALLOC_CTX *mem_ctx)
2592 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2595 /*******************************************************************
2596 * fill a notify_info_data with the print processor
2597 * jfm:xxxx return always winprint to indicate we don't do anything to it
2598 ********************************************************************/
2600 static void spoolss_notify_print_processor(int snum,
2601 struct spoolss_Notify *data,
2602 print_queue_struct *queue,
2603 struct spoolss_PrinterInfo2 *pinfo2,
2604 TALLOC_CTX *mem_ctx)
2606 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2609 /*******************************************************************
2610 * fill a notify_info_data with the print processor options
2611 * jfm:xxxx send an empty string
2612 ********************************************************************/
2614 static void spoolss_notify_parameters(int snum,
2615 struct spoolss_Notify *data,
2616 print_queue_struct *queue,
2617 struct spoolss_PrinterInfo2 *pinfo2,
2618 TALLOC_CTX *mem_ctx)
2620 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2623 /*******************************************************************
2624 * fill a notify_info_data with the data type
2625 * jfm:xxxx always send RAW as data type
2626 ********************************************************************/
2628 static void spoolss_notify_datatype(int snum,
2629 struct spoolss_Notify *data,
2630 print_queue_struct *queue,
2631 struct spoolss_PrinterInfo2 *pinfo2,
2632 TALLOC_CTX *mem_ctx)
2634 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2637 /*******************************************************************
2638 * fill a notify_info_data with the security descriptor
2639 * jfm:xxxx send an null pointer to say no security desc
2640 * have to implement security before !
2641 ********************************************************************/
2643 static void spoolss_notify_security_desc(int snum,
2644 struct spoolss_Notify *data,
2645 print_queue_struct *queue,
2646 struct spoolss_PrinterInfo2 *pinfo2,
2647 TALLOC_CTX *mem_ctx)
2649 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2652 /*******************************************************************
2653 * fill a notify_info_data with the attributes
2654 * jfm:xxxx a samba printer is always shared
2655 ********************************************************************/
2657 static void spoolss_notify_attributes(int snum,
2658 struct spoolss_Notify *data,
2659 print_queue_struct *queue,
2660 struct spoolss_PrinterInfo2 *pinfo2,
2661 TALLOC_CTX *mem_ctx)
2663 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2666 /*******************************************************************
2667 * fill a notify_info_data with the priority
2668 ********************************************************************/
2670 static void spoolss_notify_priority(int snum,
2671 struct spoolss_Notify *data,
2672 print_queue_struct *queue,
2673 struct spoolss_PrinterInfo2 *pinfo2,
2674 TALLOC_CTX *mem_ctx)
2676 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2679 /*******************************************************************
2680 * fill a notify_info_data with the default priority
2681 ********************************************************************/
2683 static void spoolss_notify_default_priority(int snum,
2684 struct spoolss_Notify *data,
2685 print_queue_struct *queue,
2686 struct spoolss_PrinterInfo2 *pinfo2,
2687 TALLOC_CTX *mem_ctx)
2689 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2692 /*******************************************************************
2693 * fill a notify_info_data with the start time
2694 ********************************************************************/
2696 static void spoolss_notify_start_time(int snum,
2697 struct spoolss_Notify *data,
2698 print_queue_struct *queue,
2699 struct spoolss_PrinterInfo2 *pinfo2,
2700 TALLOC_CTX *mem_ctx)
2702 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2705 /*******************************************************************
2706 * fill a notify_info_data with the until time
2707 ********************************************************************/
2709 static void spoolss_notify_until_time(int snum,
2710 struct spoolss_Notify *data,
2711 print_queue_struct *queue,
2712 struct spoolss_PrinterInfo2 *pinfo2,
2713 TALLOC_CTX *mem_ctx)
2715 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2718 /*******************************************************************
2719 * fill a notify_info_data with the status
2720 ********************************************************************/
2722 static void spoolss_notify_status(int snum,
2723 struct spoolss_Notify *data,
2724 print_queue_struct *queue,
2725 struct spoolss_PrinterInfo2 *pinfo2,
2726 TALLOC_CTX *mem_ctx)
2728 print_status_struct status;
2730 print_queue_length(snum, &status);
2731 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2734 /*******************************************************************
2735 * fill a notify_info_data with the number of jobs queued
2736 ********************************************************************/
2738 static void spoolss_notify_cjobs(int snum,
2739 struct spoolss_Notify *data,
2740 print_queue_struct *queue,
2741 struct spoolss_PrinterInfo2 *pinfo2,
2742 TALLOC_CTX *mem_ctx)
2744 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2747 /*******************************************************************
2748 * fill a notify_info_data with the average ppm
2749 ********************************************************************/
2751 static void spoolss_notify_average_ppm(int snum,
2752 struct spoolss_Notify *data,
2753 print_queue_struct *queue,
2754 struct spoolss_PrinterInfo2 *pinfo2,
2755 TALLOC_CTX *mem_ctx)
2757 /* always respond 8 pages per minutes */
2758 /* a little hard ! */
2759 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2762 /*******************************************************************
2763 * fill a notify_info_data with username
2764 ********************************************************************/
2766 static void spoolss_notify_username(int snum,
2767 struct spoolss_Notify *data,
2768 print_queue_struct *queue,
2769 struct spoolss_PrinterInfo2 *pinfo2,
2770 TALLOC_CTX *mem_ctx)
2772 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2775 /*******************************************************************
2776 * fill a notify_info_data with job status
2777 ********************************************************************/
2779 static void spoolss_notify_job_status(int snum,
2780 struct spoolss_Notify *data,
2781 print_queue_struct *queue,
2782 struct spoolss_PrinterInfo2 *pinfo2,
2783 TALLOC_CTX *mem_ctx)
2785 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2788 /*******************************************************************
2789 * fill a notify_info_data with job name
2790 ********************************************************************/
2792 static void spoolss_notify_job_name(int snum,
2793 struct spoolss_Notify *data,
2794 print_queue_struct *queue,
2795 struct spoolss_PrinterInfo2 *pinfo2,
2796 TALLOC_CTX *mem_ctx)
2798 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2801 /*******************************************************************
2802 * fill a notify_info_data with job status
2803 ********************************************************************/
2805 static void spoolss_notify_job_status_string(int snum,
2806 struct spoolss_Notify *data,
2807 print_queue_struct *queue,
2808 struct spoolss_PrinterInfo2 *pinfo2,
2809 TALLOC_CTX *mem_ctx)
2812 * Now we're returning job status codes we just return a "" here. JRA.
2817 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2820 switch (queue->status) {
2825 p = ""; /* NT provides the paused string */
2834 #endif /* NO LONGER NEEDED. */
2836 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2839 /*******************************************************************
2840 * fill a notify_info_data with job time
2841 ********************************************************************/
2843 static void spoolss_notify_job_time(int snum,
2844 struct spoolss_Notify *data,
2845 print_queue_struct *queue,
2846 struct spoolss_PrinterInfo2 *pinfo2,
2847 TALLOC_CTX *mem_ctx)
2849 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2852 /*******************************************************************
2853 * fill a notify_info_data with job size
2854 ********************************************************************/
2856 static void spoolss_notify_job_size(int snum,
2857 struct spoolss_Notify *data,
2858 print_queue_struct *queue,
2859 struct spoolss_PrinterInfo2 *pinfo2,
2860 TALLOC_CTX *mem_ctx)
2862 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2865 /*******************************************************************
2866 * fill a notify_info_data with page info
2867 ********************************************************************/
2868 static void spoolss_notify_total_pages(int snum,
2869 struct spoolss_Notify *data,
2870 print_queue_struct *queue,
2871 struct spoolss_PrinterInfo2 *pinfo2,
2872 TALLOC_CTX *mem_ctx)
2874 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2877 /*******************************************************************
2878 * fill a notify_info_data with pages printed info.
2879 ********************************************************************/
2880 static void spoolss_notify_pages_printed(int snum,
2881 struct spoolss_Notify *data,
2882 print_queue_struct *queue,
2883 struct spoolss_PrinterInfo2 *pinfo2,
2884 TALLOC_CTX *mem_ctx)
2886 /* Add code when back-end tracks this */
2887 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2890 /*******************************************************************
2891 Fill a notify_info_data with job position.
2892 ********************************************************************/
2894 static void spoolss_notify_job_position(int snum,
2895 struct spoolss_Notify *data,
2896 print_queue_struct *queue,
2897 struct spoolss_PrinterInfo2 *pinfo2,
2898 TALLOC_CTX *mem_ctx)
2900 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2903 /*******************************************************************
2904 Fill a notify_info_data with submitted time.
2905 ********************************************************************/
2907 static void spoolss_notify_submitted_time(int snum,
2908 struct spoolss_Notify *data,
2909 print_queue_struct *queue,
2910 struct spoolss_PrinterInfo2 *pinfo2,
2911 TALLOC_CTX *mem_ctx)
2913 data->data.string.string = NULL;
2914 data->data.string.size = 0;
2916 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2917 &data->data.string.string,
2918 &data->data.string.size);
2922 struct s_notify_info_data_table
2924 enum spoolss_NotifyType type;
2927 enum spoolss_NotifyTable variable_type;
2928 void (*fn) (int snum, struct spoolss_Notify *data,
2929 print_queue_struct *queue,
2930 struct spoolss_PrinterInfo2 *pinfo2,
2931 TALLOC_CTX *mem_ctx);
2934 /* A table describing the various print notification constants and
2935 whether the notification data is a pointer to a variable sized
2936 buffer, a one value uint32_t or a two value uint32_t. */
2938 static const struct s_notify_info_data_table notify_info_data_table[] =
2940 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2941 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2942 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2943 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2950 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2951 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2952 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2953 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2954 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2955 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2956 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2957 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2958 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2959 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2960 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2961 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2962 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2963 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2964 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2965 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2966 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2967 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2968 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2969 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2970 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2971 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2972 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2973 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2974 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2975 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2976 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2977 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2978 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2979 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2980 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2981 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2982 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2983 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2984 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2985 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2986 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2987 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2988 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2991 /*******************************************************************
2992 Return the variable_type of info_data structure.
2993 ********************************************************************/
2995 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3000 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3001 if ( (notify_info_data_table[i].type == type) &&
3002 (notify_info_data_table[i].field == field) ) {
3003 return notify_info_data_table[i].variable_type;
3007 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3012 /****************************************************************************
3013 ****************************************************************************/
3015 static bool search_notify(enum spoolss_NotifyType type,
3021 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3022 if (notify_info_data_table[i].type == type &&
3023 notify_info_data_table[i].field == field &&
3024 notify_info_data_table[i].fn != NULL) {
3033 /****************************************************************************
3034 ****************************************************************************/
3036 static void construct_info_data(struct spoolss_Notify *info_data,
3037 enum spoolss_NotifyType type,
3038 uint16_t field, int id)
3040 info_data->type = type;
3041 info_data->field.field = field;
3042 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3043 info_data->job_id = id;
3046 /*******************************************************************
3048 * fill a notify_info struct with info asked
3050 ********************************************************************/
3052 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3053 struct spoolss_NotifyInfo *info,
3054 struct spoolss_PrinterInfo2 *pinfo2,
3056 const struct spoolss_NotifyOptionType *option_type,
3058 TALLOC_CTX *mem_ctx)
3061 enum spoolss_NotifyType type;
3064 struct spoolss_Notify *current_data;
3065 print_queue_struct *queue=NULL;
3067 type = option_type->type;
3069 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3070 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3071 option_type->count, lp_servicename(snum)));
3073 for(field_num=0; field_num < option_type->count; field_num++) {
3074 field = option_type->fields[field_num].field;
3076 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3078 if (!search_notify(type, field, &j) )
3081 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3082 struct spoolss_Notify,
3084 if (info->notifies == NULL) {
3085 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3089 current_data = &info->notifies[info->count];
3091 construct_info_data(current_data, type, field, id);
3093 DEBUG(10, ("construct_notify_printer_info: "
3094 "calling [%s] snum=%d printername=[%s])\n",
3095 notify_info_data_table[j].name, snum,
3096 pinfo2->printername));
3098 notify_info_data_table[j].fn(snum, current_data, queue,
3107 /*******************************************************************
3109 * fill a notify_info struct with info asked
3111 ********************************************************************/
3113 static bool construct_notify_jobs_info(print_queue_struct *queue,
3114 struct spoolss_NotifyInfo *info,
3115 struct spoolss_PrinterInfo2 *pinfo2,
3117 const struct spoolss_NotifyOptionType *option_type,
3119 TALLOC_CTX *mem_ctx)
3122 enum spoolss_NotifyType type;
3124 struct spoolss_Notify *current_data;
3126 DEBUG(4,("construct_notify_jobs_info\n"));
3128 type = option_type->type;
3130 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3131 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3132 option_type->count));
3134 for(field_num=0; field_num<option_type->count; field_num++) {
3135 field = option_type->fields[field_num].field;
3137 if (!search_notify(type, field, &j) )
3140 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3141 struct spoolss_Notify,
3143 if (info->notifies == NULL) {
3144 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3148 current_data=&(info->notifies[info->count]);
3150 construct_info_data(current_data, type, field, id);
3151 notify_info_data_table[j].fn(snum, current_data, queue,
3160 * JFM: The enumeration is not that simple, it's even non obvious.
3162 * let's take an example: I want to monitor the PRINTER SERVER for
3163 * the printer's name and the number of jobs currently queued.
3164 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3165 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3167 * I have 3 printers on the back of my server.
3169 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3172 * 1 printer 1 name 1
3173 * 2 printer 1 cjob 1
3174 * 3 printer 2 name 2
3175 * 4 printer 2 cjob 2
3176 * 5 printer 3 name 3
3177 * 6 printer 3 name 3
3179 * that's the print server case, the printer case is even worse.
3182 /*******************************************************************
3184 * enumerate all printers on the printserver
3185 * fill a notify_info struct with info asked
3187 ********************************************************************/
3189 static WERROR printserver_notify_info(struct pipes_struct *p,
3190 struct policy_handle *hnd,
3191 struct spoolss_NotifyInfo *info,
3192 TALLOC_CTX *mem_ctx)
3195 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3196 int n_services=lp_numservices();
3198 struct spoolss_NotifyOption *option;
3199 struct spoolss_NotifyOptionType option_type;
3200 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3203 DEBUG(4,("printserver_notify_info\n"));
3208 option = Printer->notify.option;
3211 info->notifies = NULL;
3214 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3215 sending a ffpcn() request first */
3220 for (i=0; i<option->count; i++) {
3221 option_type = option->types[i];
3223 if (option_type.type != PRINTER_NOTIFY_TYPE)
3226 for (snum = 0; snum < n_services; snum++) {
3227 if (!lp_browseable(snum) ||
3228 !lp_snum_ok(snum) ||
3229 !lp_print_ok(snum)) {
3230 continue; /* skip */
3233 /* Maybe we should use the SYSTEM server_info here... */
3234 result = winreg_get_printer(mem_ctx, p->server_info,
3235 Printer->servername,
3236 lp_servicename(snum),
3238 if (!W_ERROR_IS_OK(result)) {
3239 DEBUG(4, ("printserver_notify_info: "
3240 "Failed to get printer [%s]\n",
3241 lp_servicename(snum)));
3246 construct_notify_printer_info(Printer, info,
3251 TALLOC_FREE(pinfo2);
3257 * Debugging information, don't delete.
3260 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3261 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3262 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3264 for (i=0; i<info->count; i++) {
3265 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3266 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3267 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3274 /*******************************************************************
3276 * fill a notify_info struct with info asked
3278 ********************************************************************/
3280 static WERROR printer_notify_info(struct pipes_struct *p,
3281 struct policy_handle *hnd,
3282 struct spoolss_NotifyInfo *info,
3283 TALLOC_CTX *mem_ctx)
3286 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3289 struct spoolss_NotifyOption *option;
3290 struct spoolss_NotifyOptionType option_type;
3292 print_queue_struct *queue=NULL;
3293 print_status_struct status;
3294 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3297 DEBUG(4,("printer_notify_info\n"));
3302 option = Printer->notify.option;
3306 info->notifies = NULL;
3309 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3310 sending a ffpcn() request first */
3315 get_printer_snum(p, hnd, &snum, NULL);
3317 /* Maybe we should use the SYSTEM server_info here... */
3318 result = winreg_get_printer(mem_ctx, p->server_info,
3319 Printer->servername,
3320 lp_servicename(snum), &pinfo2);
3321 if (!W_ERROR_IS_OK(result)) {
3325 for (i=0; i<option->count; i++) {
3326 option_type = option->types[i];
3328 switch (option_type.type) {
3329 case PRINTER_NOTIFY_TYPE:
3330 if (construct_notify_printer_info(Printer, info,
3338 case JOB_NOTIFY_TYPE:
3340 count = print_queue_status(snum, &queue, &status);
3342 for (j=0; j<count; j++) {
3343 construct_notify_jobs_info(&queue[j], info,
3356 * Debugging information, don't delete.
3359 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3360 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3361 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3363 for (i=0; i<info->count; i++) {
3364 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3365 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3366 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3370 talloc_free(pinfo2);
3374 /****************************************************************
3375 _spoolss_RouterRefreshPrinterChangeNotify
3376 ****************************************************************/
3378 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3379 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3381 struct spoolss_NotifyInfo *info;
3383 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3384 WERROR result = WERR_BADFID;
3386 /* we always have a spoolss_NotifyInfo struct */
3387 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3389 result = WERR_NOMEM;
3393 *r->out.info = info;
3396 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3397 "Invalid handle (%s:%u:%u).\n",
3398 OUR_HANDLE(r->in.handle)));
3402 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3405 * We are now using the change value, and
3406 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3407 * I don't have a global notification system, I'm sending back all the
3408 * informations even when _NOTHING_ has changed.
3411 /* We need to keep track of the change value to send back in
3412 RRPCN replies otherwise our updates are ignored. */
3414 Printer->notify.fnpcn = true;
3416 if (Printer->notify.client_connected) {
3417 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3418 "Saving change value in request [%x]\n",
3420 Printer->notify.change = r->in.change_low;
3423 /* just ignore the spoolss_NotifyOption */
3425 switch (Printer->printer_type) {
3427 result = printserver_notify_info(p, r->in.handle,
3431 case SPLHND_PRINTER:
3432 result = printer_notify_info(p, r->in.handle,
3437 Printer->notify.fnpcn = false;
3443 /********************************************************************
3444 * construct_printer_info_0
3445 * fill a printer_info_0 struct
3446 ********************************************************************/
3448 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3449 struct auth_serversupplied_info *server_info,
3450 struct spoolss_PrinterInfo2 *info2,
3451 struct spoolss_PrinterInfo0 *r,
3455 counter_printer_0 *session_counter;
3456 struct timeval setuptime;
3457 print_status_struct status;
3459 r->printername = talloc_strdup(mem_ctx, info2->printername);
3460 W_ERROR_HAVE_NO_MEMORY(r->printername);
3462 r->servername = talloc_strdup(mem_ctx, info2->servername);
3463 W_ERROR_HAVE_NO_MEMORY(r->servername);
3465 count = print_queue_length(snum, &status);
3467 /* check if we already have a counter for this printer */
3468 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3469 if (session_counter->snum == snum)
3473 /* it's the first time, add it to the list */
3474 if (session_counter == NULL) {
3475 session_counter = SMB_MALLOC_P(counter_printer_0);
3476 W_ERROR_HAVE_NO_MEMORY(session_counter);
3477 ZERO_STRUCTP(session_counter);
3478 session_counter->snum = snum;
3479 session_counter->counter = 0;
3480 DLIST_ADD(counter_list, session_counter);
3484 session_counter->counter++;
3490 get_startup_time(&setuptime);
3491 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3494 * the global_counter should be stored in a TDB as it's common to all the clients
3495 * and should be zeroed on samba startup
3497 r->global_counter = session_counter->counter;
3499 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3500 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3501 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3502 r->free_build = SPOOLSS_RELEASE_BUILD;
3504 r->max_spooling = 0;
3505 r->session_counter = session_counter->counter;
3506 r->num_error_out_of_paper = 0x0;
3507 r->num_error_not_ready = 0x0; /* number of print failure */
3509 r->number_of_processors = 0x1;
3510 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3511 r->high_part_total_bytes = 0x0;
3512 winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3513 r->last_error = WERR_OK;
3514 r->status = nt_printq_status(status.status);
3515 r->enumerate_network_printers = 0x0;
3516 r->c_setprinter = 0x0;
3517 r->processor_architecture = 0x0;
3518 r->processor_level = 0x6; /* 6 ???*/
3527 /********************************************************************
3528 * construct_printer_info1
3529 * fill a spoolss_PrinterInfo1 struct
3530 ********************************************************************/
3532 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3533 const struct spoolss_PrinterInfo2 *info2,
3535 struct spoolss_PrinterInfo1 *r,
3540 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3544 W_ERROR_HAVE_NO_MEMORY(r->description);
3546 if (info2->comment == NULL || info2->comment[0] == '\0') {
3547 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3549 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3551 W_ERROR_HAVE_NO_MEMORY(r->comment);
3553 r->name = talloc_strdup(mem_ctx, info2->printername);
3554 W_ERROR_HAVE_NO_MEMORY(r->name);
3559 /********************************************************************
3560 * construct_printer_info2
3561 * fill a spoolss_PrinterInfo2 struct
3562 ********************************************************************/
3564 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3565 const struct spoolss_PrinterInfo2 *info2,
3566 struct spoolss_PrinterInfo2 *r,
3570 print_status_struct status;
3572 count = print_queue_length(snum, &status);
3574 r->servername = talloc_strdup(mem_ctx, info2->servername);
3575 W_ERROR_HAVE_NO_MEMORY(r->servername);
3576 r->printername = talloc_strdup(mem_ctx, info2->printername);
3577 W_ERROR_HAVE_NO_MEMORY(r->printername);
3578 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3579 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3580 r->portname = talloc_strdup(mem_ctx, info2->portname);
3581 W_ERROR_HAVE_NO_MEMORY(r->portname);
3582 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3583 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3585 if (info2->comment[0] == '\0') {
3586 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3588 r->comment = talloc_strdup(mem_ctx, info2->comment);
3590 W_ERROR_HAVE_NO_MEMORY(r->comment);
3592 r->location = talloc_strdup(mem_ctx, info2->location);
3593 W_ERROR_HAVE_NO_MEMORY(r->location);
3594 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3595 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3596 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3597 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3598 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3599 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3600 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3601 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3603 r->attributes = info2->attributes;
3605 r->priority = info2->priority;
3606 r->defaultpriority = info2->defaultpriority;
3607 r->starttime = info2->starttime;
3608 r->untiltime = info2->untiltime;
3609 r->status = nt_printq_status(status.status);
3611 r->averageppm = info2->averageppm;
3613 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3615 DEBUG(8,("Returning NULL Devicemode!\n"));
3620 if (info2->secdesc != NULL) {
3621 /* don't use talloc_steal() here unless you do a deep steal of all
3622 the SEC_DESC members */
3624 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3630 /********************************************************************
3631 * construct_printer_info3
3632 * fill a spoolss_PrinterInfo3 struct
3633 ********************************************************************/
3635 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3636 const struct spoolss_PrinterInfo2 *info2,
3637 struct spoolss_PrinterInfo3 *r,
3640 /* These are the components of the SD we are returning. */
3642 if (info2->secdesc != NULL) {
3643 /* don't use talloc_steal() here unless you do a deep steal of all
3644 the SEC_DESC members */
3646 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3647 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3653 /********************************************************************
3654 * construct_printer_info4
3655 * fill a spoolss_PrinterInfo4 struct
3656 ********************************************************************/
3658 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3659 const struct spoolss_PrinterInfo2 *info2,
3660 struct spoolss_PrinterInfo4 *r,
3663 r->printername = talloc_strdup(mem_ctx, info2->printername);
3664 W_ERROR_HAVE_NO_MEMORY(r->printername);
3665 r->servername = talloc_strdup(mem_ctx, info2->servername);
3666 W_ERROR_HAVE_NO_MEMORY(r->servername);
3668 r->attributes = info2->attributes;
3673 /********************************************************************
3674 * construct_printer_info5
3675 * fill a spoolss_PrinterInfo5 struct
3676 ********************************************************************/
3678 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3679 const struct spoolss_PrinterInfo2 *info2,
3680 struct spoolss_PrinterInfo5 *r,
3683 r->printername = talloc_strdup(mem_ctx, info2->printername);
3684 W_ERROR_HAVE_NO_MEMORY(r->printername);
3685 r->portname = talloc_strdup(mem_ctx, info2->portname);
3686 W_ERROR_HAVE_NO_MEMORY(r->portname);
3688 r->attributes = info2->attributes;
3690 /* these two are not used by NT+ according to MSDN */
3691 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3692 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3697 /********************************************************************
3698 * construct_printer_info_6
3699 * fill a spoolss_PrinterInfo6 struct
3700 ********************************************************************/
3702 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3703 const struct spoolss_PrinterInfo2 *info2,
3704 struct spoolss_PrinterInfo6 *r,
3708 print_status_struct status;
3710 count = print_queue_length(snum, &status);
3712 r->status = nt_printq_status(status.status);
3717 /********************************************************************
3718 * construct_printer_info7
3719 * fill a spoolss_PrinterInfo7 struct
3720 ********************************************************************/
3722 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3723 Printer_entry *print_hnd,
3724 struct spoolss_PrinterInfo7 *r,
3727 struct auth_serversupplied_info *server_info;
3731 status = make_server_info_system(mem_ctx, &server_info);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 DEBUG(0, ("construct_printer_info7: "
3734 "Could not create system server_info\n"));
3738 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3739 lp_servicename(snum), &guid, NULL)) {
3740 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3741 r->action = DSPRINT_PUBLISH;
3743 r->guid = talloc_strdup(mem_ctx, "");
3744 r->action = DSPRINT_UNPUBLISH;
3746 W_ERROR_HAVE_NO_MEMORY(r->guid);
3748 TALLOC_FREE(server_info);
3752 /********************************************************************
3753 * construct_printer_info8
3754 * fill a spoolss_PrinterInfo8 struct
3755 ********************************************************************/
3757 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3758 const struct spoolss_PrinterInfo2 *info2,
3759 struct spoolss_DeviceModeInfo *r,
3762 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3764 DEBUG(8,("Returning NULL Devicemode!\n"));
3771 /********************************************************************
3772 ********************************************************************/
3774 static bool snum_is_shared_printer(int snum)
3776 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3779 /********************************************************************
3780 Spoolss_enumprinters.
3781 ********************************************************************/
3783 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3784 struct auth_serversupplied_info *server_info,
3787 union spoolss_PrinterInfo **info_p,
3791 int n_services = lp_numservices();
3792 union spoolss_PrinterInfo *info = NULL;
3794 WERROR result = WERR_OK;
3799 for (snum = 0; snum < n_services; snum++) {
3801 const char *printer;
3802 struct spoolss_PrinterInfo2 *info2;
3804 if (!snum_is_shared_printer(snum)) {
3808 printer = lp_const_servicename(snum);
3810 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3813 result = winreg_create_printer(mem_ctx,
3815 smbd_messaging_context(),
3818 if (!W_ERROR_IS_OK(result)) {
3822 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3823 union spoolss_PrinterInfo,
3826 result = WERR_NOMEM;
3830 result = winreg_get_printer(mem_ctx, server_info,
3831 NULL, printer, &info2);
3832 if (!W_ERROR_IS_OK(result)) {
3838 result = construct_printer_info0(info, server_info, info2,
3839 &info[count].info0, snum);
3842 result = construct_printer_info1(info, info2, flags,
3843 &info[count].info1, snum);
3846 result = construct_printer_info2(info, info2,
3847 &info[count].info2, snum);
3850 result = construct_printer_info4(info, info2,
3851 &info[count].info4, snum);
3854 result = construct_printer_info5(info, info2,
3855 &info[count].info5, snum);
3859 result = WERR_UNKNOWN_LEVEL;
3863 if (!W_ERROR_IS_OK(result)) {
3874 if (!W_ERROR_IS_OK(result)) {
3884 /********************************************************************
3885 * handle enumeration of printers at level 0
3886 ********************************************************************/
3888 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3889 struct auth_serversupplied_info *server_info,
3891 const char *servername,
3892 union spoolss_PrinterInfo **info,
3895 DEBUG(4,("enum_all_printers_info_0\n"));
3897 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3901 /********************************************************************
3902 ********************************************************************/
3904 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3905 struct auth_serversupplied_info *server_info,
3907 union spoolss_PrinterInfo **info,
3910 DEBUG(4,("enum_all_printers_info_1\n"));
3912 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3915 /********************************************************************
3916 enum_all_printers_info_1_local.
3917 *********************************************************************/
3919 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3920 struct auth_serversupplied_info *server_info,
3921 union spoolss_PrinterInfo **info,
3924 DEBUG(4,("enum_all_printers_info_1_local\n"));
3926 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3929 /********************************************************************
3930 enum_all_printers_info_1_name.
3931 *********************************************************************/
3933 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3934 struct auth_serversupplied_info *server_info,
3936 union spoolss_PrinterInfo **info,
3939 const char *s = name;
3941 DEBUG(4,("enum_all_printers_info_1_name\n"));
3943 if ((name[0] == '\\') && (name[1] == '\\')) {
3947 if (!is_myname_or_ipaddr(s)) {
3948 return WERR_INVALID_NAME;
3951 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3954 /********************************************************************
3955 enum_all_printers_info_1_network.
3956 *********************************************************************/
3958 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3959 struct auth_serversupplied_info *server_info,
3961 union spoolss_PrinterInfo **info,
3964 const char *s = name;
3966 DEBUG(4,("enum_all_printers_info_1_network\n"));
3968 /* If we respond to a enum_printers level 1 on our name with flags
3969 set to PRINTER_ENUM_REMOTE with a list of printers then these
3970 printers incorrectly appear in the APW browse list.
3971 Specifically the printers for the server appear at the workgroup
3972 level where all the other servers in the domain are
3973 listed. Windows responds to this call with a
3974 WERR_CAN_NOT_COMPLETE so we should do the same. */
3976 if (name[0] == '\\' && name[1] == '\\') {
3980 if (is_myname_or_ipaddr(s)) {
3981 return WERR_CAN_NOT_COMPLETE;
3984 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3987 /********************************************************************
3988 * api_spoolss_enumprinters
3990 * called from api_spoolss_enumprinters (see this to understand)
3991 ********************************************************************/
3993 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3994 struct auth_serversupplied_info *server_info,
3995 union spoolss_PrinterInfo **info,
3998 DEBUG(4,("enum_all_printers_info_2\n"));
4000 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
4003 /********************************************************************
4004 * handle enumeration of printers at level 1
4005 ********************************************************************/
4007 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4008 struct auth_serversupplied_info *server_info,
4011 union spoolss_PrinterInfo **info,
4014 /* Not all the flags are equals */
4016 if (flags & PRINTER_ENUM_LOCAL) {
4017 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4020 if (flags & PRINTER_ENUM_NAME) {
4021 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4024 if (flags & PRINTER_ENUM_NETWORK) {
4025 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4028 return WERR_OK; /* NT4sp5 does that */
4031 /********************************************************************
4032 * handle enumeration of printers at level 2
4033 ********************************************************************/
4035 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4036 struct auth_serversupplied_info *server_info,
4038 const char *servername,
4039 union spoolss_PrinterInfo **info,
4042 if (flags & PRINTER_ENUM_LOCAL) {
4043 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4046 if (flags & PRINTER_ENUM_NAME) {
4047 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4048 return WERR_INVALID_NAME;
4051 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4054 if (flags & PRINTER_ENUM_REMOTE) {
4055 return WERR_UNKNOWN_LEVEL;
4061 /********************************************************************
4062 * handle enumeration of printers at level 4
4063 ********************************************************************/
4065 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4066 struct auth_serversupplied_info *server_info,
4068 const char *servername,
4069 union spoolss_PrinterInfo **info,
4072 DEBUG(4,("enum_all_printers_info_4\n"));
4074 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4078 /********************************************************************
4079 * handle enumeration of printers at level 5
4080 ********************************************************************/
4082 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4083 struct auth_serversupplied_info *server_info,
4085 const char *servername,
4086 union spoolss_PrinterInfo **info,
4089 DEBUG(4,("enum_all_printers_info_5\n"));
4091 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4094 /****************************************************************
4095 _spoolss_EnumPrinters
4096 ****************************************************************/
4098 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4099 struct spoolss_EnumPrinters *r)
4101 const char *name = NULL;
4104 /* that's an [in out] buffer */
4106 if (!r->in.buffer && (r->in.offered != 0)) {
4107 return WERR_INVALID_PARAM;
4110 DEBUG(4,("_spoolss_EnumPrinters\n"));
4114 *r->out.info = NULL;
4118 * flags==PRINTER_ENUM_NAME
4119 * if name=="" then enumerates all printers
4120 * if name!="" then enumerate the printer
4121 * flags==PRINTER_ENUM_REMOTE
4122 * name is NULL, enumerate printers
4123 * Level 2: name!="" enumerates printers, name can't be NULL
4124 * Level 3: doesn't exist
4125 * Level 4: does a local registry lookup
4126 * Level 5: same as Level 2
4130 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4131 W_ERROR_HAVE_NO_MEMORY(name);
4134 switch (r->in.level) {
4136 result = enumprinters_level0(p->mem_ctx, p->server_info,
4138 r->out.info, r->out.count);
4141 result = enumprinters_level1(p->mem_ctx, p->server_info,
4143 r->out.info, r->out.count);
4146 result = enumprinters_level2(p->mem_ctx, p->server_info,
4148 r->out.info, r->out.count);
4151 result = enumprinters_level4(p->mem_ctx, p->server_info,
4153 r->out.info, r->out.count);
4156 result = enumprinters_level5(p->mem_ctx, p->server_info,
4158 r->out.info, r->out.count);
4161 return WERR_UNKNOWN_LEVEL;
4164 if (!W_ERROR_IS_OK(result)) {
4168 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4169 spoolss_EnumPrinters,
4170 *r->out.info, r->in.level,
4172 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4173 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4175 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4178 /****************************************************************
4180 ****************************************************************/
4182 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4183 struct spoolss_GetPrinter *r)
4185 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4186 struct spoolss_PrinterInfo2 *info2 = NULL;
4187 WERROR result = WERR_OK;
4188 const char *servername = NULL;
4191 /* that's an [in out] buffer */
4193 if (!r->in.buffer && (r->in.offered != 0)) {
4194 return WERR_INVALID_PARAM;
4199 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4203 if (Printer != NULL || Printer->servername != NULL) {
4204 servername = Printer->servername;
4207 result = winreg_get_printer(p->mem_ctx,
4210 lp_const_servicename(snum),
4212 if (!W_ERROR_IS_OK(result)) {
4216 switch (r->in.level) {
4218 result = construct_printer_info0(p->mem_ctx, p->server_info,
4220 &r->out.info->info0, snum);
4223 result = construct_printer_info1(p->mem_ctx, info2,
4225 &r->out.info->info1, snum);
4228 result = construct_printer_info2(p->mem_ctx, info2,
4229 &r->out.info->info2, snum);
4232 result = construct_printer_info3(p->mem_ctx, info2,
4233 &r->out.info->info3, snum);
4236 result = construct_printer_info4(p->mem_ctx, info2,
4237 &r->out.info->info4, snum);
4240 result = construct_printer_info5(p->mem_ctx, info2,
4241 &r->out.info->info5, snum);
4244 result = construct_printer_info6(p->mem_ctx, info2,
4245 &r->out.info->info6, snum);
4248 result = construct_printer_info7(p->mem_ctx, Printer,
4249 &r->out.info->info7, snum);
4252 result = construct_printer_info8(p->mem_ctx, info2,
4253 &r->out.info->info8, snum);
4256 result = WERR_UNKNOWN_LEVEL;
4260 if (!W_ERROR_IS_OK(result)) {
4261 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4262 r->in.level, win_errstr(result)));
4263 TALLOC_FREE(r->out.info);
4267 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4268 r->out.info, r->in.level);
4269 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4271 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4274 /********************************************************************
4275 ********************************************************************/
4277 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4279 if (in && strlen(in)) { \
4280 out = talloc_strdup(mem_ctx, in); \
4282 out = talloc_strdup(mem_ctx, ""); \
4284 W_ERROR_HAVE_NO_MEMORY(out); \
4287 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4289 if (in && strlen(in)) { \
4290 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4292 out = talloc_strdup(mem_ctx, ""); \
4294 W_ERROR_HAVE_NO_MEMORY(out); \
4297 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4298 const char **string_array,
4299 const char ***presult,
4300 const char *cservername,
4304 int i, num_strings = 0;
4305 const char **array = NULL;
4307 if (string_array == NULL) {
4308 return WERR_INVALID_PARAMETER;;
4311 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4312 const char *str = NULL;
4314 if (cservername == NULL || arch == NULL) {
4315 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4317 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4320 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4327 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4328 &array, &num_strings);
4338 /********************************************************************
4339 * fill a spoolss_DriverInfo1 struct
4340 ********************************************************************/
4342 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4343 struct spoolss_DriverInfo1 *r,
4344 const struct spoolss_DriverInfo8 *driver,
4345 const char *servername)
4347 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4348 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4353 /********************************************************************
4354 * fill a spoolss_DriverInfo2 struct
4355 ********************************************************************/
4357 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4358 struct spoolss_DriverInfo2 *r,
4359 const struct spoolss_DriverInfo8 *driver,
4360 const char *servername)
4363 const char *cservername = canon_servername(servername);
4365 r->version = driver->version;
4367 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4368 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4369 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4370 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4372 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4373 driver->architecture,
4375 driver->driver_path,
4378 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4379 driver->architecture,
4384 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4385 driver->architecture,
4387 driver->config_file,
4393 /********************************************************************
4394 * fill a spoolss_DriverInfo3 struct
4395 ********************************************************************/
4397 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4398 struct spoolss_DriverInfo3 *r,
4399 const struct spoolss_DriverInfo8 *driver,
4400 const char *servername)
4402 const char *cservername = canon_servername(servername);
4404 r->version = driver->version;
4406 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4407 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4408 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4409 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4411 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4412 driver->architecture,
4414 driver->driver_path,
4417 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4418 driver->architecture,
4423 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4424 driver->architecture,
4426 driver->config_file,
4429 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4430 driver->architecture,
4435 FILL_DRIVER_STRING(mem_ctx,
4436 driver->monitor_name,
4439 FILL_DRIVER_STRING(mem_ctx,
4440 driver->default_datatype,
4441 r->default_datatype);
4443 return string_array_from_driver_info(mem_ctx,
4444 driver->dependent_files,
4445 &r->dependent_files,
4447 driver->architecture,
4451 /********************************************************************
4452 * fill a spoolss_DriverInfo4 struct
4453 ********************************************************************/
4455 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4456 struct spoolss_DriverInfo4 *r,
4457 const struct spoolss_DriverInfo8 *driver,
4458 const char *servername)
4460 const char *cservername = canon_servername(servername);
4463 r->version = driver->version;
4465 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4466 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4467 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4468 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4470 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4471 driver->architecture,
4473 driver->driver_path,
4476 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4477 driver->architecture,
4482 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4483 driver->architecture,
4485 driver->config_file,
4488 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4489 driver->architecture,
4494 result = string_array_from_driver_info(mem_ctx,
4495 driver->dependent_files,
4496 &r->dependent_files,
4498 driver->architecture,
4500 if (!W_ERROR_IS_OK(result)) {
4504 FILL_DRIVER_STRING(mem_ctx,
4505 driver->monitor_name,
4508 FILL_DRIVER_STRING(mem_ctx,
4509 driver->default_datatype,
4510 r->default_datatype);
4513 result = string_array_from_driver_info(mem_ctx,
4514 driver->previous_names,
4521 /********************************************************************
4522 * fill a spoolss_DriverInfo5 struct
4523 ********************************************************************/
4525 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4526 struct spoolss_DriverInfo5 *r,
4527 const struct spoolss_DriverInfo8 *driver,
4528 const char *servername)
4530 const char *cservername = canon_servername(servername);
4532 r->version = driver->version;
4534 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4535 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4536 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4537 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4539 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4540 driver->architecture,
4542 driver->driver_path,
4545 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4546 driver->architecture,
4551 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4552 driver->architecture,
4554 driver->config_file,
4557 r->driver_attributes = 0;
4558 r->config_version = 0;
4559 r->driver_version = 0;
4563 /********************************************************************
4564 * fill a spoolss_DriverInfo6 struct
4565 ********************************************************************/
4567 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4568 struct spoolss_DriverInfo6 *r,
4569 const struct spoolss_DriverInfo8 *driver,
4570 const char *servername)
4572 const char *cservername = canon_servername(servername);
4575 r->version = driver->version;
4577 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4578 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4579 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4580 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4582 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4583 driver->architecture,
4585 driver->driver_path,
4588 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4589 driver->architecture,
4594 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4595 driver->architecture,
4597 driver->config_file,
4600 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4601 driver->architecture,
4606 FILL_DRIVER_STRING(mem_ctx,
4607 driver->monitor_name,
4610 FILL_DRIVER_STRING(mem_ctx,
4611 driver->default_datatype,
4612 r->default_datatype);
4614 result = string_array_from_driver_info(mem_ctx,
4615 driver->dependent_files,
4616 &r->dependent_files,
4618 driver->architecture,
4620 if (!W_ERROR_IS_OK(result)) {
4624 result = string_array_from_driver_info(mem_ctx,
4625 driver->previous_names,
4628 if (!W_ERROR_IS_OK(result)) {
4632 r->driver_date = driver->driver_date;
4633 r->driver_version = driver->driver_version;
4635 FILL_DRIVER_STRING(mem_ctx,
4636 driver->manufacturer_name,
4637 r->manufacturer_name);
4638 FILL_DRIVER_STRING(mem_ctx,
4639 driver->manufacturer_url,
4640 r->manufacturer_url);
4641 FILL_DRIVER_STRING(mem_ctx,
4642 driver->hardware_id,
4644 FILL_DRIVER_STRING(mem_ctx,
4651 /********************************************************************
4652 * fill a spoolss_DriverInfo8 struct
4653 ********************************************************************/
4655 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4656 struct spoolss_DriverInfo8 *r,
4657 const struct spoolss_DriverInfo8 *driver,
4658 const char *servername)
4660 const char *cservername = canon_servername(servername);
4663 r->version = driver->version;
4665 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4666 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4667 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4668 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4670 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4671 driver->architecture,
4673 driver->driver_path,
4676 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4677 driver->architecture,
4682 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4683 driver->architecture,
4685 driver->config_file,
4688 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4689 driver->architecture,
4694 FILL_DRIVER_STRING(mem_ctx,
4695 driver->monitor_name,
4698 FILL_DRIVER_STRING(mem_ctx,
4699 driver->default_datatype,
4700 r->default_datatype);
4702 result = string_array_from_driver_info(mem_ctx,
4703 driver->dependent_files,
4704 &r->dependent_files,
4706 driver->architecture,
4708 if (!W_ERROR_IS_OK(result)) {
4712 result = string_array_from_driver_info(mem_ctx,
4713 driver->previous_names,
4716 if (!W_ERROR_IS_OK(result)) {
4720 r->driver_date = driver->driver_date;
4721 r->driver_version = driver->driver_version;
4723 FILL_DRIVER_STRING(mem_ctx,
4724 driver->manufacturer_name,
4725 r->manufacturer_name);
4726 FILL_DRIVER_STRING(mem_ctx,
4727 driver->manufacturer_url,
4728 r->manufacturer_url);
4729 FILL_DRIVER_STRING(mem_ctx,
4730 driver->hardware_id,
4732 FILL_DRIVER_STRING(mem_ctx,
4736 FILL_DRIVER_STRING(mem_ctx,
4737 driver->print_processor,
4738 r->print_processor);
4739 FILL_DRIVER_STRING(mem_ctx,
4740 driver->vendor_setup,
4743 result = string_array_from_driver_info(mem_ctx,
4744 driver->color_profiles,
4747 if (!W_ERROR_IS_OK(result)) {
4751 FILL_DRIVER_STRING(mem_ctx,
4755 r->printer_driver_attributes = driver->printer_driver_attributes;
4757 result = string_array_from_driver_info(mem_ctx,
4758 driver->core_driver_dependencies,
4759 &r->core_driver_dependencies,
4761 if (!W_ERROR_IS_OK(result)) {
4765 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4766 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4771 #if 0 /* disabled until marshalling issues are resolved - gd */
4772 /********************************************************************
4773 ********************************************************************/
4775 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4776 struct spoolss_DriverFileInfo *r,
4777 const char *cservername,
4778 const char *file_name,
4779 enum spoolss_DriverFileType file_type,
4780 uint32_t file_version)
4782 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4783 cservername, file_name);
4784 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4785 r->file_type = file_type;
4786 r->file_version = file_version;
4791 /********************************************************************
4792 ********************************************************************/
4794 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4795 const struct spoolss_DriverInfo8 *driver,
4796 const char *cservername,
4797 struct spoolss_DriverFileInfo **info_p,
4800 struct spoolss_DriverFileInfo *info = NULL;
4808 if (strlen(driver->driver_path)) {
4809 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4810 struct spoolss_DriverFileInfo,
4812 W_ERROR_HAVE_NO_MEMORY(info);
4813 result = fill_spoolss_DriverFileInfo(info,
4816 driver->driver_path,
4817 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4819 W_ERROR_NOT_OK_RETURN(result);
4823 if (strlen(driver->config_file)) {
4824 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4825 struct spoolss_DriverFileInfo,
4827 W_ERROR_HAVE_NO_MEMORY(info);
4828 result = fill_spoolss_DriverFileInfo(info,
4831 driver->config_file,
4832 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4834 W_ERROR_NOT_OK_RETURN(result);
4838 if (strlen(driver->data_file)) {
4839 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4840 struct spoolss_DriverFileInfo,
4842 W_ERROR_HAVE_NO_MEMORY(info);
4843 result = fill_spoolss_DriverFileInfo(info,
4847 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4849 W_ERROR_NOT_OK_RETURN(result);
4853 if (strlen(driver->help_file)) {
4854 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4855 struct spoolss_DriverFileInfo,
4857 W_ERROR_HAVE_NO_MEMORY(info);
4858 result = fill_spoolss_DriverFileInfo(info,
4862 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4864 W_ERROR_NOT_OK_RETURN(result);
4868 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4869 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4870 struct spoolss_DriverFileInfo,
4872 W_ERROR_HAVE_NO_MEMORY(info);
4873 result = fill_spoolss_DriverFileInfo(info,
4876 driver->dependent_files[i],
4877 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4879 W_ERROR_NOT_OK_RETURN(result);
4889 /********************************************************************
4890 * fill a spoolss_DriverInfo101 struct
4891 ********************************************************************/
4893 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4894 struct spoolss_DriverInfo101 *r,
4895 const struct spoolss_DriverInfo8 *driver,
4896 const char *servername)
4898 const char *cservername = canon_servername(servername);
4901 r->version = driver->version;
4903 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4904 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4905 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4906 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4908 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4912 if (!W_ERROR_IS_OK(result)) {
4916 FILL_DRIVER_STRING(mem_ctx,
4917 driver->monitor_name,
4920 FILL_DRIVER_STRING(mem_ctx,
4921 driver->default_datatype,
4922 r->default_datatype);
4924 result = string_array_from_driver_info(mem_ctx,
4925 driver->previous_names,
4928 if (!W_ERROR_IS_OK(result)) {
4932 r->driver_date = driver->driver_date;
4933 r->driver_version = driver->driver_version;
4935 FILL_DRIVER_STRING(mem_ctx,
4936 driver->manufacturer_name,
4937 r->manufacturer_name);
4938 FILL_DRIVER_STRING(mem_ctx,
4939 driver->manufacturer_url,
4940 r->manufacturer_url);
4941 FILL_DRIVER_STRING(mem_ctx,
4942 driver->hardware_id,
4944 FILL_DRIVER_STRING(mem_ctx,
4951 /********************************************************************
4952 ********************************************************************/
4954 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4955 struct auth_serversupplied_info *server_info,
4957 union spoolss_DriverInfo *r,
4959 const char *servername,
4960 const char *architecture,
4963 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4964 struct spoolss_DriverInfo8 *driver;
4967 result = winreg_get_printer(mem_ctx,
4970 lp_const_servicename(snum),
4973 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4974 win_errstr(result)));
4976 if (!W_ERROR_IS_OK(result)) {
4977 return WERR_INVALID_PRINTER_NAME;
4980 result = winreg_get_driver(mem_ctx, server_info, architecture,
4981 pinfo2->drivername, version, &driver);
4983 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4984 win_errstr(result)));
4986 if (!W_ERROR_IS_OK(result)) {
4988 * Is this a W2k client ?
4992 talloc_free(pinfo2);
4993 return WERR_UNKNOWN_PRINTER_DRIVER;
4996 /* Yes - try again with a WinNT driver. */
4998 result = winreg_get_driver(mem_ctx, server_info, architecture,
5001 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5002 win_errstr(result)));
5003 if (!W_ERROR_IS_OK(result)) {
5004 talloc_free(pinfo2);
5005 return WERR_UNKNOWN_PRINTER_DRIVER;
5011 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5014 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5017 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5020 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5023 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5026 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5029 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5031 #if 0 /* disabled until marshalling issues are resolved - gd */
5033 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5037 result = WERR_UNKNOWN_LEVEL;
5041 talloc_free(pinfo2);
5042 talloc_free(driver);
5047 /****************************************************************
5048 _spoolss_GetPrinterDriver2
5049 ****************************************************************/
5051 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5052 struct spoolss_GetPrinterDriver2 *r)
5054 Printer_entry *printer;
5059 /* that's an [in out] buffer */
5061 if (!r->in.buffer && (r->in.offered != 0)) {
5062 return WERR_INVALID_PARAM;
5065 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5067 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5068 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5069 return WERR_INVALID_PRINTER_NAME;
5073 *r->out.server_major_version = 0;
5074 *r->out.server_minor_version = 0;
5076 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5080 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5081 r->in.level, r->out.info,
5082 snum, printer->servername,
5084 r->in.client_major_version);
5085 if (!W_ERROR_IS_OK(result)) {
5086 TALLOC_FREE(r->out.info);
5090 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5091 r->out.info, r->in.level);
5092 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5094 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5098 /****************************************************************
5099 _spoolss_StartPagePrinter
5100 ****************************************************************/
5102 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5103 struct spoolss_StartPagePrinter *r)
5105 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5108 DEBUG(3,("_spoolss_StartPagePrinter: "
5109 "Error in startpageprinter printer handle\n"));
5113 Printer->page_started = true;
5117 /****************************************************************
5118 _spoolss_EndPagePrinter
5119 ****************************************************************/
5121 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5122 struct spoolss_EndPagePrinter *r)
5126 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5129 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5130 OUR_HANDLE(r->in.handle)));
5134 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5137 Printer->page_started = false;
5138 print_job_endpage(snum, Printer->jobid);
5143 /****************************************************************
5144 _spoolss_StartDocPrinter
5145 ****************************************************************/
5147 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5148 struct spoolss_StartDocPrinter *r)
5150 struct spoolss_DocumentInfo1 *info_1;
5152 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5156 DEBUG(2,("_spoolss_StartDocPrinter: "
5157 "Invalid handle (%s:%u:%u)\n",
5158 OUR_HANDLE(r->in.handle)));
5162 if (Printer->jobid) {
5163 DEBUG(2, ("_spoolss_StartDocPrinter: "
5164 "StartDocPrinter called twice! "
5165 "(existing jobid = %d)\n", Printer->jobid));
5166 return WERR_INVALID_HANDLE;
5169 if (r->in.level != 1) {
5170 return WERR_UNKNOWN_LEVEL;
5173 info_1 = r->in.info.info1;
5176 * a nice thing with NT is it doesn't listen to what you tell it.
5177 * when asked to send _only_ RAW datas, it tries to send datas
5180 * So I add checks like in NT Server ...
5183 if (info_1->datatype) {
5184 if (strcmp(info_1->datatype, "RAW") != 0) {
5186 return WERR_INVALID_DATATYPE;
5190 /* get the share number of the printer */
5191 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5195 werr = print_job_start(p->server_info, snum,
5196 info_1->document_name, info_1->output_file,
5197 Printer->devmode, &Printer->jobid);
5199 /* An error occured in print_job_start() so return an appropriate
5202 if (!W_ERROR_IS_OK(werr)) {
5206 Printer->document_started = true;
5207 *r->out.job_id = Printer->jobid;
5212 /****************************************************************
5213 _spoolss_EndDocPrinter
5214 ****************************************************************/
5216 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5217 struct spoolss_EndDocPrinter *r)
5219 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5224 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5225 OUR_HANDLE(r->in.handle)));
5229 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5233 Printer->document_started = false;
5234 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5235 if (!NT_STATUS_IS_OK(status)) {
5236 DEBUG(2, ("_spoolss_EndDocPrinter: "
5237 "print_job_end failed [%s]\n",
5238 nt_errstr(status)));
5242 return ntstatus_to_werror(status);
5245 /****************************************************************
5246 _spoolss_WritePrinter
5247 ****************************************************************/
5249 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5250 struct spoolss_WritePrinter *r)
5252 ssize_t buffer_written;
5254 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5257 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5258 OUR_HANDLE(r->in.handle)));
5259 *r->out.num_written = r->in._data_size;
5263 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5266 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5267 buffer_written = print_job_write(snum, Printer->jobid,
5268 (const char *)r->in.data.data,
5270 (size_t)r->in._data_size);
5271 if (buffer_written == (ssize_t)-1) {
5272 *r->out.num_written = 0;
5273 if (errno == ENOSPC)
5274 return WERR_NO_SPOOL_SPACE;
5276 return WERR_ACCESS_DENIED;
5279 *r->out.num_written = r->in._data_size;
5284 /********************************************************************
5285 * api_spoolss_getprinter
5286 * called from the spoolss dispatcher
5288 ********************************************************************/
5290 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5291 struct pipes_struct *p)
5294 WERROR errcode = WERR_BADFUNC;
5295 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5298 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5299 OUR_HANDLE(handle)));
5303 if (!get_printer_snum(p, handle, &snum, NULL))
5307 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5308 errcode = print_queue_pause(p->server_info, snum);
5310 case SPOOLSS_PRINTER_CONTROL_RESUME:
5311 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5312 errcode = print_queue_resume(p->server_info, snum);
5314 case SPOOLSS_PRINTER_CONTROL_PURGE:
5315 errcode = print_queue_purge(p->server_info, snum);
5318 return WERR_UNKNOWN_LEVEL;
5325 /****************************************************************
5326 _spoolss_AbortPrinter
5327 * From MSDN: "Deletes printer's spool file if printer is configured
5329 ****************************************************************/
5331 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5332 struct spoolss_AbortPrinter *r)
5334 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5336 WERROR errcode = WERR_OK;
5339 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5340 OUR_HANDLE(r->in.handle)));
5344 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5347 if (!Printer->document_started) {
5348 return WERR_SPL_NO_STARTDOC;
5351 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5356 /********************************************************************
5357 * called by spoolss_api_setprinter
5358 * when updating a printer description
5359 ********************************************************************/
5361 static WERROR update_printer_sec(struct policy_handle *handle,
5362 struct pipes_struct *p,
5363 struct sec_desc_buf *secdesc_ctr)
5365 struct spoolss_security_descriptor *new_secdesc = NULL;
5366 struct spoolss_security_descriptor *old_secdesc = NULL;
5367 const char *printer;
5371 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5373 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5374 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5375 OUR_HANDLE(handle)));
5377 result = WERR_BADFID;
5381 if (secdesc_ctr == NULL) {
5382 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5383 result = WERR_INVALID_PARAM;
5386 printer = lp_const_servicename(snum);
5388 /* Check the user has permissions to change the security
5389 descriptor. By experimentation with two NT machines, the user
5390 requires Full Access to the printer to change security
5393 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5394 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5395 result = WERR_ACCESS_DENIED;
5399 /* NT seems to like setting the security descriptor even though
5400 nothing may have actually changed. */
5401 result = winreg_get_printer_secdesc(p->mem_ctx,
5405 if (!W_ERROR_IS_OK(result)) {
5406 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5407 result = WERR_BADFID;
5411 if (DEBUGLEVEL >= 10) {
5412 struct security_acl *the_acl;
5415 the_acl = old_secdesc->dacl;
5416 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5417 printer, the_acl->num_aces));
5419 for (i = 0; i < the_acl->num_aces; i++) {
5420 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5421 &the_acl->aces[i].trustee),
5422 the_acl->aces[i].access_mask));
5425 the_acl = secdesc_ctr->sd->dacl;
5428 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5429 printer, the_acl->num_aces));
5431 for (i = 0; i < the_acl->num_aces; i++) {
5432 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5433 &the_acl->aces[i].trustee),
5434 the_acl->aces[i].access_mask));
5437 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5441 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5442 if (new_secdesc == NULL) {
5443 result = WERR_NOMEM;
5447 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5452 result = winreg_set_printer_secdesc(p->mem_ctx,
5461 /********************************************************************
5462 Canonicalize printer info from a client
5463 ********************************************************************/
5465 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5466 struct spoolss_SetPrinterInfo2 *info2,
5469 fstring printername;
5472 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5473 "portname=%s drivername=%s comment=%s location=%s\n",
5474 info2->servername, info2->printername, info2->sharename,
5475 info2->portname, info2->drivername, info2->comment,
5478 /* we force some elements to "correct" values */
5479 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5480 if (info2->servername == NULL) {
5483 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5484 if (info2->sharename == NULL) {
5488 /* check to see if we allow printername != sharename */
5489 if (lp_force_printername(snum)) {
5490 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5491 global_myname(), info2->sharename);
5493 /* make sure printername is in \\server\printername format */
5494 fstrcpy(printername, info2->printername);
5496 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5497 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5501 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5502 global_myname(), p);
5504 if (info2->printername == NULL) {
5508 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5509 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5514 /****************************************************************************
5515 ****************************************************************************/
5517 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5519 char *cmd = lp_addport_cmd();
5520 char *command = NULL;
5522 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5523 bool is_print_op = false;
5526 return WERR_ACCESS_DENIED;
5529 command = talloc_asprintf(ctx,
5530 "%s \"%s\" \"%s\"", cmd, portname, uri );
5536 is_print_op = user_has_privileges( token, &se_printop );
5538 DEBUG(10,("Running [%s]\n", command));
5540 /********* BEGIN SePrintOperatorPrivilege **********/
5545 ret = smbrun(command, NULL);
5550 /********* END SePrintOperatorPrivilege **********/
5552 DEBUGADD(10,("returned [%d]\n", ret));
5554 TALLOC_FREE(command);
5557 return WERR_ACCESS_DENIED;
5563 /****************************************************************************
5564 ****************************************************************************/
5566 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5567 struct spoolss_SetPrinterInfo2 *info2,
5568 const char *remote_machine,
5569 struct messaging_context *msg_ctx)
5571 char *cmd = lp_addprinter_cmd();
5573 char *command = NULL;
5577 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5578 bool is_print_op = false;
5580 if (!remote_machine) {
5584 command = talloc_asprintf(ctx,
5585 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5586 cmd, info2->printername, info2->sharename,
5587 info2->portname, info2->drivername,
5588 info2->location, info2->comment, remote_machine);
5594 is_print_op = user_has_privileges( token, &se_printop );
5596 DEBUG(10,("Running [%s]\n", command));
5598 /********* BEGIN SePrintOperatorPrivilege **********/
5603 if ( (ret = smbrun(command, &fd)) == 0 ) {
5604 /* Tell everyone we updated smb.conf. */
5605 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5611 /********* END SePrintOperatorPrivilege **********/
5613 DEBUGADD(10,("returned [%d]\n", ret));
5615 TALLOC_FREE(command);
5623 /* reload our services immediately */
5625 reload_services(false);
5629 /* Get lines and convert them back to dos-codepage */
5630 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5631 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5634 /* Set the portname to what the script says the portname should be. */
5635 /* but don't require anything to be return from the script exit a good error code */
5638 /* Set the portname to what the script says the portname should be. */
5639 info2->portname = talloc_strdup(ctx, qlines[0]);
5640 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5643 TALLOC_FREE(qlines);
5647 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5648 struct auth_serversupplied_info *server_info,
5650 struct spoolss_SetPrinterInfo2 *printer,
5651 struct spoolss_PrinterInfo2 *old_printer)
5653 bool force_update = (old_printer == NULL);
5654 const char *dnsdomname;
5655 const char *longname;
5656 const char *uncname;
5657 const char *spooling;
5659 WERROR result = WERR_OK;
5661 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5662 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5663 winreg_set_printer_dataex(mem_ctx,
5666 SPOOL_DSSPOOLER_KEY,
5667 SPOOL_REG_DRIVERNAME,
5672 if (!force_update) {
5673 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5674 printer->drivername));
5676 notify_printer_driver(snum, printer->drivername);
5680 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5681 push_reg_sz(mem_ctx, &buffer, printer->comment);
5682 winreg_set_printer_dataex(mem_ctx,
5685 SPOOL_DSSPOOLER_KEY,
5686 SPOOL_REG_DESCRIPTION,
5691 if (!force_update) {
5692 notify_printer_comment(snum, printer->comment);
5696 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5697 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5698 winreg_set_printer_dataex(mem_ctx,
5701 SPOOL_DSSPOOLER_KEY,
5702 SPOOL_REG_PRINTSHARENAME,
5707 if (!force_update) {
5708 notify_printer_sharename(snum, printer->sharename);
5712 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5715 p = strrchr(printer->printername, '\\' );
5719 p = printer->printername;
5722 push_reg_sz(mem_ctx, &buffer, p);
5723 winreg_set_printer_dataex(mem_ctx,
5726 SPOOL_DSSPOOLER_KEY,
5727 SPOOL_REG_PRINTERNAME,
5732 if (!force_update) {
5733 notify_printer_printername(snum, p);
5737 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5738 push_reg_sz(mem_ctx, &buffer, printer->portname);
5739 winreg_set_printer_dataex(mem_ctx,
5742 SPOOL_DSSPOOLER_KEY,
5748 if (!force_update) {
5749 notify_printer_port(snum, printer->portname);
5753 if (force_update || !strequal(printer->location, old_printer->location)) {
5754 push_reg_sz(mem_ctx, &buffer, printer->location);
5755 winreg_set_printer_dataex(mem_ctx,
5758 SPOOL_DSSPOOLER_KEY,
5764 if (!force_update) {
5765 notify_printer_location(snum, printer->location);
5769 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5770 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5771 winreg_set_printer_dataex(mem_ctx,
5774 SPOOL_DSSPOOLER_KEY,
5775 SPOOL_REG_PRINTSEPARATORFILE,
5780 if (!force_update) {
5781 notify_printer_location(snum, printer->location);
5785 if (force_update || printer->starttime != old_printer->starttime) {
5786 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5787 SIVAL(buffer.data, 0, printer->starttime);
5788 winreg_set_printer_dataex(mem_ctx,
5791 SPOOL_DSSPOOLER_KEY,
5792 SPOOL_REG_PRINTSTARTTIME,
5798 if (force_update || printer->untiltime != old_printer->untiltime) {
5799 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5800 SIVAL(buffer.data, 0, printer->untiltime);
5801 winreg_set_printer_dataex(mem_ctx,
5804 SPOOL_DSSPOOLER_KEY,
5805 SPOOL_REG_PRINTENDTIME,
5811 if (force_update || printer->priority != old_printer->priority) {
5812 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5813 SIVAL(buffer.data, 0, printer->priority);
5814 winreg_set_printer_dataex(mem_ctx,
5817 SPOOL_DSSPOOLER_KEY,
5824 if (force_update || printer->attributes != old_printer->attributes) {
5825 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5826 SIVAL(buffer.data, 0, (printer->attributes &
5827 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5828 winreg_set_printer_dataex(mem_ctx,
5831 SPOOL_DSSPOOLER_KEY,
5832 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5837 switch (printer->attributes & 0x3) {
5839 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5842 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5845 spooling = SPOOL_REGVAL_PRINTDIRECT;
5848 spooling = "unknown";
5850 push_reg_sz(mem_ctx, &buffer, spooling);
5851 winreg_set_printer_dataex(mem_ctx,
5854 SPOOL_DSSPOOLER_KEY,
5855 SPOOL_REG_PRINTSPOOLING,
5861 push_reg_sz(mem_ctx, &buffer, global_myname());
5862 winreg_set_printer_dataex(mem_ctx,
5865 SPOOL_DSSPOOLER_KEY,
5866 SPOOL_REG_SHORTSERVERNAME,
5871 dnsdomname = get_mydnsfullname();
5872 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5873 longname = talloc_strdup(mem_ctx, dnsdomname);
5875 longname = talloc_strdup(mem_ctx, global_myname());
5877 if (longname == NULL) {
5878 result = WERR_NOMEM;
5882 push_reg_sz(mem_ctx, &buffer, longname);
5883 winreg_set_printer_dataex(mem_ctx,
5886 SPOOL_DSSPOOLER_KEY,
5887 SPOOL_REG_SERVERNAME,
5892 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5893 global_myname(), printer->sharename);
5894 push_reg_sz(mem_ctx, &buffer, uncname);
5895 winreg_set_printer_dataex(mem_ctx,
5898 SPOOL_DSSPOOLER_KEY,
5908 /********************************************************************
5909 * Called by spoolss_api_setprinter
5910 * when updating a printer description.
5911 ********************************************************************/
5913 static WERROR update_printer(struct pipes_struct *p,
5914 struct policy_handle *handle,
5915 struct spoolss_SetPrinterInfoCtr *info_ctr,
5916 struct spoolss_DeviceMode *devmode)
5918 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5919 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5920 struct spoolss_PrinterInfo2 *old_printer;
5921 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5922 const char *servername = NULL;
5924 WERROR result = WERR_OK;
5925 TALLOC_CTX *tmp_ctx;
5927 DEBUG(8,("update_printer\n"));
5929 tmp_ctx = talloc_new(p->mem_ctx);
5930 if (tmp_ctx == NULL) {
5935 result = WERR_BADFID;
5939 if (!get_printer_snum(p, handle, &snum, NULL)) {
5940 result = WERR_BADFID;
5944 if (Printer != NULL || Printer->servername != NULL) {
5945 servername = Printer->servername;
5948 result = winreg_get_printer(tmp_ctx,
5951 lp_const_servicename(snum),
5953 if (!W_ERROR_IS_OK(result)) {
5954 result = WERR_BADFID;
5958 /* Do sanity check on the requested changes for Samba */
5959 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5960 result = WERR_INVALID_PARAM;
5964 /* FIXME!!! If the driver has changed we really should verify that
5965 it is installed before doing much else --jerry */
5967 /* Check calling user has permission to update printer description */
5968 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5969 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5970 result = WERR_ACCESS_DENIED;
5974 /* Call addprinter hook */
5975 /* Check changes to see if this is really needed */
5977 if (*lp_addprinter_cmd() &&
5978 (!strequal(printer->drivername, old_printer->drivername) ||
5979 !strequal(printer->comment, old_printer->comment) ||
5980 !strequal(printer->portname, old_printer->portname) ||
5981 !strequal(printer->location, old_printer->location)) )
5983 /* add_printer_hook() will call reload_services() */
5984 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5985 printer, p->client_address,
5987 result = WERR_ACCESS_DENIED;
5992 update_dsspooler(tmp_ctx,
5998 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6000 if (devmode == NULL) {
6001 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6003 result = winreg_update_printer(tmp_ctx,
6013 talloc_free(tmp_ctx);
6018 /****************************************************************************
6019 ****************************************************************************/
6020 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6021 struct policy_handle *handle,
6022 struct spoolss_SetPrinterInfo7 *info7)
6025 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6028 Printer_entry *Printer;
6030 if ( lp_security() != SEC_ADS ) {
6031 return WERR_UNKNOWN_LEVEL;
6034 Printer = find_printer_index_by_hnd(p, handle);
6036 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6041 if (!get_printer_snum(p, handle, &snum, NULL))
6044 result = winreg_get_printer(p->mem_ctx, p->server_info,
6045 Printer->servername,
6046 lp_servicename(snum), &pinfo2);
6047 if (!W_ERROR_IS_OK(result)) {
6051 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6053 TALLOC_FREE(pinfo2);
6056 return WERR_UNKNOWN_LEVEL;
6060 /********************************************************************
6061 ********************************************************************/
6063 static WERROR update_printer_devmode(struct pipes_struct *p,
6064 struct policy_handle *handle,
6065 struct spoolss_DeviceMode *devmode)
6068 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6069 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6071 DEBUG(8,("update_printer_devmode\n"));
6077 if (!get_printer_snum(p, handle, &snum, NULL)) {
6081 /* Check calling user has permission to update printer description */
6082 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6083 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6084 return WERR_ACCESS_DENIED;
6087 return winreg_update_printer(p->mem_ctx,
6090 lp_const_servicename(snum),
6098 /****************************************************************
6100 ****************************************************************/
6102 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6103 struct spoolss_SetPrinter *r)
6107 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6110 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6111 OUR_HANDLE(r->in.handle)));
6115 /* check the level */
6116 switch (r->in.info_ctr->level) {
6118 return control_printer(r->in.handle, r->in.command, p);
6120 result = update_printer(p, r->in.handle,
6122 r->in.devmode_ctr->devmode);
6123 if (!W_ERROR_IS_OK(result))
6125 if (r->in.secdesc_ctr->sd)
6126 result = update_printer_sec(r->in.handle, p,
6130 return update_printer_sec(r->in.handle, p,
6133 return publish_or_unpublish_printer(p, r->in.handle,
6134 r->in.info_ctr->info.info7);
6136 return update_printer_devmode(p, r->in.handle,
6137 r->in.devmode_ctr->devmode);
6139 return WERR_UNKNOWN_LEVEL;
6143 /****************************************************************
6144 _spoolss_FindClosePrinterNotify
6145 ****************************************************************/
6147 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6148 struct spoolss_FindClosePrinterNotify *r)
6150 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6153 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6154 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6158 if (Printer->notify.client_connected == true) {
6161 if ( Printer->printer_type == SPLHND_SERVER)
6163 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6164 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6167 srv_spoolss_replycloseprinter(
6168 snum, &Printer->notify.client_hnd, p->msg_ctx);
6171 Printer->notify.flags=0;
6172 Printer->notify.options=0;
6173 Printer->notify.localmachine[0]='\0';
6174 Printer->notify.printerlocal=0;
6175 TALLOC_FREE(Printer->notify.option);
6176 Printer->notify.client_connected = false;
6181 /****************************************************************
6183 ****************************************************************/
6185 WERROR _spoolss_AddJob(struct pipes_struct *p,
6186 struct spoolss_AddJob *r)
6188 if (!r->in.buffer && (r->in.offered != 0)) {
6189 return WERR_INVALID_PARAM;
6192 /* this is what a NT server returns for AddJob. AddJob must fail on
6193 * non-local printers */
6195 if (r->in.level != 1) {
6196 return WERR_UNKNOWN_LEVEL;
6199 return WERR_INVALID_PARAM;
6202 /****************************************************************************
6204 ****************************************************************************/
6206 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6207 struct spoolss_JobInfo1 *r,
6208 const print_queue_struct *queue,
6209 int position, int snum,
6210 struct spoolss_PrinterInfo2 *pinfo2)
6214 t = gmtime(&queue->time);
6216 r->job_id = queue->job;
6218 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6219 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6220 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6221 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6222 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6223 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6224 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6225 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6226 r->data_type = talloc_strdup(mem_ctx, "RAW");
6227 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6228 r->text_status = talloc_strdup(mem_ctx, "");
6229 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6231 r->status = nt_printj_status(queue->status);
6232 r->priority = queue->priority;
6233 r->position = position;
6234 r->total_pages = queue->page_count;
6235 r->pages_printed = 0; /* ??? */
6237 init_systemtime(&r->submitted, t);
6242 /****************************************************************************
6244 ****************************************************************************/
6246 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6247 struct spoolss_JobInfo2 *r,
6248 const print_queue_struct *queue,
6249 int position, int snum,
6250 struct spoolss_PrinterInfo2 *pinfo2,
6251 struct spoolss_DeviceMode *devmode)
6255 t = gmtime(&queue->time);
6257 r->job_id = queue->job;
6259 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6260 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6261 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6262 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6263 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6264 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6265 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6266 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6267 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6268 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6269 r->data_type = talloc_strdup(mem_ctx, "RAW");
6270 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6271 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6272 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6273 r->parameters = talloc_strdup(mem_ctx, "");
6274 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6275 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6276 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6278 r->devmode = devmode;
6280 r->text_status = talloc_strdup(mem_ctx, "");
6281 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6285 r->status = nt_printj_status(queue->status);
6286 r->priority = queue->priority;
6287 r->position = position;
6290 r->total_pages = queue->page_count;
6291 r->size = queue->size;
6292 init_systemtime(&r->submitted, t);
6294 r->pages_printed = 0; /* ??? */
6299 /****************************************************************************
6301 ****************************************************************************/
6303 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6304 struct spoolss_JobInfo3 *r,
6305 const print_queue_struct *queue,
6306 const print_queue_struct *next_queue,
6307 int position, int snum,
6308 struct spoolss_PrinterInfo2 *pinfo2)
6310 r->job_id = queue->job;
6313 r->next_job_id = next_queue->job;
6320 /****************************************************************************
6321 Enumjobs at level 1.
6322 ****************************************************************************/
6324 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6325 const print_queue_struct *queue,
6326 uint32_t num_queues, int snum,
6327 struct spoolss_PrinterInfo2 *pinfo2,
6328 union spoolss_JobInfo **info_p,
6331 union spoolss_JobInfo *info;
6333 WERROR result = WERR_OK;
6335 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6336 W_ERROR_HAVE_NO_MEMORY(info);
6338 *count = num_queues;
6340 for (i=0; i<*count; i++) {
6341 result = fill_job_info1(info,
6347 if (!W_ERROR_IS_OK(result)) {
6353 if (!W_ERROR_IS_OK(result)) {
6364 /****************************************************************************
6365 Enumjobs at level 2.
6366 ****************************************************************************/
6368 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6369 const print_queue_struct *queue,
6370 uint32_t num_queues, int snum,
6371 struct spoolss_PrinterInfo2 *pinfo2,
6372 union spoolss_JobInfo **info_p,
6375 union spoolss_JobInfo *info;
6377 WERROR result = WERR_OK;
6379 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6380 W_ERROR_HAVE_NO_MEMORY(info);
6382 *count = num_queues;
6384 for (i=0; i<*count; i++) {
6385 struct spoolss_DeviceMode *devmode;
6387 result = spoolss_create_default_devmode(info,
6388 pinfo2->printername,
6390 if (!W_ERROR_IS_OK(result)) {
6391 DEBUG(3, ("Can't proceed w/o a devmode!"));
6395 result = fill_job_info2(info,
6402 if (!W_ERROR_IS_OK(result)) {
6408 if (!W_ERROR_IS_OK(result)) {
6419 /****************************************************************************
6420 Enumjobs at level 3.
6421 ****************************************************************************/
6423 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6424 const print_queue_struct *queue,
6425 uint32_t num_queues, int snum,
6426 struct spoolss_PrinterInfo2 *pinfo2,
6427 union spoolss_JobInfo **info_p,
6430 union spoolss_JobInfo *info;
6432 WERROR result = WERR_OK;
6434 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6435 W_ERROR_HAVE_NO_MEMORY(info);
6437 *count = num_queues;
6439 for (i=0; i<*count; i++) {
6440 const print_queue_struct *next_queue = NULL;
6443 next_queue = &queue[i+1];
6446 result = fill_job_info3(info,
6453 if (!W_ERROR_IS_OK(result)) {
6459 if (!W_ERROR_IS_OK(result)) {
6470 /****************************************************************
6472 ****************************************************************/
6474 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6475 struct spoolss_EnumJobs *r)
6478 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6480 print_status_struct prt_status;
6481 print_queue_struct *queue = NULL;
6484 /* that's an [in out] buffer */
6486 if (!r->in.buffer && (r->in.offered != 0)) {
6487 return WERR_INVALID_PARAM;
6490 DEBUG(4,("_spoolss_EnumJobs\n"));
6494 *r->out.info = NULL;
6496 /* lookup the printer snum and tdb entry */
6498 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6502 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6503 lp_servicename(snum), &pinfo2);
6504 if (!W_ERROR_IS_OK(result)) {
6508 count = print_queue_status(snum, &queue, &prt_status);
6509 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6510 count, prt_status.status, prt_status.message));
6514 TALLOC_FREE(pinfo2);
6518 switch (r->in.level) {
6520 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6521 pinfo2, r->out.info, r->out.count);
6524 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6525 pinfo2, r->out.info, r->out.count);
6528 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6529 pinfo2, r->out.info, r->out.count);
6532 result = WERR_UNKNOWN_LEVEL;
6537 TALLOC_FREE(pinfo2);
6539 if (!W_ERROR_IS_OK(result)) {
6543 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6545 *r->out.info, r->in.level,
6547 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6548 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6550 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6553 /****************************************************************
6554 _spoolss_ScheduleJob
6555 ****************************************************************/
6557 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6558 struct spoolss_ScheduleJob *r)
6563 /****************************************************************
6564 ****************************************************************/
6566 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6567 const char *printer_name,
6569 struct spoolss_SetJobInfo1 *r)
6573 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6577 if (strequal(old_doc_name, r->document_name)) {
6581 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6588 /****************************************************************
6590 ****************************************************************/
6592 WERROR _spoolss_SetJob(struct pipes_struct *p,
6593 struct spoolss_SetJob *r)
6596 WERROR errcode = WERR_BADFUNC;
6598 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6602 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6603 return WERR_INVALID_PRINTER_NAME;
6606 switch (r->in.command) {
6607 case SPOOLSS_JOB_CONTROL_CANCEL:
6608 case SPOOLSS_JOB_CONTROL_DELETE:
6609 errcode = print_job_delete(p->server_info,
6610 snum, r->in.job_id);
6611 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6615 case SPOOLSS_JOB_CONTROL_PAUSE:
6616 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6620 case SPOOLSS_JOB_CONTROL_RESTART:
6621 case SPOOLSS_JOB_CONTROL_RESUME:
6622 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6630 return WERR_UNKNOWN_LEVEL;
6633 if (!W_ERROR_IS_OK(errcode)) {
6637 if (r->in.ctr == NULL) {
6641 switch (r->in.ctr->level) {
6643 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6645 r->in.ctr->info.info1);
6651 return WERR_UNKNOWN_LEVEL;
6657 /****************************************************************************
6658 Enumerates all printer drivers by level and architecture.
6659 ****************************************************************************/
6661 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6662 struct auth_serversupplied_info *server_info,
6663 const char *servername,
6664 const char *architecture,
6666 union spoolss_DriverInfo **info_p,
6671 struct spoolss_DriverInfo8 *driver;
6672 union spoolss_DriverInfo *info = NULL;
6674 WERROR result = WERR_OK;
6675 uint32_t num_drivers;
6676 const char **drivers;
6681 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6682 result = winreg_get_driver_list(mem_ctx, server_info,
6683 architecture, version,
6684 &num_drivers, &drivers);
6685 if (!W_ERROR_IS_OK(result)) {
6688 DEBUG(4, ("we have:[%d] drivers in environment"
6689 " [%s] and version [%d]\n",
6690 num_drivers, architecture, version));
6692 if (num_drivers != 0) {
6693 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6694 union spoolss_DriverInfo,
6695 count + num_drivers);
6697 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6698 "failed to enlarge driver info buffer!\n"));
6699 result = WERR_NOMEM;
6704 for (i = 0; i < num_drivers; i++) {
6705 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6707 result = winreg_get_driver(mem_ctx, server_info,
6708 architecture, drivers[i],
6710 if (!W_ERROR_IS_OK(result)) {
6716 result = fill_printer_driver_info1(info, &info[count+i].info1,
6717 driver, servername);
6720 result = fill_printer_driver_info2(info, &info[count+i].info2,
6721 driver, servername);
6724 result = fill_printer_driver_info3(info, &info[count+i].info3,
6725 driver, servername);
6728 result = fill_printer_driver_info4(info, &info[count+i].info4,
6729 driver, servername);
6732 result = fill_printer_driver_info5(info, &info[count+i].info5,
6733 driver, servername);
6736 result = fill_printer_driver_info6(info, &info[count+i].info6,
6737 driver, servername);
6740 result = fill_printer_driver_info8(info, &info[count+i].info8,
6741 driver, servername);
6744 result = WERR_UNKNOWN_LEVEL;
6748 TALLOC_FREE(driver);
6750 if (!W_ERROR_IS_OK(result)) {
6755 count += num_drivers;
6756 TALLOC_FREE(drivers);
6760 TALLOC_FREE(drivers);
6762 if (!W_ERROR_IS_OK(result)) {
6773 /****************************************************************************
6774 Enumerates all printer drivers by level.
6775 ****************************************************************************/
6777 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6778 struct auth_serversupplied_info *server_info,
6779 const char *servername,
6780 const char *architecture,
6782 union spoolss_DriverInfo **info_p,
6786 WERROR result = WERR_OK;
6788 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6790 for (a=0; archi_table[a].long_archi != NULL; a++) {
6792 union spoolss_DriverInfo *info = NULL;
6795 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6798 archi_table[a].long_archi,
6802 if (!W_ERROR_IS_OK(result)) {
6806 for (i=0; i < count; i++) {
6807 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6808 info[i], info_p, count_p);
6815 return enumprinterdrivers_level_by_architecture(mem_ctx,
6824 /****************************************************************
6825 _spoolss_EnumPrinterDrivers
6826 ****************************************************************/
6828 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6829 struct spoolss_EnumPrinterDrivers *r)
6831 const char *cservername;
6834 /* that's an [in out] buffer */
6836 if (!r->in.buffer && (r->in.offered != 0)) {
6837 return WERR_INVALID_PARAM;
6840 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6844 *r->out.info = NULL;
6846 cservername = canon_servername(r->in.server);
6848 if (!is_myname_or_ipaddr(cservername)) {
6849 return WERR_UNKNOWN_PRINTER_DRIVER;
6852 result = enumprinterdrivers_level(p->mem_ctx,
6859 if (!W_ERROR_IS_OK(result)) {
6863 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6864 spoolss_EnumPrinterDrivers,
6865 *r->out.info, r->in.level,
6867 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6868 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6870 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6873 /****************************************************************
6875 ****************************************************************/
6877 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6878 struct spoolss_EnumForms *r)
6884 *r->out.info = NULL;
6886 /* that's an [in out] buffer */
6888 if (!r->in.buffer && (r->in.offered != 0) ) {
6889 return WERR_INVALID_PARAM;
6892 DEBUG(4,("_spoolss_EnumForms\n"));
6893 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6894 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6896 switch (r->in.level) {
6898 result = winreg_printer_enumforms1(p->mem_ctx,
6904 result = WERR_UNKNOWN_LEVEL;
6908 if (!W_ERROR_IS_OK(result)) {
6912 if (*r->out.count == 0) {
6913 return WERR_NO_MORE_ITEMS;
6916 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6918 *r->out.info, r->in.level,
6920 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6921 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6923 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6926 /****************************************************************
6928 ****************************************************************/
6930 WERROR _spoolss_GetForm(struct pipes_struct *p,
6931 struct spoolss_GetForm *r)
6935 /* that's an [in out] buffer */
6937 if (!r->in.buffer && (r->in.offered != 0)) {
6938 return WERR_INVALID_PARAM;
6941 DEBUG(4,("_spoolss_GetForm\n"));
6942 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6943 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6945 switch (r->in.level) {
6947 result = winreg_printer_getform1(p->mem_ctx,
6950 &r->out.info->info1);
6953 result = WERR_UNKNOWN_LEVEL;
6957 if (!W_ERROR_IS_OK(result)) {
6958 TALLOC_FREE(r->out.info);
6962 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6963 r->out.info, r->in.level);
6964 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6966 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6969 /****************************************************************************
6970 ****************************************************************************/
6972 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6973 struct spoolss_PortInfo1 *r,
6976 r->port_name = talloc_strdup(mem_ctx, name);
6977 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6982 /****************************************************************************
6983 TODO: This probably needs distinguish between TCP/IP and Local ports
6985 ****************************************************************************/
6987 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6988 struct spoolss_PortInfo2 *r,
6991 r->port_name = talloc_strdup(mem_ctx, name);
6992 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6994 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6995 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6997 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6998 W_ERROR_HAVE_NO_MEMORY(r->description);
7000 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7007 /****************************************************************************
7008 wrapper around the enumer ports command
7009 ****************************************************************************/
7011 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7013 char *cmd = lp_enumports_cmd();
7014 char **qlines = NULL;
7015 char *command = NULL;
7023 /* if no hook then just fill in the default port */
7026 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7029 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7030 TALLOC_FREE(qlines);
7037 /* we have a valid enumport command */
7039 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7044 DEBUG(10,("Running [%s]\n", command));
7045 ret = smbrun(command, &fd);
7046 DEBUG(10,("Returned [%d]\n", ret));
7047 TALLOC_FREE(command);
7052 return WERR_ACCESS_DENIED;
7056 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7057 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7067 /****************************************************************************
7069 ****************************************************************************/
7071 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7072 union spoolss_PortInfo **info_p,
7075 union spoolss_PortInfo *info = NULL;
7077 WERROR result = WERR_OK;
7078 char **qlines = NULL;
7081 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7082 if (!W_ERROR_IS_OK(result)) {
7087 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7089 DEBUG(10,("Returning WERR_NOMEM\n"));
7090 result = WERR_NOMEM;
7094 for (i=0; i<numlines; i++) {
7095 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7096 result = fill_port_1(info, &info[i].info1, qlines[i]);
7097 if (!W_ERROR_IS_OK(result)) {
7102 TALLOC_FREE(qlines);
7105 if (!W_ERROR_IS_OK(result)) {
7107 TALLOC_FREE(qlines);
7119 /****************************************************************************
7121 ****************************************************************************/
7123 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7124 union spoolss_PortInfo **info_p,
7127 union spoolss_PortInfo *info = NULL;
7129 WERROR result = WERR_OK;
7130 char **qlines = NULL;
7133 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7134 if (!W_ERROR_IS_OK(result)) {
7139 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7141 DEBUG(10,("Returning WERR_NOMEM\n"));
7142 result = WERR_NOMEM;
7146 for (i=0; i<numlines; i++) {
7147 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7148 result = fill_port_2(info, &info[i].info2, qlines[i]);
7149 if (!W_ERROR_IS_OK(result)) {
7154 TALLOC_FREE(qlines);
7157 if (!W_ERROR_IS_OK(result)) {
7159 TALLOC_FREE(qlines);
7171 /****************************************************************
7173 ****************************************************************/
7175 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7176 struct spoolss_EnumPorts *r)
7180 /* that's an [in out] buffer */
7182 if (!r->in.buffer && (r->in.offered != 0)) {
7183 return WERR_INVALID_PARAM;
7186 DEBUG(4,("_spoolss_EnumPorts\n"));
7190 *r->out.info = NULL;
7192 switch (r->in.level) {
7194 result = enumports_level_1(p->mem_ctx, r->out.info,
7198 result = enumports_level_2(p->mem_ctx, r->out.info,
7202 return WERR_UNKNOWN_LEVEL;
7205 if (!W_ERROR_IS_OK(result)) {
7209 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7211 *r->out.info, r->in.level,
7213 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7214 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7216 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7219 /****************************************************************************
7220 ****************************************************************************/
7222 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7224 struct spoolss_SetPrinterInfoCtr *info_ctr,
7225 struct spoolss_DeviceMode *devmode,
7226 struct security_descriptor *secdesc,
7227 struct spoolss_UserLevelCtr *user_ctr,
7228 struct policy_handle *handle)
7230 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7231 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7233 WERROR err = WERR_OK;
7235 /* samba does not have a concept of local, non-shared printers yet, so
7236 * make sure we always setup sharename - gd */
7237 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7238 (info2->printername != NULL && info2->printername[0] != '\0')) {
7239 DEBUG(5, ("spoolss_addprinterex_level_2: "
7240 "no sharename has been set, setting printername %s as sharename\n",
7241 info2->printername));
7242 info2->sharename = info2->printername;
7245 /* check to see if the printer already exists */
7246 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7247 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7249 return WERR_PRINTER_ALREADY_EXISTS;
7252 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7253 if ((snum = print_queue_snum(info2->printername)) != -1) {
7254 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7255 info2->printername));
7256 return WERR_PRINTER_ALREADY_EXISTS;
7260 /* validate printer info struct */
7261 if (!info2->printername || strlen(info2->printername) == 0) {
7262 return WERR_INVALID_PRINTER_NAME;
7264 if (!info2->portname || strlen(info2->portname) == 0) {
7265 return WERR_UNKNOWN_PORT;
7267 if (!info2->drivername || strlen(info2->drivername) == 0) {
7268 return WERR_UNKNOWN_PRINTER_DRIVER;
7270 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7271 return WERR_UNKNOWN_PRINTPROCESSOR;
7274 /* FIXME!!! smbd should check to see if the driver is installed before
7275 trying to add a printer like this --jerry */
7277 if (*lp_addprinter_cmd() ) {
7278 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7279 info2, p->client_address,
7281 return WERR_ACCESS_DENIED;
7284 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7285 "smb.conf parameter \"addprinter command\" is defined. This"
7286 "parameter must exist for this call to succeed\n",
7287 info2->sharename ));
7290 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7291 return WERR_ACCESS_DENIED;
7294 /* you must be a printer admin to add a new printer */
7295 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7296 return WERR_ACCESS_DENIED;
7300 * Do sanity check on the requested changes for Samba.
7303 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7304 return WERR_INVALID_PARAM;
7307 if (devmode == NULL) {
7308 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7311 update_dsspooler(p->mem_ctx,
7317 err = winreg_update_printer(p->mem_ctx,
7325 if (!W_ERROR_IS_OK(err)) {
7329 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7330 /* Handle open failed - remove addition. */
7331 ZERO_STRUCTP(handle);
7332 return WERR_ACCESS_DENIED;
7338 /****************************************************************
7339 _spoolss_AddPrinterEx
7340 ****************************************************************/
7342 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7343 struct spoolss_AddPrinterEx *r)
7345 switch (r->in.info_ctr->level) {
7347 /* we don't handle yet */
7348 /* but I know what to do ... */
7349 return WERR_UNKNOWN_LEVEL;
7351 return spoolss_addprinterex_level_2(p, r->in.server,
7353 r->in.devmode_ctr->devmode,
7354 r->in.secdesc_ctr->sd,
7355 r->in.userlevel_ctr,
7358 return WERR_UNKNOWN_LEVEL;
7362 /****************************************************************
7364 ****************************************************************/
7366 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7367 struct spoolss_AddPrinter *r)
7369 struct spoolss_AddPrinterEx a;
7370 struct spoolss_UserLevelCtr userlevel_ctr;
7372 ZERO_STRUCT(userlevel_ctr);
7374 userlevel_ctr.level = 1;
7376 a.in.server = r->in.server;
7377 a.in.info_ctr = r->in.info_ctr;
7378 a.in.devmode_ctr = r->in.devmode_ctr;
7379 a.in.secdesc_ctr = r->in.secdesc_ctr;
7380 a.in.userlevel_ctr = &userlevel_ctr;
7381 a.out.handle = r->out.handle;
7383 return _spoolss_AddPrinterEx(p, &a);
7386 /****************************************************************
7387 _spoolss_AddPrinterDriverEx
7388 ****************************************************************/
7390 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7391 struct spoolss_AddPrinterDriverEx *r)
7393 WERROR err = WERR_OK;
7394 const char *driver_name = NULL;
7399 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7400 fn = "_spoolss_AddPrinterDriver";
7402 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7403 fn = "_spoolss_AddPrinterDriverEx";
7406 return WERR_INVALID_PARAM;
7410 * we only support the semantics of AddPrinterDriver()
7411 * i.e. only copy files that are newer than existing ones
7414 if (r->in.flags == 0) {
7415 return WERR_INVALID_PARAM;
7418 if (r->in.flags != APD_COPY_NEW_FILES) {
7419 return WERR_ACCESS_DENIED;
7423 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7424 /* Clever hack from Martin Zielinski <mz@seh.de>
7425 * to allow downgrade from level 8 (Vista).
7427 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7428 r->in.info_ctr->level));
7429 return WERR_UNKNOWN_LEVEL;
7432 DEBUG(5,("Cleaning driver's information\n"));
7433 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7434 if (!W_ERROR_IS_OK(err))
7437 DEBUG(5,("Moving driver to final destination\n"));
7438 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7443 err = winreg_add_driver(p->mem_ctx, p->server_info,
7444 r->in.info_ctr, &driver_name, &version);
7445 if (!W_ERROR_IS_OK(err)) {
7450 * I think this is where he DrvUpgradePrinter() hook would be
7451 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7452 * server. Right now, we just need to send ourselves a message
7453 * to update each printer bound to this driver. --jerry
7456 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7457 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7465 /****************************************************************
7466 _spoolss_AddPrinterDriver
7467 ****************************************************************/
7469 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7470 struct spoolss_AddPrinterDriver *r)
7472 struct spoolss_AddPrinterDriverEx a;
7474 switch (r->in.info_ctr->level) {
7481 return WERR_UNKNOWN_LEVEL;
7484 a.in.servername = r->in.servername;
7485 a.in.info_ctr = r->in.info_ctr;
7486 a.in.flags = APD_COPY_NEW_FILES;
7488 return _spoolss_AddPrinterDriverEx(p, &a);
7491 /****************************************************************************
7492 ****************************************************************************/
7494 struct _spoolss_paths {
7500 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7502 static const struct _spoolss_paths spoolss_paths[]= {
7503 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7504 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7507 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7508 const char *servername,
7509 const char *environment,
7513 const char *pservername = NULL;
7514 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7515 const char *short_archi;
7519 /* environment may be empty */
7520 if (environment && strlen(environment)) {
7521 long_archi = environment;
7524 /* servername may be empty */
7525 if (servername && strlen(servername)) {
7526 pservername = canon_servername(servername);
7528 if (!is_myname_or_ipaddr(pservername)) {
7529 return WERR_INVALID_PARAM;
7533 if (!(short_archi = get_short_archi(long_archi))) {
7534 return WERR_INVALID_ENVIRONMENT;
7537 switch (component) {
7538 case SPOOLSS_PRTPROCS_PATH:
7539 case SPOOLSS_DRIVER_PATH:
7541 *path = talloc_asprintf(mem_ctx,
7544 spoolss_paths[component].share,
7547 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7548 SPOOLSS_DEFAULT_SERVER_PATH,
7549 spoolss_paths[component].dir,
7554 return WERR_INVALID_PARAM;
7564 /****************************************************************************
7565 ****************************************************************************/
7567 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7568 const char *servername,
7569 const char *environment,
7570 struct spoolss_DriverDirectoryInfo1 *r)
7575 werr = compose_spoolss_server_path(mem_ctx,
7578 SPOOLSS_DRIVER_PATH,
7580 if (!W_ERROR_IS_OK(werr)) {
7584 DEBUG(4,("printer driver directory: [%s]\n", path));
7586 r->directory_name = path;
7591 /****************************************************************
7592 _spoolss_GetPrinterDriverDirectory
7593 ****************************************************************/
7595 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7596 struct spoolss_GetPrinterDriverDirectory *r)
7600 /* that's an [in out] buffer */
7602 if (!r->in.buffer && (r->in.offered != 0)) {
7603 return WERR_INVALID_PARAM;
7606 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7611 /* r->in.level is ignored */
7613 werror = getprinterdriverdir_level_1(p->mem_ctx,
7616 &r->out.info->info1);
7617 if (!W_ERROR_IS_OK(werror)) {
7618 TALLOC_FREE(r->out.info);
7622 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7623 r->out.info, r->in.level);
7624 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7626 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7629 /****************************************************************
7630 _spoolss_EnumPrinterData
7631 ****************************************************************/
7633 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7634 struct spoolss_EnumPrinterData *r)
7637 struct spoolss_EnumPrinterDataEx r2;
7639 struct spoolss_PrinterEnumValues *info, *val = NULL;
7642 r2.in.handle = r->in.handle;
7643 r2.in.key_name = "PrinterDriverData";
7645 r2.out.count = &count;
7646 r2.out.info = &info;
7647 r2.out.needed = &needed;
7649 result = _spoolss_EnumPrinterDataEx(p, &r2);
7650 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7651 r2.in.offered = needed;
7652 result = _spoolss_EnumPrinterDataEx(p, &r2);
7654 if (!W_ERROR_IS_OK(result)) {
7659 * The NT machine wants to know the biggest size of value and data
7661 * cf: MSDN EnumPrinterData remark section
7664 if (!r->in.value_offered && !r->in.data_offered) {
7665 uint32_t biggest_valuesize = 0;
7666 uint32_t biggest_datasize = 0;
7669 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7671 for (i=0; i<count; i++) {
7673 name_length = strlen(info[i].value_name);
7674 if (strlen(info[i].value_name) > biggest_valuesize) {
7675 biggest_valuesize = name_length;
7678 if (info[i].data_length > biggest_datasize) {
7679 biggest_datasize = info[i].data_length;
7682 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7686 /* the value is an UNICODE string but real_value_size is the length
7687 in bytes including the trailing 0 */
7689 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7690 *r->out.data_needed = biggest_datasize;
7692 DEBUG(6,("final values: [%d], [%d]\n",
7693 *r->out.value_needed, *r->out.data_needed));
7698 if (r->in.enum_index < count) {
7699 val = &info[r->in.enum_index];
7703 /* out_value should default to "" or else NT4 has
7704 problems unmarshalling the response */
7706 if (r->in.value_offered) {
7707 *r->out.value_needed = 1;
7708 r->out.value_name = talloc_strdup(r, "");
7709 if (!r->out.value_name) {
7713 r->out.value_name = NULL;
7714 *r->out.value_needed = 0;
7717 /* the data is counted in bytes */
7719 *r->out.data_needed = r->in.data_offered;
7721 result = WERR_NO_MORE_ITEMS;
7725 * - counted in bytes in the request
7726 * - counted in UNICODE chars in the max reply
7727 * - counted in bytes in the real size
7729 * take a pause *before* coding not *during* coding
7733 if (r->in.value_offered) {
7734 r->out.value_name = talloc_strdup(r, val->value_name);
7735 if (!r->out.value_name) {
7738 *r->out.value_needed = val->value_name_len;
7740 r->out.value_name = NULL;
7741 *r->out.value_needed = 0;
7746 *r->out.type = val->type;
7748 /* data - counted in bytes */
7751 * See the section "Dynamically Typed Query Parameters"
7755 if (r->out.data && val->data && val->data->data &&
7756 val->data_length && r->in.data_offered) {
7757 memcpy(r->out.data, val->data->data,
7758 MIN(val->data_length,r->in.data_offered));
7761 *r->out.data_needed = val->data_length;
7769 /****************************************************************
7770 _spoolss_SetPrinterData
7771 ****************************************************************/
7773 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7774 struct spoolss_SetPrinterData *r)
7776 struct spoolss_SetPrinterDataEx r2;
7778 r2.in.handle = r->in.handle;
7779 r2.in.key_name = "PrinterDriverData";
7780 r2.in.value_name = r->in.value_name;
7781 r2.in.type = r->in.type;
7782 r2.in.data = r->in.data;
7783 r2.in.offered = r->in.offered;
7785 return _spoolss_SetPrinterDataEx(p, &r2);
7788 /****************************************************************
7789 _spoolss_ResetPrinter
7790 ****************************************************************/
7792 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7793 struct spoolss_ResetPrinter *r)
7795 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7798 DEBUG(5,("_spoolss_ResetPrinter\n"));
7801 * All we do is to check to see if the handle and queue is valid.
7802 * This call really doesn't mean anything to us because we only
7803 * support RAW printing. --jerry
7807 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7808 OUR_HANDLE(r->in.handle)));
7812 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7816 /* blindly return success */
7820 /****************************************************************
7821 _spoolss_DeletePrinterData
7822 ****************************************************************/
7824 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7825 struct spoolss_DeletePrinterData *r)
7827 struct spoolss_DeletePrinterDataEx r2;
7829 r2.in.handle = r->in.handle;
7830 r2.in.key_name = "PrinterDriverData";
7831 r2.in.value_name = r->in.value_name;
7833 return _spoolss_DeletePrinterDataEx(p, &r2);
7836 /****************************************************************
7838 ****************************************************************/
7840 WERROR _spoolss_AddForm(struct pipes_struct *p,
7841 struct spoolss_AddForm *r)
7843 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7845 WERROR status = WERR_OK;
7846 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7848 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7850 DEBUG(5,("_spoolss_AddForm\n"));
7853 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7854 OUR_HANDLE(r->in.handle)));
7858 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7859 and not a printer admin, then fail */
7861 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7862 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7863 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7864 p->server_info->info3->base.domain.string,
7866 p->server_info->ptok,
7867 lp_printer_admin(snum))) {
7868 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7869 return WERR_ACCESS_DENIED;
7872 switch (form->flags) {
7873 case SPOOLSS_FORM_USER:
7874 case SPOOLSS_FORM_BUILTIN:
7875 case SPOOLSS_FORM_PRINTER:
7878 return WERR_INVALID_PARAM;
7881 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7882 if (!W_ERROR_IS_OK(status)) {
7887 * ChangeID must always be set if this is a printer
7889 if (Printer->printer_type == SPLHND_PRINTER) {
7890 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7894 status = winreg_printer_update_changeid(p->mem_ctx,
7896 lp_const_servicename(snum));
7897 if (!W_ERROR_IS_OK(status)) {
7905 /****************************************************************
7907 ****************************************************************/
7909 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7910 struct spoolss_DeleteForm *r)
7912 const char *form_name = r->in.form_name;
7913 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7915 WERROR status = WERR_OK;
7916 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7918 DEBUG(5,("_spoolss_DeleteForm\n"));
7921 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7922 OUR_HANDLE(r->in.handle)));
7926 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7927 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7928 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7929 p->server_info->info3->base.domain.string,
7931 p->server_info->ptok,
7932 lp_printer_admin(snum))) {
7933 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7934 return WERR_ACCESS_DENIED;
7937 status = winreg_printer_deleteform1(p->mem_ctx,
7940 if (!W_ERROR_IS_OK(status)) {
7945 * ChangeID must always be set if this is a printer
7947 if (Printer->printer_type == SPLHND_PRINTER) {
7948 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7952 status = winreg_printer_update_changeid(p->mem_ctx,
7954 lp_const_servicename(snum));
7955 if (!W_ERROR_IS_OK(status)) {
7963 /****************************************************************
7965 ****************************************************************/
7967 WERROR _spoolss_SetForm(struct pipes_struct *p,
7968 struct spoolss_SetForm *r)
7970 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7971 const char *form_name = r->in.form_name;
7973 WERROR status = WERR_OK;
7974 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7976 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7978 DEBUG(5,("_spoolss_SetForm\n"));
7981 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7982 OUR_HANDLE(r->in.handle)));
7986 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7987 and not a printer admin, then fail */
7989 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7990 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7991 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7992 p->server_info->info3->base.domain.string,
7994 p->server_info->ptok,
7995 lp_printer_admin(snum))) {
7996 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7997 return WERR_ACCESS_DENIED;
8000 status = winreg_printer_setform1(p->mem_ctx,
8004 if (!W_ERROR_IS_OK(status)) {
8009 * ChangeID must always be set if this is a printer
8011 if (Printer->printer_type == SPLHND_PRINTER) {
8012 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8016 status = winreg_printer_update_changeid(p->mem_ctx,
8018 lp_const_servicename(snum));
8019 if (!W_ERROR_IS_OK(status)) {
8027 /****************************************************************************
8028 fill_print_processor1
8029 ****************************************************************************/
8031 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8032 struct spoolss_PrintProcessorInfo1 *r,
8033 const char *print_processor_name)
8035 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8036 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8041 /****************************************************************************
8042 enumprintprocessors level 1.
8043 ****************************************************************************/
8045 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8046 union spoolss_PrintProcessorInfo **info_p,
8049 union spoolss_PrintProcessorInfo *info;
8052 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8053 W_ERROR_HAVE_NO_MEMORY(info);
8057 result = fill_print_processor1(info, &info[0].info1, "winprint");
8058 if (!W_ERROR_IS_OK(result)) {
8063 if (!W_ERROR_IS_OK(result)) {
8074 /****************************************************************
8075 _spoolss_EnumPrintProcessors
8076 ****************************************************************/
8078 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8079 struct spoolss_EnumPrintProcessors *r)
8083 /* that's an [in out] buffer */
8085 if (!r->in.buffer && (r->in.offered != 0)) {
8086 return WERR_INVALID_PARAM;
8089 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8092 * Enumerate the print processors ...
8094 * Just reply with "winprint", to keep NT happy
8095 * and I can use my nice printer checker.
8100 *r->out.info = NULL;
8102 switch (r->in.level) {
8104 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8108 return WERR_UNKNOWN_LEVEL;
8111 if (!W_ERROR_IS_OK(result)) {
8115 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8116 spoolss_EnumPrintProcessors,
8117 *r->out.info, r->in.level,
8119 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8120 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8122 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8125 /****************************************************************************
8126 fill_printprocdatatype1
8127 ****************************************************************************/
8129 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8130 struct spoolss_PrintProcDataTypesInfo1 *r,
8131 const char *name_array)
8133 r->name_array = talloc_strdup(mem_ctx, name_array);
8134 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8139 /****************************************************************************
8140 enumprintprocdatatypes level 1.
8141 ****************************************************************************/
8143 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8144 union spoolss_PrintProcDataTypesInfo **info_p,
8148 union spoolss_PrintProcDataTypesInfo *info;
8150 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8151 W_ERROR_HAVE_NO_MEMORY(info);
8155 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8156 if (!W_ERROR_IS_OK(result)) {
8161 if (!W_ERROR_IS_OK(result)) {
8172 /****************************************************************
8173 _spoolss_EnumPrintProcDataTypes
8174 ****************************************************************/
8176 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8177 struct spoolss_EnumPrintProcDataTypes *r)
8181 /* that's an [in out] buffer */
8183 if (!r->in.buffer && (r->in.offered != 0)) {
8184 return WERR_INVALID_PARAM;
8187 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8191 *r->out.info = NULL;
8193 switch (r->in.level) {
8195 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8199 return WERR_UNKNOWN_LEVEL;
8202 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8203 spoolss_EnumPrintProcDataTypes,
8204 *r->out.info, r->in.level,
8206 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8207 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8209 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8212 /****************************************************************************
8214 ****************************************************************************/
8216 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8217 struct spoolss_MonitorInfo1 *r,
8218 const char *monitor_name)
8220 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8221 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8226 /****************************************************************************
8228 ****************************************************************************/
8230 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8231 struct spoolss_MonitorInfo2 *r,
8232 const char *monitor_name,
8233 const char *environment,
8234 const char *dll_name)
8236 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8237 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8238 r->environment = talloc_strdup(mem_ctx, environment);
8239 W_ERROR_HAVE_NO_MEMORY(r->environment);
8240 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8241 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8246 /****************************************************************************
8247 enumprintmonitors level 1.
8248 ****************************************************************************/
8250 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8251 union spoolss_MonitorInfo **info_p,
8254 union spoolss_MonitorInfo *info;
8255 WERROR result = WERR_OK;
8257 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8258 W_ERROR_HAVE_NO_MEMORY(info);
8262 result = fill_monitor_1(info, &info[0].info1,
8264 if (!W_ERROR_IS_OK(result)) {
8268 result = fill_monitor_1(info, &info[1].info1,
8270 if (!W_ERROR_IS_OK(result)) {
8275 if (!W_ERROR_IS_OK(result)) {
8286 /****************************************************************************
8287 enumprintmonitors level 2.
8288 ****************************************************************************/
8290 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8291 union spoolss_MonitorInfo **info_p,
8294 union spoolss_MonitorInfo *info;
8295 WERROR result = WERR_OK;
8297 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8298 W_ERROR_HAVE_NO_MEMORY(info);
8302 result = fill_monitor_2(info, &info[0].info2,
8304 "Windows NT X86", /* FIXME */
8306 if (!W_ERROR_IS_OK(result)) {
8310 result = fill_monitor_2(info, &info[1].info2,
8312 "Windows NT X86", /* FIXME */
8314 if (!W_ERROR_IS_OK(result)) {
8319 if (!W_ERROR_IS_OK(result)) {
8330 /****************************************************************
8331 _spoolss_EnumMonitors
8332 ****************************************************************/
8334 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8335 struct spoolss_EnumMonitors *r)
8339 /* that's an [in out] buffer */
8341 if (!r->in.buffer && (r->in.offered != 0)) {
8342 return WERR_INVALID_PARAM;
8345 DEBUG(5,("_spoolss_EnumMonitors\n"));
8348 * Enumerate the print monitors ...
8350 * Just reply with "Local Port", to keep NT happy
8351 * and I can use my nice printer checker.
8356 *r->out.info = NULL;
8358 switch (r->in.level) {
8360 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8364 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8368 return WERR_UNKNOWN_LEVEL;
8371 if (!W_ERROR_IS_OK(result)) {
8375 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8376 spoolss_EnumMonitors,
8377 *r->out.info, r->in.level,
8379 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8380 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8382 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8385 /****************************************************************************
8386 ****************************************************************************/
8388 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8389 const print_queue_struct *queue,
8390 int count, int snum,
8391 struct spoolss_PrinterInfo2 *pinfo2,
8393 struct spoolss_JobInfo1 *r)
8398 for (i=0; i<count; i++) {
8399 if (queue[i].job == (int)jobid) {
8405 if (found == false) {
8406 /* NT treats not found as bad param... yet another bad choice */
8407 return WERR_INVALID_PARAM;
8410 return fill_job_info1(mem_ctx,
8418 /****************************************************************************
8419 ****************************************************************************/
8421 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8422 const print_queue_struct *queue,
8423 int count, int snum,
8424 struct spoolss_PrinterInfo2 *pinfo2,
8426 struct spoolss_JobInfo2 *r)
8430 struct spoolss_DeviceMode *devmode;
8433 for (i=0; i<count; i++) {
8434 if (queue[i].job == (int)jobid) {
8440 if (found == false) {
8441 /* NT treats not found as bad param... yet another bad
8443 return WERR_INVALID_PARAM;
8447 * if the print job does not have a DEVMODE associated with it,
8448 * just use the one for the printer. A NULL devicemode is not
8449 * a failure condition
8452 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8454 result = spoolss_create_default_devmode(mem_ctx,
8455 pinfo2->printername,
8457 if (!W_ERROR_IS_OK(result)) {
8458 DEBUG(3, ("Can't proceed w/o a devmode!"));
8463 return fill_job_info2(mem_ctx,
8472 /****************************************************************
8474 ****************************************************************/
8476 WERROR _spoolss_GetJob(struct pipes_struct *p,
8477 struct spoolss_GetJob *r)
8479 WERROR result = WERR_OK;
8480 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8483 print_queue_struct *queue = NULL;
8484 print_status_struct prt_status;
8486 /* that's an [in out] buffer */
8488 if (!r->in.buffer && (r->in.offered != 0)) {
8489 return WERR_INVALID_PARAM;
8492 DEBUG(5,("_spoolss_GetJob\n"));
8496 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8500 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8501 lp_servicename(snum), &pinfo2);
8502 if (!W_ERROR_IS_OK(result)) {
8506 count = print_queue_status(snum, &queue, &prt_status);
8508 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8509 count, prt_status.status, prt_status.message));
8511 switch (r->in.level) {
8513 result = getjob_level_1(p->mem_ctx,
8514 queue, count, snum, pinfo2,
8515 r->in.job_id, &r->out.info->info1);
8518 result = getjob_level_2(p->mem_ctx,
8519 queue, count, snum, pinfo2,
8520 r->in.job_id, &r->out.info->info2);
8523 result = WERR_UNKNOWN_LEVEL;
8528 TALLOC_FREE(pinfo2);
8530 if (!W_ERROR_IS_OK(result)) {
8531 TALLOC_FREE(r->out.info);
8535 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8537 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8539 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8542 /****************************************************************
8543 _spoolss_GetPrinterDataEx
8544 ****************************************************************/
8546 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8547 struct spoolss_GetPrinterDataEx *r)
8550 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8551 const char *printer;
8553 WERROR result = WERR_OK;
8555 enum winreg_Type val_type;
8560 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8562 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8563 r->in.key_name, r->in.value_name));
8565 /* in case of problem, return some default values */
8568 *r->out.type = REG_NONE;
8571 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8572 OUR_HANDLE(r->in.handle)));
8573 result = WERR_BADFID;
8577 /* Is the handle to a printer or to the server? */
8579 if (Printer->printer_type == SPLHND_SERVER) {
8581 union spoolss_PrinterData data;
8583 result = getprinterdata_printer_server(p->mem_ctx,
8587 if (!W_ERROR_IS_OK(result)) {
8591 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8592 *r->out.type, &data);
8593 if (!W_ERROR_IS_OK(result)) {
8597 *r->out.needed = blob.length;
8599 if (r->in.offered >= *r->out.needed) {
8600 memcpy(r->out.data, blob.data, blob.length);
8603 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8606 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8609 printer = lp_const_servicename(snum);
8611 /* check to see if the keyname is valid */
8612 if (!strlen(r->in.key_name)) {
8613 return WERR_INVALID_PARAM;
8616 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8617 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8618 strequal(r->in.value_name, "ChangeId")) {
8619 *r->out.type = REG_DWORD;
8621 if (r->in.offered >= *r->out.needed) {
8622 uint32_t changeid = 0;
8624 result = winreg_printer_get_changeid(p->mem_ctx,
8628 if (!W_ERROR_IS_OK(result)) {
8632 SIVAL(r->out.data, 0, changeid);
8638 result = winreg_get_printer_dataex(p->mem_ctx,
8646 if (!W_ERROR_IS_OK(result)) {
8650 *r->out.needed = val_size;
8651 *r->out.type = val_type;
8653 if (r->in.offered >= *r->out.needed) {
8654 memcpy(r->out.data, val_data, val_size);
8658 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8659 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8661 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8664 /****************************************************************
8665 _spoolss_SetPrinterDataEx
8666 ****************************************************************/
8668 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8669 struct spoolss_SetPrinterDataEx *r)
8671 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8673 WERROR result = WERR_OK;
8674 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8677 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8679 /* From MSDN documentation of SetPrinterDataEx: pass request to
8680 SetPrinterData if key is "PrinterDriverData" */
8683 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8684 OUR_HANDLE(r->in.handle)));
8688 if (Printer->printer_type == SPLHND_SERVER) {
8689 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8690 "Not implemented for server handles yet\n"));
8691 return WERR_INVALID_PARAM;
8694 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8699 * Access check : NT returns "access denied" if you make a
8700 * SetPrinterData call without the necessary privildge.
8701 * we were originally returning OK if nothing changed
8702 * which made Win2k issue **a lot** of SetPrinterData
8703 * when connecting to a printer --jerry
8706 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8707 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8708 "change denied by handle access permissions\n"));
8709 return WERR_ACCESS_DENIED;
8712 result = winreg_get_printer(Printer, p->server_info,
8713 Printer->servername,
8714 lp_servicename(snum),
8716 if (!W_ERROR_IS_OK(result)) {
8720 /* check for OID in valuename */
8722 oid_string = strchr(r->in.value_name, ',');
8728 /* save the registry data */
8730 result = winreg_set_printer_dataex(p->mem_ctx,
8739 if (W_ERROR_IS_OK(result)) {
8740 /* save the OID if one was specified */
8742 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8743 r->in.key_name, SPOOL_OID_KEY);
8745 result = WERR_NOMEM;
8750 * I'm not checking the status here on purpose. Don't know
8751 * if this is right, but I'm returning the status from the
8752 * previous set_printer_dataex() call. I have no idea if
8753 * this is right. --jerry
8755 winreg_set_printer_dataex(p->mem_ctx,
8761 (uint8_t *) oid_string,
8762 strlen(oid_string) + 1);
8765 result = winreg_printer_update_changeid(p->mem_ctx,
8767 lp_const_servicename(snum));
8772 talloc_free(pinfo2);
8776 /****************************************************************
8777 _spoolss_DeletePrinterDataEx
8778 ****************************************************************/
8780 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8781 struct spoolss_DeletePrinterDataEx *r)
8783 const char *printer;
8785 WERROR status = WERR_OK;
8786 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8788 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8791 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8792 "Invalid handle (%s:%u:%u).\n",
8793 OUR_HANDLE(r->in.handle)));
8797 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8798 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8799 "printer properties change denied by handle\n"));
8800 return WERR_ACCESS_DENIED;
8803 if (!r->in.value_name || !r->in.key_name) {
8807 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8810 printer = lp_const_servicename(snum);
8812 status = winreg_delete_printer_dataex(p->mem_ctx,
8817 if (W_ERROR_IS_OK(status)) {
8818 status = winreg_printer_update_changeid(p->mem_ctx,
8826 /****************************************************************
8827 _spoolss_EnumPrinterKey
8828 ****************************************************************/
8830 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8831 struct spoolss_EnumPrinterKey *r)
8834 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8836 WERROR result = WERR_BADFILE;
8837 const char **array = NULL;
8840 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8843 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8844 OUR_HANDLE(r->in.handle)));
8848 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8852 result = winreg_enum_printer_key(p->mem_ctx,
8854 lp_const_servicename(snum),
8858 if (!W_ERROR_IS_OK(result)) {
8862 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8863 result = WERR_NOMEM;
8867 *r->out._ndr_size = r->in.offered / 2;
8868 *r->out.needed = blob.length;
8870 if (r->in.offered < *r->out.needed) {
8871 result = WERR_MORE_DATA;
8874 r->out.key_buffer->string_array = array;
8878 if (!W_ERROR_IS_OK(result)) {
8880 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8888 /****************************************************************
8889 _spoolss_DeletePrinterKey
8890 ****************************************************************/
8892 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8893 struct spoolss_DeletePrinterKey *r)
8895 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8898 const char *printer;
8900 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8903 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8904 OUR_HANDLE(r->in.handle)));
8908 /* if keyname == NULL, return error */
8909 if ( !r->in.key_name )
8910 return WERR_INVALID_PARAM;
8912 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8916 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8917 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8918 "printer properties change denied by handle\n"));
8919 return WERR_ACCESS_DENIED;
8922 printer = lp_const_servicename(snum);
8924 /* delete the key and all subkeys */
8925 status = winreg_delete_printer_key(p->mem_ctx,
8929 if (W_ERROR_IS_OK(status)) {
8930 status = winreg_printer_update_changeid(p->mem_ctx,
8938 /****************************************************************
8939 _spoolss_EnumPrinterDataEx
8940 ****************************************************************/
8942 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8943 struct spoolss_EnumPrinterDataEx *r)
8946 struct spoolss_PrinterEnumValues *info = NULL;
8947 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8951 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8955 *r->out.info = NULL;
8958 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8959 OUR_HANDLE(r->in.handle)));
8964 * first check for a keyname of NULL or "". Win2k seems to send
8965 * this a lot and we should send back WERR_INVALID_PARAM
8966 * no need to spend time looking up the printer in this case.
8970 if (!strlen(r->in.key_name)) {
8971 result = WERR_INVALID_PARAM;
8975 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8979 /* now look for a match on the key name */
8980 result = winreg_enum_printer_dataex(p->mem_ctx,
8982 lp_const_servicename(snum),
8986 if (!W_ERROR_IS_OK(result)) {
8990 #if 0 /* FIXME - gd */
8991 /* housekeeping information in the reply */
8993 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8994 * the hand marshalled container size is a multiple
8995 * of 4 bytes for RPC alignment.
8999 needed += 4-(needed % 4);
9002 *r->out.count = count;
9003 *r->out.info = info;
9006 if (!W_ERROR_IS_OK(result)) {
9010 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9011 spoolss_EnumPrinterDataEx,
9014 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9015 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9017 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9020 /****************************************************************************
9021 ****************************************************************************/
9023 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9024 const char *servername,
9025 const char *environment,
9026 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9031 werr = compose_spoolss_server_path(mem_ctx,
9034 SPOOLSS_PRTPROCS_PATH,
9036 if (!W_ERROR_IS_OK(werr)) {
9040 DEBUG(4,("print processor directory: [%s]\n", path));
9042 r->directory_name = path;
9047 /****************************************************************
9048 _spoolss_GetPrintProcessorDirectory
9049 ****************************************************************/
9051 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9052 struct spoolss_GetPrintProcessorDirectory *r)
9056 /* that's an [in out] buffer */
9058 if (!r->in.buffer && (r->in.offered != 0)) {
9059 return WERR_INVALID_PARAM;
9062 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9067 /* r->in.level is ignored */
9069 /* We always should reply with a local print processor directory so that
9070 * users are not forced to have a [prnproc$] share on the Samba spoolss
9071 * server - Guenther */
9073 result = getprintprocessordirectory_level_1(p->mem_ctx,
9074 NULL, /* r->in.server */
9076 &r->out.info->info1);
9077 if (!W_ERROR_IS_OK(result)) {
9078 TALLOC_FREE(r->out.info);
9082 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9083 r->out.info, r->in.level);
9084 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9086 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9089 /*******************************************************************
9090 ********************************************************************/
9092 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9093 const char *dllname)
9095 enum ndr_err_code ndr_err;
9096 struct spoolss_MonitorUi ui;
9098 ui.dll_name = dllname;
9100 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9101 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9102 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9103 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9105 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9108 /*******************************************************************
9109 Streams the monitor UI DLL name in UNICODE
9110 *******************************************************************/
9112 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9113 NT_USER_TOKEN *token, DATA_BLOB *in,
9114 DATA_BLOB *out, uint32_t *needed)
9116 const char *dllname = "tcpmonui.dll";
9118 *needed = (strlen(dllname)+1) * 2;
9120 if (out->length < *needed) {
9121 return WERR_INSUFFICIENT_BUFFER;
9124 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9131 /*******************************************************************
9132 ********************************************************************/
9134 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9135 struct spoolss_PortData1 *port1,
9136 const DATA_BLOB *buf)
9138 enum ndr_err_code ndr_err;
9139 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9140 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9141 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9142 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9144 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9147 /*******************************************************************
9148 ********************************************************************/
9150 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9151 struct spoolss_PortData2 *port2,
9152 const DATA_BLOB *buf)
9154 enum ndr_err_code ndr_err;
9155 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9156 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9157 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9158 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9160 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9163 /*******************************************************************
9164 Create a new TCP/IP port
9165 *******************************************************************/
9167 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9168 NT_USER_TOKEN *token, DATA_BLOB *in,
9169 DATA_BLOB *out, uint32_t *needed)
9171 struct spoolss_PortData1 port1;
9172 struct spoolss_PortData2 port2;
9173 char *device_uri = NULL;
9176 const char *portname;
9177 const char *hostaddress;
9179 uint32_t port_number;
9182 /* peek for spoolss_PortData version */
9184 if (!in || (in->length < (128 + 4))) {
9185 return WERR_GENERAL_FAILURE;
9188 version = IVAL(in->data, 128);
9194 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9198 portname = port1.portname;
9199 hostaddress = port1.hostaddress;
9200 queue = port1.queue;
9201 protocol = port1.protocol;
9202 port_number = port1.port_number;
9208 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9212 portname = port2.portname;
9213 hostaddress = port2.hostaddress;
9214 queue = port2.queue;
9215 protocol = port2.protocol;
9216 port_number = port2.port_number;
9220 DEBUG(1,("xcvtcp_addport: "
9221 "unknown version of port_data: %d\n", version));
9222 return WERR_UNKNOWN_PORT;
9225 /* create the device URI and call the add_port_hook() */
9228 case PROTOCOL_RAWTCP_TYPE:
9229 device_uri = talloc_asprintf(mem_ctx,
9230 "socket://%s:%d/", hostaddress,
9234 case PROTOCOL_LPR_TYPE:
9235 device_uri = talloc_asprintf(mem_ctx,
9236 "lpr://%s/%s", hostaddress, queue );
9240 return WERR_UNKNOWN_PORT;
9247 return add_port_hook(mem_ctx, token, portname, device_uri);
9250 /*******************************************************************
9251 *******************************************************************/
9253 struct xcv_api_table xcvtcp_cmds[] = {
9254 { "MonitorUI", xcvtcp_monitorui },
9255 { "AddPort", xcvtcp_addport},
9259 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9260 NT_USER_TOKEN *token, const char *command,
9267 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9269 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9270 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9271 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9274 return WERR_BADFUNC;
9277 /*******************************************************************
9278 *******************************************************************/
9279 #if 0 /* don't support management using the "Local Port" monitor */
9281 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9282 NT_USER_TOKEN *token, DATA_BLOB *in,
9283 DATA_BLOB *out, uint32_t *needed)
9285 const char *dllname = "localui.dll";
9287 *needed = (strlen(dllname)+1) * 2;
9289 if (out->length < *needed) {
9290 return WERR_INSUFFICIENT_BUFFER;
9293 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9300 /*******************************************************************
9301 *******************************************************************/
9303 struct xcv_api_table xcvlocal_cmds[] = {
9304 { "MonitorUI", xcvlocal_monitorui },
9308 struct xcv_api_table xcvlocal_cmds[] = {
9315 /*******************************************************************
9316 *******************************************************************/
9318 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9319 NT_USER_TOKEN *token, const char *command,
9320 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9325 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9327 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9328 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9329 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9331 return WERR_BADFUNC;
9334 /****************************************************************
9336 ****************************************************************/
9338 WERROR _spoolss_XcvData(struct pipes_struct *p,
9339 struct spoolss_XcvData *r)
9341 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9342 DATA_BLOB out_data = data_blob_null;
9346 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9347 OUR_HANDLE(r->in.handle)));
9351 /* Has to be a handle to the TCP/IP port monitor */
9353 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9354 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9358 /* requires administrative access to the server */
9360 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9361 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9362 return WERR_ACCESS_DENIED;
9365 /* Allocate the outgoing buffer */
9367 if (r->in.out_data_size) {
9368 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9369 if (out_data.data == NULL) {
9374 switch ( Printer->printer_type ) {
9375 case SPLHND_PORTMON_TCP:
9376 werror = process_xcvtcp_command(p->mem_ctx,
9377 p->server_info->ptok,
9378 r->in.function_name,
9379 &r->in.in_data, &out_data,
9382 case SPLHND_PORTMON_LOCAL:
9383 werror = process_xcvlocal_command(p->mem_ctx,
9384 p->server_info->ptok,
9385 r->in.function_name,
9386 &r->in.in_data, &out_data,
9390 werror = WERR_INVALID_PRINT_MONITOR;
9393 if (!W_ERROR_IS_OK(werror)) {
9397 *r->out.status_code = 0;
9399 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9400 memcpy(r->out.out_data, out_data.data,
9401 MIN(r->in.out_data_size, out_data.length));
9407 /****************************************************************
9408 _spoolss_AddPrintProcessor
9409 ****************************************************************/
9411 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9412 struct spoolss_AddPrintProcessor *r)
9414 /* for now, just indicate success and ignore the add. We'll
9415 automatically set the winprint processor for printer
9416 entries later. Used to debug the LexMark Optra S 1855 PCL
9422 /****************************************************************
9424 ****************************************************************/
9426 WERROR _spoolss_AddPort(struct pipes_struct *p,
9427 struct spoolss_AddPort *r)
9429 /* do what w2k3 does */
9431 return WERR_NOT_SUPPORTED;
9434 /****************************************************************
9435 _spoolss_GetPrinterDriver
9436 ****************************************************************/
9438 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9439 struct spoolss_GetPrinterDriver *r)
9441 p->rng_fault_state = true;
9442 return WERR_NOT_SUPPORTED;
9445 /****************************************************************
9446 _spoolss_ReadPrinter
9447 ****************************************************************/
9449 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9450 struct spoolss_ReadPrinter *r)
9452 p->rng_fault_state = true;
9453 return WERR_NOT_SUPPORTED;
9456 /****************************************************************
9457 _spoolss_WaitForPrinterChange
9458 ****************************************************************/
9460 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9461 struct spoolss_WaitForPrinterChange *r)
9463 p->rng_fault_state = true;
9464 return WERR_NOT_SUPPORTED;
9467 /****************************************************************
9468 _spoolss_ConfigurePort
9469 ****************************************************************/
9471 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9472 struct spoolss_ConfigurePort *r)
9474 p->rng_fault_state = true;
9475 return WERR_NOT_SUPPORTED;
9478 /****************************************************************
9480 ****************************************************************/
9482 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9483 struct spoolss_DeletePort *r)
9485 p->rng_fault_state = true;
9486 return WERR_NOT_SUPPORTED;
9489 /****************************************************************
9490 _spoolss_CreatePrinterIC
9491 ****************************************************************/
9493 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9494 struct spoolss_CreatePrinterIC *r)
9496 p->rng_fault_state = true;
9497 return WERR_NOT_SUPPORTED;
9500 /****************************************************************
9501 _spoolss_PlayGDIScriptOnPrinterIC
9502 ****************************************************************/
9504 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9505 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9507 p->rng_fault_state = true;
9508 return WERR_NOT_SUPPORTED;
9511 /****************************************************************
9512 _spoolss_DeletePrinterIC
9513 ****************************************************************/
9515 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9516 struct spoolss_DeletePrinterIC *r)
9518 p->rng_fault_state = true;
9519 return WERR_NOT_SUPPORTED;
9522 /****************************************************************
9523 _spoolss_AddPrinterConnection
9524 ****************************************************************/
9526 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9527 struct spoolss_AddPrinterConnection *r)
9529 p->rng_fault_state = true;
9530 return WERR_NOT_SUPPORTED;
9533 /****************************************************************
9534 _spoolss_DeletePrinterConnection
9535 ****************************************************************/
9537 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9538 struct spoolss_DeletePrinterConnection *r)
9540 p->rng_fault_state = true;
9541 return WERR_NOT_SUPPORTED;
9544 /****************************************************************
9545 _spoolss_PrinterMessageBox
9546 ****************************************************************/
9548 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9549 struct spoolss_PrinterMessageBox *r)
9551 p->rng_fault_state = true;
9552 return WERR_NOT_SUPPORTED;
9555 /****************************************************************
9557 ****************************************************************/
9559 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9560 struct spoolss_AddMonitor *r)
9562 p->rng_fault_state = true;
9563 return WERR_NOT_SUPPORTED;
9566 /****************************************************************
9567 _spoolss_DeleteMonitor
9568 ****************************************************************/
9570 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9571 struct spoolss_DeleteMonitor *r)
9573 p->rng_fault_state = true;
9574 return WERR_NOT_SUPPORTED;
9577 /****************************************************************
9578 _spoolss_DeletePrintProcessor
9579 ****************************************************************/
9581 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9582 struct spoolss_DeletePrintProcessor *r)
9584 p->rng_fault_state = true;
9585 return WERR_NOT_SUPPORTED;
9588 /****************************************************************
9589 _spoolss_AddPrintProvidor
9590 ****************************************************************/
9592 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9593 struct spoolss_AddPrintProvidor *r)
9595 p->rng_fault_state = true;
9596 return WERR_NOT_SUPPORTED;
9599 /****************************************************************
9600 _spoolss_DeletePrintProvidor
9601 ****************************************************************/
9603 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9604 struct spoolss_DeletePrintProvidor *r)
9606 p->rng_fault_state = true;
9607 return WERR_NOT_SUPPORTED;
9610 /****************************************************************
9611 _spoolss_FindFirstPrinterChangeNotification
9612 ****************************************************************/
9614 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9615 struct spoolss_FindFirstPrinterChangeNotification *r)
9617 p->rng_fault_state = true;
9618 return WERR_NOT_SUPPORTED;
9621 /****************************************************************
9622 _spoolss_FindNextPrinterChangeNotification
9623 ****************************************************************/
9625 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9626 struct spoolss_FindNextPrinterChangeNotification *r)
9628 p->rng_fault_state = true;
9629 return WERR_NOT_SUPPORTED;
9632 /****************************************************************
9633 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9634 ****************************************************************/
9636 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9637 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9639 p->rng_fault_state = true;
9640 return WERR_NOT_SUPPORTED;
9643 /****************************************************************
9644 _spoolss_ReplyOpenPrinter
9645 ****************************************************************/
9647 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9648 struct spoolss_ReplyOpenPrinter *r)
9650 p->rng_fault_state = true;
9651 return WERR_NOT_SUPPORTED;
9654 /****************************************************************
9655 _spoolss_RouterReplyPrinter
9656 ****************************************************************/
9658 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9659 struct spoolss_RouterReplyPrinter *r)
9661 p->rng_fault_state = true;
9662 return WERR_NOT_SUPPORTED;
9665 /****************************************************************
9666 _spoolss_ReplyClosePrinter
9667 ****************************************************************/
9669 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9670 struct spoolss_ReplyClosePrinter *r)
9672 p->rng_fault_state = true;
9673 return WERR_NOT_SUPPORTED;
9676 /****************************************************************
9678 ****************************************************************/
9680 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9681 struct spoolss_AddPortEx *r)
9683 p->rng_fault_state = true;
9684 return WERR_NOT_SUPPORTED;
9687 /****************************************************************
9688 _spoolss_RouterFindFirstPrinterChangeNotification
9689 ****************************************************************/
9691 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9692 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9694 p->rng_fault_state = true;
9695 return WERR_NOT_SUPPORTED;
9698 /****************************************************************
9699 _spoolss_SpoolerInit
9700 ****************************************************************/
9702 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9703 struct spoolss_SpoolerInit *r)
9705 p->rng_fault_state = true;
9706 return WERR_NOT_SUPPORTED;
9709 /****************************************************************
9710 _spoolss_ResetPrinterEx
9711 ****************************************************************/
9713 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9714 struct spoolss_ResetPrinterEx *r)
9716 p->rng_fault_state = true;
9717 return WERR_NOT_SUPPORTED;
9720 /****************************************************************
9721 _spoolss_RouterReplyPrinterEx
9722 ****************************************************************/
9724 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9725 struct spoolss_RouterReplyPrinterEx *r)
9727 p->rng_fault_state = true;
9728 return WERR_NOT_SUPPORTED;
9731 /****************************************************************
9733 ****************************************************************/
9735 WERROR _spoolss_44(struct pipes_struct *p,
9736 struct spoolss_44 *r)
9738 p->rng_fault_state = true;
9739 return WERR_NOT_SUPPORTED;
9742 /****************************************************************
9744 ****************************************************************/
9746 WERROR _spoolss_47(struct pipes_struct *p,
9747 struct spoolss_47 *r)
9749 p->rng_fault_state = true;
9750 return WERR_NOT_SUPPORTED;
9753 /****************************************************************
9755 ****************************************************************/
9757 WERROR _spoolss_4a(struct pipes_struct *p,
9758 struct spoolss_4a *r)
9760 p->rng_fault_state = true;
9761 return WERR_NOT_SUPPORTED;
9764 /****************************************************************
9766 ****************************************************************/
9768 WERROR _spoolss_4b(struct pipes_struct *p,
9769 struct spoolss_4b *r)
9771 p->rng_fault_state = true;
9772 return WERR_NOT_SUPPORTED;
9775 /****************************************************************
9777 ****************************************************************/
9779 WERROR _spoolss_4c(struct pipes_struct *p,
9780 struct spoolss_4c *r)
9782 p->rng_fault_state = true;
9783 return WERR_NOT_SUPPORTED;
9786 /****************************************************************
9788 ****************************************************************/
9790 WERROR _spoolss_53(struct pipes_struct *p,
9791 struct spoolss_53 *r)
9793 p->rng_fault_state = true;
9794 return WERR_NOT_SUPPORTED;
9797 /****************************************************************
9799 ****************************************************************/
9801 WERROR _spoolss_55(struct pipes_struct *p,
9802 struct spoolss_55 *r)
9804 p->rng_fault_state = true;
9805 return WERR_NOT_SUPPORTED;
9808 /****************************************************************
9810 ****************************************************************/
9812 WERROR _spoolss_56(struct pipes_struct *p,
9813 struct spoolss_56 *r)
9815 p->rng_fault_state = true;
9816 return WERR_NOT_SUPPORTED;
9819 /****************************************************************
9821 ****************************************************************/
9823 WERROR _spoolss_57(struct pipes_struct *p,
9824 struct spoolss_57 *r)
9826 p->rng_fault_state = true;
9827 return WERR_NOT_SUPPORTED;
9830 /****************************************************************
9832 ****************************************************************/
9834 WERROR _spoolss_5a(struct pipes_struct *p,
9835 struct spoolss_5a *r)
9837 p->rng_fault_state = true;
9838 return WERR_NOT_SUPPORTED;
9841 /****************************************************************
9843 ****************************************************************/
9845 WERROR _spoolss_5b(struct pipes_struct *p,
9846 struct spoolss_5b *r)
9848 p->rng_fault_state = true;
9849 return WERR_NOT_SUPPORTED;
9852 /****************************************************************
9854 ****************************************************************/
9856 WERROR _spoolss_5c(struct pipes_struct *p,
9857 struct spoolss_5c *r)
9859 p->rng_fault_state = true;
9860 return WERR_NOT_SUPPORTED;
9863 /****************************************************************
9865 ****************************************************************/
9867 WERROR _spoolss_5d(struct pipes_struct *p,
9868 struct spoolss_5d *r)
9870 p->rng_fault_state = true;
9871 return WERR_NOT_SUPPORTED;
9874 /****************************************************************
9876 ****************************************************************/
9878 WERROR _spoolss_5e(struct pipes_struct *p,
9879 struct spoolss_5e *r)
9881 p->rng_fault_state = true;
9882 return WERR_NOT_SUPPORTED;
9885 /****************************************************************
9887 ****************************************************************/
9889 WERROR _spoolss_5f(struct pipes_struct *p,
9890 struct spoolss_5f *r)
9892 p->rng_fault_state = true;
9893 return WERR_NOT_SUPPORTED;
9896 /****************************************************************
9898 ****************************************************************/
9900 WERROR _spoolss_60(struct pipes_struct *p,
9901 struct spoolss_60 *r)
9903 p->rng_fault_state = true;
9904 return WERR_NOT_SUPPORTED;
9907 /****************************************************************
9909 ****************************************************************/
9911 WERROR _spoolss_61(struct pipes_struct *p,
9912 struct spoolss_61 *r)
9914 p->rng_fault_state = true;
9915 return WERR_NOT_SUPPORTED;
9918 /****************************************************************
9920 ****************************************************************/
9922 WERROR _spoolss_62(struct pipes_struct *p,
9923 struct spoolss_62 *r)
9925 p->rng_fault_state = true;
9926 return WERR_NOT_SUPPORTED;
9929 /****************************************************************
9931 ****************************************************************/
9933 WERROR _spoolss_63(struct pipes_struct *p,
9934 struct spoolss_63 *r)
9936 p->rng_fault_state = true;
9937 return WERR_NOT_SUPPORTED;
9940 /****************************************************************
9942 ****************************************************************/
9944 WERROR _spoolss_64(struct pipes_struct *p,
9945 struct spoolss_64 *r)
9947 p->rng_fault_state = true;
9948 return WERR_NOT_SUPPORTED;
9951 /****************************************************************
9953 ****************************************************************/
9955 WERROR _spoolss_65(struct pipes_struct *p,
9956 struct spoolss_65 *r)
9958 p->rng_fault_state = true;
9959 return WERR_NOT_SUPPORTED;
9962 /****************************************************************
9963 _spoolss_GetCorePrinterDrivers
9964 ****************************************************************/
9966 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9967 struct spoolss_GetCorePrinterDrivers *r)
9969 p->rng_fault_state = true;
9970 return WERR_NOT_SUPPORTED;
9973 /****************************************************************
9975 ****************************************************************/
9977 WERROR _spoolss_67(struct pipes_struct *p,
9978 struct spoolss_67 *r)
9980 p->rng_fault_state = true;
9981 return WERR_NOT_SUPPORTED;
9984 /****************************************************************
9985 _spoolss_GetPrinterDriverPackagePath
9986 ****************************************************************/
9988 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
9989 struct spoolss_GetPrinterDriverPackagePath *r)
9991 p->rng_fault_state = true;
9992 return WERR_NOT_SUPPORTED;
9995 /****************************************************************
9997 ****************************************************************/
9999 WERROR _spoolss_69(struct pipes_struct *p,
10000 struct spoolss_69 *r)
10002 p->rng_fault_state = true;
10003 return WERR_NOT_SUPPORTED;
10006 /****************************************************************
10008 ****************************************************************/
10010 WERROR _spoolss_6a(struct pipes_struct *p,
10011 struct spoolss_6a *r)
10013 p->rng_fault_state = true;
10014 return WERR_NOT_SUPPORTED;
10017 /****************************************************************
10019 ****************************************************************/
10021 WERROR _spoolss_6b(struct pipes_struct *p,
10022 struct spoolss_6b *r)
10024 p->rng_fault_state = true;
10025 return WERR_NOT_SUPPORTED;
10028 /****************************************************************
10030 ****************************************************************/
10032 WERROR _spoolss_6c(struct pipes_struct *p,
10033 struct spoolss_6c *r)
10035 p->rng_fault_state = true;
10036 return WERR_NOT_SUPPORTED;
10039 /****************************************************************
10041 ****************************************************************/
10043 WERROR _spoolss_6d(struct pipes_struct *p,
10044 struct spoolss_6d *r)
10046 p->rng_fault_state = true;
10047 return WERR_NOT_SUPPORTED;