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,
6012 talloc_free(tmp_ctx);
6017 /****************************************************************************
6018 ****************************************************************************/
6019 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6020 struct policy_handle *handle,
6021 struct spoolss_SetPrinterInfo7 *info7)
6024 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6027 Printer_entry *Printer;
6029 if ( lp_security() != SEC_ADS ) {
6030 return WERR_UNKNOWN_LEVEL;
6033 Printer = find_printer_index_by_hnd(p, handle);
6035 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6040 if (!get_printer_snum(p, handle, &snum, NULL))
6043 result = winreg_get_printer(p->mem_ctx, p->server_info,
6044 Printer->servername,
6045 lp_servicename(snum), &pinfo2);
6046 if (!W_ERROR_IS_OK(result)) {
6050 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6052 TALLOC_FREE(pinfo2);
6055 return WERR_UNKNOWN_LEVEL;
6059 /********************************************************************
6060 ********************************************************************/
6062 static WERROR update_printer_devmode(struct pipes_struct *p,
6063 struct policy_handle *handle,
6064 struct spoolss_DeviceMode *devmode)
6067 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6068 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6070 DEBUG(8,("update_printer_devmode\n"));
6076 if (!get_printer_snum(p, handle, &snum, NULL)) {
6080 /* Check calling user has permission to update printer description */
6081 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6082 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6083 return WERR_ACCESS_DENIED;
6086 return winreg_update_printer(p->mem_ctx,
6088 lp_const_servicename(snum),
6096 /****************************************************************
6098 ****************************************************************/
6100 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6101 struct spoolss_SetPrinter *r)
6105 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6108 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6109 OUR_HANDLE(r->in.handle)));
6113 /* check the level */
6114 switch (r->in.info_ctr->level) {
6116 return control_printer(r->in.handle, r->in.command, p);
6118 result = update_printer(p, r->in.handle,
6120 r->in.devmode_ctr->devmode);
6121 if (!W_ERROR_IS_OK(result))
6123 if (r->in.secdesc_ctr->sd)
6124 result = update_printer_sec(r->in.handle, p,
6128 return update_printer_sec(r->in.handle, p,
6131 return publish_or_unpublish_printer(p, r->in.handle,
6132 r->in.info_ctr->info.info7);
6134 return update_printer_devmode(p, r->in.handle,
6135 r->in.devmode_ctr->devmode);
6137 return WERR_UNKNOWN_LEVEL;
6141 /****************************************************************
6142 _spoolss_FindClosePrinterNotify
6143 ****************************************************************/
6145 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6146 struct spoolss_FindClosePrinterNotify *r)
6148 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6151 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6152 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6156 if (Printer->notify.client_connected == true) {
6159 if ( Printer->printer_type == SPLHND_SERVER)
6161 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6162 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6165 srv_spoolss_replycloseprinter(
6166 snum, &Printer->notify.client_hnd, p->msg_ctx);
6169 Printer->notify.flags=0;
6170 Printer->notify.options=0;
6171 Printer->notify.localmachine[0]='\0';
6172 Printer->notify.printerlocal=0;
6173 TALLOC_FREE(Printer->notify.option);
6174 Printer->notify.client_connected = false;
6179 /****************************************************************
6181 ****************************************************************/
6183 WERROR _spoolss_AddJob(struct pipes_struct *p,
6184 struct spoolss_AddJob *r)
6186 if (!r->in.buffer && (r->in.offered != 0)) {
6187 return WERR_INVALID_PARAM;
6190 /* this is what a NT server returns for AddJob. AddJob must fail on
6191 * non-local printers */
6193 if (r->in.level != 1) {
6194 return WERR_UNKNOWN_LEVEL;
6197 return WERR_INVALID_PARAM;
6200 /****************************************************************************
6202 ****************************************************************************/
6204 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6205 struct spoolss_JobInfo1 *r,
6206 const print_queue_struct *queue,
6207 int position, int snum,
6208 struct spoolss_PrinterInfo2 *pinfo2)
6212 t = gmtime(&queue->time);
6214 r->job_id = queue->job;
6216 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6217 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6218 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6219 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6220 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6221 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6222 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6223 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6224 r->data_type = talloc_strdup(mem_ctx, "RAW");
6225 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6226 r->text_status = talloc_strdup(mem_ctx, "");
6227 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6229 r->status = nt_printj_status(queue->status);
6230 r->priority = queue->priority;
6231 r->position = position;
6232 r->total_pages = queue->page_count;
6233 r->pages_printed = 0; /* ??? */
6235 init_systemtime(&r->submitted, t);
6240 /****************************************************************************
6242 ****************************************************************************/
6244 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6245 struct spoolss_JobInfo2 *r,
6246 const print_queue_struct *queue,
6247 int position, int snum,
6248 struct spoolss_PrinterInfo2 *pinfo2,
6249 struct spoolss_DeviceMode *devmode)
6253 t = gmtime(&queue->time);
6255 r->job_id = queue->job;
6257 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6258 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6259 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6260 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6261 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6262 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6263 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6264 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6265 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6266 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6267 r->data_type = talloc_strdup(mem_ctx, "RAW");
6268 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6269 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6270 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6271 r->parameters = talloc_strdup(mem_ctx, "");
6272 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6273 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6274 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6276 r->devmode = devmode;
6278 r->text_status = talloc_strdup(mem_ctx, "");
6279 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6283 r->status = nt_printj_status(queue->status);
6284 r->priority = queue->priority;
6285 r->position = position;
6288 r->total_pages = queue->page_count;
6289 r->size = queue->size;
6290 init_systemtime(&r->submitted, t);
6292 r->pages_printed = 0; /* ??? */
6297 /****************************************************************************
6299 ****************************************************************************/
6301 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6302 struct spoolss_JobInfo3 *r,
6303 const print_queue_struct *queue,
6304 const print_queue_struct *next_queue,
6305 int position, int snum,
6306 struct spoolss_PrinterInfo2 *pinfo2)
6308 r->job_id = queue->job;
6311 r->next_job_id = next_queue->job;
6318 /****************************************************************************
6319 Enumjobs at level 1.
6320 ****************************************************************************/
6322 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6323 const print_queue_struct *queue,
6324 uint32_t num_queues, int snum,
6325 struct spoolss_PrinterInfo2 *pinfo2,
6326 union spoolss_JobInfo **info_p,
6329 union spoolss_JobInfo *info;
6331 WERROR result = WERR_OK;
6333 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6334 W_ERROR_HAVE_NO_MEMORY(info);
6336 *count = num_queues;
6338 for (i=0; i<*count; i++) {
6339 result = fill_job_info1(info,
6345 if (!W_ERROR_IS_OK(result)) {
6351 if (!W_ERROR_IS_OK(result)) {
6362 /****************************************************************************
6363 Enumjobs at level 2.
6364 ****************************************************************************/
6366 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6367 const print_queue_struct *queue,
6368 uint32_t num_queues, int snum,
6369 struct spoolss_PrinterInfo2 *pinfo2,
6370 union spoolss_JobInfo **info_p,
6373 union spoolss_JobInfo *info;
6375 WERROR result = WERR_OK;
6377 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6378 W_ERROR_HAVE_NO_MEMORY(info);
6380 *count = num_queues;
6382 for (i=0; i<*count; i++) {
6383 struct spoolss_DeviceMode *devmode;
6385 result = spoolss_create_default_devmode(info,
6386 pinfo2->printername,
6388 if (!W_ERROR_IS_OK(result)) {
6389 DEBUG(3, ("Can't proceed w/o a devmode!"));
6393 result = fill_job_info2(info,
6400 if (!W_ERROR_IS_OK(result)) {
6406 if (!W_ERROR_IS_OK(result)) {
6417 /****************************************************************************
6418 Enumjobs at level 3.
6419 ****************************************************************************/
6421 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6422 const print_queue_struct *queue,
6423 uint32_t num_queues, int snum,
6424 struct spoolss_PrinterInfo2 *pinfo2,
6425 union spoolss_JobInfo **info_p,
6428 union spoolss_JobInfo *info;
6430 WERROR result = WERR_OK;
6432 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6433 W_ERROR_HAVE_NO_MEMORY(info);
6435 *count = num_queues;
6437 for (i=0; i<*count; i++) {
6438 const print_queue_struct *next_queue = NULL;
6441 next_queue = &queue[i+1];
6444 result = fill_job_info3(info,
6451 if (!W_ERROR_IS_OK(result)) {
6457 if (!W_ERROR_IS_OK(result)) {
6468 /****************************************************************
6470 ****************************************************************/
6472 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6473 struct spoolss_EnumJobs *r)
6476 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6478 print_status_struct prt_status;
6479 print_queue_struct *queue = NULL;
6482 /* that's an [in out] buffer */
6484 if (!r->in.buffer && (r->in.offered != 0)) {
6485 return WERR_INVALID_PARAM;
6488 DEBUG(4,("_spoolss_EnumJobs\n"));
6492 *r->out.info = NULL;
6494 /* lookup the printer snum and tdb entry */
6496 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6500 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6501 lp_servicename(snum), &pinfo2);
6502 if (!W_ERROR_IS_OK(result)) {
6506 count = print_queue_status(snum, &queue, &prt_status);
6507 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6508 count, prt_status.status, prt_status.message));
6512 TALLOC_FREE(pinfo2);
6516 switch (r->in.level) {
6518 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6519 pinfo2, r->out.info, r->out.count);
6522 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6523 pinfo2, r->out.info, r->out.count);
6526 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6527 pinfo2, r->out.info, r->out.count);
6530 result = WERR_UNKNOWN_LEVEL;
6535 TALLOC_FREE(pinfo2);
6537 if (!W_ERROR_IS_OK(result)) {
6541 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6543 *r->out.info, r->in.level,
6545 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6546 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6548 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6551 /****************************************************************
6552 _spoolss_ScheduleJob
6553 ****************************************************************/
6555 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6556 struct spoolss_ScheduleJob *r)
6561 /****************************************************************
6562 ****************************************************************/
6564 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6565 const char *printer_name,
6567 struct spoolss_SetJobInfo1 *r)
6571 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6575 if (strequal(old_doc_name, r->document_name)) {
6579 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6586 /****************************************************************
6588 ****************************************************************/
6590 WERROR _spoolss_SetJob(struct pipes_struct *p,
6591 struct spoolss_SetJob *r)
6594 WERROR errcode = WERR_BADFUNC;
6596 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6600 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6601 return WERR_INVALID_PRINTER_NAME;
6604 switch (r->in.command) {
6605 case SPOOLSS_JOB_CONTROL_CANCEL:
6606 case SPOOLSS_JOB_CONTROL_DELETE:
6607 errcode = print_job_delete(p->server_info,
6608 snum, r->in.job_id);
6609 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6613 case SPOOLSS_JOB_CONTROL_PAUSE:
6614 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6618 case SPOOLSS_JOB_CONTROL_RESTART:
6619 case SPOOLSS_JOB_CONTROL_RESUME:
6620 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6628 return WERR_UNKNOWN_LEVEL;
6631 if (!W_ERROR_IS_OK(errcode)) {
6635 if (r->in.ctr == NULL) {
6639 switch (r->in.ctr->level) {
6641 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6643 r->in.ctr->info.info1);
6649 return WERR_UNKNOWN_LEVEL;
6655 /****************************************************************************
6656 Enumerates all printer drivers by level and architecture.
6657 ****************************************************************************/
6659 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6660 struct auth_serversupplied_info *server_info,
6661 const char *servername,
6662 const char *architecture,
6664 union spoolss_DriverInfo **info_p,
6669 struct spoolss_DriverInfo8 *driver;
6670 union spoolss_DriverInfo *info = NULL;
6672 WERROR result = WERR_OK;
6673 uint32_t num_drivers;
6674 const char **drivers;
6679 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6680 result = winreg_get_driver_list(mem_ctx, server_info,
6681 architecture, version,
6682 &num_drivers, &drivers);
6683 if (!W_ERROR_IS_OK(result)) {
6686 DEBUG(4, ("we have:[%d] drivers in environment"
6687 " [%s] and version [%d]\n",
6688 num_drivers, architecture, version));
6690 if (num_drivers != 0) {
6691 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6692 union spoolss_DriverInfo,
6693 count + num_drivers);
6695 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6696 "failed to enlarge driver info buffer!\n"));
6697 result = WERR_NOMEM;
6702 for (i = 0; i < num_drivers; i++) {
6703 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6705 result = winreg_get_driver(mem_ctx, server_info,
6706 architecture, drivers[i],
6708 if (!W_ERROR_IS_OK(result)) {
6714 result = fill_printer_driver_info1(info, &info[count+i].info1,
6715 driver, servername);
6718 result = fill_printer_driver_info2(info, &info[count+i].info2,
6719 driver, servername);
6722 result = fill_printer_driver_info3(info, &info[count+i].info3,
6723 driver, servername);
6726 result = fill_printer_driver_info4(info, &info[count+i].info4,
6727 driver, servername);
6730 result = fill_printer_driver_info5(info, &info[count+i].info5,
6731 driver, servername);
6734 result = fill_printer_driver_info6(info, &info[count+i].info6,
6735 driver, servername);
6738 result = fill_printer_driver_info8(info, &info[count+i].info8,
6739 driver, servername);
6742 result = WERR_UNKNOWN_LEVEL;
6746 TALLOC_FREE(driver);
6748 if (!W_ERROR_IS_OK(result)) {
6753 count += num_drivers;
6754 TALLOC_FREE(drivers);
6758 TALLOC_FREE(drivers);
6760 if (!W_ERROR_IS_OK(result)) {
6771 /****************************************************************************
6772 Enumerates all printer drivers by level.
6773 ****************************************************************************/
6775 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6776 struct auth_serversupplied_info *server_info,
6777 const char *servername,
6778 const char *architecture,
6780 union spoolss_DriverInfo **info_p,
6784 WERROR result = WERR_OK;
6786 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6788 for (a=0; archi_table[a].long_archi != NULL; a++) {
6790 union spoolss_DriverInfo *info = NULL;
6793 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6796 archi_table[a].long_archi,
6800 if (!W_ERROR_IS_OK(result)) {
6804 for (i=0; i < count; i++) {
6805 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6806 info[i], info_p, count_p);
6813 return enumprinterdrivers_level_by_architecture(mem_ctx,
6822 /****************************************************************
6823 _spoolss_EnumPrinterDrivers
6824 ****************************************************************/
6826 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6827 struct spoolss_EnumPrinterDrivers *r)
6829 const char *cservername;
6832 /* that's an [in out] buffer */
6834 if (!r->in.buffer && (r->in.offered != 0)) {
6835 return WERR_INVALID_PARAM;
6838 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6842 *r->out.info = NULL;
6844 cservername = canon_servername(r->in.server);
6846 if (!is_myname_or_ipaddr(cservername)) {
6847 return WERR_UNKNOWN_PRINTER_DRIVER;
6850 result = enumprinterdrivers_level(p->mem_ctx,
6857 if (!W_ERROR_IS_OK(result)) {
6861 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6862 spoolss_EnumPrinterDrivers,
6863 *r->out.info, r->in.level,
6865 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6866 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6868 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6871 /****************************************************************
6873 ****************************************************************/
6875 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6876 struct spoolss_EnumForms *r)
6882 *r->out.info = NULL;
6884 /* that's an [in out] buffer */
6886 if (!r->in.buffer && (r->in.offered != 0) ) {
6887 return WERR_INVALID_PARAM;
6890 DEBUG(4,("_spoolss_EnumForms\n"));
6891 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6892 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6894 switch (r->in.level) {
6896 result = winreg_printer_enumforms1(p->mem_ctx,
6902 result = WERR_UNKNOWN_LEVEL;
6906 if (!W_ERROR_IS_OK(result)) {
6910 if (*r->out.count == 0) {
6911 return WERR_NO_MORE_ITEMS;
6914 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6916 *r->out.info, r->in.level,
6918 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6919 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6921 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6924 /****************************************************************
6926 ****************************************************************/
6928 WERROR _spoolss_GetForm(struct pipes_struct *p,
6929 struct spoolss_GetForm *r)
6933 /* that's an [in out] buffer */
6935 if (!r->in.buffer && (r->in.offered != 0)) {
6936 return WERR_INVALID_PARAM;
6939 DEBUG(4,("_spoolss_GetForm\n"));
6940 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6941 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6943 switch (r->in.level) {
6945 result = winreg_printer_getform1(p->mem_ctx,
6948 &r->out.info->info1);
6951 result = WERR_UNKNOWN_LEVEL;
6955 if (!W_ERROR_IS_OK(result)) {
6956 TALLOC_FREE(r->out.info);
6960 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6961 r->out.info, r->in.level);
6962 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6964 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6967 /****************************************************************************
6968 ****************************************************************************/
6970 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6971 struct spoolss_PortInfo1 *r,
6974 r->port_name = talloc_strdup(mem_ctx, name);
6975 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6980 /****************************************************************************
6981 TODO: This probably needs distinguish between TCP/IP and Local ports
6983 ****************************************************************************/
6985 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6986 struct spoolss_PortInfo2 *r,
6989 r->port_name = talloc_strdup(mem_ctx, name);
6990 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6992 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6993 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6995 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6996 W_ERROR_HAVE_NO_MEMORY(r->description);
6998 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7005 /****************************************************************************
7006 wrapper around the enumer ports command
7007 ****************************************************************************/
7009 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7011 char *cmd = lp_enumports_cmd();
7012 char **qlines = NULL;
7013 char *command = NULL;
7021 /* if no hook then just fill in the default port */
7024 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7027 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7028 TALLOC_FREE(qlines);
7035 /* we have a valid enumport command */
7037 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7042 DEBUG(10,("Running [%s]\n", command));
7043 ret = smbrun(command, &fd);
7044 DEBUG(10,("Returned [%d]\n", ret));
7045 TALLOC_FREE(command);
7050 return WERR_ACCESS_DENIED;
7054 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7055 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7065 /****************************************************************************
7067 ****************************************************************************/
7069 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7070 union spoolss_PortInfo **info_p,
7073 union spoolss_PortInfo *info = NULL;
7075 WERROR result = WERR_OK;
7076 char **qlines = NULL;
7079 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7080 if (!W_ERROR_IS_OK(result)) {
7085 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7087 DEBUG(10,("Returning WERR_NOMEM\n"));
7088 result = WERR_NOMEM;
7092 for (i=0; i<numlines; i++) {
7093 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7094 result = fill_port_1(info, &info[i].info1, qlines[i]);
7095 if (!W_ERROR_IS_OK(result)) {
7100 TALLOC_FREE(qlines);
7103 if (!W_ERROR_IS_OK(result)) {
7105 TALLOC_FREE(qlines);
7117 /****************************************************************************
7119 ****************************************************************************/
7121 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7122 union spoolss_PortInfo **info_p,
7125 union spoolss_PortInfo *info = NULL;
7127 WERROR result = WERR_OK;
7128 char **qlines = NULL;
7131 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7132 if (!W_ERROR_IS_OK(result)) {
7137 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7139 DEBUG(10,("Returning WERR_NOMEM\n"));
7140 result = WERR_NOMEM;
7144 for (i=0; i<numlines; i++) {
7145 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7146 result = fill_port_2(info, &info[i].info2, qlines[i]);
7147 if (!W_ERROR_IS_OK(result)) {
7152 TALLOC_FREE(qlines);
7155 if (!W_ERROR_IS_OK(result)) {
7157 TALLOC_FREE(qlines);
7169 /****************************************************************
7171 ****************************************************************/
7173 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7174 struct spoolss_EnumPorts *r)
7178 /* that's an [in out] buffer */
7180 if (!r->in.buffer && (r->in.offered != 0)) {
7181 return WERR_INVALID_PARAM;
7184 DEBUG(4,("_spoolss_EnumPorts\n"));
7188 *r->out.info = NULL;
7190 switch (r->in.level) {
7192 result = enumports_level_1(p->mem_ctx, r->out.info,
7196 result = enumports_level_2(p->mem_ctx, r->out.info,
7200 return WERR_UNKNOWN_LEVEL;
7203 if (!W_ERROR_IS_OK(result)) {
7207 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7209 *r->out.info, r->in.level,
7211 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7212 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7214 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7217 /****************************************************************************
7218 ****************************************************************************/
7220 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7222 struct spoolss_SetPrinterInfoCtr *info_ctr,
7223 struct spoolss_DeviceMode *devmode,
7224 struct security_descriptor *secdesc,
7225 struct spoolss_UserLevelCtr *user_ctr,
7226 struct policy_handle *handle)
7228 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7229 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7231 WERROR err = WERR_OK;
7233 /* samba does not have a concept of local, non-shared printers yet, so
7234 * make sure we always setup sharename - gd */
7235 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7236 (info2->printername != NULL && info2->printername[0] != '\0')) {
7237 DEBUG(5, ("spoolss_addprinterex_level_2: "
7238 "no sharename has been set, setting printername %s as sharename\n",
7239 info2->printername));
7240 info2->sharename = info2->printername;
7243 /* check to see if the printer already exists */
7244 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7245 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7247 return WERR_PRINTER_ALREADY_EXISTS;
7250 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7251 if ((snum = print_queue_snum(info2->printername)) != -1) {
7252 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7253 info2->printername));
7254 return WERR_PRINTER_ALREADY_EXISTS;
7258 /* validate printer info struct */
7259 if (!info2->printername || strlen(info2->printername) == 0) {
7260 return WERR_INVALID_PRINTER_NAME;
7262 if (!info2->portname || strlen(info2->portname) == 0) {
7263 return WERR_UNKNOWN_PORT;
7265 if (!info2->drivername || strlen(info2->drivername) == 0) {
7266 return WERR_UNKNOWN_PRINTER_DRIVER;
7268 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7269 return WERR_UNKNOWN_PRINTPROCESSOR;
7272 /* FIXME!!! smbd should check to see if the driver is installed before
7273 trying to add a printer like this --jerry */
7275 if (*lp_addprinter_cmd() ) {
7276 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7277 info2, p->client_address,
7279 return WERR_ACCESS_DENIED;
7282 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7283 "smb.conf parameter \"addprinter command\" is defined. This"
7284 "parameter must exist for this call to succeed\n",
7285 info2->sharename ));
7288 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7289 return WERR_ACCESS_DENIED;
7292 /* you must be a printer admin to add a new printer */
7293 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7294 return WERR_ACCESS_DENIED;
7298 * Do sanity check on the requested changes for Samba.
7301 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7302 return WERR_INVALID_PARAM;
7305 if (devmode == NULL) {
7306 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7309 update_dsspooler(p->mem_ctx,
7315 err = winreg_update_printer(p->mem_ctx,
7322 if (!W_ERROR_IS_OK(err)) {
7326 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7327 /* Handle open failed - remove addition. */
7328 ZERO_STRUCTP(handle);
7329 return WERR_ACCESS_DENIED;
7335 /****************************************************************
7336 _spoolss_AddPrinterEx
7337 ****************************************************************/
7339 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7340 struct spoolss_AddPrinterEx *r)
7342 switch (r->in.info_ctr->level) {
7344 /* we don't handle yet */
7345 /* but I know what to do ... */
7346 return WERR_UNKNOWN_LEVEL;
7348 return spoolss_addprinterex_level_2(p, r->in.server,
7350 r->in.devmode_ctr->devmode,
7351 r->in.secdesc_ctr->sd,
7352 r->in.userlevel_ctr,
7355 return WERR_UNKNOWN_LEVEL;
7359 /****************************************************************
7361 ****************************************************************/
7363 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7364 struct spoolss_AddPrinter *r)
7366 struct spoolss_AddPrinterEx a;
7367 struct spoolss_UserLevelCtr userlevel_ctr;
7369 ZERO_STRUCT(userlevel_ctr);
7371 userlevel_ctr.level = 1;
7373 a.in.server = r->in.server;
7374 a.in.info_ctr = r->in.info_ctr;
7375 a.in.devmode_ctr = r->in.devmode_ctr;
7376 a.in.secdesc_ctr = r->in.secdesc_ctr;
7377 a.in.userlevel_ctr = &userlevel_ctr;
7378 a.out.handle = r->out.handle;
7380 return _spoolss_AddPrinterEx(p, &a);
7383 /****************************************************************
7384 _spoolss_AddPrinterDriverEx
7385 ****************************************************************/
7387 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7388 struct spoolss_AddPrinterDriverEx *r)
7390 WERROR err = WERR_OK;
7391 const char *driver_name = NULL;
7396 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7397 fn = "_spoolss_AddPrinterDriver";
7399 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7400 fn = "_spoolss_AddPrinterDriverEx";
7403 return WERR_INVALID_PARAM;
7407 * we only support the semantics of AddPrinterDriver()
7408 * i.e. only copy files that are newer than existing ones
7411 if (r->in.flags == 0) {
7412 return WERR_INVALID_PARAM;
7415 if (r->in.flags != APD_COPY_NEW_FILES) {
7416 return WERR_ACCESS_DENIED;
7420 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7421 /* Clever hack from Martin Zielinski <mz@seh.de>
7422 * to allow downgrade from level 8 (Vista).
7424 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7425 r->in.info_ctr->level));
7426 return WERR_UNKNOWN_LEVEL;
7429 DEBUG(5,("Cleaning driver's information\n"));
7430 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7431 if (!W_ERROR_IS_OK(err))
7434 DEBUG(5,("Moving driver to final destination\n"));
7435 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7440 err = winreg_add_driver(p->mem_ctx, p->server_info,
7441 r->in.info_ctr, &driver_name, &version);
7442 if (!W_ERROR_IS_OK(err)) {
7447 * I think this is where he DrvUpgradePrinter() hook would be
7448 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7449 * server. Right now, we just need to send ourselves a message
7450 * to update each printer bound to this driver. --jerry
7453 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7454 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7462 /****************************************************************
7463 _spoolss_AddPrinterDriver
7464 ****************************************************************/
7466 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7467 struct spoolss_AddPrinterDriver *r)
7469 struct spoolss_AddPrinterDriverEx a;
7471 switch (r->in.info_ctr->level) {
7478 return WERR_UNKNOWN_LEVEL;
7481 a.in.servername = r->in.servername;
7482 a.in.info_ctr = r->in.info_ctr;
7483 a.in.flags = APD_COPY_NEW_FILES;
7485 return _spoolss_AddPrinterDriverEx(p, &a);
7488 /****************************************************************************
7489 ****************************************************************************/
7491 struct _spoolss_paths {
7497 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7499 static const struct _spoolss_paths spoolss_paths[]= {
7500 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7501 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7504 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7505 const char *servername,
7506 const char *environment,
7510 const char *pservername = NULL;
7511 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7512 const char *short_archi;
7516 /* environment may be empty */
7517 if (environment && strlen(environment)) {
7518 long_archi = environment;
7521 /* servername may be empty */
7522 if (servername && strlen(servername)) {
7523 pservername = canon_servername(servername);
7525 if (!is_myname_or_ipaddr(pservername)) {
7526 return WERR_INVALID_PARAM;
7530 if (!(short_archi = get_short_archi(long_archi))) {
7531 return WERR_INVALID_ENVIRONMENT;
7534 switch (component) {
7535 case SPOOLSS_PRTPROCS_PATH:
7536 case SPOOLSS_DRIVER_PATH:
7538 *path = talloc_asprintf(mem_ctx,
7541 spoolss_paths[component].share,
7544 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7545 SPOOLSS_DEFAULT_SERVER_PATH,
7546 spoolss_paths[component].dir,
7551 return WERR_INVALID_PARAM;
7561 /****************************************************************************
7562 ****************************************************************************/
7564 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7565 const char *servername,
7566 const char *environment,
7567 struct spoolss_DriverDirectoryInfo1 *r)
7572 werr = compose_spoolss_server_path(mem_ctx,
7575 SPOOLSS_DRIVER_PATH,
7577 if (!W_ERROR_IS_OK(werr)) {
7581 DEBUG(4,("printer driver directory: [%s]\n", path));
7583 r->directory_name = path;
7588 /****************************************************************
7589 _spoolss_GetPrinterDriverDirectory
7590 ****************************************************************/
7592 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7593 struct spoolss_GetPrinterDriverDirectory *r)
7597 /* that's an [in out] buffer */
7599 if (!r->in.buffer && (r->in.offered != 0)) {
7600 return WERR_INVALID_PARAM;
7603 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7608 /* r->in.level is ignored */
7610 werror = getprinterdriverdir_level_1(p->mem_ctx,
7613 &r->out.info->info1);
7614 if (!W_ERROR_IS_OK(werror)) {
7615 TALLOC_FREE(r->out.info);
7619 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7620 r->out.info, r->in.level);
7621 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7623 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7626 /****************************************************************
7627 _spoolss_EnumPrinterData
7628 ****************************************************************/
7630 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7631 struct spoolss_EnumPrinterData *r)
7634 struct spoolss_EnumPrinterDataEx r2;
7636 struct spoolss_PrinterEnumValues *info, *val = NULL;
7639 r2.in.handle = r->in.handle;
7640 r2.in.key_name = "PrinterDriverData";
7642 r2.out.count = &count;
7643 r2.out.info = &info;
7644 r2.out.needed = &needed;
7646 result = _spoolss_EnumPrinterDataEx(p, &r2);
7647 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7648 r2.in.offered = needed;
7649 result = _spoolss_EnumPrinterDataEx(p, &r2);
7651 if (!W_ERROR_IS_OK(result)) {
7656 * The NT machine wants to know the biggest size of value and data
7658 * cf: MSDN EnumPrinterData remark section
7661 if (!r->in.value_offered && !r->in.data_offered) {
7662 uint32_t biggest_valuesize = 0;
7663 uint32_t biggest_datasize = 0;
7666 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7668 for (i=0; i<count; i++) {
7670 name_length = strlen(info[i].value_name);
7671 if (strlen(info[i].value_name) > biggest_valuesize) {
7672 biggest_valuesize = name_length;
7675 if (info[i].data_length > biggest_datasize) {
7676 biggest_datasize = info[i].data_length;
7679 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7683 /* the value is an UNICODE string but real_value_size is the length
7684 in bytes including the trailing 0 */
7686 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7687 *r->out.data_needed = biggest_datasize;
7689 DEBUG(6,("final values: [%d], [%d]\n",
7690 *r->out.value_needed, *r->out.data_needed));
7695 if (r->in.enum_index < count) {
7696 val = &info[r->in.enum_index];
7700 /* out_value should default to "" or else NT4 has
7701 problems unmarshalling the response */
7703 if (r->in.value_offered) {
7704 *r->out.value_needed = 1;
7705 r->out.value_name = talloc_strdup(r, "");
7706 if (!r->out.value_name) {
7710 r->out.value_name = NULL;
7711 *r->out.value_needed = 0;
7714 /* the data is counted in bytes */
7716 *r->out.data_needed = r->in.data_offered;
7718 result = WERR_NO_MORE_ITEMS;
7722 * - counted in bytes in the request
7723 * - counted in UNICODE chars in the max reply
7724 * - counted in bytes in the real size
7726 * take a pause *before* coding not *during* coding
7730 if (r->in.value_offered) {
7731 r->out.value_name = talloc_strdup(r, val->value_name);
7732 if (!r->out.value_name) {
7735 *r->out.value_needed = val->value_name_len;
7737 r->out.value_name = NULL;
7738 *r->out.value_needed = 0;
7743 *r->out.type = val->type;
7745 /* data - counted in bytes */
7748 * See the section "Dynamically Typed Query Parameters"
7752 if (r->out.data && val->data && val->data->data &&
7753 val->data_length && r->in.data_offered) {
7754 memcpy(r->out.data, val->data->data,
7755 MIN(val->data_length,r->in.data_offered));
7758 *r->out.data_needed = val->data_length;
7766 /****************************************************************
7767 _spoolss_SetPrinterData
7768 ****************************************************************/
7770 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7771 struct spoolss_SetPrinterData *r)
7773 struct spoolss_SetPrinterDataEx r2;
7775 r2.in.handle = r->in.handle;
7776 r2.in.key_name = "PrinterDriverData";
7777 r2.in.value_name = r->in.value_name;
7778 r2.in.type = r->in.type;
7779 r2.in.data = r->in.data;
7780 r2.in.offered = r->in.offered;
7782 return _spoolss_SetPrinterDataEx(p, &r2);
7785 /****************************************************************
7786 _spoolss_ResetPrinter
7787 ****************************************************************/
7789 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7790 struct spoolss_ResetPrinter *r)
7792 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7795 DEBUG(5,("_spoolss_ResetPrinter\n"));
7798 * All we do is to check to see if the handle and queue is valid.
7799 * This call really doesn't mean anything to us because we only
7800 * support RAW printing. --jerry
7804 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7805 OUR_HANDLE(r->in.handle)));
7809 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7813 /* blindly return success */
7817 /****************************************************************
7818 _spoolss_DeletePrinterData
7819 ****************************************************************/
7821 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7822 struct spoolss_DeletePrinterData *r)
7824 struct spoolss_DeletePrinterDataEx r2;
7826 r2.in.handle = r->in.handle;
7827 r2.in.key_name = "PrinterDriverData";
7828 r2.in.value_name = r->in.value_name;
7830 return _spoolss_DeletePrinterDataEx(p, &r2);
7833 /****************************************************************
7835 ****************************************************************/
7837 WERROR _spoolss_AddForm(struct pipes_struct *p,
7838 struct spoolss_AddForm *r)
7840 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7842 WERROR status = WERR_OK;
7843 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7845 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7847 DEBUG(5,("_spoolss_AddForm\n"));
7850 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7851 OUR_HANDLE(r->in.handle)));
7855 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7856 and not a printer admin, then fail */
7858 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7859 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7860 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7861 p->server_info->info3->base.domain.string,
7863 p->server_info->ptok,
7864 lp_printer_admin(snum))) {
7865 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7866 return WERR_ACCESS_DENIED;
7869 switch (form->flags) {
7870 case SPOOLSS_FORM_USER:
7871 case SPOOLSS_FORM_BUILTIN:
7872 case SPOOLSS_FORM_PRINTER:
7875 return WERR_INVALID_PARAM;
7878 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7879 if (!W_ERROR_IS_OK(status)) {
7884 * ChangeID must always be set if this is a printer
7886 if (Printer->printer_type == SPLHND_PRINTER) {
7887 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7891 status = winreg_printer_update_changeid(p->mem_ctx,
7893 lp_const_servicename(snum));
7894 if (!W_ERROR_IS_OK(status)) {
7902 /****************************************************************
7904 ****************************************************************/
7906 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7907 struct spoolss_DeleteForm *r)
7909 const char *form_name = r->in.form_name;
7910 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7912 WERROR status = WERR_OK;
7913 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7915 DEBUG(5,("_spoolss_DeleteForm\n"));
7918 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7919 OUR_HANDLE(r->in.handle)));
7923 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7924 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7925 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7926 p->server_info->info3->base.domain.string,
7928 p->server_info->ptok,
7929 lp_printer_admin(snum))) {
7930 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7931 return WERR_ACCESS_DENIED;
7934 status = winreg_printer_deleteform1(p->mem_ctx,
7937 if (!W_ERROR_IS_OK(status)) {
7942 * ChangeID must always be set if this is a printer
7944 if (Printer->printer_type == SPLHND_PRINTER) {
7945 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7949 status = winreg_printer_update_changeid(p->mem_ctx,
7951 lp_const_servicename(snum));
7952 if (!W_ERROR_IS_OK(status)) {
7960 /****************************************************************
7962 ****************************************************************/
7964 WERROR _spoolss_SetForm(struct pipes_struct *p,
7965 struct spoolss_SetForm *r)
7967 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7968 const char *form_name = r->in.form_name;
7970 WERROR status = WERR_OK;
7971 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7973 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7975 DEBUG(5,("_spoolss_SetForm\n"));
7978 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7979 OUR_HANDLE(r->in.handle)));
7983 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7984 and not a printer admin, then fail */
7986 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7987 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7988 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7989 p->server_info->info3->base.domain.string,
7991 p->server_info->ptok,
7992 lp_printer_admin(snum))) {
7993 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7994 return WERR_ACCESS_DENIED;
7997 status = winreg_printer_setform1(p->mem_ctx,
8001 if (!W_ERROR_IS_OK(status)) {
8006 * ChangeID must always be set if this is a printer
8008 if (Printer->printer_type == SPLHND_PRINTER) {
8009 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8013 status = winreg_printer_update_changeid(p->mem_ctx,
8015 lp_const_servicename(snum));
8016 if (!W_ERROR_IS_OK(status)) {
8024 /****************************************************************************
8025 fill_print_processor1
8026 ****************************************************************************/
8028 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8029 struct spoolss_PrintProcessorInfo1 *r,
8030 const char *print_processor_name)
8032 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8033 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8038 /****************************************************************************
8039 enumprintprocessors level 1.
8040 ****************************************************************************/
8042 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8043 union spoolss_PrintProcessorInfo **info_p,
8046 union spoolss_PrintProcessorInfo *info;
8049 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8050 W_ERROR_HAVE_NO_MEMORY(info);
8054 result = fill_print_processor1(info, &info[0].info1, "winprint");
8055 if (!W_ERROR_IS_OK(result)) {
8060 if (!W_ERROR_IS_OK(result)) {
8071 /****************************************************************
8072 _spoolss_EnumPrintProcessors
8073 ****************************************************************/
8075 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8076 struct spoolss_EnumPrintProcessors *r)
8080 /* that's an [in out] buffer */
8082 if (!r->in.buffer && (r->in.offered != 0)) {
8083 return WERR_INVALID_PARAM;
8086 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8089 * Enumerate the print processors ...
8091 * Just reply with "winprint", to keep NT happy
8092 * and I can use my nice printer checker.
8097 *r->out.info = NULL;
8099 switch (r->in.level) {
8101 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8105 return WERR_UNKNOWN_LEVEL;
8108 if (!W_ERROR_IS_OK(result)) {
8112 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8113 spoolss_EnumPrintProcessors,
8114 *r->out.info, r->in.level,
8116 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8117 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8119 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8122 /****************************************************************************
8123 fill_printprocdatatype1
8124 ****************************************************************************/
8126 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8127 struct spoolss_PrintProcDataTypesInfo1 *r,
8128 const char *name_array)
8130 r->name_array = talloc_strdup(mem_ctx, name_array);
8131 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8136 /****************************************************************************
8137 enumprintprocdatatypes level 1.
8138 ****************************************************************************/
8140 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8141 union spoolss_PrintProcDataTypesInfo **info_p,
8145 union spoolss_PrintProcDataTypesInfo *info;
8147 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8148 W_ERROR_HAVE_NO_MEMORY(info);
8152 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8153 if (!W_ERROR_IS_OK(result)) {
8158 if (!W_ERROR_IS_OK(result)) {
8169 /****************************************************************
8170 _spoolss_EnumPrintProcDataTypes
8171 ****************************************************************/
8173 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8174 struct spoolss_EnumPrintProcDataTypes *r)
8178 /* that's an [in out] buffer */
8180 if (!r->in.buffer && (r->in.offered != 0)) {
8181 return WERR_INVALID_PARAM;
8184 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8188 *r->out.info = NULL;
8190 switch (r->in.level) {
8192 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8196 return WERR_UNKNOWN_LEVEL;
8199 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8200 spoolss_EnumPrintProcDataTypes,
8201 *r->out.info, r->in.level,
8203 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8204 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8206 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8209 /****************************************************************************
8211 ****************************************************************************/
8213 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8214 struct spoolss_MonitorInfo1 *r,
8215 const char *monitor_name)
8217 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8218 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8223 /****************************************************************************
8225 ****************************************************************************/
8227 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8228 struct spoolss_MonitorInfo2 *r,
8229 const char *monitor_name,
8230 const char *environment,
8231 const char *dll_name)
8233 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8234 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8235 r->environment = talloc_strdup(mem_ctx, environment);
8236 W_ERROR_HAVE_NO_MEMORY(r->environment);
8237 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8238 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8243 /****************************************************************************
8244 enumprintmonitors level 1.
8245 ****************************************************************************/
8247 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8248 union spoolss_MonitorInfo **info_p,
8251 union spoolss_MonitorInfo *info;
8252 WERROR result = WERR_OK;
8254 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8255 W_ERROR_HAVE_NO_MEMORY(info);
8259 result = fill_monitor_1(info, &info[0].info1,
8261 if (!W_ERROR_IS_OK(result)) {
8265 result = fill_monitor_1(info, &info[1].info1,
8267 if (!W_ERROR_IS_OK(result)) {
8272 if (!W_ERROR_IS_OK(result)) {
8283 /****************************************************************************
8284 enumprintmonitors level 2.
8285 ****************************************************************************/
8287 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8288 union spoolss_MonitorInfo **info_p,
8291 union spoolss_MonitorInfo *info;
8292 WERROR result = WERR_OK;
8294 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8295 W_ERROR_HAVE_NO_MEMORY(info);
8299 result = fill_monitor_2(info, &info[0].info2,
8301 "Windows NT X86", /* FIXME */
8303 if (!W_ERROR_IS_OK(result)) {
8307 result = fill_monitor_2(info, &info[1].info2,
8309 "Windows NT X86", /* FIXME */
8311 if (!W_ERROR_IS_OK(result)) {
8316 if (!W_ERROR_IS_OK(result)) {
8327 /****************************************************************
8328 _spoolss_EnumMonitors
8329 ****************************************************************/
8331 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8332 struct spoolss_EnumMonitors *r)
8336 /* that's an [in out] buffer */
8338 if (!r->in.buffer && (r->in.offered != 0)) {
8339 return WERR_INVALID_PARAM;
8342 DEBUG(5,("_spoolss_EnumMonitors\n"));
8345 * Enumerate the print monitors ...
8347 * Just reply with "Local Port", to keep NT happy
8348 * and I can use my nice printer checker.
8353 *r->out.info = NULL;
8355 switch (r->in.level) {
8357 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8361 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8365 return WERR_UNKNOWN_LEVEL;
8368 if (!W_ERROR_IS_OK(result)) {
8372 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8373 spoolss_EnumMonitors,
8374 *r->out.info, r->in.level,
8376 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8377 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8379 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8382 /****************************************************************************
8383 ****************************************************************************/
8385 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8386 const print_queue_struct *queue,
8387 int count, int snum,
8388 struct spoolss_PrinterInfo2 *pinfo2,
8390 struct spoolss_JobInfo1 *r)
8395 for (i=0; i<count; i++) {
8396 if (queue[i].job == (int)jobid) {
8402 if (found == false) {
8403 /* NT treats not found as bad param... yet another bad choice */
8404 return WERR_INVALID_PARAM;
8407 return fill_job_info1(mem_ctx,
8415 /****************************************************************************
8416 ****************************************************************************/
8418 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8419 const print_queue_struct *queue,
8420 int count, int snum,
8421 struct spoolss_PrinterInfo2 *pinfo2,
8423 struct spoolss_JobInfo2 *r)
8427 struct spoolss_DeviceMode *devmode;
8430 for (i=0; i<count; i++) {
8431 if (queue[i].job == (int)jobid) {
8437 if (found == false) {
8438 /* NT treats not found as bad param... yet another bad
8440 return WERR_INVALID_PARAM;
8444 * if the print job does not have a DEVMODE associated with it,
8445 * just use the one for the printer. A NULL devicemode is not
8446 * a failure condition
8449 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8451 result = spoolss_create_default_devmode(mem_ctx,
8452 pinfo2->printername,
8454 if (!W_ERROR_IS_OK(result)) {
8455 DEBUG(3, ("Can't proceed w/o a devmode!"));
8460 return fill_job_info2(mem_ctx,
8469 /****************************************************************
8471 ****************************************************************/
8473 WERROR _spoolss_GetJob(struct pipes_struct *p,
8474 struct spoolss_GetJob *r)
8476 WERROR result = WERR_OK;
8477 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8480 print_queue_struct *queue = NULL;
8481 print_status_struct prt_status;
8483 /* that's an [in out] buffer */
8485 if (!r->in.buffer && (r->in.offered != 0)) {
8486 return WERR_INVALID_PARAM;
8489 DEBUG(5,("_spoolss_GetJob\n"));
8493 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8497 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8498 lp_servicename(snum), &pinfo2);
8499 if (!W_ERROR_IS_OK(result)) {
8503 count = print_queue_status(snum, &queue, &prt_status);
8505 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8506 count, prt_status.status, prt_status.message));
8508 switch (r->in.level) {
8510 result = getjob_level_1(p->mem_ctx,
8511 queue, count, snum, pinfo2,
8512 r->in.job_id, &r->out.info->info1);
8515 result = getjob_level_2(p->mem_ctx,
8516 queue, count, snum, pinfo2,
8517 r->in.job_id, &r->out.info->info2);
8520 result = WERR_UNKNOWN_LEVEL;
8525 TALLOC_FREE(pinfo2);
8527 if (!W_ERROR_IS_OK(result)) {
8528 TALLOC_FREE(r->out.info);
8532 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8534 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8536 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8539 /****************************************************************
8540 _spoolss_GetPrinterDataEx
8541 ****************************************************************/
8543 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8544 struct spoolss_GetPrinterDataEx *r)
8547 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8548 const char *printer;
8550 WERROR result = WERR_OK;
8552 enum winreg_Type val_type;
8557 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8559 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8560 r->in.key_name, r->in.value_name));
8562 /* in case of problem, return some default values */
8565 *r->out.type = REG_NONE;
8568 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8569 OUR_HANDLE(r->in.handle)));
8570 result = WERR_BADFID;
8574 /* Is the handle to a printer or to the server? */
8576 if (Printer->printer_type == SPLHND_SERVER) {
8578 union spoolss_PrinterData data;
8580 result = getprinterdata_printer_server(p->mem_ctx,
8584 if (!W_ERROR_IS_OK(result)) {
8588 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8589 *r->out.type, &data);
8590 if (!W_ERROR_IS_OK(result)) {
8594 *r->out.needed = blob.length;
8596 if (r->in.offered >= *r->out.needed) {
8597 memcpy(r->out.data, blob.data, blob.length);
8600 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8603 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8606 printer = lp_const_servicename(snum);
8608 /* check to see if the keyname is valid */
8609 if (!strlen(r->in.key_name)) {
8610 return WERR_INVALID_PARAM;
8613 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8614 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8615 strequal(r->in.value_name, "ChangeId")) {
8616 *r->out.type = REG_DWORD;
8618 if (r->in.offered >= *r->out.needed) {
8619 uint32_t changeid = 0;
8621 result = winreg_printer_get_changeid(p->mem_ctx,
8625 if (!W_ERROR_IS_OK(result)) {
8629 SIVAL(r->out.data, 0, changeid);
8635 result = winreg_get_printer_dataex(p->mem_ctx,
8643 if (!W_ERROR_IS_OK(result)) {
8647 *r->out.needed = val_size;
8648 *r->out.type = val_type;
8650 if (r->in.offered >= *r->out.needed) {
8651 memcpy(r->out.data, val_data, val_size);
8655 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8656 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8658 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8661 /****************************************************************
8662 _spoolss_SetPrinterDataEx
8663 ****************************************************************/
8665 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8666 struct spoolss_SetPrinterDataEx *r)
8668 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8670 WERROR result = WERR_OK;
8671 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8674 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8676 /* From MSDN documentation of SetPrinterDataEx: pass request to
8677 SetPrinterData if key is "PrinterDriverData" */
8680 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8681 OUR_HANDLE(r->in.handle)));
8685 if (Printer->printer_type == SPLHND_SERVER) {
8686 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8687 "Not implemented for server handles yet\n"));
8688 return WERR_INVALID_PARAM;
8691 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8696 * Access check : NT returns "access denied" if you make a
8697 * SetPrinterData call without the necessary privildge.
8698 * we were originally returning OK if nothing changed
8699 * which made Win2k issue **a lot** of SetPrinterData
8700 * when connecting to a printer --jerry
8703 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8704 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8705 "change denied by handle access permissions\n"));
8706 return WERR_ACCESS_DENIED;
8709 result = winreg_get_printer(Printer, p->server_info,
8710 Printer->servername,
8711 lp_servicename(snum),
8713 if (!W_ERROR_IS_OK(result)) {
8717 /* check for OID in valuename */
8719 oid_string = strchr(r->in.value_name, ',');
8725 /* save the registry data */
8727 result = winreg_set_printer_dataex(p->mem_ctx,
8736 if (W_ERROR_IS_OK(result)) {
8737 /* save the OID if one was specified */
8739 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8740 r->in.key_name, SPOOL_OID_KEY);
8742 result = WERR_NOMEM;
8747 * I'm not checking the status here on purpose. Don't know
8748 * if this is right, but I'm returning the status from the
8749 * previous set_printer_dataex() call. I have no idea if
8750 * this is right. --jerry
8752 winreg_set_printer_dataex(p->mem_ctx,
8758 (uint8_t *) oid_string,
8759 strlen(oid_string) + 1);
8762 result = winreg_printer_update_changeid(p->mem_ctx,
8764 lp_const_servicename(snum));
8769 talloc_free(pinfo2);
8773 /****************************************************************
8774 _spoolss_DeletePrinterDataEx
8775 ****************************************************************/
8777 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8778 struct spoolss_DeletePrinterDataEx *r)
8780 const char *printer;
8782 WERROR status = WERR_OK;
8783 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8785 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8788 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8789 "Invalid handle (%s:%u:%u).\n",
8790 OUR_HANDLE(r->in.handle)));
8794 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8795 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8796 "printer properties change denied by handle\n"));
8797 return WERR_ACCESS_DENIED;
8800 if (!r->in.value_name || !r->in.key_name) {
8804 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8807 printer = lp_const_servicename(snum);
8809 status = winreg_delete_printer_dataex(p->mem_ctx,
8814 if (W_ERROR_IS_OK(status)) {
8815 status = winreg_printer_update_changeid(p->mem_ctx,
8823 /****************************************************************
8824 _spoolss_EnumPrinterKey
8825 ****************************************************************/
8827 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8828 struct spoolss_EnumPrinterKey *r)
8831 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8833 WERROR result = WERR_BADFILE;
8834 const char **array = NULL;
8837 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8840 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8841 OUR_HANDLE(r->in.handle)));
8845 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8849 result = winreg_enum_printer_key(p->mem_ctx,
8851 lp_const_servicename(snum),
8855 if (!W_ERROR_IS_OK(result)) {
8859 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8860 result = WERR_NOMEM;
8864 *r->out._ndr_size = r->in.offered / 2;
8865 *r->out.needed = blob.length;
8867 if (r->in.offered < *r->out.needed) {
8868 result = WERR_MORE_DATA;
8871 r->out.key_buffer->string_array = array;
8875 if (!W_ERROR_IS_OK(result)) {
8877 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8885 /****************************************************************
8886 _spoolss_DeletePrinterKey
8887 ****************************************************************/
8889 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8890 struct spoolss_DeletePrinterKey *r)
8892 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8895 const char *printer;
8897 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8900 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8901 OUR_HANDLE(r->in.handle)));
8905 /* if keyname == NULL, return error */
8906 if ( !r->in.key_name )
8907 return WERR_INVALID_PARAM;
8909 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8913 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8914 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8915 "printer properties change denied by handle\n"));
8916 return WERR_ACCESS_DENIED;
8919 printer = lp_const_servicename(snum);
8921 /* delete the key and all subkeys */
8922 status = winreg_delete_printer_key(p->mem_ctx,
8926 if (W_ERROR_IS_OK(status)) {
8927 status = winreg_printer_update_changeid(p->mem_ctx,
8935 /****************************************************************
8936 _spoolss_EnumPrinterDataEx
8937 ****************************************************************/
8939 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8940 struct spoolss_EnumPrinterDataEx *r)
8943 struct spoolss_PrinterEnumValues *info = NULL;
8944 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8948 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8952 *r->out.info = NULL;
8955 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8956 OUR_HANDLE(r->in.handle)));
8961 * first check for a keyname of NULL or "". Win2k seems to send
8962 * this a lot and we should send back WERR_INVALID_PARAM
8963 * no need to spend time looking up the printer in this case.
8967 if (!strlen(r->in.key_name)) {
8968 result = WERR_INVALID_PARAM;
8972 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8976 /* now look for a match on the key name */
8977 result = winreg_enum_printer_dataex(p->mem_ctx,
8979 lp_const_servicename(snum),
8983 if (!W_ERROR_IS_OK(result)) {
8987 #if 0 /* FIXME - gd */
8988 /* housekeeping information in the reply */
8990 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8991 * the hand marshalled container size is a multiple
8992 * of 4 bytes for RPC alignment.
8996 needed += 4-(needed % 4);
8999 *r->out.count = count;
9000 *r->out.info = info;
9003 if (!W_ERROR_IS_OK(result)) {
9007 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9008 spoolss_EnumPrinterDataEx,
9011 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9012 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9014 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9017 /****************************************************************************
9018 ****************************************************************************/
9020 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9021 const char *servername,
9022 const char *environment,
9023 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9028 werr = compose_spoolss_server_path(mem_ctx,
9031 SPOOLSS_PRTPROCS_PATH,
9033 if (!W_ERROR_IS_OK(werr)) {
9037 DEBUG(4,("print processor directory: [%s]\n", path));
9039 r->directory_name = path;
9044 /****************************************************************
9045 _spoolss_GetPrintProcessorDirectory
9046 ****************************************************************/
9048 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9049 struct spoolss_GetPrintProcessorDirectory *r)
9053 /* that's an [in out] buffer */
9055 if (!r->in.buffer && (r->in.offered != 0)) {
9056 return WERR_INVALID_PARAM;
9059 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9064 /* r->in.level is ignored */
9066 /* We always should reply with a local print processor directory so that
9067 * users are not forced to have a [prnproc$] share on the Samba spoolss
9068 * server - Guenther */
9070 result = getprintprocessordirectory_level_1(p->mem_ctx,
9071 NULL, /* r->in.server */
9073 &r->out.info->info1);
9074 if (!W_ERROR_IS_OK(result)) {
9075 TALLOC_FREE(r->out.info);
9079 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9080 r->out.info, r->in.level);
9081 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9083 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9086 /*******************************************************************
9087 ********************************************************************/
9089 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9090 const char *dllname)
9092 enum ndr_err_code ndr_err;
9093 struct spoolss_MonitorUi ui;
9095 ui.dll_name = dllname;
9097 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9098 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9099 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9100 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9102 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9105 /*******************************************************************
9106 Streams the monitor UI DLL name in UNICODE
9107 *******************************************************************/
9109 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9110 NT_USER_TOKEN *token, DATA_BLOB *in,
9111 DATA_BLOB *out, uint32_t *needed)
9113 const char *dllname = "tcpmonui.dll";
9115 *needed = (strlen(dllname)+1) * 2;
9117 if (out->length < *needed) {
9118 return WERR_INSUFFICIENT_BUFFER;
9121 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9128 /*******************************************************************
9129 ********************************************************************/
9131 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9132 struct spoolss_PortData1 *port1,
9133 const DATA_BLOB *buf)
9135 enum ndr_err_code ndr_err;
9136 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9137 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9138 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9139 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9141 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9144 /*******************************************************************
9145 ********************************************************************/
9147 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9148 struct spoolss_PortData2 *port2,
9149 const DATA_BLOB *buf)
9151 enum ndr_err_code ndr_err;
9152 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9153 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9154 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9155 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9157 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9160 /*******************************************************************
9161 Create a new TCP/IP port
9162 *******************************************************************/
9164 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9165 NT_USER_TOKEN *token, DATA_BLOB *in,
9166 DATA_BLOB *out, uint32_t *needed)
9168 struct spoolss_PortData1 port1;
9169 struct spoolss_PortData2 port2;
9170 char *device_uri = NULL;
9173 const char *portname;
9174 const char *hostaddress;
9176 uint32_t port_number;
9179 /* peek for spoolss_PortData version */
9181 if (!in || (in->length < (128 + 4))) {
9182 return WERR_GENERAL_FAILURE;
9185 version = IVAL(in->data, 128);
9191 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9195 portname = port1.portname;
9196 hostaddress = port1.hostaddress;
9197 queue = port1.queue;
9198 protocol = port1.protocol;
9199 port_number = port1.port_number;
9205 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9209 portname = port2.portname;
9210 hostaddress = port2.hostaddress;
9211 queue = port2.queue;
9212 protocol = port2.protocol;
9213 port_number = port2.port_number;
9217 DEBUG(1,("xcvtcp_addport: "
9218 "unknown version of port_data: %d\n", version));
9219 return WERR_UNKNOWN_PORT;
9222 /* create the device URI and call the add_port_hook() */
9225 case PROTOCOL_RAWTCP_TYPE:
9226 device_uri = talloc_asprintf(mem_ctx,
9227 "socket://%s:%d/", hostaddress,
9231 case PROTOCOL_LPR_TYPE:
9232 device_uri = talloc_asprintf(mem_ctx,
9233 "lpr://%s/%s", hostaddress, queue );
9237 return WERR_UNKNOWN_PORT;
9244 return add_port_hook(mem_ctx, token, portname, device_uri);
9247 /*******************************************************************
9248 *******************************************************************/
9250 struct xcv_api_table xcvtcp_cmds[] = {
9251 { "MonitorUI", xcvtcp_monitorui },
9252 { "AddPort", xcvtcp_addport},
9256 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9257 NT_USER_TOKEN *token, const char *command,
9264 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9266 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9267 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9268 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9271 return WERR_BADFUNC;
9274 /*******************************************************************
9275 *******************************************************************/
9276 #if 0 /* don't support management using the "Local Port" monitor */
9278 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9279 NT_USER_TOKEN *token, DATA_BLOB *in,
9280 DATA_BLOB *out, uint32_t *needed)
9282 const char *dllname = "localui.dll";
9284 *needed = (strlen(dllname)+1) * 2;
9286 if (out->length < *needed) {
9287 return WERR_INSUFFICIENT_BUFFER;
9290 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9297 /*******************************************************************
9298 *******************************************************************/
9300 struct xcv_api_table xcvlocal_cmds[] = {
9301 { "MonitorUI", xcvlocal_monitorui },
9305 struct xcv_api_table xcvlocal_cmds[] = {
9312 /*******************************************************************
9313 *******************************************************************/
9315 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9316 NT_USER_TOKEN *token, const char *command,
9317 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9322 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9324 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9325 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9326 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9328 return WERR_BADFUNC;
9331 /****************************************************************
9333 ****************************************************************/
9335 WERROR _spoolss_XcvData(struct pipes_struct *p,
9336 struct spoolss_XcvData *r)
9338 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9339 DATA_BLOB out_data = data_blob_null;
9343 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9344 OUR_HANDLE(r->in.handle)));
9348 /* Has to be a handle to the TCP/IP port monitor */
9350 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9351 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9355 /* requires administrative access to the server */
9357 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9358 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9359 return WERR_ACCESS_DENIED;
9362 /* Allocate the outgoing buffer */
9364 if (r->in.out_data_size) {
9365 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9366 if (out_data.data == NULL) {
9371 switch ( Printer->printer_type ) {
9372 case SPLHND_PORTMON_TCP:
9373 werror = process_xcvtcp_command(p->mem_ctx,
9374 p->server_info->ptok,
9375 r->in.function_name,
9376 &r->in.in_data, &out_data,
9379 case SPLHND_PORTMON_LOCAL:
9380 werror = process_xcvlocal_command(p->mem_ctx,
9381 p->server_info->ptok,
9382 r->in.function_name,
9383 &r->in.in_data, &out_data,
9387 werror = WERR_INVALID_PRINT_MONITOR;
9390 if (!W_ERROR_IS_OK(werror)) {
9394 *r->out.status_code = 0;
9396 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9397 memcpy(r->out.out_data, out_data.data,
9398 MIN(r->in.out_data_size, out_data.length));
9404 /****************************************************************
9405 _spoolss_AddPrintProcessor
9406 ****************************************************************/
9408 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9409 struct spoolss_AddPrintProcessor *r)
9411 /* for now, just indicate success and ignore the add. We'll
9412 automatically set the winprint processor for printer
9413 entries later. Used to debug the LexMark Optra S 1855 PCL
9419 /****************************************************************
9421 ****************************************************************/
9423 WERROR _spoolss_AddPort(struct pipes_struct *p,
9424 struct spoolss_AddPort *r)
9426 /* do what w2k3 does */
9428 return WERR_NOT_SUPPORTED;
9431 /****************************************************************
9432 _spoolss_GetPrinterDriver
9433 ****************************************************************/
9435 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9436 struct spoolss_GetPrinterDriver *r)
9438 p->rng_fault_state = true;
9439 return WERR_NOT_SUPPORTED;
9442 /****************************************************************
9443 _spoolss_ReadPrinter
9444 ****************************************************************/
9446 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9447 struct spoolss_ReadPrinter *r)
9449 p->rng_fault_state = true;
9450 return WERR_NOT_SUPPORTED;
9453 /****************************************************************
9454 _spoolss_WaitForPrinterChange
9455 ****************************************************************/
9457 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9458 struct spoolss_WaitForPrinterChange *r)
9460 p->rng_fault_state = true;
9461 return WERR_NOT_SUPPORTED;
9464 /****************************************************************
9465 _spoolss_ConfigurePort
9466 ****************************************************************/
9468 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9469 struct spoolss_ConfigurePort *r)
9471 p->rng_fault_state = true;
9472 return WERR_NOT_SUPPORTED;
9475 /****************************************************************
9477 ****************************************************************/
9479 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9480 struct spoolss_DeletePort *r)
9482 p->rng_fault_state = true;
9483 return WERR_NOT_SUPPORTED;
9486 /****************************************************************
9487 _spoolss_CreatePrinterIC
9488 ****************************************************************/
9490 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9491 struct spoolss_CreatePrinterIC *r)
9493 p->rng_fault_state = true;
9494 return WERR_NOT_SUPPORTED;
9497 /****************************************************************
9498 _spoolss_PlayGDIScriptOnPrinterIC
9499 ****************************************************************/
9501 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9502 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9504 p->rng_fault_state = true;
9505 return WERR_NOT_SUPPORTED;
9508 /****************************************************************
9509 _spoolss_DeletePrinterIC
9510 ****************************************************************/
9512 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9513 struct spoolss_DeletePrinterIC *r)
9515 p->rng_fault_state = true;
9516 return WERR_NOT_SUPPORTED;
9519 /****************************************************************
9520 _spoolss_AddPrinterConnection
9521 ****************************************************************/
9523 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9524 struct spoolss_AddPrinterConnection *r)
9526 p->rng_fault_state = true;
9527 return WERR_NOT_SUPPORTED;
9530 /****************************************************************
9531 _spoolss_DeletePrinterConnection
9532 ****************************************************************/
9534 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9535 struct spoolss_DeletePrinterConnection *r)
9537 p->rng_fault_state = true;
9538 return WERR_NOT_SUPPORTED;
9541 /****************************************************************
9542 _spoolss_PrinterMessageBox
9543 ****************************************************************/
9545 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9546 struct spoolss_PrinterMessageBox *r)
9548 p->rng_fault_state = true;
9549 return WERR_NOT_SUPPORTED;
9552 /****************************************************************
9554 ****************************************************************/
9556 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9557 struct spoolss_AddMonitor *r)
9559 p->rng_fault_state = true;
9560 return WERR_NOT_SUPPORTED;
9563 /****************************************************************
9564 _spoolss_DeleteMonitor
9565 ****************************************************************/
9567 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9568 struct spoolss_DeleteMonitor *r)
9570 p->rng_fault_state = true;
9571 return WERR_NOT_SUPPORTED;
9574 /****************************************************************
9575 _spoolss_DeletePrintProcessor
9576 ****************************************************************/
9578 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9579 struct spoolss_DeletePrintProcessor *r)
9581 p->rng_fault_state = true;
9582 return WERR_NOT_SUPPORTED;
9585 /****************************************************************
9586 _spoolss_AddPrintProvidor
9587 ****************************************************************/
9589 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9590 struct spoolss_AddPrintProvidor *r)
9592 p->rng_fault_state = true;
9593 return WERR_NOT_SUPPORTED;
9596 /****************************************************************
9597 _spoolss_DeletePrintProvidor
9598 ****************************************************************/
9600 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9601 struct spoolss_DeletePrintProvidor *r)
9603 p->rng_fault_state = true;
9604 return WERR_NOT_SUPPORTED;
9607 /****************************************************************
9608 _spoolss_FindFirstPrinterChangeNotification
9609 ****************************************************************/
9611 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9612 struct spoolss_FindFirstPrinterChangeNotification *r)
9614 p->rng_fault_state = true;
9615 return WERR_NOT_SUPPORTED;
9618 /****************************************************************
9619 _spoolss_FindNextPrinterChangeNotification
9620 ****************************************************************/
9622 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9623 struct spoolss_FindNextPrinterChangeNotification *r)
9625 p->rng_fault_state = true;
9626 return WERR_NOT_SUPPORTED;
9629 /****************************************************************
9630 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9631 ****************************************************************/
9633 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9634 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9636 p->rng_fault_state = true;
9637 return WERR_NOT_SUPPORTED;
9640 /****************************************************************
9641 _spoolss_ReplyOpenPrinter
9642 ****************************************************************/
9644 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9645 struct spoolss_ReplyOpenPrinter *r)
9647 p->rng_fault_state = true;
9648 return WERR_NOT_SUPPORTED;
9651 /****************************************************************
9652 _spoolss_RouterReplyPrinter
9653 ****************************************************************/
9655 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9656 struct spoolss_RouterReplyPrinter *r)
9658 p->rng_fault_state = true;
9659 return WERR_NOT_SUPPORTED;
9662 /****************************************************************
9663 _spoolss_ReplyClosePrinter
9664 ****************************************************************/
9666 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9667 struct spoolss_ReplyClosePrinter *r)
9669 p->rng_fault_state = true;
9670 return WERR_NOT_SUPPORTED;
9673 /****************************************************************
9675 ****************************************************************/
9677 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9678 struct spoolss_AddPortEx *r)
9680 p->rng_fault_state = true;
9681 return WERR_NOT_SUPPORTED;
9684 /****************************************************************
9685 _spoolss_RouterFindFirstPrinterChangeNotification
9686 ****************************************************************/
9688 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9689 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9691 p->rng_fault_state = true;
9692 return WERR_NOT_SUPPORTED;
9695 /****************************************************************
9696 _spoolss_SpoolerInit
9697 ****************************************************************/
9699 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9700 struct spoolss_SpoolerInit *r)
9702 p->rng_fault_state = true;
9703 return WERR_NOT_SUPPORTED;
9706 /****************************************************************
9707 _spoolss_ResetPrinterEx
9708 ****************************************************************/
9710 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9711 struct spoolss_ResetPrinterEx *r)
9713 p->rng_fault_state = true;
9714 return WERR_NOT_SUPPORTED;
9717 /****************************************************************
9718 _spoolss_RouterReplyPrinterEx
9719 ****************************************************************/
9721 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9722 struct spoolss_RouterReplyPrinterEx *r)
9724 p->rng_fault_state = true;
9725 return WERR_NOT_SUPPORTED;
9728 /****************************************************************
9730 ****************************************************************/
9732 WERROR _spoolss_44(struct pipes_struct *p,
9733 struct spoolss_44 *r)
9735 p->rng_fault_state = true;
9736 return WERR_NOT_SUPPORTED;
9739 /****************************************************************
9741 ****************************************************************/
9743 WERROR _spoolss_47(struct pipes_struct *p,
9744 struct spoolss_47 *r)
9746 p->rng_fault_state = true;
9747 return WERR_NOT_SUPPORTED;
9750 /****************************************************************
9752 ****************************************************************/
9754 WERROR _spoolss_4a(struct pipes_struct *p,
9755 struct spoolss_4a *r)
9757 p->rng_fault_state = true;
9758 return WERR_NOT_SUPPORTED;
9761 /****************************************************************
9763 ****************************************************************/
9765 WERROR _spoolss_4b(struct pipes_struct *p,
9766 struct spoolss_4b *r)
9768 p->rng_fault_state = true;
9769 return WERR_NOT_SUPPORTED;
9772 /****************************************************************
9774 ****************************************************************/
9776 WERROR _spoolss_4c(struct pipes_struct *p,
9777 struct spoolss_4c *r)
9779 p->rng_fault_state = true;
9780 return WERR_NOT_SUPPORTED;
9783 /****************************************************************
9785 ****************************************************************/
9787 WERROR _spoolss_53(struct pipes_struct *p,
9788 struct spoolss_53 *r)
9790 p->rng_fault_state = true;
9791 return WERR_NOT_SUPPORTED;
9794 /****************************************************************
9796 ****************************************************************/
9798 WERROR _spoolss_55(struct pipes_struct *p,
9799 struct spoolss_55 *r)
9801 p->rng_fault_state = true;
9802 return WERR_NOT_SUPPORTED;
9805 /****************************************************************
9807 ****************************************************************/
9809 WERROR _spoolss_56(struct pipes_struct *p,
9810 struct spoolss_56 *r)
9812 p->rng_fault_state = true;
9813 return WERR_NOT_SUPPORTED;
9816 /****************************************************************
9818 ****************************************************************/
9820 WERROR _spoolss_57(struct pipes_struct *p,
9821 struct spoolss_57 *r)
9823 p->rng_fault_state = true;
9824 return WERR_NOT_SUPPORTED;
9827 /****************************************************************
9829 ****************************************************************/
9831 WERROR _spoolss_5a(struct pipes_struct *p,
9832 struct spoolss_5a *r)
9834 p->rng_fault_state = true;
9835 return WERR_NOT_SUPPORTED;
9838 /****************************************************************
9840 ****************************************************************/
9842 WERROR _spoolss_5b(struct pipes_struct *p,
9843 struct spoolss_5b *r)
9845 p->rng_fault_state = true;
9846 return WERR_NOT_SUPPORTED;
9849 /****************************************************************
9851 ****************************************************************/
9853 WERROR _spoolss_5c(struct pipes_struct *p,
9854 struct spoolss_5c *r)
9856 p->rng_fault_state = true;
9857 return WERR_NOT_SUPPORTED;
9860 /****************************************************************
9862 ****************************************************************/
9864 WERROR _spoolss_5d(struct pipes_struct *p,
9865 struct spoolss_5d *r)
9867 p->rng_fault_state = true;
9868 return WERR_NOT_SUPPORTED;
9871 /****************************************************************
9873 ****************************************************************/
9875 WERROR _spoolss_5e(struct pipes_struct *p,
9876 struct spoolss_5e *r)
9878 p->rng_fault_state = true;
9879 return WERR_NOT_SUPPORTED;
9882 /****************************************************************
9884 ****************************************************************/
9886 WERROR _spoolss_5f(struct pipes_struct *p,
9887 struct spoolss_5f *r)
9889 p->rng_fault_state = true;
9890 return WERR_NOT_SUPPORTED;
9893 /****************************************************************
9895 ****************************************************************/
9897 WERROR _spoolss_60(struct pipes_struct *p,
9898 struct spoolss_60 *r)
9900 p->rng_fault_state = true;
9901 return WERR_NOT_SUPPORTED;
9904 /****************************************************************
9906 ****************************************************************/
9908 WERROR _spoolss_61(struct pipes_struct *p,
9909 struct spoolss_61 *r)
9911 p->rng_fault_state = true;
9912 return WERR_NOT_SUPPORTED;
9915 /****************************************************************
9917 ****************************************************************/
9919 WERROR _spoolss_62(struct pipes_struct *p,
9920 struct spoolss_62 *r)
9922 p->rng_fault_state = true;
9923 return WERR_NOT_SUPPORTED;
9926 /****************************************************************
9928 ****************************************************************/
9930 WERROR _spoolss_63(struct pipes_struct *p,
9931 struct spoolss_63 *r)
9933 p->rng_fault_state = true;
9934 return WERR_NOT_SUPPORTED;
9937 /****************************************************************
9939 ****************************************************************/
9941 WERROR _spoolss_64(struct pipes_struct *p,
9942 struct spoolss_64 *r)
9944 p->rng_fault_state = true;
9945 return WERR_NOT_SUPPORTED;
9948 /****************************************************************
9950 ****************************************************************/
9952 WERROR _spoolss_65(struct pipes_struct *p,
9953 struct spoolss_65 *r)
9955 p->rng_fault_state = true;
9956 return WERR_NOT_SUPPORTED;
9959 /****************************************************************
9960 _spoolss_GetCorePrinterDrivers
9961 ****************************************************************/
9963 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9964 struct spoolss_GetCorePrinterDrivers *r)
9966 p->rng_fault_state = true;
9967 return WERR_NOT_SUPPORTED;
9970 /****************************************************************
9972 ****************************************************************/
9974 WERROR _spoolss_67(struct pipes_struct *p,
9975 struct spoolss_67 *r)
9977 p->rng_fault_state = true;
9978 return WERR_NOT_SUPPORTED;
9981 /****************************************************************
9982 _spoolss_GetPrinterDriverPackagePath
9983 ****************************************************************/
9985 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
9986 struct spoolss_GetPrinterDriverPackagePath *r)
9988 p->rng_fault_state = true;
9989 return WERR_NOT_SUPPORTED;
9992 /****************************************************************
9994 ****************************************************************/
9996 WERROR _spoolss_69(struct pipes_struct *p,
9997 struct spoolss_69 *r)
9999 p->rng_fault_state = true;
10000 return WERR_NOT_SUPPORTED;
10003 /****************************************************************
10005 ****************************************************************/
10007 WERROR _spoolss_6a(struct pipes_struct *p,
10008 struct spoolss_6a *r)
10010 p->rng_fault_state = true;
10011 return WERR_NOT_SUPPORTED;
10014 /****************************************************************
10016 ****************************************************************/
10018 WERROR _spoolss_6b(struct pipes_struct *p,
10019 struct spoolss_6b *r)
10021 p->rng_fault_state = true;
10022 return WERR_NOT_SUPPORTED;
10025 /****************************************************************
10027 ****************************************************************/
10029 WERROR _spoolss_6c(struct pipes_struct *p,
10030 struct spoolss_6c *r)
10032 p->rng_fault_state = true;
10033 return WERR_NOT_SUPPORTED;
10036 /****************************************************************
10038 ****************************************************************/
10040 WERROR _spoolss_6d(struct pipes_struct *p,
10041 struct spoolss_6d *r)
10043 p->rng_fault_state = true;
10044 return WERR_NOT_SUPPORTED;