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"
45 /* macros stolen from s4 spoolss server */
46 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
47 ((info)?ndr_size_##fn(info, level, 0):0)
49 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
50 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
52 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
53 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
55 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
58 #define DBGC_CLASS DBGC_RPC_SRV
60 static Printer_entry *printers_list;
62 typedef struct _counter_printer_0 {
63 struct _counter_printer_0 *next;
64 struct _counter_printer_0 *prev;
70 static counter_printer_0 *counter_list;
72 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
73 static uint32_t smb_connections = 0;
76 /* Map generic permissions to printer object specific permissions */
78 const struct standard_mapping printer_std_mapping = {
85 /* Map generic permissions to print server object specific permissions */
87 const struct standard_mapping printserver_std_mapping = {
94 /* API table for Xcv Monitor functions */
96 struct xcv_api_table {
98 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
101 /********************************************************************
102 * Canonicalize servername.
103 ********************************************************************/
105 static const char *canon_servername(const char *servername)
107 const char *pservername = servername;
108 while (*pservername == '\\') {
114 /* translate between internal status numbers and NT status numbers */
115 static int nt_printj_status(int v)
121 return JOB_STATUS_PAUSED;
123 return JOB_STATUS_SPOOLING;
125 return JOB_STATUS_PRINTING;
127 return JOB_STATUS_ERROR;
129 return JOB_STATUS_DELETING;
131 return JOB_STATUS_OFFLINE;
133 return JOB_STATUS_PAPEROUT;
135 return JOB_STATUS_PRINTED;
137 return JOB_STATUS_DELETED;
139 return JOB_STATUS_BLOCKED_DEVQ;
140 case LPQ_USER_INTERVENTION:
141 return JOB_STATUS_USER_INTERVENTION;
146 static int nt_printq_status(int v)
150 return PRINTER_STATUS_PAUSED;
159 /***************************************************************************
160 Disconnect from the client
161 ****************************************************************************/
163 static void srv_spoolss_replycloseprinter(
164 int snum, struct policy_handle *handle,
165 struct messaging_context *msg_ctx)
171 * Tell the specific printing tdb we no longer want messages for this printer
172 * by deregistering our PID.
175 if (!print_notify_deregister_pid(snum))
176 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
178 /* weird if the test succeeds !!! */
179 if (smb_connections==0) {
180 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
184 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
187 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
188 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
189 win_errstr(result)));
191 /* if it's the last connection, deconnect the IPC$ share */
192 if (smb_connections==1) {
194 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
196 * The above call shuts down the pipe also.
198 notify_cli_pipe = NULL;
200 if (msg_ctx != NULL) {
201 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
205 * Tell the serverid.tdb we're no longer
206 * interested in printer notify messages.
209 serverid_register_msg_flags(
210 messaging_server_id(msg_ctx),
211 false, FLAG_MSG_PRINT_NOTIFY);
218 /****************************************************************************
219 Functions to free a printer entry datastruct.
220 ****************************************************************************/
222 static int printer_entry_destructor(Printer_entry *Printer)
224 if (Printer->notify.client_connected == true) {
227 if ( Printer->printer_type == SPLHND_SERVER) {
229 srv_spoolss_replycloseprinter(
230 snum, &Printer->notify.client_hnd,
231 Printer->notify.msg_ctx);
232 } else if (Printer->printer_type == SPLHND_PRINTER) {
233 snum = print_queue_snum(Printer->sharename);
235 srv_spoolss_replycloseprinter(
236 snum, &Printer->notify.client_hnd,
237 Printer->notify.msg_ctx);
241 Printer->notify.flags=0;
242 Printer->notify.options=0;
243 Printer->notify.localmachine[0]='\0';
244 Printer->notify.printerlocal=0;
245 TALLOC_FREE(Printer->notify.option);
246 Printer->notify.client_connected = false;
248 TALLOC_FREE(Printer->devmode);
250 /* Remove from the internal list. */
251 DLIST_REMOVE(printers_list, Printer);
255 /****************************************************************************
256 find printer index by handle
257 ****************************************************************************/
259 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
260 struct policy_handle *hnd)
262 Printer_entry *find_printer = NULL;
264 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
265 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
272 /****************************************************************************
273 Close printer index by handle.
274 ****************************************************************************/
276 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
278 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
281 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
286 close_policy_hnd(p, hnd);
291 /****************************************************************************
292 Delete a printer given a handle.
293 ****************************************************************************/
295 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
296 const char *sharename,
297 struct messaging_context *msg_ctx)
299 char *cmd = lp_deleteprinter_cmd();
300 char *command = NULL;
302 SE_PRIV se_printop = SE_PRINT_OPERATOR;
303 bool is_print_op = false;
305 /* can't fail if we don't try */
310 command = talloc_asprintf(ctx,
317 is_print_op = user_has_privileges( token, &se_printop );
319 DEBUG(10,("Running [%s]\n", command));
321 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
326 if ( (ret = smbrun(command, NULL)) == 0 ) {
327 /* Tell everyone we updated smb.conf. */
328 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
334 /********** END SePrintOperatorPrivlege BLOCK **********/
336 DEBUGADD(10,("returned [%d]\n", ret));
338 TALLOC_FREE(command);
341 return WERR_BADFID; /* What to return here? */
343 /* go ahead and re-read the services immediately */
345 reload_services(msg_ctx, smbd_server_fd(), false);
348 if ( lp_servicenumber( sharename ) > 0 )
349 return WERR_ACCESS_DENIED;
354 /****************************************************************************
355 Delete a printer given a handle.
356 ****************************************************************************/
358 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
360 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
364 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
370 * It turns out that Windows allows delete printer on a handle
371 * opened by an admin user, then used on a pipe handle created
372 * by an anonymous user..... but they're working on security.... riiight !
376 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
377 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
378 return WERR_ACCESS_DENIED;
381 /* this does not need a become root since the access check has been
382 done on the handle already */
384 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
385 p->msg_ctx, Printer->sharename, "");
386 if (!W_ERROR_IS_OK(result)) {
387 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
391 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
392 Printer->sharename, p->msg_ctx);
395 /****************************************************************************
396 Return the snum of a printer corresponding to an handle.
397 ****************************************************************************/
399 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
400 int *number, struct share_params **params)
402 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
405 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
410 switch (Printer->printer_type) {
412 DEBUG(4,("short name:%s\n", Printer->sharename));
413 *number = print_queue_snum(Printer->sharename);
414 return (*number != -1);
422 /****************************************************************************
423 Set printer handle type.
424 Check if it's \\server or \\server\printer
425 ****************************************************************************/
427 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
429 DEBUG(3,("Setting printer type=%s\n", handlename));
431 if ( strlen(handlename) < 3 ) {
432 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
436 /* it's a print server */
437 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
438 DEBUGADD(4,("Printer is a print server\n"));
439 Printer->printer_type = SPLHND_SERVER;
441 /* it's a printer (set_printer_hnd_name() will handle port monitors */
443 DEBUGADD(4,("Printer is a printer\n"));
444 Printer->printer_type = SPLHND_PRINTER;
450 /****************************************************************************
451 Set printer handle name.. Accept names like \\server, \\server\printer,
452 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
453 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
454 XcvDataPort() interface.
455 ****************************************************************************/
457 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
458 struct auth_serversupplied_info *server_info,
459 struct messaging_context *msg_ctx,
460 Printer_entry *Printer,
461 const char *handlename)
464 int n_services=lp_numservices();
466 const char *printername;
467 const char *servername = NULL;
470 struct spoolss_PrinterInfo2 *info2 = NULL;
473 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
474 (unsigned long)strlen(handlename)));
476 aprinter = CONST_DISCARD(char *, handlename);
477 if ( *handlename == '\\' ) {
478 servername = canon_servername(handlename);
479 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
483 if (!is_myname_or_ipaddr(servername)) {
487 fstrcpy(Printer->servername, servername);
490 if (Printer->printer_type == SPLHND_SERVER) {
494 if (Printer->printer_type != SPLHND_PRINTER) {
498 DEBUGADD(5, ("searching for [%s]\n", aprinter));
500 /* check for the Port Monitor Interface */
501 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
502 Printer->printer_type = SPLHND_PORTMON_TCP;
503 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
506 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
507 Printer->printer_type = SPLHND_PORTMON_LOCAL;
508 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
512 /* Search all sharenames first as this is easier than pulling
513 the printer_info_2 off of disk. Don't use find_service() since
514 that calls out to map_username() */
516 /* do another loop to look for printernames */
517 for (snum = 0; !found && snum < n_services; snum++) {
518 const char *printer = lp_const_servicename(snum);
520 /* no point going on if this is not a printer */
521 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
525 /* ignore [printers] share */
526 if (strequal(printer, "printers")) {
530 fstrcpy(sname, printer);
531 if (strequal(aprinter, printer)) {
536 /* no point looking up the printer object if
537 we aren't allowing printername != sharename */
538 if (lp_force_printername(snum)) {
542 result = winreg_get_printer(mem_ctx,
548 if ( !W_ERROR_IS_OK(result) ) {
549 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
550 sname, win_errstr(result)));
554 printername = strrchr(info2->printername, '\\');
555 if (printername == NULL) {
556 printername = info2->printername;
561 if (strequal(printername, aprinter)) {
566 DEBUGADD(10, ("printername: %s\n", printername));
572 DEBUGADD(4,("Printer not found\n"));
576 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
578 fstrcpy(Printer->sharename, sname);
583 /****************************************************************************
584 Find first available printer slot. creates a printer handle for you.
585 ****************************************************************************/
587 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
588 const char *name, uint32_t access_granted)
590 Printer_entry *new_printer;
592 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
594 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
595 if (new_printer == NULL) {
598 talloc_set_destructor(new_printer, printer_entry_destructor);
600 if (!create_policy_hnd(p, hnd, new_printer)) {
601 TALLOC_FREE(new_printer);
605 /* Add to the internal list. */
606 DLIST_ADD(printers_list, new_printer);
608 new_printer->notify.option=NULL;
610 if (!set_printer_hnd_printertype(new_printer, name)) {
611 close_printer_handle(p, hnd);
615 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, p->msg_ctx,
616 new_printer, name)) {
617 close_printer_handle(p, hnd);
621 new_printer->access_granted = access_granted;
623 DEBUG(5, ("%d printer handles active\n",
624 (int)num_pipe_handles(p)));
629 /***************************************************************************
630 check to see if the client motify handle is monitoring the notification
631 given by (notify_type, notify_field).
632 **************************************************************************/
634 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
635 uint16_t notify_field)
640 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
641 uint16_t notify_field)
643 struct spoolss_NotifyOption *option = p->notify.option;
647 * Flags should always be zero when the change notify
648 * is registered by the client's spooler. A user Win32 app
649 * might use the flags though instead of the NOTIFY_OPTION_INFO
658 return is_monitoring_event_flags(
659 p->notify.flags, notify_type, notify_field);
661 for (i = 0; i < option->count; i++) {
663 /* Check match for notify_type */
665 if (option->types[i].type != notify_type)
668 /* Check match for field */
670 for (j = 0; j < option->types[i].count; j++) {
671 if (option->types[i].fields[j].field == notify_field) {
677 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
678 p->servername, p->sharename, notify_type, notify_field));
683 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
684 _data->data.integer[0] = _integer; \
685 _data->data.integer[1] = 0;
688 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
689 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
690 if (!_data->data.string.string) {\
691 _data->data.string.size = 0; \
693 _data->data.string.size = strlen_m_term(_p) * 2;
695 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
696 _data->data.devmode.devmode = _devmode;
698 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
699 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
700 if (!_data->data.sd.sd) { \
701 _data->data.sd.sd_size = 0; \
703 _data->data.sd.sd_size = \
704 ndr_size_security_descriptor(_data->data.sd.sd, 0);
706 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
711 struct spoolss_Time st;
715 if (!init_systemtime(&st, t)) {
719 p = talloc_array(mem_ctx, char, len);
725 * Systemtime must be linearized as a set of UINT16's.
726 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
729 SSVAL(p, 0, st.year);
730 SSVAL(p, 2, st.month);
731 SSVAL(p, 4, st.day_of_week);
733 SSVAL(p, 8, st.hour);
734 SSVAL(p, 10, st.minute);
735 SSVAL(p, 12, st.second);
736 SSVAL(p, 14, st.millisecond);
742 /* Convert a notification message to a struct spoolss_Notify */
744 static void notify_one_value(struct spoolss_notify_msg *msg,
745 struct spoolss_Notify *data,
748 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
751 static void notify_string(struct spoolss_notify_msg *msg,
752 struct spoolss_Notify *data,
755 /* The length of the message includes the trailing \0 */
757 data->data.string.size = msg->len * 2;
758 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
759 if (!data->data.string.string) {
760 data->data.string.size = 0;
765 static void notify_system_time(struct spoolss_notify_msg *msg,
766 struct spoolss_Notify *data,
769 data->data.string.string = NULL;
770 data->data.string.size = 0;
772 if (msg->len != sizeof(time_t)) {
773 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
778 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
779 &data->data.string.string,
780 &data->data.string.size);
783 struct notify2_message_table {
785 void (*fn)(struct spoolss_notify_msg *msg,
786 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
789 static struct notify2_message_table printer_notify_table[] = {
790 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
791 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
792 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
793 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
794 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
795 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
796 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
797 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
798 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
799 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
800 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
801 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
802 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
803 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
804 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
805 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
806 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
807 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
808 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
811 static struct notify2_message_table job_notify_table[] = {
812 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
813 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
814 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
815 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
816 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
817 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
818 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
819 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
820 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
821 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
822 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
823 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
824 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
825 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
826 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
827 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
828 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
829 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
830 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
831 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
832 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
833 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
834 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
835 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
839 /***********************************************************************
840 Allocate talloc context for container object
841 **********************************************************************/
843 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
848 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
853 /***********************************************************************
854 release all allocated memory and zero out structure
855 **********************************************************************/
857 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
863 talloc_destroy(ctr->ctx);
870 /***********************************************************************
871 **********************************************************************/
873 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
881 /***********************************************************************
882 **********************************************************************/
884 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
886 if ( !ctr || !ctr->msg_groups )
889 if ( idx >= ctr->num_groups )
892 return &ctr->msg_groups[idx];
896 /***********************************************************************
897 How many groups of change messages do we have ?
898 **********************************************************************/
900 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
905 return ctr->num_groups;
908 /***********************************************************************
909 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
910 **********************************************************************/
912 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
914 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
915 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
916 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
922 /* loop over all groups looking for a matching printer name */
924 for ( i=0; i<ctr->num_groups; i++ ) {
925 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
929 /* add a new group? */
931 if ( i == ctr->num_groups ) {
934 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
935 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
938 ctr->msg_groups = groups;
940 /* clear the new entry and set the printer name */
942 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
943 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
946 /* add the change messages; 'i' is the correct index now regardless */
948 msg_grp = &ctr->msg_groups[i];
952 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
953 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
956 msg_grp->msgs = msg_list;
958 new_slot = msg_grp->num_msgs-1;
959 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
961 /* need to allocate own copy of data */
964 msg_grp->msgs[new_slot].notify.data = (char *)
965 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
967 return ctr->num_groups;
970 static void construct_info_data(struct spoolss_Notify *info_data,
971 enum spoolss_NotifyType type,
972 uint16_t field, int id);
974 /***********************************************************************
975 Send a change notication message on all handles which have a call
977 **********************************************************************/
979 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
982 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
983 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
984 SPOOLSS_NOTIFY_MSG *messages;
985 int sending_msg_count;
988 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
992 messages = msg_group->msgs;
995 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
999 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1001 /* loop over all printers */
1003 for (p = printers_list; p; p = p->next) {
1004 struct spoolss_Notify *notifies;
1009 /* Is there notification on this handle? */
1011 if ( !p->notify.client_connected )
1014 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1016 /* For this printer? Print servers always receive
1019 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1020 ( !strequal(msg_group->printername, p->sharename) ) )
1023 DEBUG(10,("Our printer\n"));
1025 /* allocate the max entries possible */
1027 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1032 /* build the array of change notifications */
1034 sending_msg_count = 0;
1036 for ( i=0; i<msg_group->num_msgs; i++ ) {
1037 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1039 /* Are we monitoring this event? */
1041 if (!is_monitoring_event(p, msg->type, msg->field))
1044 sending_msg_count++;
1047 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1048 msg->type, msg->field, p->sharename));
1051 * if the is a printer notification handle and not a job notification
1052 * type, then set the id to 0. Other wise just use what was specified
1055 * When registering change notification on a print server handle
1056 * we always need to send back the id (snum) matching the printer
1057 * for which the change took place. For change notify registered
1058 * on a printer handle, this does not matter and the id should be 0.
1063 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1069 /* Convert unix jobid to smb jobid */
1071 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1072 id = sysjob_to_jobid(msg->id);
1075 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1080 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1083 case PRINTER_NOTIFY_TYPE:
1084 if ( printer_notify_table[msg->field].fn )
1085 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1088 case JOB_NOTIFY_TYPE:
1089 if ( job_notify_table[msg->field].fn )
1090 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1094 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1101 if ( sending_msg_count ) {
1104 union spoolss_ReplyPrinterInfo info;
1105 struct spoolss_NotifyInfo info0;
1106 uint32_t reply_result;
1108 info0.version = 0x2;
1109 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1110 info0.count = count;
1111 info0.notifies = notifies;
1113 info.info0 = &info0;
1115 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1116 &p->notify.client_hnd,
1117 p->notify.change, /* color */
1120 0, /* reply_type, must be 0 */
1123 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1124 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1125 notify_cli_pipe->srv_name_slash,
1128 switch (reply_result) {
1131 case PRINTER_NOTIFY_INFO_DISCARDED:
1132 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1133 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1142 DEBUG(8,("send_notify2_changes: Exit...\n"));
1146 /***********************************************************************
1147 **********************************************************************/
1149 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1152 uint32_t tv_sec, tv_usec;
1155 /* Unpack message */
1157 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1160 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1162 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1165 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1166 &msg->notify.value[0], &msg->notify.value[1]);
1168 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1169 &msg->len, &msg->notify.data);
1171 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1172 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1174 tv->tv_sec = tv_sec;
1175 tv->tv_usec = tv_usec;
1178 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1179 msg->notify.value[1]));
1181 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1186 /********************************************************************
1187 Receive a notify2 message list
1188 ********************************************************************/
1190 static void receive_notify2_message_list(struct messaging_context *msg,
1193 struct server_id server_id,
1196 size_t msg_count, i;
1197 char *buf = (char *)data->data;
1200 SPOOLSS_NOTIFY_MSG notify;
1201 SPOOLSS_NOTIFY_MSG_CTR messages;
1204 if (data->length < 4) {
1205 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1209 msg_count = IVAL(buf, 0);
1212 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1214 if (msg_count == 0) {
1215 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1219 /* initialize the container */
1221 ZERO_STRUCT( messages );
1222 notify_msg_ctr_init( &messages );
1225 * build message groups for each printer identified
1226 * in a change_notify msg. Remember that a PCN message
1227 * includes the handle returned for the srv_spoolss_replyopenprinter()
1228 * call. Therefore messages are grouped according to printer handle.
1231 for ( i=0; i<msg_count; i++ ) {
1232 struct timeval msg_tv;
1234 if (msg_ptr + 4 - buf > data->length) {
1235 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1239 msg_len = IVAL(msg_ptr,0);
1242 if (msg_ptr + msg_len - buf > data->length) {
1243 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1247 /* unpack messages */
1249 ZERO_STRUCT( notify );
1250 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1253 /* add to correct list in container */
1255 notify_msg_ctr_addmsg( &messages, ¬ify );
1257 /* free memory that might have been allocated by notify2_unpack_msg() */
1259 if ( notify.len != 0 )
1260 SAFE_FREE( notify.notify.data );
1263 /* process each group of messages */
1265 num_groups = notify_msg_ctr_numgroups( &messages );
1266 for ( i=0; i<num_groups; i++ )
1267 send_notify2_changes( &messages, i );
1272 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1273 (uint32_t)msg_count ));
1275 notify_msg_ctr_destroy( &messages );
1280 /********************************************************************
1281 Send a message to ourself about new driver being installed
1282 so we can upgrade the information for each printer bound to this
1284 ********************************************************************/
1286 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1287 struct messaging_context *msg_ctx)
1289 int len = strlen(drivername);
1294 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1297 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1298 MSG_PRINTER_DRVUPGRADE,
1299 (uint8_t *)drivername, len+1);
1304 /**********************************************************************
1305 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1306 over all printers, upgrading ones as necessary
1307 **********************************************************************/
1309 void do_drv_upgrade_printer(struct messaging_context *msg,
1312 struct server_id server_id,
1315 TALLOC_CTX *tmp_ctx;
1316 struct auth_serversupplied_info *server_info = NULL;
1317 struct spoolss_PrinterInfo2 *pinfo2;
1320 const char *drivername;
1322 int n_services = lp_numservices();
1325 tmp_ctx = talloc_new(NULL);
1326 if (!tmp_ctx) return;
1328 status = make_server_info_system(tmp_ctx, &server_info);
1329 if (!NT_STATUS_IS_OK(status)) {
1330 DEBUG(0, ("do_drv_upgrade_printer: "
1331 "Could not create system server_info\n"));
1335 len = MIN(data->length,sizeof(drivername)-1);
1336 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1338 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1342 DEBUG(10, ("do_drv_upgrade_printer: "
1343 "Got message for new driver [%s]\n", drivername));
1345 /* Iterate the printer list */
1347 for (snum = 0; snum < n_services; snum++) {
1348 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1352 result = winreg_get_printer(tmp_ctx, server_info, msg,
1354 lp_const_servicename(snum),
1357 if (!W_ERROR_IS_OK(result)) {
1361 if (!pinfo2->drivername) {
1365 if (strcmp(drivername, pinfo2->drivername) != 0) {
1369 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1371 /* all we care about currently is the change_id */
1372 result = winreg_printer_update_changeid(tmp_ctx,
1375 pinfo2->printername);
1377 if (!W_ERROR_IS_OK(result)) {
1378 DEBUG(3, ("do_drv_upgrade_printer: "
1379 "Failed to update changeid [%s]\n",
1380 win_errstr(result)));
1386 talloc_free(tmp_ctx);
1389 /********************************************************************
1390 Update the cache for all printq's with a registered client
1392 ********************************************************************/
1394 void update_monitored_printq_cache(struct messaging_context *msg_ctx)
1396 Printer_entry *printer = printers_list;
1399 /* loop through all printers and update the cache where
1400 client_connected == true */
1403 if ( (printer->printer_type == SPLHND_PRINTER)
1404 && printer->notify.client_connected )
1406 snum = print_queue_snum(printer->sharename);
1407 print_queue_status(msg_ctx, snum, NULL, NULL );
1410 printer = printer->next;
1416 /****************************************************************
1417 _spoolss_OpenPrinter
1418 ****************************************************************/
1420 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1421 struct spoolss_OpenPrinter *r)
1423 struct spoolss_OpenPrinterEx e;
1426 ZERO_STRUCT(e.in.userlevel);
1428 e.in.printername = r->in.printername;
1429 e.in.datatype = r->in.datatype;
1430 e.in.devmode_ctr = r->in.devmode_ctr;
1431 e.in.access_mask = r->in.access_mask;
1434 e.out.handle = r->out.handle;
1436 werr = _spoolss_OpenPrinterEx(p, &e);
1438 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1439 /* OpenPrinterEx returns this for a bad
1440 * printer name. We must return WERR_INVALID_PRINTER_NAME
1443 werr = WERR_INVALID_PRINTER_NAME;
1449 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1450 struct spoolss_DeviceMode *orig,
1451 struct spoolss_DeviceMode **dest)
1453 struct spoolss_DeviceMode *dm;
1455 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1460 /* copy all values, then duplicate strings and structs */
1463 dm->devicename = talloc_strdup(dm, orig->devicename);
1464 if (!dm->devicename) {
1467 dm->formname = talloc_strdup(dm, orig->formname);
1468 if (!dm->formname) {
1471 if (orig->driverextra_data.data) {
1472 dm->driverextra_data.data =
1473 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1474 orig->driverextra_data.length);
1475 if (!dm->driverextra_data.data) {
1484 /****************************************************************
1485 _spoolss_OpenPrinterEx
1486 ****************************************************************/
1488 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1489 struct spoolss_OpenPrinterEx *r)
1492 Printer_entry *Printer=NULL;
1494 if (!r->in.printername) {
1495 return WERR_INVALID_PARAM;
1498 /* some sanity check because you can open a printer or a print server */
1499 /* aka: \\server\printer or \\server */
1501 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1503 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1504 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1505 " for printer %s\n", r->in.printername));
1506 ZERO_STRUCTP(r->out.handle);
1507 return WERR_INVALID_PARAM;
1510 Printer = find_printer_index_by_hnd(p, r->out.handle);
1512 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1513 "handle we created for printer %s\n", r->in.printername));
1514 close_printer_handle(p, r->out.handle);
1515 ZERO_STRUCTP(r->out.handle);
1516 return WERR_INVALID_PARAM;
1520 * First case: the user is opening the print server:
1522 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1523 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1525 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1526 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1527 * or if the user is listed in the smb.conf printer admin parameter.
1529 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1530 * client view printer folder, but does not show the MSAPW.
1532 * Note: this test needs code to check access rights here too. Jeremy
1533 * could you look at this?
1535 * Second case: the user is opening a printer:
1536 * NT doesn't let us connect to a printer if the connecting user
1537 * doesn't have print permission.
1539 * Third case: user is opening a Port Monitor
1540 * access checks same as opening a handle to the print server.
1543 switch (Printer->printer_type )
1546 case SPLHND_PORTMON_TCP:
1547 case SPLHND_PORTMON_LOCAL:
1548 /* Printserver handles use global struct... */
1552 /* Map standard access rights to object specific access rights */
1554 se_map_standard(&r->in.access_mask,
1555 &printserver_std_mapping);
1557 /* Deny any object specific bits that don't apply to print
1558 servers (i.e printer and job specific bits) */
1560 r->in.access_mask &= SEC_MASK_SPECIFIC;
1562 if (r->in.access_mask &
1563 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1564 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1565 close_printer_handle(p, r->out.handle);
1566 ZERO_STRUCTP(r->out.handle);
1567 return WERR_ACCESS_DENIED;
1570 /* Allow admin access */
1572 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1574 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1576 if (!lp_ms_add_printer_wizard()) {
1577 close_printer_handle(p, r->out.handle);
1578 ZERO_STRUCTP(r->out.handle);
1579 return WERR_ACCESS_DENIED;
1582 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1583 and not a printer admin, then fail */
1585 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1586 !user_has_privileges(p->server_info->ptok,
1588 !token_contains_name_in_list(
1589 uidtoname(p->server_info->utok.uid),
1590 p->server_info->info3->base.domain.string,
1592 p->server_info->ptok,
1593 lp_printer_admin(snum))) {
1594 close_printer_handle(p, r->out.handle);
1595 ZERO_STRUCTP(r->out.handle);
1596 return WERR_ACCESS_DENIED;
1599 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1603 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1606 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1607 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1609 /* We fall through to return WERR_OK */
1612 case SPLHND_PRINTER:
1613 /* NT doesn't let us connect to a printer if the connecting user
1614 doesn't have print permission. */
1616 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1617 close_printer_handle(p, r->out.handle);
1618 ZERO_STRUCTP(r->out.handle);
1622 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1623 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1626 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1628 /* map an empty access mask to the minimum access mask */
1629 if (r->in.access_mask == 0x0)
1630 r->in.access_mask = PRINTER_ACCESS_USE;
1633 * If we are not serving the printer driver for this printer,
1634 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1635 * will keep NT clients happy --jerry
1638 if (lp_use_client_driver(snum)
1639 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1641 r->in.access_mask = PRINTER_ACCESS_USE;
1644 /* check smb.conf parameters and the the sec_desc */
1646 if (!allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
1647 p->client_id->name, p->client_id->addr)) {
1648 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1649 ZERO_STRUCTP(r->out.handle);
1650 return WERR_ACCESS_DENIED;
1653 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1654 p->server_info->ptok, snum) ||
1655 !print_access_check(p->server_info, p->msg_ctx, snum,
1656 r->in.access_mask)) {
1657 DEBUG(3, ("access DENIED for printer open\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 & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1664 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1665 close_printer_handle(p, r->out.handle);
1666 ZERO_STRUCTP(r->out.handle);
1667 return WERR_ACCESS_DENIED;
1670 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1671 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1673 r->in.access_mask = PRINTER_ACCESS_USE;
1675 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1676 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1678 winreg_create_printer(p->mem_ctx,
1681 Printer->servername,
1682 lp_const_servicename(snum));
1687 /* sanity check to prevent programmer error */
1688 ZERO_STRUCTP(r->out.handle);
1692 Printer->access_granted = r->in.access_mask;
1695 * If the client sent a devmode in the OpenPrinter() call, then
1696 * save it here in case we get a job submission on this handle
1699 if ((Printer->printer_type != SPLHND_SERVER) &&
1700 r->in.devmode_ctr.devmode) {
1701 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1705 #if 0 /* JERRY -- I'm doubtful this is really effective */
1706 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1707 optimization in Windows 2000 clients --jerry */
1709 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1710 && (RA_WIN2K == get_remote_arch()) )
1712 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1713 sys_usleep( 500000 );
1720 /****************************************************************
1721 _spoolss_ClosePrinter
1722 ****************************************************************/
1724 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1725 struct spoolss_ClosePrinter *r)
1727 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1729 if (Printer && Printer->document_started) {
1730 struct spoolss_EndDocPrinter e;
1732 e.in.handle = r->in.handle;
1734 _spoolss_EndDocPrinter(p, &e);
1737 if (!close_printer_handle(p, r->in.handle))
1740 /* clear the returned printer handle. Observed behavior
1741 from Win2k server. Don't think this really matters.
1742 Previous code just copied the value of the closed
1745 ZERO_STRUCTP(r->out.handle);
1750 /****************************************************************
1751 _spoolss_DeletePrinter
1752 ****************************************************************/
1754 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1755 struct spoolss_DeletePrinter *r)
1757 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1761 if (Printer && Printer->document_started) {
1762 struct spoolss_EndDocPrinter e;
1764 e.in.handle = r->in.handle;
1766 _spoolss_EndDocPrinter(p, &e);
1769 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1770 winreg_delete_printer_key(p->mem_ctx,
1773 lp_const_servicename(snum),
1777 result = delete_printer_handle(p, r->in.handle);
1782 /*******************************************************************
1783 * static function to lookup the version id corresponding to an
1784 * long architecture string
1785 ******************************************************************/
1787 static const struct print_architecture_table_node archi_table[]= {
1789 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1790 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1791 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1792 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1793 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1794 {"Windows IA64", SPL_ARCH_IA64, 3 },
1795 {"Windows x64", SPL_ARCH_X64, 3 },
1799 static int get_version_id(const char *arch)
1803 for (i=0; archi_table[i].long_archi != NULL; i++)
1805 if (strcmp(arch, archi_table[i].long_archi) == 0)
1806 return (archi_table[i].version);
1812 /****************************************************************
1813 _spoolss_DeletePrinterDriver
1814 ****************************************************************/
1816 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1817 struct spoolss_DeletePrinterDriver *r)
1820 struct spoolss_DriverInfo8 *info = NULL;
1821 struct spoolss_DriverInfo8 *info_win2k = NULL;
1824 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1826 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1827 and not a printer admin, then fail */
1829 if ( (p->server_info->utok.uid != sec_initial_uid())
1830 && !user_has_privileges(p->server_info->ptok, &se_printop )
1831 && !token_contains_name_in_list(
1832 uidtoname(p->server_info->utok.uid),
1833 p->server_info->info3->base.domain.string,
1835 p->server_info->ptok,
1836 lp_printer_admin(-1)) )
1838 return WERR_ACCESS_DENIED;
1841 /* check that we have a valid driver name first */
1843 if ((version = get_version_id(r->in.architecture)) == -1)
1844 return WERR_INVALID_ENVIRONMENT;
1846 status = winreg_get_driver(p->mem_ctx, p->server_info, p->msg_ctx,
1847 r->in.architecture, r->in.driver,
1849 if (!W_ERROR_IS_OK(status)) {
1850 /* try for Win2k driver if "Windows NT x86" */
1852 if ( version == 2 ) {
1855 status = winreg_get_driver(p->mem_ctx, p->server_info,
1860 if (!W_ERROR_IS_OK(status)) {
1861 status = WERR_UNKNOWN_PRINTER_DRIVER;
1865 /* otherwise it was a failure */
1867 status = WERR_UNKNOWN_PRINTER_DRIVER;
1873 if (printer_driver_in_use(p->mem_ctx, p->server_info, p->msg_ctx,
1875 status = WERR_PRINTER_DRIVER_IN_USE;
1880 status = winreg_get_driver(p->mem_ctx, p->server_info,
1883 r->in.driver, 3, &info_win2k);
1884 if (W_ERROR_IS_OK(status)) {
1885 /* if we get to here, we now have 2 driver info structures to remove */
1886 /* remove the Win2k driver first*/
1888 status = winreg_del_driver(p->mem_ctx,
1892 talloc_free(info_win2k);
1894 /* this should not have failed---if it did, report to client */
1895 if (!W_ERROR_IS_OK(status)) {
1901 status = winreg_del_driver(p->mem_ctx, p->server_info, p->msg_ctx,
1910 /****************************************************************
1911 _spoolss_DeletePrinterDriverEx
1912 ****************************************************************/
1914 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1915 struct spoolss_DeletePrinterDriverEx *r)
1917 struct spoolss_DriverInfo8 *info = NULL;
1918 struct spoolss_DriverInfo8 *info_win2k = NULL;
1922 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1924 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1925 and not a printer admin, then fail */
1927 if ( (p->server_info->utok.uid != sec_initial_uid())
1928 && !user_has_privileges(p->server_info->ptok, &se_printop )
1929 && !token_contains_name_in_list(
1930 uidtoname(p->server_info->utok.uid),
1931 p->server_info->info3->base.domain.string,
1933 p->server_info->ptok, lp_printer_admin(-1)) )
1935 return WERR_ACCESS_DENIED;
1938 /* check that we have a valid driver name first */
1939 if ((version = get_version_id(r->in.architecture)) == -1) {
1940 /* this is what NT returns */
1941 return WERR_INVALID_ENVIRONMENT;
1944 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1945 version = r->in.version;
1947 status = winreg_get_driver(p->mem_ctx, p->server_info,
1948 p->msg_ctx, r->in.architecture,
1949 r->in.driver, version, &info);
1950 if (!W_ERROR_IS_OK(status)) {
1951 status = WERR_UNKNOWN_PRINTER_DRIVER;
1954 * if the client asked for a specific version,
1955 * or this is something other than Windows NT x86,
1959 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1962 /* try for Win2k driver if "Windows NT x86" */
1965 status = winreg_get_driver(info, p->server_info, p->msg_ctx,
1969 if (!W_ERROR_IS_OK(status)) {
1970 status = WERR_UNKNOWN_PRINTER_DRIVER;
1975 if (printer_driver_in_use(info, p->server_info, p->msg_ctx, info)) {
1976 status = WERR_PRINTER_DRIVER_IN_USE;
1981 * we have a couple of cases to consider.
1982 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1983 * then the delete should fail if **any** files overlap with
1985 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1986 * non-overlapping files
1987 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1988 * is set, the do not delete any files
1989 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1992 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1994 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1997 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1998 printer_driver_files_in_use(info, p->server_info, p->msg_ctx,
2000 /* no idea of the correct error here */
2001 status = WERR_ACCESS_DENIED;
2006 /* also check for W32X86/3 if necessary; maybe we already have? */
2008 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2009 status = winreg_get_driver(info, p->server_info, p->msg_ctx,
2011 r->in.driver, 3, &info_win2k);
2012 if (W_ERROR_IS_OK(status)) {
2015 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2016 printer_driver_files_in_use(info, p->server_info,
2019 /* no idea of the correct error here */
2020 talloc_free(info_win2k);
2021 status = WERR_ACCESS_DENIED;
2025 /* if we get to here, we now have 2 driver info structures to remove */
2026 /* remove the Win2k driver first*/
2028 status = winreg_del_driver(info, p->server_info,
2029 p->msg_ctx, info_win2k, 3);
2031 /* this should not have failed---if it did, report to client */
2033 if (!W_ERROR_IS_OK(status)) {
2038 * now delete any associated files if delete_files is
2039 * true. Even if this part failes, we return succes
2040 * because the driver doesn not exist any more
2043 delete_driver_files(p->server_info,
2049 status = winreg_del_driver(info, p->server_info, p->msg_ctx, info,
2051 if (!W_ERROR_IS_OK(status)) {
2056 * now delete any associated files if delete_files is
2057 * true. Even if this part failes, we return succes
2058 * because the driver doesn not exist any more
2061 delete_driver_files(p->server_info, info);
2070 /********************************************************************
2071 GetPrinterData on a printer server Handle.
2072 ********************************************************************/
2074 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2076 enum winreg_Type *type,
2077 union spoolss_PrinterData *data)
2079 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2081 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2087 if (!StrCaseCmp(value, "BeepEnabled")) {
2093 if (!StrCaseCmp(value, "EventLog")) {
2095 /* formally was 0x1b */
2100 if (!StrCaseCmp(value, "NetPopup")) {
2106 if (!StrCaseCmp(value, "MajorVersion")) {
2109 /* Windows NT 4.0 seems to not allow uploading of drivers
2110 to a server that reports 0x3 as the MajorVersion.
2111 need to investigate more how Win2k gets around this .
2114 if (RA_WINNT == get_remote_arch()) {
2123 if (!StrCaseCmp(value, "MinorVersion")) {
2130 * uint32_t size = 0x114
2131 * uint32_t major = 5
2132 * uint32_t minor = [0|1]
2133 * uint32_t build = [2195|2600]
2134 * extra unicode string = e.g. "Service Pack 3"
2136 if (!StrCaseCmp(value, "OSVersion")) {
2138 enum ndr_err_code ndr_err;
2139 struct spoolss_OSVersion os;
2141 os.major = 5; /* Windows 2000 == 5.0 */
2143 os.build = 2195; /* build */
2144 os.extra_string = ""; /* leave extra string empty */
2146 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2147 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2148 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2149 return WERR_GENERAL_FAILURE;
2153 data->binary = blob;
2159 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2162 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2163 W_ERROR_HAVE_NO_MEMORY(data->string);
2168 if (!StrCaseCmp(value, "Architecture")) {
2170 data->string = talloc_strdup(mem_ctx,
2171 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2172 W_ERROR_HAVE_NO_MEMORY(data->string);
2177 if (!StrCaseCmp(value, "DsPresent")) {
2180 /* only show the publish check box if we are a
2181 member of a AD domain */
2183 if (lp_security() == SEC_ADS) {
2191 if (!StrCaseCmp(value, "DNSMachineName")) {
2192 const char *hostname = get_mydnsfullname();
2195 return WERR_BADFILE;
2199 data->string = talloc_strdup(mem_ctx, hostname);
2200 W_ERROR_HAVE_NO_MEMORY(data->string);
2207 return WERR_INVALID_PARAM;
2210 /****************************************************************
2211 _spoolss_GetPrinterData
2212 ****************************************************************/
2214 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2215 struct spoolss_GetPrinterData *r)
2217 struct spoolss_GetPrinterDataEx r2;
2219 r2.in.handle = r->in.handle;
2220 r2.in.key_name = "PrinterDriverData";
2221 r2.in.value_name = r->in.value_name;
2222 r2.in.offered = r->in.offered;
2223 r2.out.type = r->out.type;
2224 r2.out.data = r->out.data;
2225 r2.out.needed = r->out.needed;
2227 return _spoolss_GetPrinterDataEx(p, &r2);
2230 /*********************************************************
2231 Connect to the client machine.
2232 **********************************************************/
2234 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2235 struct sockaddr_storage *client_ss, const char *remote_machine)
2238 struct cli_state *the_cli;
2239 struct sockaddr_storage rm_addr;
2240 char addr[INET6_ADDRSTRLEN];
2242 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2243 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2245 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2246 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2249 print_sockaddr(addr, sizeof(addr), &rm_addr);
2251 rm_addr = *client_ss;
2252 print_sockaddr(addr, sizeof(addr), &rm_addr);
2253 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2257 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2258 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2263 /* setup the connection */
2264 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2265 &rm_addr, 0, "IPC$", "IPC",
2269 0, lp_client_signing(), NULL );
2271 if ( !NT_STATUS_IS_OK( ret ) ) {
2272 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2277 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2278 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2279 cli_shutdown(the_cli);
2284 * Ok - we have an anonymous connection to the IPC$ share.
2285 * Now start the NT Domain stuff :-).
2288 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2289 if (!NT_STATUS_IS_OK(ret)) {
2290 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2291 remote_machine, nt_errstr(ret)));
2292 cli_shutdown(the_cli);
2299 /***************************************************************************
2300 Connect to the client.
2301 ****************************************************************************/
2303 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2304 uint32_t localprinter, uint32_t type,
2305 struct policy_handle *handle,
2306 struct sockaddr_storage *client_ss,
2307 struct messaging_context *msg_ctx)
2313 * If it's the first connection, contact the client
2314 * and connect to the IPC$ share anonymously
2316 if (smb_connections==0) {
2317 fstring unix_printer;
2319 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2321 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2324 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2325 receive_notify2_message_list);
2326 /* Tell the connections db we're now interested in printer
2327 * notify messages. */
2328 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2329 true, FLAG_MSG_PRINT_NOTIFY);
2333 * Tell the specific printing tdb we want messages for this printer
2334 * by registering our PID.
2337 if (!print_notify_register_pid(snum))
2338 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2342 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2350 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2351 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2352 win_errstr(result)));
2354 return (W_ERROR_IS_OK(result));
2357 /****************************************************************
2358 ****************************************************************/
2360 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2361 const struct spoolss_NotifyOption *r)
2363 struct spoolss_NotifyOption *option;
2370 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2377 if (!option->count) {
2381 option->types = talloc_zero_array(option,
2382 struct spoolss_NotifyOptionType, option->count);
2383 if (!option->types) {
2384 talloc_free(option);
2388 for (i=0; i < option->count; i++) {
2389 option->types[i] = r->types[i];
2391 if (option->types[i].count) {
2392 option->types[i].fields = talloc_zero_array(option,
2393 union spoolss_Field, option->types[i].count);
2394 if (!option->types[i].fields) {
2395 talloc_free(option);
2398 for (k=0; k<option->types[i].count; k++) {
2399 option->types[i].fields[k] =
2400 r->types[i].fields[k];
2408 /****************************************************************
2409 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2411 * before replying OK: status=0 a rpc call is made to the workstation
2412 * asking ReplyOpenPrinter
2414 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2415 * called from api_spoolss_rffpcnex
2416 ****************************************************************/
2418 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2419 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2422 struct spoolss_NotifyOption *option = r->in.notify_options;
2423 struct sockaddr_storage client_ss;
2425 /* store the notify value in the printer struct */
2427 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2430 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2431 "Invalid handle (%s:%u:%u).\n",
2432 OUR_HANDLE(r->in.handle)));
2436 Printer->notify.flags = r->in.flags;
2437 Printer->notify.options = r->in.options;
2438 Printer->notify.printerlocal = r->in.printer_local;
2439 Printer->notify.msg_ctx = p->msg_ctx;
2441 TALLOC_FREE(Printer->notify.option);
2442 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2444 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2446 /* Connect to the client machine and send a ReplyOpenPrinter */
2448 if ( Printer->printer_type == SPLHND_SERVER)
2450 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2451 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2454 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2455 "client_address is %s\n", p->client_id->addr));
2457 if (!interpret_string_addr(&client_ss, p->client_id->addr,
2459 return WERR_SERVER_UNAVAILABLE;
2462 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2463 Printer->notify.printerlocal, 1,
2464 &Printer->notify.client_hnd,
2465 &client_ss, p->msg_ctx))
2466 return WERR_SERVER_UNAVAILABLE;
2468 Printer->notify.client_connected = true;
2473 /*******************************************************************
2474 * fill a notify_info_data with the servername
2475 ********************************************************************/
2477 static void spoolss_notify_server_name(struct messaging_context *msg_ctx,
2479 struct spoolss_Notify *data,
2480 print_queue_struct *queue,
2481 struct spoolss_PrinterInfo2 *pinfo2,
2482 TALLOC_CTX *mem_ctx)
2484 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2487 /*******************************************************************
2488 * fill a notify_info_data with the printername (not including the servername).
2489 ********************************************************************/
2491 static void spoolss_notify_printer_name(struct messaging_context *msg_ctx,
2493 struct spoolss_Notify *data,
2494 print_queue_struct *queue,
2495 struct spoolss_PrinterInfo2 *pinfo2,
2496 TALLOC_CTX *mem_ctx)
2498 /* the notify name should not contain the \\server\ part */
2499 const char *p = strrchr(pinfo2->printername, '\\');
2502 p = pinfo2->printername;
2507 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2510 /*******************************************************************
2511 * fill a notify_info_data with the servicename
2512 ********************************************************************/
2514 static void spoolss_notify_share_name(struct messaging_context *msg_ctx,
2516 struct spoolss_Notify *data,
2517 print_queue_struct *queue,
2518 struct spoolss_PrinterInfo2 *pinfo2,
2519 TALLOC_CTX *mem_ctx)
2521 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2524 /*******************************************************************
2525 * fill a notify_info_data with the port name
2526 ********************************************************************/
2528 static void spoolss_notify_port_name(struct messaging_context *msg_ctx,
2530 struct spoolss_Notify *data,
2531 print_queue_struct *queue,
2532 struct spoolss_PrinterInfo2 *pinfo2,
2533 TALLOC_CTX *mem_ctx)
2535 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2538 /*******************************************************************
2539 * fill a notify_info_data with the printername
2540 * but it doesn't exist, have to see what to do
2541 ********************************************************************/
2543 static void spoolss_notify_driver_name(struct messaging_context *msg_ctx,
2545 struct spoolss_Notify *data,
2546 print_queue_struct *queue,
2547 struct spoolss_PrinterInfo2 *pinfo2,
2548 TALLOC_CTX *mem_ctx)
2550 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2553 /*******************************************************************
2554 * fill a notify_info_data with the comment
2555 ********************************************************************/
2557 static void spoolss_notify_comment(struct messaging_context *msg_ctx,
2559 struct spoolss_Notify *data,
2560 print_queue_struct *queue,
2561 struct spoolss_PrinterInfo2 *pinfo2,
2562 TALLOC_CTX *mem_ctx)
2566 if (*pinfo2->comment == '\0') {
2567 p = lp_comment(snum);
2569 p = pinfo2->comment;
2572 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2575 /*******************************************************************
2576 * fill a notify_info_data with the comment
2577 * location = "Room 1, floor 2, building 3"
2578 ********************************************************************/
2580 static void spoolss_notify_location(struct messaging_context *msg_ctx,
2582 struct spoolss_Notify *data,
2583 print_queue_struct *queue,
2584 struct spoolss_PrinterInfo2 *pinfo2,
2585 TALLOC_CTX *mem_ctx)
2587 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2590 /*******************************************************************
2591 * fill a notify_info_data with the device mode
2592 * jfm:xxxx don't to it for know but that's a real problem !!!
2593 ********************************************************************/
2595 static void spoolss_notify_devmode(struct messaging_context *msg_ctx,
2597 struct spoolss_Notify *data,
2598 print_queue_struct *queue,
2599 struct spoolss_PrinterInfo2 *pinfo2,
2600 TALLOC_CTX *mem_ctx)
2602 /* for a dummy implementation we have to zero the fields */
2603 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2606 /*******************************************************************
2607 * fill a notify_info_data with the separator file name
2608 ********************************************************************/
2610 static void spoolss_notify_sepfile(struct messaging_context *msg_ctx,
2612 struct spoolss_Notify *data,
2613 print_queue_struct *queue,
2614 struct spoolss_PrinterInfo2 *pinfo2,
2615 TALLOC_CTX *mem_ctx)
2617 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2620 /*******************************************************************
2621 * fill a notify_info_data with the print processor
2622 * jfm:xxxx return always winprint to indicate we don't do anything to it
2623 ********************************************************************/
2625 static void spoolss_notify_print_processor(struct messaging_context *msg_ctx,
2627 struct spoolss_Notify *data,
2628 print_queue_struct *queue,
2629 struct spoolss_PrinterInfo2 *pinfo2,
2630 TALLOC_CTX *mem_ctx)
2632 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2635 /*******************************************************************
2636 * fill a notify_info_data with the print processor options
2637 * jfm:xxxx send an empty string
2638 ********************************************************************/
2640 static void spoolss_notify_parameters(struct messaging_context *msg_ctx,
2642 struct spoolss_Notify *data,
2643 print_queue_struct *queue,
2644 struct spoolss_PrinterInfo2 *pinfo2,
2645 TALLOC_CTX *mem_ctx)
2647 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2650 /*******************************************************************
2651 * fill a notify_info_data with the data type
2652 * jfm:xxxx always send RAW as data type
2653 ********************************************************************/
2655 static void spoolss_notify_datatype(struct messaging_context *msg_ctx,
2657 struct spoolss_Notify *data,
2658 print_queue_struct *queue,
2659 struct spoolss_PrinterInfo2 *pinfo2,
2660 TALLOC_CTX *mem_ctx)
2662 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2665 /*******************************************************************
2666 * fill a notify_info_data with the security descriptor
2667 * jfm:xxxx send an null pointer to say no security desc
2668 * have to implement security before !
2669 ********************************************************************/
2671 static void spoolss_notify_security_desc(struct messaging_context *msg_ctx,
2673 struct spoolss_Notify *data,
2674 print_queue_struct *queue,
2675 struct spoolss_PrinterInfo2 *pinfo2,
2676 TALLOC_CTX *mem_ctx)
2678 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2681 /*******************************************************************
2682 * fill a notify_info_data with the attributes
2683 * jfm:xxxx a samba printer is always shared
2684 ********************************************************************/
2686 static void spoolss_notify_attributes(struct messaging_context *msg_ctx,
2688 struct spoolss_Notify *data,
2689 print_queue_struct *queue,
2690 struct spoolss_PrinterInfo2 *pinfo2,
2691 TALLOC_CTX *mem_ctx)
2693 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2696 /*******************************************************************
2697 * fill a notify_info_data with the priority
2698 ********************************************************************/
2700 static void spoolss_notify_priority(struct messaging_context *msg_ctx,
2702 struct spoolss_Notify *data,
2703 print_queue_struct *queue,
2704 struct spoolss_PrinterInfo2 *pinfo2,
2705 TALLOC_CTX *mem_ctx)
2707 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2710 /*******************************************************************
2711 * fill a notify_info_data with the default priority
2712 ********************************************************************/
2714 static void spoolss_notify_default_priority(struct messaging_context *msg_ctx,
2716 struct spoolss_Notify *data,
2717 print_queue_struct *queue,
2718 struct spoolss_PrinterInfo2 *pinfo2,
2719 TALLOC_CTX *mem_ctx)
2721 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2724 /*******************************************************************
2725 * fill a notify_info_data with the start time
2726 ********************************************************************/
2728 static void spoolss_notify_start_time(struct messaging_context *msg_ctx,
2730 struct spoolss_Notify *data,
2731 print_queue_struct *queue,
2732 struct spoolss_PrinterInfo2 *pinfo2,
2733 TALLOC_CTX *mem_ctx)
2735 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2738 /*******************************************************************
2739 * fill a notify_info_data with the until time
2740 ********************************************************************/
2742 static void spoolss_notify_until_time(struct messaging_context *msg_ctx,
2744 struct spoolss_Notify *data,
2745 print_queue_struct *queue,
2746 struct spoolss_PrinterInfo2 *pinfo2,
2747 TALLOC_CTX *mem_ctx)
2749 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2752 /*******************************************************************
2753 * fill a notify_info_data with the status
2754 ********************************************************************/
2756 static void spoolss_notify_status(struct messaging_context *msg_ctx,
2758 struct spoolss_Notify *data,
2759 print_queue_struct *queue,
2760 struct spoolss_PrinterInfo2 *pinfo2,
2761 TALLOC_CTX *mem_ctx)
2763 print_status_struct status;
2765 print_queue_length(msg_ctx, snum, &status);
2766 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2769 /*******************************************************************
2770 * fill a notify_info_data with the number of jobs queued
2771 ********************************************************************/
2773 static void spoolss_notify_cjobs(struct messaging_context *msg_ctx,
2775 struct spoolss_Notify *data,
2776 print_queue_struct *queue,
2777 struct spoolss_PrinterInfo2 *pinfo2,
2778 TALLOC_CTX *mem_ctx)
2780 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(
2781 data, print_queue_length(msg_ctx, snum, NULL));
2784 /*******************************************************************
2785 * fill a notify_info_data with the average ppm
2786 ********************************************************************/
2788 static void spoolss_notify_average_ppm(struct messaging_context *msg_ctx,
2790 struct spoolss_Notify *data,
2791 print_queue_struct *queue,
2792 struct spoolss_PrinterInfo2 *pinfo2,
2793 TALLOC_CTX *mem_ctx)
2795 /* always respond 8 pages per minutes */
2796 /* a little hard ! */
2797 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2800 /*******************************************************************
2801 * fill a notify_info_data with username
2802 ********************************************************************/
2804 static void spoolss_notify_username(struct messaging_context *msg_ctx,
2806 struct spoolss_Notify *data,
2807 print_queue_struct *queue,
2808 struct spoolss_PrinterInfo2 *pinfo2,
2809 TALLOC_CTX *mem_ctx)
2811 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2814 /*******************************************************************
2815 * fill a notify_info_data with job status
2816 ********************************************************************/
2818 static void spoolss_notify_job_status(struct messaging_context *msg_ctx,
2820 struct spoolss_Notify *data,
2821 print_queue_struct *queue,
2822 struct spoolss_PrinterInfo2 *pinfo2,
2823 TALLOC_CTX *mem_ctx)
2825 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2828 /*******************************************************************
2829 * fill a notify_info_data with job name
2830 ********************************************************************/
2832 static void spoolss_notify_job_name(struct messaging_context *msg_ctx,
2834 struct spoolss_Notify *data,
2835 print_queue_struct *queue,
2836 struct spoolss_PrinterInfo2 *pinfo2,
2837 TALLOC_CTX *mem_ctx)
2839 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2842 /*******************************************************************
2843 * fill a notify_info_data with job status
2844 ********************************************************************/
2846 static void spoolss_notify_job_status_string(struct messaging_context *msg_ctx,
2848 struct spoolss_Notify *data,
2849 print_queue_struct *queue,
2850 struct spoolss_PrinterInfo2 *pinfo2,
2851 TALLOC_CTX *mem_ctx)
2854 * Now we're returning job status codes we just return a "" here. JRA.
2859 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2862 switch (queue->status) {
2867 p = ""; /* NT provides the paused string */
2876 #endif /* NO LONGER NEEDED. */
2878 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2881 /*******************************************************************
2882 * fill a notify_info_data with job time
2883 ********************************************************************/
2885 static void spoolss_notify_job_time(struct messaging_context *msg_ctx,
2887 struct spoolss_Notify *data,
2888 print_queue_struct *queue,
2889 struct spoolss_PrinterInfo2 *pinfo2,
2890 TALLOC_CTX *mem_ctx)
2892 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2895 /*******************************************************************
2896 * fill a notify_info_data with job size
2897 ********************************************************************/
2899 static void spoolss_notify_job_size(struct messaging_context *msg_ctx,
2901 struct spoolss_Notify *data,
2902 print_queue_struct *queue,
2903 struct spoolss_PrinterInfo2 *pinfo2,
2904 TALLOC_CTX *mem_ctx)
2906 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2909 /*******************************************************************
2910 * fill a notify_info_data with page info
2911 ********************************************************************/
2912 static void spoolss_notify_total_pages(struct messaging_context *msg_ctx,
2914 struct spoolss_Notify *data,
2915 print_queue_struct *queue,
2916 struct spoolss_PrinterInfo2 *pinfo2,
2917 TALLOC_CTX *mem_ctx)
2919 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2922 /*******************************************************************
2923 * fill a notify_info_data with pages printed info.
2924 ********************************************************************/
2925 static void spoolss_notify_pages_printed(struct messaging_context *msg_ctx,
2927 struct spoolss_Notify *data,
2928 print_queue_struct *queue,
2929 struct spoolss_PrinterInfo2 *pinfo2,
2930 TALLOC_CTX *mem_ctx)
2932 /* Add code when back-end tracks this */
2933 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2936 /*******************************************************************
2937 Fill a notify_info_data with job position.
2938 ********************************************************************/
2940 static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
2942 struct spoolss_Notify *data,
2943 print_queue_struct *queue,
2944 struct spoolss_PrinterInfo2 *pinfo2,
2945 TALLOC_CTX *mem_ctx)
2947 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2950 /*******************************************************************
2951 Fill a notify_info_data with submitted time.
2952 ********************************************************************/
2954 static void spoolss_notify_submitted_time(struct messaging_context *msg_ctx,
2956 struct spoolss_Notify *data,
2957 print_queue_struct *queue,
2958 struct spoolss_PrinterInfo2 *pinfo2,
2959 TALLOC_CTX *mem_ctx)
2961 data->data.string.string = NULL;
2962 data->data.string.size = 0;
2964 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2965 &data->data.string.string,
2966 &data->data.string.size);
2970 struct s_notify_info_data_table
2972 enum spoolss_NotifyType type;
2975 enum spoolss_NotifyTable variable_type;
2976 void (*fn) (struct messaging_context *msg_ctx,
2977 int snum, struct spoolss_Notify *data,
2978 print_queue_struct *queue,
2979 struct spoolss_PrinterInfo2 *pinfo2,
2980 TALLOC_CTX *mem_ctx);
2983 /* A table describing the various print notification constants and
2984 whether the notification data is a pointer to a variable sized
2985 buffer, a one value uint32_t or a two value uint32_t. */
2987 static const struct s_notify_info_data_table notify_info_data_table[] =
2989 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2990 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2991 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2992 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2993 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2994 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2995 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2996 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2997 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2998 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2999 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3000 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3001 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3002 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3003 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3004 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3005 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3006 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3007 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3008 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3009 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3010 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3011 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3012 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3013 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3014 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3015 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3016 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3017 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3018 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3019 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3020 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3021 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3022 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3023 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3024 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3025 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3026 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3027 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3028 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3029 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3030 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3031 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3032 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3033 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3034 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3035 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3036 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3037 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3040 /*******************************************************************
3041 Return the variable_type of info_data structure.
3042 ********************************************************************/
3044 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3049 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3050 if ( (notify_info_data_table[i].type == type) &&
3051 (notify_info_data_table[i].field == field) ) {
3052 return notify_info_data_table[i].variable_type;
3056 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3061 /****************************************************************************
3062 ****************************************************************************/
3064 static bool search_notify(enum spoolss_NotifyType type,
3070 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3071 if (notify_info_data_table[i].type == type &&
3072 notify_info_data_table[i].field == field &&
3073 notify_info_data_table[i].fn != NULL) {
3082 /****************************************************************************
3083 ****************************************************************************/
3085 static void construct_info_data(struct spoolss_Notify *info_data,
3086 enum spoolss_NotifyType type,
3087 uint16_t field, int id)
3089 info_data->type = type;
3090 info_data->field.field = field;
3091 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3092 info_data->job_id = id;
3095 /*******************************************************************
3097 * fill a notify_info struct with info asked
3099 ********************************************************************/
3101 static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
3102 Printer_entry *print_hnd,
3103 struct spoolss_NotifyInfo *info,
3104 struct spoolss_PrinterInfo2 *pinfo2,
3106 const struct spoolss_NotifyOptionType *option_type,
3108 TALLOC_CTX *mem_ctx)
3111 enum spoolss_NotifyType type;
3114 struct spoolss_Notify *current_data;
3115 print_queue_struct *queue=NULL;
3117 type = option_type->type;
3119 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3120 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3121 option_type->count, lp_servicename(snum)));
3123 for(field_num=0; field_num < option_type->count; field_num++) {
3124 field = option_type->fields[field_num].field;
3126 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3128 if (!search_notify(type, field, &j) )
3131 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3132 struct spoolss_Notify,
3134 if (info->notifies == NULL) {
3135 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3139 current_data = &info->notifies[info->count];
3141 construct_info_data(current_data, type, field, id);
3143 DEBUG(10, ("construct_notify_printer_info: "
3144 "calling [%s] snum=%d printername=[%s])\n",
3145 notify_info_data_table[j].name, snum,
3146 pinfo2->printername));
3148 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3149 queue, pinfo2, mem_ctx);
3157 /*******************************************************************
3159 * fill a notify_info struct with info asked
3161 ********************************************************************/
3163 static bool construct_notify_jobs_info(struct messaging_context *msg_ctx,
3164 print_queue_struct *queue,
3165 struct spoolss_NotifyInfo *info,
3166 struct spoolss_PrinterInfo2 *pinfo2,
3168 const struct spoolss_NotifyOptionType *option_type,
3170 TALLOC_CTX *mem_ctx)
3173 enum spoolss_NotifyType type;
3175 struct spoolss_Notify *current_data;
3177 DEBUG(4,("construct_notify_jobs_info\n"));
3179 type = option_type->type;
3181 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3182 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3183 option_type->count));
3185 for(field_num=0; field_num<option_type->count; field_num++) {
3186 field = option_type->fields[field_num].field;
3188 if (!search_notify(type, field, &j) )
3191 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3192 struct spoolss_Notify,
3194 if (info->notifies == NULL) {
3195 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3199 current_data=&(info->notifies[info->count]);
3201 construct_info_data(current_data, type, field, id);
3202 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3203 queue, pinfo2, mem_ctx);
3211 * JFM: The enumeration is not that simple, it's even non obvious.
3213 * let's take an example: I want to monitor the PRINTER SERVER for
3214 * the printer's name and the number of jobs currently queued.
3215 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3216 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3218 * I have 3 printers on the back of my server.
3220 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3223 * 1 printer 1 name 1
3224 * 2 printer 1 cjob 1
3225 * 3 printer 2 name 2
3226 * 4 printer 2 cjob 2
3227 * 5 printer 3 name 3
3228 * 6 printer 3 name 3
3230 * that's the print server case, the printer case is even worse.
3233 /*******************************************************************
3235 * enumerate all printers on the printserver
3236 * fill a notify_info struct with info asked
3238 ********************************************************************/
3240 static WERROR printserver_notify_info(struct pipes_struct *p,
3241 struct policy_handle *hnd,
3242 struct spoolss_NotifyInfo *info,
3243 TALLOC_CTX *mem_ctx)
3246 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3247 int n_services=lp_numservices();
3249 struct spoolss_NotifyOption *option;
3250 struct spoolss_NotifyOptionType option_type;
3251 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3254 DEBUG(4,("printserver_notify_info\n"));
3259 option = Printer->notify.option;
3262 info->notifies = NULL;
3265 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3266 sending a ffpcn() request first */
3271 for (i=0; i<option->count; i++) {
3272 option_type = option->types[i];
3274 if (option_type.type != PRINTER_NOTIFY_TYPE)
3277 for (snum = 0; snum < n_services; snum++) {
3278 if (!lp_browseable(snum) ||
3279 !lp_snum_ok(snum) ||
3280 !lp_print_ok(snum)) {
3281 continue; /* skip */
3284 /* Maybe we should use the SYSTEM server_info here... */
3285 result = winreg_get_printer(mem_ctx, p->server_info,
3287 Printer->servername,
3288 lp_servicename(snum),
3290 if (!W_ERROR_IS_OK(result)) {
3291 DEBUG(4, ("printserver_notify_info: "
3292 "Failed to get printer [%s]\n",
3293 lp_servicename(snum)));
3298 construct_notify_printer_info(p->msg_ctx,
3304 TALLOC_FREE(pinfo2);
3310 * Debugging information, don't delete.
3313 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3314 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3315 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3317 for (i=0; i<info->count; i++) {
3318 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3319 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3320 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3327 /*******************************************************************
3329 * fill a notify_info struct with info asked
3331 ********************************************************************/
3333 static WERROR printer_notify_info(struct pipes_struct *p,
3334 struct policy_handle *hnd,
3335 struct spoolss_NotifyInfo *info,
3336 TALLOC_CTX *mem_ctx)
3339 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3342 struct spoolss_NotifyOption *option;
3343 struct spoolss_NotifyOptionType option_type;
3345 print_queue_struct *queue=NULL;
3346 print_status_struct status;
3347 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3350 DEBUG(4,("printer_notify_info\n"));
3355 option = Printer->notify.option;
3359 info->notifies = NULL;
3362 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3363 sending a ffpcn() request first */
3368 get_printer_snum(p, hnd, &snum, NULL);
3370 /* Maybe we should use the SYSTEM server_info here... */
3371 result = winreg_get_printer(mem_ctx, p->server_info, p->msg_ctx,
3372 Printer->servername,
3373 lp_servicename(snum), &pinfo2);
3374 if (!W_ERROR_IS_OK(result)) {
3378 for (i=0; i<option->count; i++) {
3379 option_type = option->types[i];
3381 switch (option_type.type) {
3382 case PRINTER_NOTIFY_TYPE:
3383 if (construct_notify_printer_info(p->msg_ctx,
3392 case JOB_NOTIFY_TYPE:
3394 count = print_queue_status(p->msg_ctx, snum, &queue,
3397 for (j=0; j<count; j++) {
3398 construct_notify_jobs_info(p->msg_ctx,
3412 * Debugging information, don't delete.
3415 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3416 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3417 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3419 for (i=0; i<info->count; i++) {
3420 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3421 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3422 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3426 talloc_free(pinfo2);
3430 /****************************************************************
3431 _spoolss_RouterRefreshPrinterChangeNotify
3432 ****************************************************************/
3434 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3435 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3437 struct spoolss_NotifyInfo *info;
3439 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3440 WERROR result = WERR_BADFID;
3442 /* we always have a spoolss_NotifyInfo struct */
3443 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3445 result = WERR_NOMEM;
3449 *r->out.info = info;
3452 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3453 "Invalid handle (%s:%u:%u).\n",
3454 OUR_HANDLE(r->in.handle)));
3458 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3461 * We are now using the change value, and
3462 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3463 * I don't have a global notification system, I'm sending back all the
3464 * informations even when _NOTHING_ has changed.
3467 /* We need to keep track of the change value to send back in
3468 RRPCN replies otherwise our updates are ignored. */
3470 Printer->notify.fnpcn = true;
3472 if (Printer->notify.client_connected) {
3473 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3474 "Saving change value in request [%x]\n",
3476 Printer->notify.change = r->in.change_low;
3479 /* just ignore the spoolss_NotifyOption */
3481 switch (Printer->printer_type) {
3483 result = printserver_notify_info(p, r->in.handle,
3487 case SPLHND_PRINTER:
3488 result = printer_notify_info(p, r->in.handle,
3493 Printer->notify.fnpcn = false;
3499 /********************************************************************
3500 * construct_printer_info_0
3501 * fill a printer_info_0 struct
3502 ********************************************************************/
3504 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3505 struct auth_serversupplied_info *server_info,
3506 struct messaging_context *msg_ctx,
3507 struct spoolss_PrinterInfo2 *info2,
3508 struct spoolss_PrinterInfo0 *r,
3512 counter_printer_0 *session_counter;
3513 struct timeval setuptime;
3514 print_status_struct status;
3516 r->printername = talloc_strdup(mem_ctx, info2->printername);
3517 W_ERROR_HAVE_NO_MEMORY(r->printername);
3519 r->servername = talloc_strdup(mem_ctx, info2->servername);
3520 W_ERROR_HAVE_NO_MEMORY(r->servername);
3522 count = print_queue_length(msg_ctx, snum, &status);
3524 /* check if we already have a counter for this printer */
3525 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3526 if (session_counter->snum == snum)
3530 /* it's the first time, add it to the list */
3531 if (session_counter == NULL) {
3532 session_counter = SMB_MALLOC_P(counter_printer_0);
3533 W_ERROR_HAVE_NO_MEMORY(session_counter);
3534 ZERO_STRUCTP(session_counter);
3535 session_counter->snum = snum;
3536 session_counter->counter = 0;
3537 DLIST_ADD(counter_list, session_counter);
3541 session_counter->counter++;
3547 get_startup_time(&setuptime);
3548 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3551 * the global_counter should be stored in a TDB as it's common to all the clients
3552 * and should be zeroed on samba startup
3554 r->global_counter = session_counter->counter;
3556 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3557 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3558 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3559 r->free_build = SPOOLSS_RELEASE_BUILD;
3561 r->max_spooling = 0;
3562 r->session_counter = session_counter->counter;
3563 r->num_error_out_of_paper = 0x0;
3564 r->num_error_not_ready = 0x0; /* number of print failure */
3566 r->number_of_processors = 0x1;
3567 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3568 r->high_part_total_bytes = 0x0;
3570 /* ChangeID in milliseconds*/
3571 winreg_printer_get_changeid(mem_ctx, server_info, msg_ctx,
3572 info2->sharename, &r->change_id);
3574 r->last_error = WERR_OK;
3575 r->status = nt_printq_status(status.status);
3576 r->enumerate_network_printers = 0x0;
3577 r->c_setprinter = 0x0;
3578 r->processor_architecture = 0x0;
3579 r->processor_level = 0x6; /* 6 ???*/
3588 /********************************************************************
3589 * construct_printer_info1
3590 * fill a spoolss_PrinterInfo1 struct
3591 ********************************************************************/
3593 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3594 const struct spoolss_PrinterInfo2 *info2,
3596 struct spoolss_PrinterInfo1 *r,
3601 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3605 W_ERROR_HAVE_NO_MEMORY(r->description);
3607 if (info2->comment == NULL || info2->comment[0] == '\0') {
3608 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3610 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3612 W_ERROR_HAVE_NO_MEMORY(r->comment);
3614 r->name = talloc_strdup(mem_ctx, info2->printername);
3615 W_ERROR_HAVE_NO_MEMORY(r->name);
3620 /********************************************************************
3621 * construct_printer_info2
3622 * fill a spoolss_PrinterInfo2 struct
3623 ********************************************************************/
3625 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3626 struct messaging_context *msg_ctx,
3627 const struct spoolss_PrinterInfo2 *info2,
3628 struct spoolss_PrinterInfo2 *r,
3632 print_status_struct status;
3634 count = print_queue_length(msg_ctx, snum, &status);
3636 r->servername = talloc_strdup(mem_ctx, info2->servername);
3637 W_ERROR_HAVE_NO_MEMORY(r->servername);
3638 r->printername = talloc_strdup(mem_ctx, info2->printername);
3639 W_ERROR_HAVE_NO_MEMORY(r->printername);
3640 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3641 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3642 r->portname = talloc_strdup(mem_ctx, info2->portname);
3643 W_ERROR_HAVE_NO_MEMORY(r->portname);
3644 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3645 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3647 if (info2->comment[0] == '\0') {
3648 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3650 r->comment = talloc_strdup(mem_ctx, info2->comment);
3652 W_ERROR_HAVE_NO_MEMORY(r->comment);
3654 r->location = talloc_strdup(mem_ctx, info2->location);
3655 W_ERROR_HAVE_NO_MEMORY(r->location);
3656 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3657 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3658 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3659 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3660 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3661 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3662 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3663 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3665 r->attributes = info2->attributes;
3667 r->priority = info2->priority;
3668 r->defaultpriority = info2->defaultpriority;
3669 r->starttime = info2->starttime;
3670 r->untiltime = info2->untiltime;
3671 r->status = nt_printq_status(status.status);
3673 r->averageppm = info2->averageppm;
3675 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3677 DEBUG(8,("Returning NULL Devicemode!\n"));
3682 if (info2->secdesc != NULL) {
3683 /* don't use talloc_steal() here unless you do a deep steal of all
3684 the SEC_DESC members */
3686 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3692 /********************************************************************
3693 * construct_printer_info3
3694 * fill a spoolss_PrinterInfo3 struct
3695 ********************************************************************/
3697 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3698 const struct spoolss_PrinterInfo2 *info2,
3699 struct spoolss_PrinterInfo3 *r,
3702 /* These are the components of the SD we are returning. */
3704 if (info2->secdesc != NULL) {
3705 /* don't use talloc_steal() here unless you do a deep steal of all
3706 the SEC_DESC members */
3708 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3709 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3715 /********************************************************************
3716 * construct_printer_info4
3717 * fill a spoolss_PrinterInfo4 struct
3718 ********************************************************************/
3720 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3721 const struct spoolss_PrinterInfo2 *info2,
3722 struct spoolss_PrinterInfo4 *r,
3725 r->printername = talloc_strdup(mem_ctx, info2->printername);
3726 W_ERROR_HAVE_NO_MEMORY(r->printername);
3727 r->servername = talloc_strdup(mem_ctx, info2->servername);
3728 W_ERROR_HAVE_NO_MEMORY(r->servername);
3730 r->attributes = info2->attributes;
3735 /********************************************************************
3736 * construct_printer_info5
3737 * fill a spoolss_PrinterInfo5 struct
3738 ********************************************************************/
3740 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3741 const struct spoolss_PrinterInfo2 *info2,
3742 struct spoolss_PrinterInfo5 *r,
3745 r->printername = talloc_strdup(mem_ctx, info2->printername);
3746 W_ERROR_HAVE_NO_MEMORY(r->printername);
3747 r->portname = talloc_strdup(mem_ctx, info2->portname);
3748 W_ERROR_HAVE_NO_MEMORY(r->portname);
3750 r->attributes = info2->attributes;
3752 /* these two are not used by NT+ according to MSDN */
3753 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3754 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3759 /********************************************************************
3760 * construct_printer_info_6
3761 * fill a spoolss_PrinterInfo6 struct
3762 ********************************************************************/
3764 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3765 struct messaging_context *msg_ctx,
3766 const struct spoolss_PrinterInfo2 *info2,
3767 struct spoolss_PrinterInfo6 *r,
3771 print_status_struct status;
3773 count = print_queue_length(msg_ctx, snum, &status);
3775 r->status = nt_printq_status(status.status);
3780 /********************************************************************
3781 * construct_printer_info7
3782 * fill a spoolss_PrinterInfo7 struct
3783 ********************************************************************/
3785 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3786 struct messaging_context *msg_ctx,
3787 Printer_entry *print_hnd,
3788 struct spoolss_PrinterInfo7 *r,
3791 struct auth_serversupplied_info *server_info;
3795 status = make_server_info_system(mem_ctx, &server_info);
3796 if (!NT_STATUS_IS_OK(status)) {
3797 DEBUG(0, ("construct_printer_info7: "
3798 "Could not create system server_info\n"));
3802 if (is_printer_published(mem_ctx, server_info, msg_ctx,
3803 print_hnd->servername,
3804 lp_servicename(snum), &guid, NULL)) {
3805 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3806 r->action = DSPRINT_PUBLISH;
3808 r->guid = talloc_strdup(mem_ctx, "");
3809 r->action = DSPRINT_UNPUBLISH;
3811 W_ERROR_HAVE_NO_MEMORY(r->guid);
3813 TALLOC_FREE(server_info);
3817 /********************************************************************
3818 * construct_printer_info8
3819 * fill a spoolss_PrinterInfo8 struct
3820 ********************************************************************/
3822 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3823 const struct spoolss_PrinterInfo2 *info2,
3824 struct spoolss_DeviceModeInfo *r,
3827 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3829 DEBUG(8,("Returning NULL Devicemode!\n"));
3836 /********************************************************************
3837 ********************************************************************/
3839 static bool snum_is_shared_printer(int snum)
3841 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3844 /********************************************************************
3845 Spoolss_enumprinters.
3846 ********************************************************************/
3848 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3849 struct auth_serversupplied_info *server_info,
3850 struct messaging_context *msg_ctx,
3853 union spoolss_PrinterInfo **info_p,
3857 int n_services = lp_numservices();
3858 union spoolss_PrinterInfo *info = NULL;
3860 WERROR result = WERR_OK;
3865 for (snum = 0; snum < n_services; snum++) {
3867 const char *printer;
3868 struct spoolss_PrinterInfo2 *info2;
3870 if (!snum_is_shared_printer(snum)) {
3874 printer = lp_const_servicename(snum);
3876 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3879 result = winreg_create_printer(mem_ctx,
3884 if (!W_ERROR_IS_OK(result)) {
3888 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3889 union spoolss_PrinterInfo,
3892 result = WERR_NOMEM;
3896 result = winreg_get_printer(mem_ctx, server_info, msg_ctx,
3897 NULL, printer, &info2);
3898 if (!W_ERROR_IS_OK(result)) {
3904 result = construct_printer_info0(info, server_info,
3906 &info[count].info0, snum);
3909 result = construct_printer_info1(info, info2, flags,
3910 &info[count].info1, snum);
3913 result = construct_printer_info2(info, msg_ctx, info2,
3914 &info[count].info2, snum);
3917 result = construct_printer_info4(info, info2,
3918 &info[count].info4, snum);
3921 result = construct_printer_info5(info, info2,
3922 &info[count].info5, snum);
3926 result = WERR_UNKNOWN_LEVEL;
3930 if (!W_ERROR_IS_OK(result)) {
3941 if (!W_ERROR_IS_OK(result)) {
3951 /********************************************************************
3952 * handle enumeration of printers at level 0
3953 ********************************************************************/
3955 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3956 struct auth_serversupplied_info *server_info,
3957 struct messaging_context *msg_ctx,
3959 const char *servername,
3960 union spoolss_PrinterInfo **info,
3963 DEBUG(4,("enum_all_printers_info_0\n"));
3965 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
3966 0, flags, info, count);
3970 /********************************************************************
3971 ********************************************************************/
3973 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3974 struct auth_serversupplied_info *server_info,
3975 struct messaging_context *msg_ctx,
3977 union spoolss_PrinterInfo **info,
3980 DEBUG(4,("enum_all_printers_info_1\n"));
3982 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
3983 1, flags, info, count);
3986 /********************************************************************
3987 enum_all_printers_info_1_local.
3988 *********************************************************************/
3990 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3991 struct auth_serversupplied_info *server_info,
3992 struct messaging_context *msg_ctx,
3993 union spoolss_PrinterInfo **info,
3996 DEBUG(4,("enum_all_printers_info_1_local\n"));
3998 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
3999 PRINTER_ENUM_ICON8, info, count);
4002 /********************************************************************
4003 enum_all_printers_info_1_name.
4004 *********************************************************************/
4006 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4007 struct auth_serversupplied_info *server_info,
4008 struct messaging_context *msg_ctx,
4010 union spoolss_PrinterInfo **info,
4013 const char *s = name;
4015 DEBUG(4,("enum_all_printers_info_1_name\n"));
4017 if ((name[0] == '\\') && (name[1] == '\\')) {
4021 if (!is_myname_or_ipaddr(s)) {
4022 return WERR_INVALID_NAME;
4025 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4026 PRINTER_ENUM_ICON8, info, count);
4029 /********************************************************************
4030 enum_all_printers_info_1_network.
4031 *********************************************************************/
4033 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4034 struct auth_serversupplied_info *server_info,
4035 struct messaging_context *msg_ctx,
4037 union spoolss_PrinterInfo **info,
4040 const char *s = name;
4042 DEBUG(4,("enum_all_printers_info_1_network\n"));
4044 /* If we respond to a enum_printers level 1 on our name with flags
4045 set to PRINTER_ENUM_REMOTE with a list of printers then these
4046 printers incorrectly appear in the APW browse list.
4047 Specifically the printers for the server appear at the workgroup
4048 level where all the other servers in the domain are
4049 listed. Windows responds to this call with a
4050 WERR_CAN_NOT_COMPLETE so we should do the same. */
4052 if (name[0] == '\\' && name[1] == '\\') {
4056 if (is_myname_or_ipaddr(s)) {
4057 return WERR_CAN_NOT_COMPLETE;
4060 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4061 PRINTER_ENUM_NAME, info, count);
4064 /********************************************************************
4065 * api_spoolss_enumprinters
4067 * called from api_spoolss_enumprinters (see this to understand)
4068 ********************************************************************/
4070 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4071 struct auth_serversupplied_info *server_info,
4072 struct messaging_context *msg_ctx,
4073 union spoolss_PrinterInfo **info,
4076 DEBUG(4,("enum_all_printers_info_2\n"));
4078 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4082 /********************************************************************
4083 * handle enumeration of printers at level 1
4084 ********************************************************************/
4086 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4087 struct auth_serversupplied_info *server_info,
4088 struct messaging_context *msg_ctx,
4091 union spoolss_PrinterInfo **info,
4094 /* Not all the flags are equals */
4096 if (flags & PRINTER_ENUM_LOCAL) {
4097 return enum_all_printers_info_1_local(mem_ctx, server_info,
4098 msg_ctx, info, count);
4101 if (flags & PRINTER_ENUM_NAME) {
4102 return enum_all_printers_info_1_name(mem_ctx, server_info,
4103 msg_ctx, name, info,
4107 if (flags & PRINTER_ENUM_NETWORK) {
4108 return enum_all_printers_info_1_network(mem_ctx, server_info,
4109 msg_ctx, name, info,
4113 return WERR_OK; /* NT4sp5 does that */
4116 /********************************************************************
4117 * handle enumeration of printers at level 2
4118 ********************************************************************/
4120 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4121 struct auth_serversupplied_info *server_info,
4122 struct messaging_context *msg_ctx,
4124 const char *servername,
4125 union spoolss_PrinterInfo **info,
4128 if (flags & PRINTER_ENUM_LOCAL) {
4129 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4133 if (flags & PRINTER_ENUM_NAME) {
4134 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4135 return WERR_INVALID_NAME;
4138 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4142 if (flags & PRINTER_ENUM_REMOTE) {
4143 return WERR_UNKNOWN_LEVEL;
4149 /********************************************************************
4150 * handle enumeration of printers at level 4
4151 ********************************************************************/
4153 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4154 struct auth_serversupplied_info *server_info,
4155 struct messaging_context *msg_ctx,
4157 const char *servername,
4158 union spoolss_PrinterInfo **info,
4161 DEBUG(4,("enum_all_printers_info_4\n"));
4163 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4164 4, flags, info, count);
4168 /********************************************************************
4169 * handle enumeration of printers at level 5
4170 ********************************************************************/
4172 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4173 struct auth_serversupplied_info *server_info,
4174 struct messaging_context *msg_ctx,
4176 const char *servername,
4177 union spoolss_PrinterInfo **info,
4180 DEBUG(4,("enum_all_printers_info_5\n"));
4182 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4183 5, flags, info, count);
4186 /****************************************************************
4187 _spoolss_EnumPrinters
4188 ****************************************************************/
4190 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4191 struct spoolss_EnumPrinters *r)
4193 const char *name = NULL;
4196 /* that's an [in out] buffer */
4198 if (!r->in.buffer && (r->in.offered != 0)) {
4199 return WERR_INVALID_PARAM;
4202 DEBUG(4,("_spoolss_EnumPrinters\n"));
4206 *r->out.info = NULL;
4210 * flags==PRINTER_ENUM_NAME
4211 * if name=="" then enumerates all printers
4212 * if name!="" then enumerate the printer
4213 * flags==PRINTER_ENUM_REMOTE
4214 * name is NULL, enumerate printers
4215 * Level 2: name!="" enumerates printers, name can't be NULL
4216 * Level 3: doesn't exist
4217 * Level 4: does a local registry lookup
4218 * Level 5: same as Level 2
4222 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4223 W_ERROR_HAVE_NO_MEMORY(name);
4226 switch (r->in.level) {
4228 result = enumprinters_level0(p->mem_ctx, p->server_info,
4229 p->msg_ctx, r->in.flags, name,
4230 r->out.info, r->out.count);
4233 result = enumprinters_level1(p->mem_ctx, p->server_info,
4234 p->msg_ctx, r->in.flags, name,
4235 r->out.info, r->out.count);
4238 result = enumprinters_level2(p->mem_ctx, p->server_info,
4239 p->msg_ctx, r->in.flags, name,
4240 r->out.info, r->out.count);
4243 result = enumprinters_level4(p->mem_ctx, p->server_info,
4244 p->msg_ctx, r->in.flags, name,
4245 r->out.info, r->out.count);
4248 result = enumprinters_level5(p->mem_ctx, p->server_info,
4249 p->msg_ctx, r->in.flags, name,
4250 r->out.info, r->out.count);
4253 return WERR_UNKNOWN_LEVEL;
4256 if (!W_ERROR_IS_OK(result)) {
4260 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4261 spoolss_EnumPrinters,
4262 *r->out.info, r->in.level,
4264 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4265 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4267 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4270 /****************************************************************
4272 ****************************************************************/
4274 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4275 struct spoolss_GetPrinter *r)
4277 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4278 struct spoolss_PrinterInfo2 *info2 = NULL;
4279 WERROR result = WERR_OK;
4280 const char *servername = NULL;
4283 /* that's an [in out] buffer */
4285 if (!r->in.buffer && (r->in.offered != 0)) {
4286 return WERR_INVALID_PARAM;
4291 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4295 if (Printer != NULL || Printer->servername != NULL) {
4296 servername = Printer->servername;
4299 result = winreg_get_printer(p->mem_ctx,
4303 lp_const_servicename(snum),
4305 if (!W_ERROR_IS_OK(result)) {
4309 switch (r->in.level) {
4311 result = construct_printer_info0(p->mem_ctx, p->server_info,
4313 &r->out.info->info0, snum);
4316 result = construct_printer_info1(p->mem_ctx, info2,
4318 &r->out.info->info1, snum);
4321 result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
4322 &r->out.info->info2, snum);
4325 result = construct_printer_info3(p->mem_ctx, info2,
4326 &r->out.info->info3, snum);
4329 result = construct_printer_info4(p->mem_ctx, info2,
4330 &r->out.info->info4, snum);
4333 result = construct_printer_info5(p->mem_ctx, info2,
4334 &r->out.info->info5, snum);
4337 result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
4338 &r->out.info->info6, snum);
4341 result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
4343 &r->out.info->info7, snum);
4346 result = construct_printer_info8(p->mem_ctx, info2,
4347 &r->out.info->info8, snum);
4350 result = WERR_UNKNOWN_LEVEL;
4354 if (!W_ERROR_IS_OK(result)) {
4355 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4356 r->in.level, win_errstr(result)));
4357 TALLOC_FREE(r->out.info);
4361 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4362 r->out.info, r->in.level);
4363 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4365 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4368 /********************************************************************
4369 ********************************************************************/
4371 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4373 if (in && strlen(in)) { \
4374 out = talloc_strdup(mem_ctx, in); \
4376 out = talloc_strdup(mem_ctx, ""); \
4378 W_ERROR_HAVE_NO_MEMORY(out); \
4381 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4383 if (in && strlen(in)) { \
4384 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4386 out = talloc_strdup(mem_ctx, ""); \
4388 W_ERROR_HAVE_NO_MEMORY(out); \
4391 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4392 const char **string_array,
4393 const char ***presult,
4394 const char *cservername,
4398 int i, num_strings = 0;
4399 const char **array = NULL;
4401 if (string_array == NULL) {
4402 return WERR_INVALID_PARAMETER;;
4405 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4406 const char *str = NULL;
4408 if (cservername == NULL || arch == NULL) {
4409 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4411 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4414 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4421 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4422 &array, &num_strings);
4432 /********************************************************************
4433 * fill a spoolss_DriverInfo1 struct
4434 ********************************************************************/
4436 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4437 struct spoolss_DriverInfo1 *r,
4438 const struct spoolss_DriverInfo8 *driver,
4439 const char *servername)
4441 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4442 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4447 /********************************************************************
4448 * fill a spoolss_DriverInfo2 struct
4449 ********************************************************************/
4451 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4452 struct spoolss_DriverInfo2 *r,
4453 const struct spoolss_DriverInfo8 *driver,
4454 const char *servername)
4457 const char *cservername = canon_servername(servername);
4459 r->version = driver->version;
4461 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4462 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4463 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4464 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4466 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4467 driver->architecture,
4469 driver->driver_path,
4472 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4473 driver->architecture,
4478 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4479 driver->architecture,
4481 driver->config_file,
4487 /********************************************************************
4488 * fill a spoolss_DriverInfo3 struct
4489 ********************************************************************/
4491 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4492 struct spoolss_DriverInfo3 *r,
4493 const struct spoolss_DriverInfo8 *driver,
4494 const char *servername)
4496 const char *cservername = canon_servername(servername);
4498 r->version = driver->version;
4500 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4501 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4502 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4503 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4505 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4506 driver->architecture,
4508 driver->driver_path,
4511 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4512 driver->architecture,
4517 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4518 driver->architecture,
4520 driver->config_file,
4523 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4524 driver->architecture,
4529 FILL_DRIVER_STRING(mem_ctx,
4530 driver->monitor_name,
4533 FILL_DRIVER_STRING(mem_ctx,
4534 driver->default_datatype,
4535 r->default_datatype);
4537 return string_array_from_driver_info(mem_ctx,
4538 driver->dependent_files,
4539 &r->dependent_files,
4541 driver->architecture,
4545 /********************************************************************
4546 * fill a spoolss_DriverInfo4 struct
4547 ********************************************************************/
4549 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4550 struct spoolss_DriverInfo4 *r,
4551 const struct spoolss_DriverInfo8 *driver,
4552 const char *servername)
4554 const char *cservername = canon_servername(servername);
4557 r->version = driver->version;
4559 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4560 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4561 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4562 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4564 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4565 driver->architecture,
4567 driver->driver_path,
4570 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4571 driver->architecture,
4576 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4577 driver->architecture,
4579 driver->config_file,
4582 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4583 driver->architecture,
4588 result = string_array_from_driver_info(mem_ctx,
4589 driver->dependent_files,
4590 &r->dependent_files,
4592 driver->architecture,
4594 if (!W_ERROR_IS_OK(result)) {
4598 FILL_DRIVER_STRING(mem_ctx,
4599 driver->monitor_name,
4602 FILL_DRIVER_STRING(mem_ctx,
4603 driver->default_datatype,
4604 r->default_datatype);
4607 result = string_array_from_driver_info(mem_ctx,
4608 driver->previous_names,
4615 /********************************************************************
4616 * fill a spoolss_DriverInfo5 struct
4617 ********************************************************************/
4619 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4620 struct spoolss_DriverInfo5 *r,
4621 const struct spoolss_DriverInfo8 *driver,
4622 const char *servername)
4624 const char *cservername = canon_servername(servername);
4626 r->version = driver->version;
4628 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4629 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4630 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4631 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4633 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4634 driver->architecture,
4636 driver->driver_path,
4639 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4640 driver->architecture,
4645 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4646 driver->architecture,
4648 driver->config_file,
4651 r->driver_attributes = 0;
4652 r->config_version = 0;
4653 r->driver_version = 0;
4657 /********************************************************************
4658 * fill a spoolss_DriverInfo6 struct
4659 ********************************************************************/
4661 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4662 struct spoolss_DriverInfo6 *r,
4663 const struct spoolss_DriverInfo8 *driver,
4664 const char *servername)
4666 const char *cservername = canon_servername(servername);
4669 r->version = driver->version;
4671 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4672 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4673 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4674 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4676 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4677 driver->architecture,
4679 driver->driver_path,
4682 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4683 driver->architecture,
4688 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4689 driver->architecture,
4691 driver->config_file,
4694 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4695 driver->architecture,
4700 FILL_DRIVER_STRING(mem_ctx,
4701 driver->monitor_name,
4704 FILL_DRIVER_STRING(mem_ctx,
4705 driver->default_datatype,
4706 r->default_datatype);
4708 result = string_array_from_driver_info(mem_ctx,
4709 driver->dependent_files,
4710 &r->dependent_files,
4712 driver->architecture,
4714 if (!W_ERROR_IS_OK(result)) {
4718 result = string_array_from_driver_info(mem_ctx,
4719 driver->previous_names,
4722 if (!W_ERROR_IS_OK(result)) {
4726 r->driver_date = driver->driver_date;
4727 r->driver_version = driver->driver_version;
4729 FILL_DRIVER_STRING(mem_ctx,
4730 driver->manufacturer_name,
4731 r->manufacturer_name);
4732 FILL_DRIVER_STRING(mem_ctx,
4733 driver->manufacturer_url,
4734 r->manufacturer_url);
4735 FILL_DRIVER_STRING(mem_ctx,
4736 driver->hardware_id,
4738 FILL_DRIVER_STRING(mem_ctx,
4745 /********************************************************************
4746 * fill a spoolss_DriverInfo8 struct
4747 ********************************************************************/
4749 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4750 struct spoolss_DriverInfo8 *r,
4751 const struct spoolss_DriverInfo8 *driver,
4752 const char *servername)
4754 const char *cservername = canon_servername(servername);
4757 r->version = driver->version;
4759 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4760 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4761 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4762 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4764 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4765 driver->architecture,
4767 driver->driver_path,
4770 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4771 driver->architecture,
4776 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4777 driver->architecture,
4779 driver->config_file,
4782 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4783 driver->architecture,
4788 FILL_DRIVER_STRING(mem_ctx,
4789 driver->monitor_name,
4792 FILL_DRIVER_STRING(mem_ctx,
4793 driver->default_datatype,
4794 r->default_datatype);
4796 result = string_array_from_driver_info(mem_ctx,
4797 driver->dependent_files,
4798 &r->dependent_files,
4800 driver->architecture,
4802 if (!W_ERROR_IS_OK(result)) {
4806 result = string_array_from_driver_info(mem_ctx,
4807 driver->previous_names,
4810 if (!W_ERROR_IS_OK(result)) {
4814 r->driver_date = driver->driver_date;
4815 r->driver_version = driver->driver_version;
4817 FILL_DRIVER_STRING(mem_ctx,
4818 driver->manufacturer_name,
4819 r->manufacturer_name);
4820 FILL_DRIVER_STRING(mem_ctx,
4821 driver->manufacturer_url,
4822 r->manufacturer_url);
4823 FILL_DRIVER_STRING(mem_ctx,
4824 driver->hardware_id,
4826 FILL_DRIVER_STRING(mem_ctx,
4830 FILL_DRIVER_STRING(mem_ctx,
4831 driver->print_processor,
4832 r->print_processor);
4833 FILL_DRIVER_STRING(mem_ctx,
4834 driver->vendor_setup,
4837 result = string_array_from_driver_info(mem_ctx,
4838 driver->color_profiles,
4841 if (!W_ERROR_IS_OK(result)) {
4845 FILL_DRIVER_STRING(mem_ctx,
4849 r->printer_driver_attributes = driver->printer_driver_attributes;
4851 result = string_array_from_driver_info(mem_ctx,
4852 driver->core_driver_dependencies,
4853 &r->core_driver_dependencies,
4855 if (!W_ERROR_IS_OK(result)) {
4859 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4860 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4865 #if 0 /* disabled until marshalling issues are resolved - gd */
4866 /********************************************************************
4867 ********************************************************************/
4869 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4870 struct spoolss_DriverFileInfo *r,
4871 const char *cservername,
4872 const char *file_name,
4873 enum spoolss_DriverFileType file_type,
4874 uint32_t file_version)
4876 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4877 cservername, file_name);
4878 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4879 r->file_type = file_type;
4880 r->file_version = file_version;
4885 /********************************************************************
4886 ********************************************************************/
4888 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4889 const struct spoolss_DriverInfo8 *driver,
4890 const char *cservername,
4891 struct spoolss_DriverFileInfo **info_p,
4894 struct spoolss_DriverFileInfo *info = NULL;
4902 if (strlen(driver->driver_path)) {
4903 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4904 struct spoolss_DriverFileInfo,
4906 W_ERROR_HAVE_NO_MEMORY(info);
4907 result = fill_spoolss_DriverFileInfo(info,
4910 driver->driver_path,
4911 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4913 W_ERROR_NOT_OK_RETURN(result);
4917 if (strlen(driver->config_file)) {
4918 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4919 struct spoolss_DriverFileInfo,
4921 W_ERROR_HAVE_NO_MEMORY(info);
4922 result = fill_spoolss_DriverFileInfo(info,
4925 driver->config_file,
4926 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4928 W_ERROR_NOT_OK_RETURN(result);
4932 if (strlen(driver->data_file)) {
4933 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4934 struct spoolss_DriverFileInfo,
4936 W_ERROR_HAVE_NO_MEMORY(info);
4937 result = fill_spoolss_DriverFileInfo(info,
4941 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4943 W_ERROR_NOT_OK_RETURN(result);
4947 if (strlen(driver->help_file)) {
4948 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4949 struct spoolss_DriverFileInfo,
4951 W_ERROR_HAVE_NO_MEMORY(info);
4952 result = fill_spoolss_DriverFileInfo(info,
4956 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4958 W_ERROR_NOT_OK_RETURN(result);
4962 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4963 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4964 struct spoolss_DriverFileInfo,
4966 W_ERROR_HAVE_NO_MEMORY(info);
4967 result = fill_spoolss_DriverFileInfo(info,
4970 driver->dependent_files[i],
4971 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4973 W_ERROR_NOT_OK_RETURN(result);
4983 /********************************************************************
4984 * fill a spoolss_DriverInfo101 struct
4985 ********************************************************************/
4987 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4988 struct spoolss_DriverInfo101 *r,
4989 const struct spoolss_DriverInfo8 *driver,
4990 const char *servername)
4992 const char *cservername = canon_servername(servername);
4995 r->version = driver->version;
4997 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4998 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4999 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5000 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5002 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5006 if (!W_ERROR_IS_OK(result)) {
5010 FILL_DRIVER_STRING(mem_ctx,
5011 driver->monitor_name,
5014 FILL_DRIVER_STRING(mem_ctx,
5015 driver->default_datatype,
5016 r->default_datatype);
5018 result = string_array_from_driver_info(mem_ctx,
5019 driver->previous_names,
5022 if (!W_ERROR_IS_OK(result)) {
5026 r->driver_date = driver->driver_date;
5027 r->driver_version = driver->driver_version;
5029 FILL_DRIVER_STRING(mem_ctx,
5030 driver->manufacturer_name,
5031 r->manufacturer_name);
5032 FILL_DRIVER_STRING(mem_ctx,
5033 driver->manufacturer_url,
5034 r->manufacturer_url);
5035 FILL_DRIVER_STRING(mem_ctx,
5036 driver->hardware_id,
5038 FILL_DRIVER_STRING(mem_ctx,
5045 /********************************************************************
5046 ********************************************************************/
5048 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5049 struct auth_serversupplied_info *server_info,
5050 struct messaging_context *msg_ctx,
5052 union spoolss_DriverInfo *r,
5054 const char *servername,
5055 const char *architecture,
5058 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5059 struct spoolss_DriverInfo8 *driver;
5062 result = winreg_get_printer(mem_ctx,
5066 lp_const_servicename(snum),
5069 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5070 win_errstr(result)));
5072 if (!W_ERROR_IS_OK(result)) {
5073 return WERR_INVALID_PRINTER_NAME;
5076 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5078 pinfo2->drivername, version, &driver);
5080 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5081 win_errstr(result)));
5083 if (!W_ERROR_IS_OK(result)) {
5085 * Is this a W2k client ?
5089 talloc_free(pinfo2);
5090 return WERR_UNKNOWN_PRINTER_DRIVER;
5093 /* Yes - try again with a WinNT driver. */
5095 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5099 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5100 win_errstr(result)));
5101 if (!W_ERROR_IS_OK(result)) {
5102 talloc_free(pinfo2);
5103 return WERR_UNKNOWN_PRINTER_DRIVER;
5109 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5112 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5115 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5118 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5121 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5124 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5127 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5129 #if 0 /* disabled until marshalling issues are resolved - gd */
5131 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5135 result = WERR_UNKNOWN_LEVEL;
5139 talloc_free(pinfo2);
5140 talloc_free(driver);
5145 /****************************************************************
5146 _spoolss_GetPrinterDriver2
5147 ****************************************************************/
5149 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5150 struct spoolss_GetPrinterDriver2 *r)
5152 Printer_entry *printer;
5157 /* that's an [in out] buffer */
5159 if (!r->in.buffer && (r->in.offered != 0)) {
5160 return WERR_INVALID_PARAM;
5163 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5165 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5166 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5167 return WERR_INVALID_PRINTER_NAME;
5171 *r->out.server_major_version = 0;
5172 *r->out.server_minor_version = 0;
5174 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5178 result = construct_printer_driver_info_level(p->mem_ctx,
5181 r->in.level, r->out.info,
5182 snum, printer->servername,
5184 r->in.client_major_version);
5185 if (!W_ERROR_IS_OK(result)) {
5186 TALLOC_FREE(r->out.info);
5190 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5191 r->out.info, r->in.level);
5192 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5194 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5198 /****************************************************************
5199 _spoolss_StartPagePrinter
5200 ****************************************************************/
5202 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5203 struct spoolss_StartPagePrinter *r)
5205 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5208 DEBUG(3,("_spoolss_StartPagePrinter: "
5209 "Error in startpageprinter printer handle\n"));
5213 Printer->page_started = true;
5217 /****************************************************************
5218 _spoolss_EndPagePrinter
5219 ****************************************************************/
5221 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5222 struct spoolss_EndPagePrinter *r)
5226 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5229 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5230 OUR_HANDLE(r->in.handle)));
5234 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5237 Printer->page_started = false;
5238 print_job_endpage(p->msg_ctx, snum, Printer->jobid);
5243 /****************************************************************
5244 _spoolss_StartDocPrinter
5245 ****************************************************************/
5247 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5248 struct spoolss_StartDocPrinter *r)
5250 struct spoolss_DocumentInfo1 *info_1;
5252 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5256 DEBUG(2,("_spoolss_StartDocPrinter: "
5257 "Invalid handle (%s:%u:%u)\n",
5258 OUR_HANDLE(r->in.handle)));
5262 if (Printer->jobid) {
5263 DEBUG(2, ("_spoolss_StartDocPrinter: "
5264 "StartDocPrinter called twice! "
5265 "(existing jobid = %d)\n", Printer->jobid));
5266 return WERR_INVALID_HANDLE;
5269 if (r->in.level != 1) {
5270 return WERR_UNKNOWN_LEVEL;
5273 info_1 = r->in.info.info1;
5276 * a nice thing with NT is it doesn't listen to what you tell it.
5277 * when asked to send _only_ RAW datas, it tries to send datas
5280 * So I add checks like in NT Server ...
5283 if (info_1->datatype) {
5284 if (strcmp(info_1->datatype, "RAW") != 0) {
5286 return WERR_INVALID_DATATYPE;
5290 /* get the share number of the printer */
5291 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5295 werr = print_job_start(p->server_info, p->msg_ctx,
5296 p->client_id->name, snum,
5297 info_1->document_name, info_1->output_file,
5298 Printer->devmode, &Printer->jobid);
5300 /* An error occured in print_job_start() so return an appropriate
5303 if (!W_ERROR_IS_OK(werr)) {
5307 Printer->document_started = true;
5308 *r->out.job_id = Printer->jobid;
5313 /****************************************************************
5314 _spoolss_EndDocPrinter
5315 ****************************************************************/
5317 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5318 struct spoolss_EndDocPrinter *r)
5320 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5325 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5326 OUR_HANDLE(r->in.handle)));
5330 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5334 Printer->document_started = false;
5335 status = print_job_end(p->msg_ctx, snum, Printer->jobid, NORMAL_CLOSE);
5336 if (!NT_STATUS_IS_OK(status)) {
5337 DEBUG(2, ("_spoolss_EndDocPrinter: "
5338 "print_job_end failed [%s]\n",
5339 nt_errstr(status)));
5343 return ntstatus_to_werror(status);
5346 /****************************************************************
5347 _spoolss_WritePrinter
5348 ****************************************************************/
5350 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5351 struct spoolss_WritePrinter *r)
5353 ssize_t buffer_written;
5355 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5358 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5359 OUR_HANDLE(r->in.handle)));
5360 *r->out.num_written = r->in._data_size;
5364 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5367 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5368 buffer_written = print_job_write(server_event_context(),p->msg_ctx,
5369 snum, Printer->jobid,
5370 (const char *)r->in.data.data,
5371 (size_t)r->in._data_size);
5372 if (buffer_written == (ssize_t)-1) {
5373 *r->out.num_written = 0;
5374 if (errno == ENOSPC)
5375 return WERR_NO_SPOOL_SPACE;
5377 return WERR_ACCESS_DENIED;
5380 *r->out.num_written = r->in._data_size;
5385 /********************************************************************
5386 * api_spoolss_getprinter
5387 * called from the spoolss dispatcher
5389 ********************************************************************/
5391 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5392 struct pipes_struct *p)
5395 WERROR errcode = WERR_BADFUNC;
5396 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5399 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5400 OUR_HANDLE(handle)));
5404 if (!get_printer_snum(p, handle, &snum, NULL))
5408 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5409 errcode = print_queue_pause(p->server_info, p->msg_ctx, snum);
5411 case SPOOLSS_PRINTER_CONTROL_RESUME:
5412 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5413 errcode = print_queue_resume(p->server_info, p->msg_ctx, snum);
5415 case SPOOLSS_PRINTER_CONTROL_PURGE:
5416 errcode = print_queue_purge(p->server_info, p->msg_ctx, snum);
5419 return WERR_UNKNOWN_LEVEL;
5426 /****************************************************************
5427 _spoolss_AbortPrinter
5428 * From MSDN: "Deletes printer's spool file if printer is configured
5430 ****************************************************************/
5432 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5433 struct spoolss_AbortPrinter *r)
5435 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5437 WERROR errcode = WERR_OK;
5440 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5441 OUR_HANDLE(r->in.handle)));
5445 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5448 if (!Printer->document_started) {
5449 return WERR_SPL_NO_STARTDOC;
5452 errcode = print_job_delete(p->server_info, p->msg_ctx, snum,
5458 /********************************************************************
5459 * called by spoolss_api_setprinter
5460 * when updating a printer description
5461 ********************************************************************/
5463 static WERROR update_printer_sec(struct policy_handle *handle,
5464 struct pipes_struct *p,
5465 struct sec_desc_buf *secdesc_ctr)
5467 struct spoolss_security_descriptor *new_secdesc = NULL;
5468 struct spoolss_security_descriptor *old_secdesc = NULL;
5469 const char *printer;
5473 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5475 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5476 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5477 OUR_HANDLE(handle)));
5479 result = WERR_BADFID;
5483 if (secdesc_ctr == NULL) {
5484 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5485 result = WERR_INVALID_PARAM;
5488 printer = lp_const_servicename(snum);
5490 /* Check the user has permissions to change the security
5491 descriptor. By experimentation with two NT machines, the user
5492 requires Full Access to the printer to change security
5495 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5496 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5497 result = WERR_ACCESS_DENIED;
5501 /* NT seems to like setting the security descriptor even though
5502 nothing may have actually changed. */
5503 result = winreg_get_printer_secdesc(p->mem_ctx,
5508 if (!W_ERROR_IS_OK(result)) {
5509 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5510 result = WERR_BADFID;
5514 if (DEBUGLEVEL >= 10) {
5515 struct security_acl *the_acl;
5518 the_acl = old_secdesc->dacl;
5519 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5520 printer, the_acl->num_aces));
5522 for (i = 0; i < the_acl->num_aces; i++) {
5523 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5524 &the_acl->aces[i].trustee),
5525 the_acl->aces[i].access_mask));
5528 the_acl = secdesc_ctr->sd->dacl;
5531 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5532 printer, the_acl->num_aces));
5534 for (i = 0; i < the_acl->num_aces; i++) {
5535 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5536 &the_acl->aces[i].trustee),
5537 the_acl->aces[i].access_mask));
5540 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5544 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5545 if (new_secdesc == NULL) {
5546 result = WERR_NOMEM;
5550 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5555 result = winreg_set_printer_secdesc(p->mem_ctx,
5565 /********************************************************************
5566 Canonicalize printer info from a client
5567 ********************************************************************/
5569 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5570 struct spoolss_SetPrinterInfo2 *info2,
5573 fstring printername;
5576 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5577 "portname=%s drivername=%s comment=%s location=%s\n",
5578 info2->servername, info2->printername, info2->sharename,
5579 info2->portname, info2->drivername, info2->comment,
5582 /* we force some elements to "correct" values */
5583 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5584 if (info2->servername == NULL) {
5587 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5588 if (info2->sharename == NULL) {
5592 /* check to see if we allow printername != sharename */
5593 if (lp_force_printername(snum)) {
5594 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5595 global_myname(), info2->sharename);
5597 /* make sure printername is in \\server\printername format */
5598 fstrcpy(printername, info2->printername);
5600 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5601 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5605 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5606 global_myname(), p);
5608 if (info2->printername == NULL) {
5612 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5613 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5618 /****************************************************************************
5619 ****************************************************************************/
5621 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5623 char *cmd = lp_addport_cmd();
5624 char *command = NULL;
5626 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5627 bool is_print_op = false;
5630 return WERR_ACCESS_DENIED;
5633 command = talloc_asprintf(ctx,
5634 "%s \"%s\" \"%s\"", cmd, portname, uri );
5640 is_print_op = user_has_privileges( token, &se_printop );
5642 DEBUG(10,("Running [%s]\n", command));
5644 /********* BEGIN SePrintOperatorPrivilege **********/
5649 ret = smbrun(command, NULL);
5654 /********* END SePrintOperatorPrivilege **********/
5656 DEBUGADD(10,("returned [%d]\n", ret));
5658 TALLOC_FREE(command);
5661 return WERR_ACCESS_DENIED;
5667 /****************************************************************************
5668 ****************************************************************************/
5670 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5671 struct spoolss_SetPrinterInfo2 *info2,
5672 const char *remote_machine,
5673 struct messaging_context *msg_ctx)
5675 char *cmd = lp_addprinter_cmd();
5677 char *command = NULL;
5681 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5682 bool is_print_op = false;
5684 if (!remote_machine) {
5688 command = talloc_asprintf(ctx,
5689 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5690 cmd, info2->printername, info2->sharename,
5691 info2->portname, info2->drivername,
5692 info2->location, info2->comment, remote_machine);
5698 is_print_op = user_has_privileges( token, &se_printop );
5700 DEBUG(10,("Running [%s]\n", command));
5702 /********* BEGIN SePrintOperatorPrivilege **********/
5707 if ( (ret = smbrun(command, &fd)) == 0 ) {
5708 /* Tell everyone we updated smb.conf. */
5709 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5715 /********* END SePrintOperatorPrivilege **********/
5717 DEBUGADD(10,("returned [%d]\n", ret));
5719 TALLOC_FREE(command);
5727 /* reload our services immediately */
5729 reload_services(msg_ctx, smbd_server_fd(), false);
5733 /* Get lines and convert them back to dos-codepage */
5734 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5735 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5738 /* Set the portname to what the script says the portname should be. */
5739 /* but don't require anything to be return from the script exit a good error code */
5742 /* Set the portname to what the script says the portname should be. */
5743 info2->portname = talloc_strdup(ctx, qlines[0]);
5744 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5747 TALLOC_FREE(qlines);
5751 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5752 struct auth_serversupplied_info *server_info,
5753 struct messaging_context *msg_ctx,
5755 struct spoolss_SetPrinterInfo2 *printer,
5756 struct spoolss_PrinterInfo2 *old_printer)
5758 bool force_update = (old_printer == NULL);
5759 const char *dnsdomname;
5760 const char *longname;
5761 const char *uncname;
5762 const char *spooling;
5764 WERROR result = WERR_OK;
5766 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5767 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5768 winreg_set_printer_dataex(mem_ctx,
5772 SPOOL_DSSPOOLER_KEY,
5773 SPOOL_REG_DRIVERNAME,
5778 if (!force_update) {
5779 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5780 printer->drivername));
5782 notify_printer_driver(server_event_context(), msg_ctx,
5783 snum, printer->drivername);
5787 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5788 push_reg_sz(mem_ctx, &buffer, printer->comment);
5789 winreg_set_printer_dataex(mem_ctx,
5793 SPOOL_DSSPOOLER_KEY,
5794 SPOOL_REG_DESCRIPTION,
5799 if (!force_update) {
5800 notify_printer_comment(server_event_context(), msg_ctx,
5801 snum, printer->comment);
5805 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5806 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5807 winreg_set_printer_dataex(mem_ctx,
5811 SPOOL_DSSPOOLER_KEY,
5812 SPOOL_REG_PRINTSHARENAME,
5817 if (!force_update) {
5818 notify_printer_sharename(server_event_context(),
5820 snum, printer->sharename);
5824 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5827 p = strrchr(printer->printername, '\\' );
5831 p = printer->printername;
5834 push_reg_sz(mem_ctx, &buffer, p);
5835 winreg_set_printer_dataex(mem_ctx,
5839 SPOOL_DSSPOOLER_KEY,
5840 SPOOL_REG_PRINTERNAME,
5845 if (!force_update) {
5846 notify_printer_printername(server_event_context(),
5851 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5852 push_reg_sz(mem_ctx, &buffer, printer->portname);
5853 winreg_set_printer_dataex(mem_ctx,
5857 SPOOL_DSSPOOLER_KEY,
5863 if (!force_update) {
5864 notify_printer_port(server_event_context(),
5865 msg_ctx, snum, printer->portname);
5869 if (force_update || !strequal(printer->location, old_printer->location)) {
5870 push_reg_sz(mem_ctx, &buffer, printer->location);
5871 winreg_set_printer_dataex(mem_ctx,
5875 SPOOL_DSSPOOLER_KEY,
5881 if (!force_update) {
5882 notify_printer_location(server_event_context(),
5888 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5889 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5890 winreg_set_printer_dataex(mem_ctx,
5894 SPOOL_DSSPOOLER_KEY,
5895 SPOOL_REG_PRINTSEPARATORFILE,
5900 if (!force_update) {
5901 notify_printer_location(server_event_context(),
5907 if (force_update || printer->starttime != old_printer->starttime) {
5908 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5909 SIVAL(buffer.data, 0, printer->starttime);
5910 winreg_set_printer_dataex(mem_ctx,
5914 SPOOL_DSSPOOLER_KEY,
5915 SPOOL_REG_PRINTSTARTTIME,
5921 if (force_update || printer->untiltime != old_printer->untiltime) {
5922 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5923 SIVAL(buffer.data, 0, printer->untiltime);
5924 winreg_set_printer_dataex(mem_ctx,
5928 SPOOL_DSSPOOLER_KEY,
5929 SPOOL_REG_PRINTENDTIME,
5935 if (force_update || printer->priority != old_printer->priority) {
5936 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5937 SIVAL(buffer.data, 0, printer->priority);
5938 winreg_set_printer_dataex(mem_ctx,
5942 SPOOL_DSSPOOLER_KEY,
5949 if (force_update || printer->attributes != old_printer->attributes) {
5950 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5951 SIVAL(buffer.data, 0, (printer->attributes &
5952 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5953 winreg_set_printer_dataex(mem_ctx,
5957 SPOOL_DSSPOOLER_KEY,
5958 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5963 switch (printer->attributes & 0x3) {
5965 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5968 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5971 spooling = SPOOL_REGVAL_PRINTDIRECT;
5974 spooling = "unknown";
5976 push_reg_sz(mem_ctx, &buffer, spooling);
5977 winreg_set_printer_dataex(mem_ctx,
5981 SPOOL_DSSPOOLER_KEY,
5982 SPOOL_REG_PRINTSPOOLING,
5988 push_reg_sz(mem_ctx, &buffer, global_myname());
5989 winreg_set_printer_dataex(mem_ctx,
5993 SPOOL_DSSPOOLER_KEY,
5994 SPOOL_REG_SHORTSERVERNAME,
5999 dnsdomname = get_mydnsfullname();
6000 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
6001 longname = talloc_strdup(mem_ctx, dnsdomname);
6003 longname = talloc_strdup(mem_ctx, global_myname());
6005 if (longname == NULL) {
6006 result = WERR_NOMEM;
6010 push_reg_sz(mem_ctx, &buffer, longname);
6011 winreg_set_printer_dataex(mem_ctx,
6015 SPOOL_DSSPOOLER_KEY,
6016 SPOOL_REG_SERVERNAME,
6021 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
6022 global_myname(), printer->sharename);
6023 push_reg_sz(mem_ctx, &buffer, uncname);
6024 winreg_set_printer_dataex(mem_ctx,
6028 SPOOL_DSSPOOLER_KEY,
6038 /********************************************************************
6039 * Called by spoolss_api_setprinter
6040 * when updating a printer description.
6041 ********************************************************************/
6043 static WERROR update_printer(struct pipes_struct *p,
6044 struct policy_handle *handle,
6045 struct spoolss_SetPrinterInfoCtr *info_ctr,
6046 struct spoolss_DeviceMode *devmode)
6048 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
6049 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
6050 struct spoolss_PrinterInfo2 *old_printer;
6051 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6052 const char *servername = NULL;
6054 WERROR result = WERR_OK;
6055 TALLOC_CTX *tmp_ctx;
6057 DEBUG(8,("update_printer\n"));
6059 tmp_ctx = talloc_new(p->mem_ctx);
6060 if (tmp_ctx == NULL) {
6065 result = WERR_BADFID;
6069 if (!get_printer_snum(p, handle, &snum, NULL)) {
6070 result = WERR_BADFID;
6074 if (Printer != NULL || Printer->servername != NULL) {
6075 servername = Printer->servername;
6078 result = winreg_get_printer(tmp_ctx,
6082 lp_const_servicename(snum),
6084 if (!W_ERROR_IS_OK(result)) {
6085 result = WERR_BADFID;
6089 /* Do sanity check on the requested changes for Samba */
6090 if (!check_printer_ok(tmp_ctx, printer, snum)) {
6091 result = WERR_INVALID_PARAM;
6095 /* FIXME!!! If the driver has changed we really should verify that
6096 it is installed before doing much else --jerry */
6098 /* Check calling user has permission to update printer description */
6099 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6100 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6101 result = WERR_ACCESS_DENIED;
6105 /* Call addprinter hook */
6106 /* Check changes to see if this is really needed */
6108 if (*lp_addprinter_cmd() &&
6109 (!strequal(printer->drivername, old_printer->drivername) ||
6110 !strequal(printer->comment, old_printer->comment) ||
6111 !strequal(printer->portname, old_printer->portname) ||
6112 !strequal(printer->location, old_printer->location)) )
6114 /* add_printer_hook() will call reload_services() */
6115 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6116 printer, p->client_id->addr,
6118 result = WERR_ACCESS_DENIED;
6123 update_dsspooler(tmp_ctx,
6130 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6132 if (devmode == NULL) {
6133 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6135 result = winreg_update_printer(tmp_ctx,
6145 talloc_free(tmp_ctx);
6150 /****************************************************************************
6151 ****************************************************************************/
6152 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6153 struct policy_handle *handle,
6154 struct spoolss_SetPrinterInfo7 *info7)
6157 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6160 Printer_entry *Printer;
6162 if ( lp_security() != SEC_ADS ) {
6163 return WERR_UNKNOWN_LEVEL;
6166 Printer = find_printer_index_by_hnd(p, handle);
6168 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6173 if (!get_printer_snum(p, handle, &snum, NULL))
6176 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6177 Printer->servername,
6178 lp_servicename(snum), &pinfo2);
6179 if (!W_ERROR_IS_OK(result)) {
6183 nt_printer_publish(pinfo2, p->server_info, p->msg_ctx, pinfo2,
6186 TALLOC_FREE(pinfo2);
6189 return WERR_UNKNOWN_LEVEL;
6193 /********************************************************************
6194 ********************************************************************/
6196 static WERROR update_printer_devmode(struct pipes_struct *p,
6197 struct policy_handle *handle,
6198 struct spoolss_DeviceMode *devmode)
6201 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6202 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6204 DEBUG(8,("update_printer_devmode\n"));
6210 if (!get_printer_snum(p, handle, &snum, NULL)) {
6214 /* Check calling user has permission to update printer description */
6215 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6216 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6217 return WERR_ACCESS_DENIED;
6220 return winreg_update_printer(p->mem_ctx,
6223 lp_const_servicename(snum),
6231 /****************************************************************
6233 ****************************************************************/
6235 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6236 struct spoolss_SetPrinter *r)
6240 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6243 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6244 OUR_HANDLE(r->in.handle)));
6248 /* check the level */
6249 switch (r->in.info_ctr->level) {
6251 return control_printer(r->in.handle, r->in.command, p);
6253 result = update_printer(p, r->in.handle,
6255 r->in.devmode_ctr->devmode);
6256 if (!W_ERROR_IS_OK(result))
6258 if (r->in.secdesc_ctr->sd)
6259 result = update_printer_sec(r->in.handle, p,
6263 return update_printer_sec(r->in.handle, p,
6266 return publish_or_unpublish_printer(p, r->in.handle,
6267 r->in.info_ctr->info.info7);
6269 return update_printer_devmode(p, r->in.handle,
6270 r->in.devmode_ctr->devmode);
6272 return WERR_UNKNOWN_LEVEL;
6276 /****************************************************************
6277 _spoolss_FindClosePrinterNotify
6278 ****************************************************************/
6280 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6281 struct spoolss_FindClosePrinterNotify *r)
6283 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6286 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6287 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6291 if (Printer->notify.client_connected == true) {
6294 if ( Printer->printer_type == SPLHND_SERVER)
6296 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6297 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6300 srv_spoolss_replycloseprinter(
6301 snum, &Printer->notify.client_hnd, p->msg_ctx);
6304 Printer->notify.flags=0;
6305 Printer->notify.options=0;
6306 Printer->notify.localmachine[0]='\0';
6307 Printer->notify.printerlocal=0;
6308 TALLOC_FREE(Printer->notify.option);
6309 Printer->notify.client_connected = false;
6314 /****************************************************************
6316 ****************************************************************/
6318 WERROR _spoolss_AddJob(struct pipes_struct *p,
6319 struct spoolss_AddJob *r)
6321 if (!r->in.buffer && (r->in.offered != 0)) {
6322 return WERR_INVALID_PARAM;
6325 /* this is what a NT server returns for AddJob. AddJob must fail on
6326 * non-local printers */
6328 if (r->in.level != 1) {
6329 return WERR_UNKNOWN_LEVEL;
6332 return WERR_INVALID_PARAM;
6335 /****************************************************************************
6337 ****************************************************************************/
6339 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6340 struct spoolss_JobInfo1 *r,
6341 const print_queue_struct *queue,
6342 int position, int snum,
6343 struct spoolss_PrinterInfo2 *pinfo2)
6347 t = gmtime(&queue->time);
6349 r->job_id = queue->job;
6351 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6352 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6353 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6354 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6355 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6356 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6357 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6358 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6359 r->data_type = talloc_strdup(mem_ctx, "RAW");
6360 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6361 r->text_status = talloc_strdup(mem_ctx, "");
6362 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6364 r->status = nt_printj_status(queue->status);
6365 r->priority = queue->priority;
6366 r->position = position;
6367 r->total_pages = queue->page_count;
6368 r->pages_printed = 0; /* ??? */
6370 init_systemtime(&r->submitted, t);
6375 /****************************************************************************
6377 ****************************************************************************/
6379 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6380 struct spoolss_JobInfo2 *r,
6381 const print_queue_struct *queue,
6382 int position, int snum,
6383 struct spoolss_PrinterInfo2 *pinfo2,
6384 struct spoolss_DeviceMode *devmode)
6388 t = gmtime(&queue->time);
6390 r->job_id = queue->job;
6392 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6393 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6394 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6395 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6396 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6397 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6398 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6399 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6400 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6401 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6402 r->data_type = talloc_strdup(mem_ctx, "RAW");
6403 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6404 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6405 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6406 r->parameters = talloc_strdup(mem_ctx, "");
6407 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6408 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6409 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6411 r->devmode = devmode;
6413 r->text_status = talloc_strdup(mem_ctx, "");
6414 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6418 r->status = nt_printj_status(queue->status);
6419 r->priority = queue->priority;
6420 r->position = position;
6423 r->total_pages = queue->page_count;
6424 r->size = queue->size;
6425 init_systemtime(&r->submitted, t);
6427 r->pages_printed = 0; /* ??? */
6432 /****************************************************************************
6434 ****************************************************************************/
6436 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6437 struct spoolss_JobInfo3 *r,
6438 const print_queue_struct *queue,
6439 const print_queue_struct *next_queue,
6440 int position, int snum,
6441 struct spoolss_PrinterInfo2 *pinfo2)
6443 r->job_id = queue->job;
6446 r->next_job_id = next_queue->job;
6453 /****************************************************************************
6454 Enumjobs at level 1.
6455 ****************************************************************************/
6457 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6458 const print_queue_struct *queue,
6459 uint32_t num_queues, int snum,
6460 struct spoolss_PrinterInfo2 *pinfo2,
6461 union spoolss_JobInfo **info_p,
6464 union spoolss_JobInfo *info;
6466 WERROR result = WERR_OK;
6468 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6469 W_ERROR_HAVE_NO_MEMORY(info);
6471 *count = num_queues;
6473 for (i=0; i<*count; i++) {
6474 result = fill_job_info1(info,
6480 if (!W_ERROR_IS_OK(result)) {
6486 if (!W_ERROR_IS_OK(result)) {
6497 /****************************************************************************
6498 Enumjobs at level 2.
6499 ****************************************************************************/
6501 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6502 const print_queue_struct *queue,
6503 uint32_t num_queues, int snum,
6504 struct spoolss_PrinterInfo2 *pinfo2,
6505 union spoolss_JobInfo **info_p,
6508 union spoolss_JobInfo *info;
6510 WERROR result = WERR_OK;
6512 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6513 W_ERROR_HAVE_NO_MEMORY(info);
6515 *count = num_queues;
6517 for (i=0; i<*count; i++) {
6518 struct spoolss_DeviceMode *devmode;
6520 result = spoolss_create_default_devmode(info,
6521 pinfo2->printername,
6523 if (!W_ERROR_IS_OK(result)) {
6524 DEBUG(3, ("Can't proceed w/o a devmode!"));
6528 result = fill_job_info2(info,
6535 if (!W_ERROR_IS_OK(result)) {
6541 if (!W_ERROR_IS_OK(result)) {
6552 /****************************************************************************
6553 Enumjobs at level 3.
6554 ****************************************************************************/
6556 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6557 const print_queue_struct *queue,
6558 uint32_t num_queues, int snum,
6559 struct spoolss_PrinterInfo2 *pinfo2,
6560 union spoolss_JobInfo **info_p,
6563 union spoolss_JobInfo *info;
6565 WERROR result = WERR_OK;
6567 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6568 W_ERROR_HAVE_NO_MEMORY(info);
6570 *count = num_queues;
6572 for (i=0; i<*count; i++) {
6573 const print_queue_struct *next_queue = NULL;
6576 next_queue = &queue[i+1];
6579 result = fill_job_info3(info,
6586 if (!W_ERROR_IS_OK(result)) {
6592 if (!W_ERROR_IS_OK(result)) {
6603 /****************************************************************
6605 ****************************************************************/
6607 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6608 struct spoolss_EnumJobs *r)
6611 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6613 print_status_struct prt_status;
6614 print_queue_struct *queue = NULL;
6617 /* that's an [in out] buffer */
6619 if (!r->in.buffer && (r->in.offered != 0)) {
6620 return WERR_INVALID_PARAM;
6623 DEBUG(4,("_spoolss_EnumJobs\n"));
6627 *r->out.info = NULL;
6629 /* lookup the printer snum and tdb entry */
6631 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6635 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6636 NULL, lp_servicename(snum), &pinfo2);
6637 if (!W_ERROR_IS_OK(result)) {
6641 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
6642 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6643 count, prt_status.status, prt_status.message));
6647 TALLOC_FREE(pinfo2);
6651 switch (r->in.level) {
6653 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6654 pinfo2, r->out.info, r->out.count);
6657 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6658 pinfo2, r->out.info, r->out.count);
6661 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6662 pinfo2, r->out.info, r->out.count);
6665 result = WERR_UNKNOWN_LEVEL;
6670 TALLOC_FREE(pinfo2);
6672 if (!W_ERROR_IS_OK(result)) {
6676 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6678 *r->out.info, r->in.level,
6680 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6681 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6683 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6686 /****************************************************************
6687 _spoolss_ScheduleJob
6688 ****************************************************************/
6690 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6691 struct spoolss_ScheduleJob *r)
6696 /****************************************************************
6697 ****************************************************************/
6699 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6700 struct messaging_context *msg_ctx,
6701 const char *printer_name,
6703 struct spoolss_SetJobInfo1 *r)
6707 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6711 if (strequal(old_doc_name, r->document_name)) {
6715 if (!print_job_set_name(server_event_context(), msg_ctx,
6716 printer_name, job_id, r->document_name)) {
6723 /****************************************************************
6725 ****************************************************************/
6727 WERROR _spoolss_SetJob(struct pipes_struct *p,
6728 struct spoolss_SetJob *r)
6731 WERROR errcode = WERR_BADFUNC;
6733 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6737 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6738 return WERR_INVALID_PRINTER_NAME;
6741 switch (r->in.command) {
6742 case SPOOLSS_JOB_CONTROL_CANCEL:
6743 case SPOOLSS_JOB_CONTROL_DELETE:
6744 errcode = print_job_delete(p->server_info, p->msg_ctx,
6745 snum, r->in.job_id);
6746 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6750 case SPOOLSS_JOB_CONTROL_PAUSE:
6751 if (print_job_pause(p->server_info, p->msg_ctx,
6752 snum, r->in.job_id, &errcode)) {
6756 case SPOOLSS_JOB_CONTROL_RESTART:
6757 case SPOOLSS_JOB_CONTROL_RESUME:
6758 if (print_job_resume(p->server_info, p->msg_ctx,
6759 snum, r->in.job_id, &errcode)) {
6767 return WERR_UNKNOWN_LEVEL;
6770 if (!W_ERROR_IS_OK(errcode)) {
6774 if (r->in.ctr == NULL) {
6778 switch (r->in.ctr->level) {
6780 errcode = spoolss_setjob_1(p->mem_ctx, p->msg_ctx,
6781 lp_const_servicename(snum),
6783 r->in.ctr->info.info1);
6789 return WERR_UNKNOWN_LEVEL;
6795 /****************************************************************************
6796 Enumerates all printer drivers by level and architecture.
6797 ****************************************************************************/
6799 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6800 struct auth_serversupplied_info *server_info,
6801 struct messaging_context *msg_ctx,
6802 const char *servername,
6803 const char *architecture,
6805 union spoolss_DriverInfo **info_p,
6810 struct spoolss_DriverInfo8 *driver;
6811 union spoolss_DriverInfo *info = NULL;
6813 WERROR result = WERR_OK;
6814 uint32_t num_drivers;
6815 const char **drivers;
6820 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6821 result = winreg_get_driver_list(mem_ctx, server_info, msg_ctx,
6822 architecture, version,
6823 &num_drivers, &drivers);
6824 if (!W_ERROR_IS_OK(result)) {
6827 DEBUG(4, ("we have:[%d] drivers in environment"
6828 " [%s] and version [%d]\n",
6829 num_drivers, architecture, version));
6831 if (num_drivers != 0) {
6832 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6833 union spoolss_DriverInfo,
6834 count + num_drivers);
6836 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6837 "failed to enlarge driver info buffer!\n"));
6838 result = WERR_NOMEM;
6843 for (i = 0; i < num_drivers; i++) {
6844 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6846 result = winreg_get_driver(mem_ctx, server_info,
6848 architecture, drivers[i],
6850 if (!W_ERROR_IS_OK(result)) {
6856 result = fill_printer_driver_info1(info, &info[count+i].info1,
6857 driver, servername);
6860 result = fill_printer_driver_info2(info, &info[count+i].info2,
6861 driver, servername);
6864 result = fill_printer_driver_info3(info, &info[count+i].info3,
6865 driver, servername);
6868 result = fill_printer_driver_info4(info, &info[count+i].info4,
6869 driver, servername);
6872 result = fill_printer_driver_info5(info, &info[count+i].info5,
6873 driver, servername);
6876 result = fill_printer_driver_info6(info, &info[count+i].info6,
6877 driver, servername);
6880 result = fill_printer_driver_info8(info, &info[count+i].info8,
6881 driver, servername);
6884 result = WERR_UNKNOWN_LEVEL;
6888 TALLOC_FREE(driver);
6890 if (!W_ERROR_IS_OK(result)) {
6895 count += num_drivers;
6896 TALLOC_FREE(drivers);
6900 TALLOC_FREE(drivers);
6902 if (!W_ERROR_IS_OK(result)) {
6913 /****************************************************************************
6914 Enumerates all printer drivers by level.
6915 ****************************************************************************/
6917 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6918 struct auth_serversupplied_info *server_info,
6919 struct messaging_context *msg_ctx,
6920 const char *servername,
6921 const char *architecture,
6923 union spoolss_DriverInfo **info_p,
6927 WERROR result = WERR_OK;
6929 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6931 for (a=0; archi_table[a].long_archi != NULL; a++) {
6933 union spoolss_DriverInfo *info = NULL;
6936 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6940 archi_table[a].long_archi,
6944 if (!W_ERROR_IS_OK(result)) {
6948 for (i=0; i < count; i++) {
6949 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6950 info[i], info_p, count_p);
6957 return enumprinterdrivers_level_by_architecture(mem_ctx,
6967 /****************************************************************
6968 _spoolss_EnumPrinterDrivers
6969 ****************************************************************/
6971 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6972 struct spoolss_EnumPrinterDrivers *r)
6974 const char *cservername;
6977 /* that's an [in out] buffer */
6979 if (!r->in.buffer && (r->in.offered != 0)) {
6980 return WERR_INVALID_PARAM;
6983 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6987 *r->out.info = NULL;
6989 cservername = canon_servername(r->in.server);
6991 if (!is_myname_or_ipaddr(cservername)) {
6992 return WERR_UNKNOWN_PRINTER_DRIVER;
6995 result = enumprinterdrivers_level(p->mem_ctx,
7003 if (!W_ERROR_IS_OK(result)) {
7007 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7008 spoolss_EnumPrinterDrivers,
7009 *r->out.info, r->in.level,
7011 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7012 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7014 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7017 /****************************************************************
7019 ****************************************************************/
7021 WERROR _spoolss_EnumForms(struct pipes_struct *p,
7022 struct spoolss_EnumForms *r)
7028 *r->out.info = NULL;
7030 /* that's an [in out] buffer */
7032 if (!r->in.buffer && (r->in.offered != 0) ) {
7033 return WERR_INVALID_PARAM;
7036 DEBUG(4,("_spoolss_EnumForms\n"));
7037 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7038 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7040 switch (r->in.level) {
7042 result = winreg_printer_enumforms1(p->mem_ctx,
7049 result = WERR_UNKNOWN_LEVEL;
7053 if (!W_ERROR_IS_OK(result)) {
7057 if (*r->out.count == 0) {
7058 return WERR_NO_MORE_ITEMS;
7061 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7063 *r->out.info, r->in.level,
7065 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7066 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7068 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7071 /****************************************************************
7073 ****************************************************************/
7075 WERROR _spoolss_GetForm(struct pipes_struct *p,
7076 struct spoolss_GetForm *r)
7080 /* that's an [in out] buffer */
7082 if (!r->in.buffer && (r->in.offered != 0)) {
7083 return WERR_INVALID_PARAM;
7086 DEBUG(4,("_spoolss_GetForm\n"));
7087 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7088 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7090 switch (r->in.level) {
7092 result = winreg_printer_getform1(p->mem_ctx,
7096 &r->out.info->info1);
7099 result = WERR_UNKNOWN_LEVEL;
7103 if (!W_ERROR_IS_OK(result)) {
7104 TALLOC_FREE(r->out.info);
7108 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
7109 r->out.info, r->in.level);
7110 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7112 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7115 /****************************************************************************
7116 ****************************************************************************/
7118 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
7119 struct spoolss_PortInfo1 *r,
7122 r->port_name = talloc_strdup(mem_ctx, name);
7123 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7128 /****************************************************************************
7129 TODO: This probably needs distinguish between TCP/IP and Local ports
7131 ****************************************************************************/
7133 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7134 struct spoolss_PortInfo2 *r,
7137 r->port_name = talloc_strdup(mem_ctx, name);
7138 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7140 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7141 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7143 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7144 W_ERROR_HAVE_NO_MEMORY(r->description);
7146 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7153 /****************************************************************************
7154 wrapper around the enumer ports command
7155 ****************************************************************************/
7157 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7159 char *cmd = lp_enumports_cmd();
7160 char **qlines = NULL;
7161 char *command = NULL;
7169 /* if no hook then just fill in the default port */
7172 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7175 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7176 TALLOC_FREE(qlines);
7183 /* we have a valid enumport command */
7185 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7190 DEBUG(10,("Running [%s]\n", command));
7191 ret = smbrun(command, &fd);
7192 DEBUG(10,("Returned [%d]\n", ret));
7193 TALLOC_FREE(command);
7198 return WERR_ACCESS_DENIED;
7202 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7203 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7213 /****************************************************************************
7215 ****************************************************************************/
7217 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7218 union spoolss_PortInfo **info_p,
7221 union spoolss_PortInfo *info = NULL;
7223 WERROR result = WERR_OK;
7224 char **qlines = NULL;
7227 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7228 if (!W_ERROR_IS_OK(result)) {
7233 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7235 DEBUG(10,("Returning WERR_NOMEM\n"));
7236 result = WERR_NOMEM;
7240 for (i=0; i<numlines; i++) {
7241 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7242 result = fill_port_1(info, &info[i].info1, qlines[i]);
7243 if (!W_ERROR_IS_OK(result)) {
7248 TALLOC_FREE(qlines);
7251 if (!W_ERROR_IS_OK(result)) {
7253 TALLOC_FREE(qlines);
7265 /****************************************************************************
7267 ****************************************************************************/
7269 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7270 union spoolss_PortInfo **info_p,
7273 union spoolss_PortInfo *info = NULL;
7275 WERROR result = WERR_OK;
7276 char **qlines = NULL;
7279 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7280 if (!W_ERROR_IS_OK(result)) {
7285 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7287 DEBUG(10,("Returning WERR_NOMEM\n"));
7288 result = WERR_NOMEM;
7292 for (i=0; i<numlines; i++) {
7293 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7294 result = fill_port_2(info, &info[i].info2, qlines[i]);
7295 if (!W_ERROR_IS_OK(result)) {
7300 TALLOC_FREE(qlines);
7303 if (!W_ERROR_IS_OK(result)) {
7305 TALLOC_FREE(qlines);
7317 /****************************************************************
7319 ****************************************************************/
7321 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7322 struct spoolss_EnumPorts *r)
7326 /* that's an [in out] buffer */
7328 if (!r->in.buffer && (r->in.offered != 0)) {
7329 return WERR_INVALID_PARAM;
7332 DEBUG(4,("_spoolss_EnumPorts\n"));
7336 *r->out.info = NULL;
7338 switch (r->in.level) {
7340 result = enumports_level_1(p->mem_ctx, r->out.info,
7344 result = enumports_level_2(p->mem_ctx, r->out.info,
7348 return WERR_UNKNOWN_LEVEL;
7351 if (!W_ERROR_IS_OK(result)) {
7355 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7357 *r->out.info, r->in.level,
7359 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7360 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7362 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7365 /****************************************************************************
7366 ****************************************************************************/
7368 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7370 struct spoolss_SetPrinterInfoCtr *info_ctr,
7371 struct spoolss_DeviceMode *devmode,
7372 struct security_descriptor *secdesc,
7373 struct spoolss_UserLevelCtr *user_ctr,
7374 struct policy_handle *handle)
7376 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7377 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7379 WERROR err = WERR_OK;
7381 /* samba does not have a concept of local, non-shared printers yet, so
7382 * make sure we always setup sharename - gd */
7383 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7384 (info2->printername != NULL && info2->printername[0] != '\0')) {
7385 DEBUG(5, ("spoolss_addprinterex_level_2: "
7386 "no sharename has been set, setting printername %s as sharename\n",
7387 info2->printername));
7388 info2->sharename = info2->printername;
7391 /* check to see if the printer already exists */
7392 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7393 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7395 return WERR_PRINTER_ALREADY_EXISTS;
7398 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7399 if ((snum = print_queue_snum(info2->printername)) != -1) {
7400 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7401 info2->printername));
7402 return WERR_PRINTER_ALREADY_EXISTS;
7406 /* validate printer info struct */
7407 if (!info2->printername || strlen(info2->printername) == 0) {
7408 return WERR_INVALID_PRINTER_NAME;
7410 if (!info2->portname || strlen(info2->portname) == 0) {
7411 return WERR_UNKNOWN_PORT;
7413 if (!info2->drivername || strlen(info2->drivername) == 0) {
7414 return WERR_UNKNOWN_PRINTER_DRIVER;
7416 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7417 return WERR_UNKNOWN_PRINTPROCESSOR;
7420 /* FIXME!!! smbd should check to see if the driver is installed before
7421 trying to add a printer like this --jerry */
7423 if (*lp_addprinter_cmd() ) {
7424 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7425 info2, p->client_id->addr,
7427 return WERR_ACCESS_DENIED;
7430 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7431 "smb.conf parameter \"addprinter command\" is defined. This"
7432 "parameter must exist for this call to succeed\n",
7433 info2->sharename ));
7436 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7437 return WERR_ACCESS_DENIED;
7440 /* you must be a printer admin to add a new printer */
7441 if (!print_access_check(p->server_info, p->msg_ctx, snum,
7442 PRINTER_ACCESS_ADMINISTER)) {
7443 return WERR_ACCESS_DENIED;
7447 * Do sanity check on the requested changes for Samba.
7450 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7451 return WERR_INVALID_PARAM;
7454 if (devmode == NULL) {
7455 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7458 update_dsspooler(p->mem_ctx,
7465 err = winreg_update_printer(p->mem_ctx,
7473 if (!W_ERROR_IS_OK(err)) {
7477 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7478 /* Handle open failed - remove addition. */
7479 ZERO_STRUCTP(handle);
7480 return WERR_ACCESS_DENIED;
7486 /****************************************************************
7487 _spoolss_AddPrinterEx
7488 ****************************************************************/
7490 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7491 struct spoolss_AddPrinterEx *r)
7493 switch (r->in.info_ctr->level) {
7495 /* we don't handle yet */
7496 /* but I know what to do ... */
7497 return WERR_UNKNOWN_LEVEL;
7499 return spoolss_addprinterex_level_2(p, r->in.server,
7501 r->in.devmode_ctr->devmode,
7502 r->in.secdesc_ctr->sd,
7503 r->in.userlevel_ctr,
7506 return WERR_UNKNOWN_LEVEL;
7510 /****************************************************************
7512 ****************************************************************/
7514 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7515 struct spoolss_AddPrinter *r)
7517 struct spoolss_AddPrinterEx a;
7518 struct spoolss_UserLevelCtr userlevel_ctr;
7520 ZERO_STRUCT(userlevel_ctr);
7522 userlevel_ctr.level = 1;
7524 a.in.server = r->in.server;
7525 a.in.info_ctr = r->in.info_ctr;
7526 a.in.devmode_ctr = r->in.devmode_ctr;
7527 a.in.secdesc_ctr = r->in.secdesc_ctr;
7528 a.in.userlevel_ctr = &userlevel_ctr;
7529 a.out.handle = r->out.handle;
7531 return _spoolss_AddPrinterEx(p, &a);
7534 /****************************************************************
7535 _spoolss_AddPrinterDriverEx
7536 ****************************************************************/
7538 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7539 struct spoolss_AddPrinterDriverEx *r)
7541 WERROR err = WERR_OK;
7542 const char *driver_name = NULL;
7547 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7548 fn = "_spoolss_AddPrinterDriver";
7550 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7551 fn = "_spoolss_AddPrinterDriverEx";
7554 return WERR_INVALID_PARAM;
7558 * we only support the semantics of AddPrinterDriver()
7559 * i.e. only copy files that are newer than existing ones
7562 if (r->in.flags == 0) {
7563 return WERR_INVALID_PARAM;
7566 if (r->in.flags != APD_COPY_NEW_FILES) {
7567 return WERR_ACCESS_DENIED;
7571 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7572 /* Clever hack from Martin Zielinski <mz@seh.de>
7573 * to allow downgrade from level 8 (Vista).
7575 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7576 r->in.info_ctr->level));
7577 return WERR_UNKNOWN_LEVEL;
7580 DEBUG(5,("Cleaning driver's information\n"));
7581 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7582 if (!W_ERROR_IS_OK(err))
7585 DEBUG(5,("Moving driver to final destination\n"));
7586 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7591 err = winreg_add_driver(p->mem_ctx, p->server_info, p->msg_ctx,
7592 r->in.info_ctr, &driver_name, &version);
7593 if (!W_ERROR_IS_OK(err)) {
7598 * I think this is where he DrvUpgradePrinter() hook would be
7599 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7600 * server. Right now, we just need to send ourselves a message
7601 * to update each printer bound to this driver. --jerry
7604 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7605 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7613 /****************************************************************
7614 _spoolss_AddPrinterDriver
7615 ****************************************************************/
7617 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7618 struct spoolss_AddPrinterDriver *r)
7620 struct spoolss_AddPrinterDriverEx a;
7622 switch (r->in.info_ctr->level) {
7629 return WERR_UNKNOWN_LEVEL;
7632 a.in.servername = r->in.servername;
7633 a.in.info_ctr = r->in.info_ctr;
7634 a.in.flags = APD_COPY_NEW_FILES;
7636 return _spoolss_AddPrinterDriverEx(p, &a);
7639 /****************************************************************************
7640 ****************************************************************************/
7642 struct _spoolss_paths {
7648 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7650 static const struct _spoolss_paths spoolss_paths[]= {
7651 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7652 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7655 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7656 const char *servername,
7657 const char *environment,
7661 const char *pservername = NULL;
7662 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7663 const char *short_archi;
7667 /* environment may be empty */
7668 if (environment && strlen(environment)) {
7669 long_archi = environment;
7672 /* servername may be empty */
7673 if (servername && strlen(servername)) {
7674 pservername = canon_servername(servername);
7676 if (!is_myname_or_ipaddr(pservername)) {
7677 return WERR_INVALID_PARAM;
7681 if (!(short_archi = get_short_archi(long_archi))) {
7682 return WERR_INVALID_ENVIRONMENT;
7685 switch (component) {
7686 case SPOOLSS_PRTPROCS_PATH:
7687 case SPOOLSS_DRIVER_PATH:
7689 *path = talloc_asprintf(mem_ctx,
7692 spoolss_paths[component].share,
7695 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7696 SPOOLSS_DEFAULT_SERVER_PATH,
7697 spoolss_paths[component].dir,
7702 return WERR_INVALID_PARAM;
7712 /****************************************************************************
7713 ****************************************************************************/
7715 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7716 const char *servername,
7717 const char *environment,
7718 struct spoolss_DriverDirectoryInfo1 *r)
7723 werr = compose_spoolss_server_path(mem_ctx,
7726 SPOOLSS_DRIVER_PATH,
7728 if (!W_ERROR_IS_OK(werr)) {
7732 DEBUG(4,("printer driver directory: [%s]\n", path));
7734 r->directory_name = path;
7739 /****************************************************************
7740 _spoolss_GetPrinterDriverDirectory
7741 ****************************************************************/
7743 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7744 struct spoolss_GetPrinterDriverDirectory *r)
7748 /* that's an [in out] buffer */
7750 if (!r->in.buffer && (r->in.offered != 0)) {
7751 return WERR_INVALID_PARAM;
7754 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7759 /* r->in.level is ignored */
7761 werror = getprinterdriverdir_level_1(p->mem_ctx,
7764 &r->out.info->info1);
7765 if (!W_ERROR_IS_OK(werror)) {
7766 TALLOC_FREE(r->out.info);
7770 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7771 r->out.info, r->in.level);
7772 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7774 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7777 /****************************************************************
7778 _spoolss_EnumPrinterData
7779 ****************************************************************/
7781 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7782 struct spoolss_EnumPrinterData *r)
7785 struct spoolss_EnumPrinterDataEx r2;
7787 struct spoolss_PrinterEnumValues *info, *val = NULL;
7790 r2.in.handle = r->in.handle;
7791 r2.in.key_name = "PrinterDriverData";
7793 r2.out.count = &count;
7794 r2.out.info = &info;
7795 r2.out.needed = &needed;
7797 result = _spoolss_EnumPrinterDataEx(p, &r2);
7798 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7799 r2.in.offered = needed;
7800 result = _spoolss_EnumPrinterDataEx(p, &r2);
7802 if (!W_ERROR_IS_OK(result)) {
7807 * The NT machine wants to know the biggest size of value and data
7809 * cf: MSDN EnumPrinterData remark section
7812 if (!r->in.value_offered && !r->in.data_offered) {
7813 uint32_t biggest_valuesize = 0;
7814 uint32_t biggest_datasize = 0;
7817 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7819 for (i=0; i<count; i++) {
7821 name_length = strlen(info[i].value_name);
7822 if (strlen(info[i].value_name) > biggest_valuesize) {
7823 biggest_valuesize = name_length;
7826 if (info[i].data_length > biggest_datasize) {
7827 biggest_datasize = info[i].data_length;
7830 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7834 /* the value is an UNICODE string but real_value_size is the length
7835 in bytes including the trailing 0 */
7837 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7838 *r->out.data_needed = biggest_datasize;
7840 DEBUG(6,("final values: [%d], [%d]\n",
7841 *r->out.value_needed, *r->out.data_needed));
7846 if (r->in.enum_index < count) {
7847 val = &info[r->in.enum_index];
7851 /* out_value should default to "" or else NT4 has
7852 problems unmarshalling the response */
7854 if (r->in.value_offered) {
7855 *r->out.value_needed = 1;
7856 r->out.value_name = talloc_strdup(r, "");
7857 if (!r->out.value_name) {
7861 r->out.value_name = NULL;
7862 *r->out.value_needed = 0;
7865 /* the data is counted in bytes */
7867 *r->out.data_needed = r->in.data_offered;
7869 result = WERR_NO_MORE_ITEMS;
7873 * - counted in bytes in the request
7874 * - counted in UNICODE chars in the max reply
7875 * - counted in bytes in the real size
7877 * take a pause *before* coding not *during* coding
7881 if (r->in.value_offered) {
7882 r->out.value_name = talloc_strdup(r, val->value_name);
7883 if (!r->out.value_name) {
7886 *r->out.value_needed = val->value_name_len;
7888 r->out.value_name = NULL;
7889 *r->out.value_needed = 0;
7894 *r->out.type = val->type;
7896 /* data - counted in bytes */
7899 * See the section "Dynamically Typed Query Parameters"
7903 if (r->out.data && val->data && val->data->data &&
7904 val->data_length && r->in.data_offered) {
7905 memcpy(r->out.data, val->data->data,
7906 MIN(val->data_length,r->in.data_offered));
7909 *r->out.data_needed = val->data_length;
7917 /****************************************************************
7918 _spoolss_SetPrinterData
7919 ****************************************************************/
7921 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7922 struct spoolss_SetPrinterData *r)
7924 struct spoolss_SetPrinterDataEx r2;
7926 r2.in.handle = r->in.handle;
7927 r2.in.key_name = "PrinterDriverData";
7928 r2.in.value_name = r->in.value_name;
7929 r2.in.type = r->in.type;
7930 r2.in.data = r->in.data;
7931 r2.in.offered = r->in.offered;
7933 return _spoolss_SetPrinterDataEx(p, &r2);
7936 /****************************************************************
7937 _spoolss_ResetPrinter
7938 ****************************************************************/
7940 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7941 struct spoolss_ResetPrinter *r)
7943 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7946 DEBUG(5,("_spoolss_ResetPrinter\n"));
7949 * All we do is to check to see if the handle and queue is valid.
7950 * This call really doesn't mean anything to us because we only
7951 * support RAW printing. --jerry
7955 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7956 OUR_HANDLE(r->in.handle)));
7960 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7964 /* blindly return success */
7968 /****************************************************************
7969 _spoolss_DeletePrinterData
7970 ****************************************************************/
7972 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7973 struct spoolss_DeletePrinterData *r)
7975 struct spoolss_DeletePrinterDataEx r2;
7977 r2.in.handle = r->in.handle;
7978 r2.in.key_name = "PrinterDriverData";
7979 r2.in.value_name = r->in.value_name;
7981 return _spoolss_DeletePrinterDataEx(p, &r2);
7984 /****************************************************************
7986 ****************************************************************/
7988 WERROR _spoolss_AddForm(struct pipes_struct *p,
7989 struct spoolss_AddForm *r)
7991 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7993 WERROR status = WERR_OK;
7994 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7996 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7998 DEBUG(5,("_spoolss_AddForm\n"));
8001 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8002 OUR_HANDLE(r->in.handle)));
8006 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8007 and not a printer admin, then fail */
8009 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8010 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8011 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8012 p->server_info->info3->base.domain.string,
8014 p->server_info->ptok,
8015 lp_printer_admin(snum))) {
8016 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
8017 return WERR_ACCESS_DENIED;
8020 switch (form->flags) {
8021 case SPOOLSS_FORM_USER:
8022 case SPOOLSS_FORM_BUILTIN:
8023 case SPOOLSS_FORM_PRINTER:
8026 return WERR_INVALID_PARAM;
8029 status = winreg_printer_addform1(p->mem_ctx, p->server_info,
8031 if (!W_ERROR_IS_OK(status)) {
8036 * ChangeID must always be set if this is a printer
8038 if (Printer->printer_type == SPLHND_PRINTER) {
8039 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8043 status = winreg_printer_update_changeid(p->mem_ctx,
8046 lp_const_servicename(snum));
8047 if (!W_ERROR_IS_OK(status)) {
8055 /****************************************************************
8057 ****************************************************************/
8059 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
8060 struct spoolss_DeleteForm *r)
8062 const char *form_name = r->in.form_name;
8063 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8065 WERROR status = WERR_OK;
8066 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8068 DEBUG(5,("_spoolss_DeleteForm\n"));
8071 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8072 OUR_HANDLE(r->in.handle)));
8076 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8077 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8078 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8079 p->server_info->info3->base.domain.string,
8081 p->server_info->ptok,
8082 lp_printer_admin(snum))) {
8083 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8084 return WERR_ACCESS_DENIED;
8087 status = winreg_printer_deleteform1(p->mem_ctx,
8091 if (!W_ERROR_IS_OK(status)) {
8096 * ChangeID must always be set if this is a printer
8098 if (Printer->printer_type == SPLHND_PRINTER) {
8099 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8103 status = winreg_printer_update_changeid(p->mem_ctx,
8106 lp_const_servicename(snum));
8107 if (!W_ERROR_IS_OK(status)) {
8115 /****************************************************************
8117 ****************************************************************/
8119 WERROR _spoolss_SetForm(struct pipes_struct *p,
8120 struct spoolss_SetForm *r)
8122 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8123 const char *form_name = r->in.form_name;
8125 WERROR status = WERR_OK;
8126 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8128 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8130 DEBUG(5,("_spoolss_SetForm\n"));
8133 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8134 OUR_HANDLE(r->in.handle)));
8138 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8139 and not a printer admin, then fail */
8141 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8142 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8143 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8144 p->server_info->info3->base.domain.string,
8146 p->server_info->ptok,
8147 lp_printer_admin(snum))) {
8148 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8149 return WERR_ACCESS_DENIED;
8152 status = winreg_printer_setform1(p->mem_ctx,
8157 if (!W_ERROR_IS_OK(status)) {
8162 * ChangeID must always be set if this is a printer
8164 if (Printer->printer_type == SPLHND_PRINTER) {
8165 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8169 status = winreg_printer_update_changeid(p->mem_ctx,
8172 lp_const_servicename(snum));
8173 if (!W_ERROR_IS_OK(status)) {
8181 /****************************************************************************
8182 fill_print_processor1
8183 ****************************************************************************/
8185 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8186 struct spoolss_PrintProcessorInfo1 *r,
8187 const char *print_processor_name)
8189 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8190 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8195 /****************************************************************************
8196 enumprintprocessors level 1.
8197 ****************************************************************************/
8199 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8200 union spoolss_PrintProcessorInfo **info_p,
8203 union spoolss_PrintProcessorInfo *info;
8206 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8207 W_ERROR_HAVE_NO_MEMORY(info);
8211 result = fill_print_processor1(info, &info[0].info1, "winprint");
8212 if (!W_ERROR_IS_OK(result)) {
8217 if (!W_ERROR_IS_OK(result)) {
8228 /****************************************************************
8229 _spoolss_EnumPrintProcessors
8230 ****************************************************************/
8232 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8233 struct spoolss_EnumPrintProcessors *r)
8237 /* that's an [in out] buffer */
8239 if (!r->in.buffer && (r->in.offered != 0)) {
8240 return WERR_INVALID_PARAM;
8243 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8246 * Enumerate the print processors ...
8248 * Just reply with "winprint", to keep NT happy
8249 * and I can use my nice printer checker.
8254 *r->out.info = NULL;
8256 switch (r->in.level) {
8258 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8262 return WERR_UNKNOWN_LEVEL;
8265 if (!W_ERROR_IS_OK(result)) {
8269 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8270 spoolss_EnumPrintProcessors,
8271 *r->out.info, r->in.level,
8273 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8274 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8276 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8279 /****************************************************************************
8280 fill_printprocdatatype1
8281 ****************************************************************************/
8283 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8284 struct spoolss_PrintProcDataTypesInfo1 *r,
8285 const char *name_array)
8287 r->name_array = talloc_strdup(mem_ctx, name_array);
8288 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8293 /****************************************************************************
8294 enumprintprocdatatypes level 1.
8295 ****************************************************************************/
8297 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8298 union spoolss_PrintProcDataTypesInfo **info_p,
8302 union spoolss_PrintProcDataTypesInfo *info;
8304 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8305 W_ERROR_HAVE_NO_MEMORY(info);
8309 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8310 if (!W_ERROR_IS_OK(result)) {
8315 if (!W_ERROR_IS_OK(result)) {
8326 /****************************************************************
8327 _spoolss_EnumPrintProcDataTypes
8328 ****************************************************************/
8330 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8331 struct spoolss_EnumPrintProcDataTypes *r)
8335 /* that's an [in out] buffer */
8337 if (!r->in.buffer && (r->in.offered != 0)) {
8338 return WERR_INVALID_PARAM;
8341 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8345 *r->out.info = NULL;
8347 switch (r->in.level) {
8349 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8353 return WERR_UNKNOWN_LEVEL;
8356 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8357 spoolss_EnumPrintProcDataTypes,
8358 *r->out.info, r->in.level,
8360 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8361 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8363 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8366 /****************************************************************************
8368 ****************************************************************************/
8370 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8371 struct spoolss_MonitorInfo1 *r,
8372 const char *monitor_name)
8374 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8375 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8380 /****************************************************************************
8382 ****************************************************************************/
8384 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8385 struct spoolss_MonitorInfo2 *r,
8386 const char *monitor_name,
8387 const char *environment,
8388 const char *dll_name)
8390 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8391 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8392 r->environment = talloc_strdup(mem_ctx, environment);
8393 W_ERROR_HAVE_NO_MEMORY(r->environment);
8394 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8395 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8400 /****************************************************************************
8401 enumprintmonitors level 1.
8402 ****************************************************************************/
8404 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8405 union spoolss_MonitorInfo **info_p,
8408 union spoolss_MonitorInfo *info;
8409 WERROR result = WERR_OK;
8411 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8412 W_ERROR_HAVE_NO_MEMORY(info);
8416 result = fill_monitor_1(info, &info[0].info1,
8418 if (!W_ERROR_IS_OK(result)) {
8422 result = fill_monitor_1(info, &info[1].info1,
8424 if (!W_ERROR_IS_OK(result)) {
8429 if (!W_ERROR_IS_OK(result)) {
8440 /****************************************************************************
8441 enumprintmonitors level 2.
8442 ****************************************************************************/
8444 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8445 union spoolss_MonitorInfo **info_p,
8448 union spoolss_MonitorInfo *info;
8449 WERROR result = WERR_OK;
8451 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8452 W_ERROR_HAVE_NO_MEMORY(info);
8456 result = fill_monitor_2(info, &info[0].info2,
8458 "Windows NT X86", /* FIXME */
8460 if (!W_ERROR_IS_OK(result)) {
8464 result = fill_monitor_2(info, &info[1].info2,
8466 "Windows NT X86", /* FIXME */
8468 if (!W_ERROR_IS_OK(result)) {
8473 if (!W_ERROR_IS_OK(result)) {
8484 /****************************************************************
8485 _spoolss_EnumMonitors
8486 ****************************************************************/
8488 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8489 struct spoolss_EnumMonitors *r)
8493 /* that's an [in out] buffer */
8495 if (!r->in.buffer && (r->in.offered != 0)) {
8496 return WERR_INVALID_PARAM;
8499 DEBUG(5,("_spoolss_EnumMonitors\n"));
8502 * Enumerate the print monitors ...
8504 * Just reply with "Local Port", to keep NT happy
8505 * and I can use my nice printer checker.
8510 *r->out.info = NULL;
8512 switch (r->in.level) {
8514 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8518 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8522 return WERR_UNKNOWN_LEVEL;
8525 if (!W_ERROR_IS_OK(result)) {
8529 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8530 spoolss_EnumMonitors,
8531 *r->out.info, r->in.level,
8533 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8534 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8536 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8539 /****************************************************************************
8540 ****************************************************************************/
8542 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8543 const print_queue_struct *queue,
8544 int count, int snum,
8545 struct spoolss_PrinterInfo2 *pinfo2,
8547 struct spoolss_JobInfo1 *r)
8552 for (i=0; i<count; i++) {
8553 if (queue[i].job == (int)jobid) {
8559 if (found == false) {
8560 /* NT treats not found as bad param... yet another bad choice */
8561 return WERR_INVALID_PARAM;
8564 return fill_job_info1(mem_ctx,
8572 /****************************************************************************
8573 ****************************************************************************/
8575 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8576 const print_queue_struct *queue,
8577 int count, int snum,
8578 struct spoolss_PrinterInfo2 *pinfo2,
8580 struct spoolss_JobInfo2 *r)
8584 struct spoolss_DeviceMode *devmode;
8587 for (i=0; i<count; i++) {
8588 if (queue[i].job == (int)jobid) {
8594 if (found == false) {
8595 /* NT treats not found as bad param... yet another bad
8597 return WERR_INVALID_PARAM;
8601 * if the print job does not have a DEVMODE associated with it,
8602 * just use the one for the printer. A NULL devicemode is not
8603 * a failure condition
8606 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8608 result = spoolss_create_default_devmode(mem_ctx,
8609 pinfo2->printername,
8611 if (!W_ERROR_IS_OK(result)) {
8612 DEBUG(3, ("Can't proceed w/o a devmode!"));
8617 return fill_job_info2(mem_ctx,
8626 /****************************************************************
8628 ****************************************************************/
8630 WERROR _spoolss_GetJob(struct pipes_struct *p,
8631 struct spoolss_GetJob *r)
8633 WERROR result = WERR_OK;
8634 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8637 print_queue_struct *queue = NULL;
8638 print_status_struct prt_status;
8640 /* that's an [in out] buffer */
8642 if (!r->in.buffer && (r->in.offered != 0)) {
8643 return WERR_INVALID_PARAM;
8646 DEBUG(5,("_spoolss_GetJob\n"));
8650 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8654 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
8655 NULL, lp_servicename(snum), &pinfo2);
8656 if (!W_ERROR_IS_OK(result)) {
8660 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
8662 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8663 count, prt_status.status, prt_status.message));
8665 switch (r->in.level) {
8667 result = getjob_level_1(p->mem_ctx,
8668 queue, count, snum, pinfo2,
8669 r->in.job_id, &r->out.info->info1);
8672 result = getjob_level_2(p->mem_ctx,
8673 queue, count, snum, pinfo2,
8674 r->in.job_id, &r->out.info->info2);
8677 result = WERR_UNKNOWN_LEVEL;
8682 TALLOC_FREE(pinfo2);
8684 if (!W_ERROR_IS_OK(result)) {
8685 TALLOC_FREE(r->out.info);
8689 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8691 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8693 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8696 /****************************************************************
8697 _spoolss_GetPrinterDataEx
8698 ****************************************************************/
8700 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8701 struct spoolss_GetPrinterDataEx *r)
8704 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8705 const char *printer;
8707 WERROR result = WERR_OK;
8709 enum winreg_Type val_type;
8714 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8716 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8717 r->in.key_name, r->in.value_name));
8719 /* in case of problem, return some default values */
8722 *r->out.type = REG_NONE;
8725 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8726 OUR_HANDLE(r->in.handle)));
8727 result = WERR_BADFID;
8731 /* Is the handle to a printer or to the server? */
8733 if (Printer->printer_type == SPLHND_SERVER) {
8735 union spoolss_PrinterData data;
8737 result = getprinterdata_printer_server(p->mem_ctx,
8741 if (!W_ERROR_IS_OK(result)) {
8745 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8746 *r->out.type, &data);
8747 if (!W_ERROR_IS_OK(result)) {
8751 *r->out.needed = blob.length;
8753 if (r->in.offered >= *r->out.needed) {
8754 memcpy(r->out.data, blob.data, blob.length);
8757 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8760 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8763 printer = lp_const_servicename(snum);
8765 /* check to see if the keyname is valid */
8766 if (!strlen(r->in.key_name)) {
8767 return WERR_INVALID_PARAM;
8770 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8771 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8772 strequal(r->in.value_name, "ChangeId")) {
8773 *r->out.type = REG_DWORD;
8775 if (r->in.offered >= *r->out.needed) {
8776 uint32_t changeid = 0;
8778 result = winreg_printer_get_changeid(p->mem_ctx,
8783 if (!W_ERROR_IS_OK(result)) {
8787 SIVAL(r->out.data, 0, changeid);
8793 result = winreg_get_printer_dataex(p->mem_ctx,
8802 if (!W_ERROR_IS_OK(result)) {
8806 *r->out.needed = val_size;
8807 *r->out.type = val_type;
8809 if (r->in.offered >= *r->out.needed) {
8810 memcpy(r->out.data, val_data, val_size);
8814 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8815 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8817 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8820 /****************************************************************
8821 _spoolss_SetPrinterDataEx
8822 ****************************************************************/
8824 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8825 struct spoolss_SetPrinterDataEx *r)
8827 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8829 WERROR result = WERR_OK;
8830 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8833 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8835 /* From MSDN documentation of SetPrinterDataEx: pass request to
8836 SetPrinterData if key is "PrinterDriverData" */
8839 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8840 OUR_HANDLE(r->in.handle)));
8844 if (Printer->printer_type == SPLHND_SERVER) {
8845 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8846 "Not implemented for server handles yet\n"));
8847 return WERR_INVALID_PARAM;
8850 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8855 * Access check : NT returns "access denied" if you make a
8856 * SetPrinterData call without the necessary privildge.
8857 * we were originally returning OK if nothing changed
8858 * which made Win2k issue **a lot** of SetPrinterData
8859 * when connecting to a printer --jerry
8862 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8863 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8864 "change denied by handle access permissions\n"));
8865 return WERR_ACCESS_DENIED;
8868 result = winreg_get_printer(Printer, p->server_info, p->msg_ctx,
8869 Printer->servername,
8870 lp_servicename(snum),
8872 if (!W_ERROR_IS_OK(result)) {
8876 /* check for OID in valuename */
8878 oid_string = strchr(r->in.value_name, ',');
8884 /* save the registry data */
8886 result = winreg_set_printer_dataex(p->mem_ctx,
8896 if (W_ERROR_IS_OK(result)) {
8897 /* save the OID if one was specified */
8899 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8900 r->in.key_name, SPOOL_OID_KEY);
8902 result = WERR_NOMEM;
8907 * I'm not checking the status here on purpose. Don't know
8908 * if this is right, but I'm returning the status from the
8909 * previous set_printer_dataex() call. I have no idea if
8910 * this is right. --jerry
8912 winreg_set_printer_dataex(p->mem_ctx,
8919 (uint8_t *) oid_string,
8920 strlen(oid_string) + 1);
8923 result = winreg_printer_update_changeid(p->mem_ctx,
8926 lp_const_servicename(snum));
8931 talloc_free(pinfo2);
8935 /****************************************************************
8936 _spoolss_DeletePrinterDataEx
8937 ****************************************************************/
8939 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8940 struct spoolss_DeletePrinterDataEx *r)
8942 const char *printer;
8944 WERROR status = WERR_OK;
8945 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8947 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8950 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8951 "Invalid handle (%s:%u:%u).\n",
8952 OUR_HANDLE(r->in.handle)));
8956 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8957 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8958 "printer properties change denied by handle\n"));
8959 return WERR_ACCESS_DENIED;
8962 if (!r->in.value_name || !r->in.key_name) {
8966 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8969 printer = lp_const_servicename(snum);
8971 status = winreg_delete_printer_dataex(p->mem_ctx,
8977 if (W_ERROR_IS_OK(status)) {
8978 status = winreg_printer_update_changeid(p->mem_ctx,
8987 /****************************************************************
8988 _spoolss_EnumPrinterKey
8989 ****************************************************************/
8991 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8992 struct spoolss_EnumPrinterKey *r)
8995 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8997 WERROR result = WERR_BADFILE;
8998 const char **array = NULL;
9001 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9004 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9005 OUR_HANDLE(r->in.handle)));
9009 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9013 result = winreg_enum_printer_key(p->mem_ctx,
9016 lp_const_servicename(snum),
9020 if (!W_ERROR_IS_OK(result)) {
9024 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
9025 result = WERR_NOMEM;
9029 *r->out._ndr_size = r->in.offered / 2;
9030 *r->out.needed = blob.length;
9032 if (r->in.offered < *r->out.needed) {
9033 result = WERR_MORE_DATA;
9036 r->out.key_buffer->string_array = array;
9040 if (!W_ERROR_IS_OK(result)) {
9042 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9050 /****************************************************************
9051 _spoolss_DeletePrinterKey
9052 ****************************************************************/
9054 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
9055 struct spoolss_DeletePrinterKey *r)
9057 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9060 const char *printer;
9062 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9065 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9066 OUR_HANDLE(r->in.handle)));
9070 /* if keyname == NULL, return error */
9071 if ( !r->in.key_name )
9072 return WERR_INVALID_PARAM;
9074 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9078 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9079 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9080 "printer properties change denied by handle\n"));
9081 return WERR_ACCESS_DENIED;
9084 printer = lp_const_servicename(snum);
9086 /* delete the key and all subkeys */
9087 status = winreg_delete_printer_key(p->mem_ctx,
9092 if (W_ERROR_IS_OK(status)) {
9093 status = winreg_printer_update_changeid(p->mem_ctx,
9102 /****************************************************************
9103 _spoolss_EnumPrinterDataEx
9104 ****************************************************************/
9106 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
9107 struct spoolss_EnumPrinterDataEx *r)
9110 struct spoolss_PrinterEnumValues *info = NULL;
9111 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9115 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9119 *r->out.info = NULL;
9122 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9123 OUR_HANDLE(r->in.handle)));
9128 * first check for a keyname of NULL or "". Win2k seems to send
9129 * this a lot and we should send back WERR_INVALID_PARAM
9130 * no need to spend time looking up the printer in this case.
9134 if (!strlen(r->in.key_name)) {
9135 result = WERR_INVALID_PARAM;
9139 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9143 /* now look for a match on the key name */
9144 result = winreg_enum_printer_dataex(p->mem_ctx,
9147 lp_const_servicename(snum),
9151 if (!W_ERROR_IS_OK(result)) {
9155 #if 0 /* FIXME - gd */
9156 /* housekeeping information in the reply */
9158 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9159 * the hand marshalled container size is a multiple
9160 * of 4 bytes for RPC alignment.
9164 needed += 4-(needed % 4);
9167 *r->out.count = count;
9168 *r->out.info = info;
9171 if (!W_ERROR_IS_OK(result)) {
9175 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9176 spoolss_EnumPrinterDataEx,
9179 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9180 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9182 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9185 /****************************************************************************
9186 ****************************************************************************/
9188 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9189 const char *servername,
9190 const char *environment,
9191 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9196 werr = compose_spoolss_server_path(mem_ctx,
9199 SPOOLSS_PRTPROCS_PATH,
9201 if (!W_ERROR_IS_OK(werr)) {
9205 DEBUG(4,("print processor directory: [%s]\n", path));
9207 r->directory_name = path;
9212 /****************************************************************
9213 _spoolss_GetPrintProcessorDirectory
9214 ****************************************************************/
9216 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9217 struct spoolss_GetPrintProcessorDirectory *r)
9221 /* that's an [in out] buffer */
9223 if (!r->in.buffer && (r->in.offered != 0)) {
9224 return WERR_INVALID_PARAM;
9227 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9232 /* r->in.level is ignored */
9234 /* We always should reply with a local print processor directory so that
9235 * users are not forced to have a [prnproc$] share on the Samba spoolss
9236 * server - Guenther */
9238 result = getprintprocessordirectory_level_1(p->mem_ctx,
9239 NULL, /* r->in.server */
9241 &r->out.info->info1);
9242 if (!W_ERROR_IS_OK(result)) {
9243 TALLOC_FREE(r->out.info);
9247 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9248 r->out.info, r->in.level);
9249 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9251 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9254 /*******************************************************************
9255 ********************************************************************/
9257 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9258 const char *dllname)
9260 enum ndr_err_code ndr_err;
9261 struct spoolss_MonitorUi ui;
9263 ui.dll_name = dllname;
9265 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9266 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9267 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9268 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9270 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9273 /*******************************************************************
9274 Streams the monitor UI DLL name in UNICODE
9275 *******************************************************************/
9277 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9278 NT_USER_TOKEN *token, DATA_BLOB *in,
9279 DATA_BLOB *out, uint32_t *needed)
9281 const char *dllname = "tcpmonui.dll";
9283 *needed = (strlen(dllname)+1) * 2;
9285 if (out->length < *needed) {
9286 return WERR_INSUFFICIENT_BUFFER;
9289 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9296 /*******************************************************************
9297 ********************************************************************/
9299 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9300 struct spoolss_PortData1 *port1,
9301 const DATA_BLOB *buf)
9303 enum ndr_err_code ndr_err;
9304 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9305 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9306 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9307 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9309 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9312 /*******************************************************************
9313 ********************************************************************/
9315 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9316 struct spoolss_PortData2 *port2,
9317 const DATA_BLOB *buf)
9319 enum ndr_err_code ndr_err;
9320 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9321 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9322 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9323 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9325 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9328 /*******************************************************************
9329 Create a new TCP/IP port
9330 *******************************************************************/
9332 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9333 NT_USER_TOKEN *token, DATA_BLOB *in,
9334 DATA_BLOB *out, uint32_t *needed)
9336 struct spoolss_PortData1 port1;
9337 struct spoolss_PortData2 port2;
9338 char *device_uri = NULL;
9341 const char *portname;
9342 const char *hostaddress;
9344 uint32_t port_number;
9347 /* peek for spoolss_PortData version */
9349 if (!in || (in->length < (128 + 4))) {
9350 return WERR_GENERAL_FAILURE;
9353 version = IVAL(in->data, 128);
9359 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9363 portname = port1.portname;
9364 hostaddress = port1.hostaddress;
9365 queue = port1.queue;
9366 protocol = port1.protocol;
9367 port_number = port1.port_number;
9373 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9377 portname = port2.portname;
9378 hostaddress = port2.hostaddress;
9379 queue = port2.queue;
9380 protocol = port2.protocol;
9381 port_number = port2.port_number;
9385 DEBUG(1,("xcvtcp_addport: "
9386 "unknown version of port_data: %d\n", version));
9387 return WERR_UNKNOWN_PORT;
9390 /* create the device URI and call the add_port_hook() */
9393 case PROTOCOL_RAWTCP_TYPE:
9394 device_uri = talloc_asprintf(mem_ctx,
9395 "socket://%s:%d/", hostaddress,
9399 case PROTOCOL_LPR_TYPE:
9400 device_uri = talloc_asprintf(mem_ctx,
9401 "lpr://%s/%s", hostaddress, queue );
9405 return WERR_UNKNOWN_PORT;
9412 return add_port_hook(mem_ctx, token, portname, device_uri);
9415 /*******************************************************************
9416 *******************************************************************/
9418 struct xcv_api_table xcvtcp_cmds[] = {
9419 { "MonitorUI", xcvtcp_monitorui },
9420 { "AddPort", xcvtcp_addport},
9424 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9425 NT_USER_TOKEN *token, const char *command,
9432 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9434 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9435 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9436 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9439 return WERR_BADFUNC;
9442 /*******************************************************************
9443 *******************************************************************/
9444 #if 0 /* don't support management using the "Local Port" monitor */
9446 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9447 NT_USER_TOKEN *token, DATA_BLOB *in,
9448 DATA_BLOB *out, uint32_t *needed)
9450 const char *dllname = "localui.dll";
9452 *needed = (strlen(dllname)+1) * 2;
9454 if (out->length < *needed) {
9455 return WERR_INSUFFICIENT_BUFFER;
9458 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9465 /*******************************************************************
9466 *******************************************************************/
9468 struct xcv_api_table xcvlocal_cmds[] = {
9469 { "MonitorUI", xcvlocal_monitorui },
9473 struct xcv_api_table xcvlocal_cmds[] = {
9480 /*******************************************************************
9481 *******************************************************************/
9483 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9484 NT_USER_TOKEN *token, const char *command,
9485 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9490 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9492 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9493 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9494 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9496 return WERR_BADFUNC;
9499 /****************************************************************
9501 ****************************************************************/
9503 WERROR _spoolss_XcvData(struct pipes_struct *p,
9504 struct spoolss_XcvData *r)
9506 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9507 DATA_BLOB out_data = data_blob_null;
9511 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9512 OUR_HANDLE(r->in.handle)));
9516 /* Has to be a handle to the TCP/IP port monitor */
9518 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9519 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9523 /* requires administrative access to the server */
9525 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9526 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9527 return WERR_ACCESS_DENIED;
9530 /* Allocate the outgoing buffer */
9532 if (r->in.out_data_size) {
9533 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9534 if (out_data.data == NULL) {
9539 switch ( Printer->printer_type ) {
9540 case SPLHND_PORTMON_TCP:
9541 werror = process_xcvtcp_command(p->mem_ctx,
9542 p->server_info->ptok,
9543 r->in.function_name,
9544 &r->in.in_data, &out_data,
9547 case SPLHND_PORTMON_LOCAL:
9548 werror = process_xcvlocal_command(p->mem_ctx,
9549 p->server_info->ptok,
9550 r->in.function_name,
9551 &r->in.in_data, &out_data,
9555 werror = WERR_INVALID_PRINT_MONITOR;
9558 if (!W_ERROR_IS_OK(werror)) {
9562 *r->out.status_code = 0;
9564 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9565 memcpy(r->out.out_data, out_data.data,
9566 MIN(r->in.out_data_size, out_data.length));
9572 /****************************************************************
9573 _spoolss_AddPrintProcessor
9574 ****************************************************************/
9576 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9577 struct spoolss_AddPrintProcessor *r)
9579 /* for now, just indicate success and ignore the add. We'll
9580 automatically set the winprint processor for printer
9581 entries later. Used to debug the LexMark Optra S 1855 PCL
9587 /****************************************************************
9589 ****************************************************************/
9591 WERROR _spoolss_AddPort(struct pipes_struct *p,
9592 struct spoolss_AddPort *r)
9594 /* do what w2k3 does */
9596 return WERR_NOT_SUPPORTED;
9599 /****************************************************************
9600 _spoolss_GetPrinterDriver
9601 ****************************************************************/
9603 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9604 struct spoolss_GetPrinterDriver *r)
9606 p->rng_fault_state = true;
9607 return WERR_NOT_SUPPORTED;
9610 /****************************************************************
9611 _spoolss_ReadPrinter
9612 ****************************************************************/
9614 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9615 struct spoolss_ReadPrinter *r)
9617 p->rng_fault_state = true;
9618 return WERR_NOT_SUPPORTED;
9621 /****************************************************************
9622 _spoolss_WaitForPrinterChange
9623 ****************************************************************/
9625 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9626 struct spoolss_WaitForPrinterChange *r)
9628 p->rng_fault_state = true;
9629 return WERR_NOT_SUPPORTED;
9632 /****************************************************************
9633 _spoolss_ConfigurePort
9634 ****************************************************************/
9636 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9637 struct spoolss_ConfigurePort *r)
9639 p->rng_fault_state = true;
9640 return WERR_NOT_SUPPORTED;
9643 /****************************************************************
9645 ****************************************************************/
9647 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9648 struct spoolss_DeletePort *r)
9650 p->rng_fault_state = true;
9651 return WERR_NOT_SUPPORTED;
9654 /****************************************************************
9655 _spoolss_CreatePrinterIC
9656 ****************************************************************/
9658 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9659 struct spoolss_CreatePrinterIC *r)
9661 p->rng_fault_state = true;
9662 return WERR_NOT_SUPPORTED;
9665 /****************************************************************
9666 _spoolss_PlayGDIScriptOnPrinterIC
9667 ****************************************************************/
9669 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9670 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9672 p->rng_fault_state = true;
9673 return WERR_NOT_SUPPORTED;
9676 /****************************************************************
9677 _spoolss_DeletePrinterIC
9678 ****************************************************************/
9680 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9681 struct spoolss_DeletePrinterIC *r)
9683 p->rng_fault_state = true;
9684 return WERR_NOT_SUPPORTED;
9687 /****************************************************************
9688 _spoolss_AddPrinterConnection
9689 ****************************************************************/
9691 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9692 struct spoolss_AddPrinterConnection *r)
9694 p->rng_fault_state = true;
9695 return WERR_NOT_SUPPORTED;
9698 /****************************************************************
9699 _spoolss_DeletePrinterConnection
9700 ****************************************************************/
9702 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9703 struct spoolss_DeletePrinterConnection *r)
9705 p->rng_fault_state = true;
9706 return WERR_NOT_SUPPORTED;
9709 /****************************************************************
9710 _spoolss_PrinterMessageBox
9711 ****************************************************************/
9713 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9714 struct spoolss_PrinterMessageBox *r)
9716 p->rng_fault_state = true;
9717 return WERR_NOT_SUPPORTED;
9720 /****************************************************************
9722 ****************************************************************/
9724 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9725 struct spoolss_AddMonitor *r)
9727 p->rng_fault_state = true;
9728 return WERR_NOT_SUPPORTED;
9731 /****************************************************************
9732 _spoolss_DeleteMonitor
9733 ****************************************************************/
9735 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9736 struct spoolss_DeleteMonitor *r)
9738 p->rng_fault_state = true;
9739 return WERR_NOT_SUPPORTED;
9742 /****************************************************************
9743 _spoolss_DeletePrintProcessor
9744 ****************************************************************/
9746 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9747 struct spoolss_DeletePrintProcessor *r)
9749 p->rng_fault_state = true;
9750 return WERR_NOT_SUPPORTED;
9753 /****************************************************************
9754 _spoolss_AddPrintProvidor
9755 ****************************************************************/
9757 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9758 struct spoolss_AddPrintProvidor *r)
9760 p->rng_fault_state = true;
9761 return WERR_NOT_SUPPORTED;
9764 /****************************************************************
9765 _spoolss_DeletePrintProvidor
9766 ****************************************************************/
9768 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9769 struct spoolss_DeletePrintProvidor *r)
9771 p->rng_fault_state = true;
9772 return WERR_NOT_SUPPORTED;
9775 /****************************************************************
9776 _spoolss_FindFirstPrinterChangeNotification
9777 ****************************************************************/
9779 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9780 struct spoolss_FindFirstPrinterChangeNotification *r)
9782 p->rng_fault_state = true;
9783 return WERR_NOT_SUPPORTED;
9786 /****************************************************************
9787 _spoolss_FindNextPrinterChangeNotification
9788 ****************************************************************/
9790 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9791 struct spoolss_FindNextPrinterChangeNotification *r)
9793 p->rng_fault_state = true;
9794 return WERR_NOT_SUPPORTED;
9797 /****************************************************************
9798 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9799 ****************************************************************/
9801 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9802 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9804 p->rng_fault_state = true;
9805 return WERR_NOT_SUPPORTED;
9808 /****************************************************************
9809 _spoolss_ReplyOpenPrinter
9810 ****************************************************************/
9812 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9813 struct spoolss_ReplyOpenPrinter *r)
9815 p->rng_fault_state = true;
9816 return WERR_NOT_SUPPORTED;
9819 /****************************************************************
9820 _spoolss_RouterReplyPrinter
9821 ****************************************************************/
9823 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9824 struct spoolss_RouterReplyPrinter *r)
9826 p->rng_fault_state = true;
9827 return WERR_NOT_SUPPORTED;
9830 /****************************************************************
9831 _spoolss_ReplyClosePrinter
9832 ****************************************************************/
9834 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9835 struct spoolss_ReplyClosePrinter *r)
9837 p->rng_fault_state = true;
9838 return WERR_NOT_SUPPORTED;
9841 /****************************************************************
9843 ****************************************************************/
9845 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9846 struct spoolss_AddPortEx *r)
9848 p->rng_fault_state = true;
9849 return WERR_NOT_SUPPORTED;
9852 /****************************************************************
9853 _spoolss_RouterFindFirstPrinterChangeNotification
9854 ****************************************************************/
9856 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9857 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9859 p->rng_fault_state = true;
9860 return WERR_NOT_SUPPORTED;
9863 /****************************************************************
9864 _spoolss_SpoolerInit
9865 ****************************************************************/
9867 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9868 struct spoolss_SpoolerInit *r)
9870 p->rng_fault_state = true;
9871 return WERR_NOT_SUPPORTED;
9874 /****************************************************************
9875 _spoolss_ResetPrinterEx
9876 ****************************************************************/
9878 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9879 struct spoolss_ResetPrinterEx *r)
9881 p->rng_fault_state = true;
9882 return WERR_NOT_SUPPORTED;
9885 /****************************************************************
9886 _spoolss_RouterReplyPrinterEx
9887 ****************************************************************/
9889 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9890 struct spoolss_RouterReplyPrinterEx *r)
9892 p->rng_fault_state = true;
9893 return WERR_NOT_SUPPORTED;
9896 /****************************************************************
9898 ****************************************************************/
9900 WERROR _spoolss_44(struct pipes_struct *p,
9901 struct spoolss_44 *r)
9903 p->rng_fault_state = true;
9904 return WERR_NOT_SUPPORTED;
9907 /****************************************************************
9909 ****************************************************************/
9911 WERROR _spoolss_47(struct pipes_struct *p,
9912 struct spoolss_47 *r)
9914 p->rng_fault_state = true;
9915 return WERR_NOT_SUPPORTED;
9918 /****************************************************************
9920 ****************************************************************/
9922 WERROR _spoolss_4a(struct pipes_struct *p,
9923 struct spoolss_4a *r)
9925 p->rng_fault_state = true;
9926 return WERR_NOT_SUPPORTED;
9929 /****************************************************************
9931 ****************************************************************/
9933 WERROR _spoolss_4b(struct pipes_struct *p,
9934 struct spoolss_4b *r)
9936 p->rng_fault_state = true;
9937 return WERR_NOT_SUPPORTED;
9940 /****************************************************************
9942 ****************************************************************/
9944 WERROR _spoolss_4c(struct pipes_struct *p,
9945 struct spoolss_4c *r)
9947 p->rng_fault_state = true;
9948 return WERR_NOT_SUPPORTED;
9951 /****************************************************************
9953 ****************************************************************/
9955 WERROR _spoolss_53(struct pipes_struct *p,
9956 struct spoolss_53 *r)
9958 p->rng_fault_state = true;
9959 return WERR_NOT_SUPPORTED;
9962 /****************************************************************
9964 ****************************************************************/
9966 WERROR _spoolss_55(struct pipes_struct *p,
9967 struct spoolss_55 *r)
9969 p->rng_fault_state = true;
9970 return WERR_NOT_SUPPORTED;
9973 /****************************************************************
9975 ****************************************************************/
9977 WERROR _spoolss_56(struct pipes_struct *p,
9978 struct spoolss_56 *r)
9980 p->rng_fault_state = true;
9981 return WERR_NOT_SUPPORTED;
9984 /****************************************************************
9986 ****************************************************************/
9988 WERROR _spoolss_57(struct pipes_struct *p,
9989 struct spoolss_57 *r)
9991 p->rng_fault_state = true;
9992 return WERR_NOT_SUPPORTED;
9995 /****************************************************************
9997 ****************************************************************/
9999 WERROR _spoolss_5a(struct pipes_struct *p,
10000 struct spoolss_5a *r)
10002 p->rng_fault_state = true;
10003 return WERR_NOT_SUPPORTED;
10006 /****************************************************************
10008 ****************************************************************/
10010 WERROR _spoolss_5b(struct pipes_struct *p,
10011 struct spoolss_5b *r)
10013 p->rng_fault_state = true;
10014 return WERR_NOT_SUPPORTED;
10017 /****************************************************************
10019 ****************************************************************/
10021 WERROR _spoolss_5c(struct pipes_struct *p,
10022 struct spoolss_5c *r)
10024 p->rng_fault_state = true;
10025 return WERR_NOT_SUPPORTED;
10028 /****************************************************************
10030 ****************************************************************/
10032 WERROR _spoolss_5d(struct pipes_struct *p,
10033 struct spoolss_5d *r)
10035 p->rng_fault_state = true;
10036 return WERR_NOT_SUPPORTED;
10039 /****************************************************************
10041 ****************************************************************/
10043 WERROR _spoolss_5e(struct pipes_struct *p,
10044 struct spoolss_5e *r)
10046 p->rng_fault_state = true;
10047 return WERR_NOT_SUPPORTED;
10050 /****************************************************************
10052 ****************************************************************/
10054 WERROR _spoolss_5f(struct pipes_struct *p,
10055 struct spoolss_5f *r)
10057 p->rng_fault_state = true;
10058 return WERR_NOT_SUPPORTED;
10061 /****************************************************************
10063 ****************************************************************/
10065 WERROR _spoolss_60(struct pipes_struct *p,
10066 struct spoolss_60 *r)
10068 p->rng_fault_state = true;
10069 return WERR_NOT_SUPPORTED;
10072 /****************************************************************
10074 ****************************************************************/
10076 WERROR _spoolss_61(struct pipes_struct *p,
10077 struct spoolss_61 *r)
10079 p->rng_fault_state = true;
10080 return WERR_NOT_SUPPORTED;
10083 /****************************************************************
10085 ****************************************************************/
10087 WERROR _spoolss_62(struct pipes_struct *p,
10088 struct spoolss_62 *r)
10090 p->rng_fault_state = true;
10091 return WERR_NOT_SUPPORTED;
10094 /****************************************************************
10096 ****************************************************************/
10098 WERROR _spoolss_63(struct pipes_struct *p,
10099 struct spoolss_63 *r)
10101 p->rng_fault_state = true;
10102 return WERR_NOT_SUPPORTED;
10105 /****************************************************************
10107 ****************************************************************/
10109 WERROR _spoolss_64(struct pipes_struct *p,
10110 struct spoolss_64 *r)
10112 p->rng_fault_state = true;
10113 return WERR_NOT_SUPPORTED;
10116 /****************************************************************
10118 ****************************************************************/
10120 WERROR _spoolss_65(struct pipes_struct *p,
10121 struct spoolss_65 *r)
10123 p->rng_fault_state = true;
10124 return WERR_NOT_SUPPORTED;
10127 /****************************************************************
10128 _spoolss_GetCorePrinterDrivers
10129 ****************************************************************/
10131 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
10132 struct spoolss_GetCorePrinterDrivers *r)
10134 p->rng_fault_state = true;
10135 return WERR_NOT_SUPPORTED;
10138 /****************************************************************
10140 ****************************************************************/
10142 WERROR _spoolss_67(struct pipes_struct *p,
10143 struct spoolss_67 *r)
10145 p->rng_fault_state = true;
10146 return WERR_NOT_SUPPORTED;
10149 /****************************************************************
10150 _spoolss_GetPrinterDriverPackagePath
10151 ****************************************************************/
10153 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10154 struct spoolss_GetPrinterDriverPackagePath *r)
10156 p->rng_fault_state = true;
10157 return WERR_NOT_SUPPORTED;
10160 /****************************************************************
10162 ****************************************************************/
10164 WERROR _spoolss_69(struct pipes_struct *p,
10165 struct spoolss_69 *r)
10167 p->rng_fault_state = true;
10168 return WERR_NOT_SUPPORTED;
10171 /****************************************************************
10173 ****************************************************************/
10175 WERROR _spoolss_6a(struct pipes_struct *p,
10176 struct spoolss_6a *r)
10178 p->rng_fault_state = true;
10179 return WERR_NOT_SUPPORTED;
10182 /****************************************************************
10184 ****************************************************************/
10186 WERROR _spoolss_6b(struct pipes_struct *p,
10187 struct spoolss_6b *r)
10189 p->rng_fault_state = true;
10190 return WERR_NOT_SUPPORTED;
10193 /****************************************************************
10195 ****************************************************************/
10197 WERROR _spoolss_6c(struct pipes_struct *p,
10198 struct spoolss_6c *r)
10200 p->rng_fault_state = true;
10201 return WERR_NOT_SUPPORTED;
10204 /****************************************************************
10206 ****************************************************************/
10208 WERROR _spoolss_6d(struct pipes_struct *p,
10209 struct spoolss_6d *r)
10211 p->rng_fault_state = true;
10212 return WERR_NOT_SUPPORTED;