2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009-2010.
11 * Copyright (C) Andreas Schneider 2010.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
39 #include "registry/reg_objects.h"
40 #include "include/printing.h"
42 #include "../librpc/gen_ndr/netlogon.h"
44 /* macros stolen from s4 spoolss server */
45 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
46 ((info)?ndr_size_##fn(info, level, 0):0)
48 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
49 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
51 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
52 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
54 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
57 #define DBGC_CLASS DBGC_RPC_SRV
59 static Printer_entry *printers_list;
61 typedef struct _counter_printer_0 {
62 struct _counter_printer_0 *next;
63 struct _counter_printer_0 *prev;
69 static counter_printer_0 *counter_list;
71 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
72 static uint32_t smb_connections = 0;
75 /* Map generic permissions to printer object specific permissions */
77 const struct standard_mapping printer_std_mapping = {
84 /* Map generic permissions to print server object specific permissions */
86 const struct standard_mapping printserver_std_mapping = {
93 /* API table for Xcv Monitor functions */
95 struct xcv_api_table {
97 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
100 /********************************************************************
101 * Canonicalize servername.
102 ********************************************************************/
104 static const char *canon_servername(const char *servername)
106 const char *pservername = servername;
107 while (*pservername == '\\') {
113 /* translate between internal status numbers and NT status numbers */
114 static int nt_printj_status(int v)
120 return JOB_STATUS_PAUSED;
122 return JOB_STATUS_SPOOLING;
124 return JOB_STATUS_PRINTING;
126 return JOB_STATUS_ERROR;
128 return JOB_STATUS_DELETING;
130 return JOB_STATUS_OFFLINE;
132 return JOB_STATUS_PAPEROUT;
134 return JOB_STATUS_PRINTED;
136 return JOB_STATUS_DELETED;
138 return JOB_STATUS_BLOCKED_DEVQ;
139 case LPQ_USER_INTERVENTION:
140 return JOB_STATUS_USER_INTERVENTION;
145 static int nt_printq_status(int v)
149 return PRINTER_STATUS_PAUSED;
158 /***************************************************************************
159 Disconnect from the client
160 ****************************************************************************/
162 static void srv_spoolss_replycloseprinter(
163 int snum, struct policy_handle *handle,
164 struct messaging_context *msg_ctx)
170 * Tell the specific printing tdb we no longer want messages for this printer
171 * by deregistering our PID.
174 if (!print_notify_deregister_pid(snum))
175 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
177 /* weird if the test succeeds !!! */
178 if (smb_connections==0) {
179 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
183 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
186 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
187 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
188 win_errstr(result)));
190 /* if it's the last connection, deconnect the IPC$ share */
191 if (smb_connections==1) {
193 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
195 * The above call shuts down the pipe also.
197 notify_cli_pipe = NULL;
199 if (msg_ctx != NULL) {
200 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
204 * Tell the serverid.tdb we're no longer
205 * interested in printer notify messages.
208 serverid_register_msg_flags(
209 messaging_server_id(msg_ctx),
210 false, FLAG_MSG_PRINT_NOTIFY);
217 /****************************************************************************
218 Functions to free a printer entry datastruct.
219 ****************************************************************************/
221 static int printer_entry_destructor(Printer_entry *Printer)
223 if (Printer->notify.client_connected == true) {
226 if ( Printer->printer_type == SPLHND_SERVER) {
228 srv_spoolss_replycloseprinter(
229 snum, &Printer->notify.client_hnd,
230 Printer->notify.msg_ctx);
231 } else if (Printer->printer_type == SPLHND_PRINTER) {
232 snum = print_queue_snum(Printer->sharename);
234 srv_spoolss_replycloseprinter(
235 snum, &Printer->notify.client_hnd,
236 Printer->notify.msg_ctx);
240 Printer->notify.flags=0;
241 Printer->notify.options=0;
242 Printer->notify.localmachine[0]='\0';
243 Printer->notify.printerlocal=0;
244 TALLOC_FREE(Printer->notify.option);
245 Printer->notify.client_connected = false;
247 TALLOC_FREE(Printer->devmode);
249 /* Remove from the internal list. */
250 DLIST_REMOVE(printers_list, Printer);
254 /****************************************************************************
255 find printer index by handle
256 ****************************************************************************/
258 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
259 struct policy_handle *hnd)
261 Printer_entry *find_printer = NULL;
263 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
264 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
271 /****************************************************************************
272 Close printer index by handle.
273 ****************************************************************************/
275 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
277 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
280 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
285 close_policy_hnd(p, hnd);
290 /****************************************************************************
291 Delete a printer given a handle.
292 ****************************************************************************/
294 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
295 const char *sharename,
296 struct messaging_context *msg_ctx)
298 char *cmd = lp_deleteprinter_cmd();
299 char *command = NULL;
301 SE_PRIV se_printop = SE_PRINT_OPERATOR;
302 bool is_print_op = false;
304 /* can't fail if we don't try */
309 command = talloc_asprintf(ctx,
316 is_print_op = user_has_privileges( token, &se_printop );
318 DEBUG(10,("Running [%s]\n", command));
320 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
325 if ( (ret = smbrun(command, NULL)) == 0 ) {
326 /* Tell everyone we updated smb.conf. */
327 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
333 /********** END SePrintOperatorPrivlege BLOCK **********/
335 DEBUGADD(10,("returned [%d]\n", ret));
337 TALLOC_FREE(command);
340 return WERR_BADFID; /* What to return here? */
342 /* go ahead and re-read the services immediately */
344 reload_services(false);
347 if ( lp_servicenumber( sharename ) > 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
363 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
369 * It turns out that Windows allows delete printer on a handle
370 * opened by an admin user, then used on a pipe handle created
371 * by an anonymous user..... but they're working on security.... riiight !
375 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
376 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
377 return WERR_ACCESS_DENIED;
380 /* this does not need a become root since the access check has been
381 done on the handle already */
383 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
384 p->msg_ctx, Printer->sharename, "");
385 if (!W_ERROR_IS_OK(result)) {
386 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
390 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
391 Printer->sharename, p->msg_ctx);
394 /****************************************************************************
395 Return the snum of a printer corresponding to an handle.
396 ****************************************************************************/
398 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
399 int *number, struct share_params **params)
401 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
404 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
409 switch (Printer->printer_type) {
411 DEBUG(4,("short name:%s\n", Printer->sharename));
412 *number = print_queue_snum(Printer->sharename);
413 return (*number != -1);
421 /****************************************************************************
422 Set printer handle type.
423 Check if it's \\server or \\server\printer
424 ****************************************************************************/
426 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
428 DEBUG(3,("Setting printer type=%s\n", handlename));
430 if ( strlen(handlename) < 3 ) {
431 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
435 /* it's a print server */
436 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
437 DEBUGADD(4,("Printer is a print server\n"));
438 Printer->printer_type = SPLHND_SERVER;
440 /* it's a printer (set_printer_hnd_name() will handle port monitors */
442 DEBUGADD(4,("Printer is a printer\n"));
443 Printer->printer_type = SPLHND_PRINTER;
449 /****************************************************************************
450 Set printer handle name.. Accept names like \\server, \\server\printer,
451 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
452 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
453 XcvDataPort() interface.
454 ****************************************************************************/
456 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
457 struct auth_serversupplied_info *server_info,
458 Printer_entry *Printer,
459 const char *handlename)
462 int n_services=lp_numservices();
464 const char *printername;
465 const char *servername = NULL;
468 struct spoolss_PrinterInfo2 *info2 = NULL;
471 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
472 (unsigned long)strlen(handlename)));
474 aprinter = CONST_DISCARD(char *, handlename);
475 if ( *handlename == '\\' ) {
476 servername = canon_servername(handlename);
477 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
481 if (!is_myname_or_ipaddr(servername)) {
485 fstrcpy(Printer->servername, servername);
488 if (Printer->printer_type == SPLHND_SERVER) {
492 if (Printer->printer_type != SPLHND_PRINTER) {
496 DEBUGADD(5, ("searching for [%s]\n", aprinter));
498 /* check for the Port Monitor Interface */
499 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
500 Printer->printer_type = SPLHND_PORTMON_TCP;
501 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
504 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
505 Printer->printer_type = SPLHND_PORTMON_LOCAL;
506 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
510 /* Search all sharenames first as this is easier than pulling
511 the printer_info_2 off of disk. Don't use find_service() since
512 that calls out to map_username() */
514 /* do another loop to look for printernames */
515 for (snum = 0; !found && snum < n_services; snum++) {
516 const char *printer = lp_const_servicename(snum);
518 /* no point going on if this is not a printer */
519 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
523 /* ignore [printers] share */
524 if (strequal(printer, "printers")) {
528 fstrcpy(sname, printer);
529 if (strequal(aprinter, printer)) {
534 /* no point looking up the printer object if
535 we aren't allowing printername != sharename */
536 if (lp_force_printername(snum)) {
540 result = winreg_get_printer(mem_ctx,
542 smbd_messaging_context(),
546 if ( !W_ERROR_IS_OK(result) ) {
547 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
548 sname, win_errstr(result)));
552 printername = strrchr(info2->printername, '\\');
553 if (printername == NULL) {
554 printername = info2->printername;
559 if (strequal(printername, aprinter)) {
564 DEBUGADD(10, ("printername: %s\n", printername));
570 DEBUGADD(4,("Printer not found\n"));
574 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
576 fstrcpy(Printer->sharename, sname);
581 /****************************************************************************
582 Find first available printer slot. creates a printer handle for you.
583 ****************************************************************************/
585 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
586 const char *name, uint32_t access_granted)
588 Printer_entry *new_printer;
590 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
592 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
593 if (new_printer == NULL) {
596 talloc_set_destructor(new_printer, printer_entry_destructor);
598 if (!create_policy_hnd(p, hnd, new_printer)) {
599 TALLOC_FREE(new_printer);
603 /* Add to the internal list. */
604 DLIST_ADD(printers_list, new_printer);
606 new_printer->notify.option=NULL;
608 if (!set_printer_hnd_printertype(new_printer, name)) {
609 close_printer_handle(p, hnd);
613 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
614 close_printer_handle(p, hnd);
618 new_printer->access_granted = access_granted;
620 DEBUG(5, ("%d printer handles active\n",
621 (int)num_pipe_handles(p)));
626 /***************************************************************************
627 check to see if the client motify handle is monitoring the notification
628 given by (notify_type, notify_field).
629 **************************************************************************/
631 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
632 uint16_t notify_field)
637 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
638 uint16_t notify_field)
640 struct spoolss_NotifyOption *option = p->notify.option;
644 * Flags should always be zero when the change notify
645 * is registered by the client's spooler. A user Win32 app
646 * might use the flags though instead of the NOTIFY_OPTION_INFO
655 return is_monitoring_event_flags(
656 p->notify.flags, notify_type, notify_field);
658 for (i = 0; i < option->count; i++) {
660 /* Check match for notify_type */
662 if (option->types[i].type != notify_type)
665 /* Check match for field */
667 for (j = 0; j < option->types[i].count; j++) {
668 if (option->types[i].fields[j].field == notify_field) {
674 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
675 p->servername, p->sharename, notify_type, notify_field));
680 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
681 _data->data.integer[0] = _integer; \
682 _data->data.integer[1] = 0;
685 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
686 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
687 if (!_data->data.string.string) {\
688 _data->data.string.size = 0; \
690 _data->data.string.size = strlen_m_term(_p) * 2;
692 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
693 _data->data.devmode.devmode = _devmode;
695 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
696 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
697 if (!_data->data.sd.sd) { \
698 _data->data.sd.sd_size = 0; \
700 _data->data.sd.sd_size = \
701 ndr_size_security_descriptor(_data->data.sd.sd, 0);
703 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
708 struct spoolss_Time st;
712 if (!init_systemtime(&st, t)) {
716 p = talloc_array(mem_ctx, char, len);
722 * Systemtime must be linearized as a set of UINT16's.
723 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
726 SSVAL(p, 0, st.year);
727 SSVAL(p, 2, st.month);
728 SSVAL(p, 4, st.day_of_week);
730 SSVAL(p, 8, st.hour);
731 SSVAL(p, 10, st.minute);
732 SSVAL(p, 12, st.second);
733 SSVAL(p, 14, st.millisecond);
739 /* Convert a notification message to a struct spoolss_Notify */
741 static void notify_one_value(struct spoolss_notify_msg *msg,
742 struct spoolss_Notify *data,
745 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
748 static void notify_string(struct spoolss_notify_msg *msg,
749 struct spoolss_Notify *data,
752 /* The length of the message includes the trailing \0 */
754 data->data.string.size = msg->len * 2;
755 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
756 if (!data->data.string.string) {
757 data->data.string.size = 0;
762 static void notify_system_time(struct spoolss_notify_msg *msg,
763 struct spoolss_Notify *data,
766 data->data.string.string = NULL;
767 data->data.string.size = 0;
769 if (msg->len != sizeof(time_t)) {
770 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
775 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
776 &data->data.string.string,
777 &data->data.string.size);
780 struct notify2_message_table {
782 void (*fn)(struct spoolss_notify_msg *msg,
783 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
786 static struct notify2_message_table printer_notify_table[] = {
787 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
788 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
789 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
790 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
791 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
792 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
793 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
794 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
795 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
796 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
797 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
798 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
799 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
800 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
801 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
802 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
803 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
804 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
805 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
808 static struct notify2_message_table job_notify_table[] = {
809 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
810 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
811 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
812 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
813 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
814 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
815 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
816 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
817 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
818 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
819 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
820 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
821 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
822 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
823 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
824 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
825 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
826 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
827 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
828 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
829 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
830 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
831 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
832 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
836 /***********************************************************************
837 Allocate talloc context for container object
838 **********************************************************************/
840 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
845 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
850 /***********************************************************************
851 release all allocated memory and zero out structure
852 **********************************************************************/
854 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
860 talloc_destroy(ctr->ctx);
867 /***********************************************************************
868 **********************************************************************/
870 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
878 /***********************************************************************
879 **********************************************************************/
881 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
883 if ( !ctr || !ctr->msg_groups )
886 if ( idx >= ctr->num_groups )
889 return &ctr->msg_groups[idx];
893 /***********************************************************************
894 How many groups of change messages do we have ?
895 **********************************************************************/
897 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
902 return ctr->num_groups;
905 /***********************************************************************
906 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
907 **********************************************************************/
909 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
911 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
912 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
913 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
919 /* loop over all groups looking for a matching printer name */
921 for ( i=0; i<ctr->num_groups; i++ ) {
922 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
926 /* add a new group? */
928 if ( i == ctr->num_groups ) {
931 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
932 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
935 ctr->msg_groups = groups;
937 /* clear the new entry and set the printer name */
939 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
940 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
943 /* add the change messages; 'i' is the correct index now regardless */
945 msg_grp = &ctr->msg_groups[i];
949 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
950 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
953 msg_grp->msgs = msg_list;
955 new_slot = msg_grp->num_msgs-1;
956 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
958 /* need to allocate own copy of data */
961 msg_grp->msgs[new_slot].notify.data = (char *)
962 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
964 return ctr->num_groups;
967 static void construct_info_data(struct spoolss_Notify *info_data,
968 enum spoolss_NotifyType type,
969 uint16_t field, int id);
971 /***********************************************************************
972 Send a change notication message on all handles which have a call
974 **********************************************************************/
976 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
979 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
980 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
981 SPOOLSS_NOTIFY_MSG *messages;
982 int sending_msg_count;
985 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
989 messages = msg_group->msgs;
992 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
996 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
998 /* loop over all printers */
1000 for (p = printers_list; p; p = p->next) {
1001 struct spoolss_Notify *notifies;
1006 /* Is there notification on this handle? */
1008 if ( !p->notify.client_connected )
1011 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1013 /* For this printer? Print servers always receive
1016 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1017 ( !strequal(msg_group->printername, p->sharename) ) )
1020 DEBUG(10,("Our printer\n"));
1022 /* allocate the max entries possible */
1024 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1029 /* build the array of change notifications */
1031 sending_msg_count = 0;
1033 for ( i=0; i<msg_group->num_msgs; i++ ) {
1034 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1036 /* Are we monitoring this event? */
1038 if (!is_monitoring_event(p, msg->type, msg->field))
1041 sending_msg_count++;
1044 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1045 msg->type, msg->field, p->sharename));
1048 * if the is a printer notification handle and not a job notification
1049 * type, then set the id to 0. Other wise just use what was specified
1052 * When registering change notification on a print server handle
1053 * we always need to send back the id (snum) matching the printer
1054 * for which the change took place. For change notify registered
1055 * on a printer handle, this does not matter and the id should be 0.
1060 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1066 /* Convert unix jobid to smb jobid */
1068 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1069 id = sysjob_to_jobid(msg->id);
1072 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1077 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1080 case PRINTER_NOTIFY_TYPE:
1081 if ( printer_notify_table[msg->field].fn )
1082 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1085 case JOB_NOTIFY_TYPE:
1086 if ( job_notify_table[msg->field].fn )
1087 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1091 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1098 if ( sending_msg_count ) {
1101 union spoolss_ReplyPrinterInfo info;
1102 struct spoolss_NotifyInfo info0;
1103 uint32_t reply_result;
1105 info0.version = 0x2;
1106 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1107 info0.count = count;
1108 info0.notifies = notifies;
1110 info.info0 = &info0;
1112 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1113 &p->notify.client_hnd,
1114 p->notify.change, /* color */
1117 0, /* reply_type, must be 0 */
1120 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1121 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1122 notify_cli_pipe->srv_name_slash,
1125 switch (reply_result) {
1128 case PRINTER_NOTIFY_INFO_DISCARDED:
1129 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1130 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1139 DEBUG(8,("send_notify2_changes: Exit...\n"));
1143 /***********************************************************************
1144 **********************************************************************/
1146 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1149 uint32_t tv_sec, tv_usec;
1152 /* Unpack message */
1154 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1157 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1159 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1162 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1163 &msg->notify.value[0], &msg->notify.value[1]);
1165 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1166 &msg->len, &msg->notify.data);
1168 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1169 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1171 tv->tv_sec = tv_sec;
1172 tv->tv_usec = tv_usec;
1175 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1176 msg->notify.value[1]));
1178 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1183 /********************************************************************
1184 Receive a notify2 message list
1185 ********************************************************************/
1187 static void receive_notify2_message_list(struct messaging_context *msg,
1190 struct server_id server_id,
1193 size_t msg_count, i;
1194 char *buf = (char *)data->data;
1197 SPOOLSS_NOTIFY_MSG notify;
1198 SPOOLSS_NOTIFY_MSG_CTR messages;
1201 if (data->length < 4) {
1202 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1206 msg_count = IVAL(buf, 0);
1209 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1211 if (msg_count == 0) {
1212 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1216 /* initialize the container */
1218 ZERO_STRUCT( messages );
1219 notify_msg_ctr_init( &messages );
1222 * build message groups for each printer identified
1223 * in a change_notify msg. Remember that a PCN message
1224 * includes the handle returned for the srv_spoolss_replyopenprinter()
1225 * call. Therefore messages are grouped according to printer handle.
1228 for ( i=0; i<msg_count; i++ ) {
1229 struct timeval msg_tv;
1231 if (msg_ptr + 4 - buf > data->length) {
1232 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1236 msg_len = IVAL(msg_ptr,0);
1239 if (msg_ptr + msg_len - buf > data->length) {
1240 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1244 /* unpack messages */
1246 ZERO_STRUCT( notify );
1247 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1250 /* add to correct list in container */
1252 notify_msg_ctr_addmsg( &messages, ¬ify );
1254 /* free memory that might have been allocated by notify2_unpack_msg() */
1256 if ( notify.len != 0 )
1257 SAFE_FREE( notify.notify.data );
1260 /* process each group of messages */
1262 num_groups = notify_msg_ctr_numgroups( &messages );
1263 for ( i=0; i<num_groups; i++ )
1264 send_notify2_changes( &messages, i );
1269 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1270 (uint32_t)msg_count ));
1272 notify_msg_ctr_destroy( &messages );
1277 /********************************************************************
1278 Send a message to ourself about new driver being installed
1279 so we can upgrade the information for each printer bound to this
1281 ********************************************************************/
1283 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1284 struct messaging_context *msg_ctx)
1286 int len = strlen(drivername);
1291 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1294 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1295 MSG_PRINTER_DRVUPGRADE,
1296 (uint8_t *)drivername, len+1);
1301 /**********************************************************************
1302 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1303 over all printers, upgrading ones as necessary
1304 **********************************************************************/
1306 void do_drv_upgrade_printer(struct messaging_context *msg,
1309 struct server_id server_id,
1312 TALLOC_CTX *tmp_ctx;
1313 struct auth_serversupplied_info *server_info = NULL;
1314 struct spoolss_PrinterInfo2 *pinfo2;
1317 const char *drivername;
1319 int n_services = lp_numservices();
1322 tmp_ctx = talloc_new(NULL);
1323 if (!tmp_ctx) return;
1325 status = make_server_info_system(tmp_ctx, &server_info);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 DEBUG(0, ("do_drv_upgrade_printer: "
1328 "Could not create system server_info\n"));
1332 len = MIN(data->length,sizeof(drivername)-1);
1333 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1335 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1339 DEBUG(10, ("do_drv_upgrade_printer: "
1340 "Got message for new driver [%s]\n", drivername));
1342 /* Iterate the printer list */
1344 for (snum = 0; snum < n_services; snum++) {
1345 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1349 result = winreg_get_printer(tmp_ctx, server_info, msg,
1351 lp_const_servicename(snum),
1354 if (!W_ERROR_IS_OK(result)) {
1358 if (!pinfo2->drivername) {
1362 if (strcmp(drivername, pinfo2->drivername) != 0) {
1366 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1368 /* all we care about currently is the change_id */
1369 result = winreg_printer_update_changeid(tmp_ctx,
1372 pinfo2->printername);
1374 if (!W_ERROR_IS_OK(result)) {
1375 DEBUG(3, ("do_drv_upgrade_printer: "
1376 "Failed to update changeid [%s]\n",
1377 win_errstr(result)));
1383 talloc_free(tmp_ctx);
1386 /********************************************************************
1387 Update the cache for all printq's with a registered client
1389 ********************************************************************/
1391 void update_monitored_printq_cache( void )
1393 Printer_entry *printer = printers_list;
1396 /* loop through all printers and update the cache where
1397 client_connected == true */
1400 if ( (printer->printer_type == SPLHND_PRINTER)
1401 && printer->notify.client_connected )
1403 snum = print_queue_snum(printer->sharename);
1404 print_queue_status( snum, NULL, NULL );
1407 printer = printer->next;
1413 /****************************************************************
1414 _spoolss_OpenPrinter
1415 ****************************************************************/
1417 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1418 struct spoolss_OpenPrinter *r)
1420 struct spoolss_OpenPrinterEx e;
1423 ZERO_STRUCT(e.in.userlevel);
1425 e.in.printername = r->in.printername;
1426 e.in.datatype = r->in.datatype;
1427 e.in.devmode_ctr = r->in.devmode_ctr;
1428 e.in.access_mask = r->in.access_mask;
1431 e.out.handle = r->out.handle;
1433 werr = _spoolss_OpenPrinterEx(p, &e);
1435 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1436 /* OpenPrinterEx returns this for a bad
1437 * printer name. We must return WERR_INVALID_PRINTER_NAME
1440 werr = WERR_INVALID_PRINTER_NAME;
1446 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1447 struct spoolss_DeviceMode *orig,
1448 struct spoolss_DeviceMode **dest)
1450 struct spoolss_DeviceMode *dm;
1452 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1457 /* copy all values, then duplicate strings and structs */
1460 dm->devicename = talloc_strdup(dm, orig->devicename);
1461 if (!dm->devicename) {
1464 dm->formname = talloc_strdup(dm, orig->formname);
1465 if (!dm->formname) {
1468 if (orig->driverextra_data.data) {
1469 dm->driverextra_data.data =
1470 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1471 orig->driverextra_data.length);
1472 if (!dm->driverextra_data.data) {
1481 /****************************************************************
1482 _spoolss_OpenPrinterEx
1483 ****************************************************************/
1485 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1486 struct spoolss_OpenPrinterEx *r)
1489 Printer_entry *Printer=NULL;
1491 if (!r->in.printername) {
1492 return WERR_INVALID_PARAM;
1495 /* some sanity check because you can open a printer or a print server */
1496 /* aka: \\server\printer or \\server */
1498 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1500 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1501 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1502 " for printer %s\n", r->in.printername));
1503 ZERO_STRUCTP(r->out.handle);
1504 return WERR_INVALID_PARAM;
1507 Printer = find_printer_index_by_hnd(p, r->out.handle);
1509 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1510 "handle we created for printer %s\n", r->in.printername));
1511 close_printer_handle(p, r->out.handle);
1512 ZERO_STRUCTP(r->out.handle);
1513 return WERR_INVALID_PARAM;
1517 * First case: the user is opening the print server:
1519 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1520 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1522 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1523 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1524 * or if the user is listed in the smb.conf printer admin parameter.
1526 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1527 * client view printer folder, but does not show the MSAPW.
1529 * Note: this test needs code to check access rights here too. Jeremy
1530 * could you look at this?
1532 * Second case: the user is opening a printer:
1533 * NT doesn't let us connect to a printer if the connecting user
1534 * doesn't have print permission.
1536 * Third case: user is opening a Port Monitor
1537 * access checks same as opening a handle to the print server.
1540 switch (Printer->printer_type )
1543 case SPLHND_PORTMON_TCP:
1544 case SPLHND_PORTMON_LOCAL:
1545 /* Printserver handles use global struct... */
1549 /* Map standard access rights to object specific access rights */
1551 se_map_standard(&r->in.access_mask,
1552 &printserver_std_mapping);
1554 /* Deny any object specific bits that don't apply to print
1555 servers (i.e printer and job specific bits) */
1557 r->in.access_mask &= SEC_MASK_SPECIFIC;
1559 if (r->in.access_mask &
1560 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1561 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1562 close_printer_handle(p, r->out.handle);
1563 ZERO_STRUCTP(r->out.handle);
1564 return WERR_ACCESS_DENIED;
1567 /* Allow admin access */
1569 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1571 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1573 if (!lp_ms_add_printer_wizard()) {
1574 close_printer_handle(p, r->out.handle);
1575 ZERO_STRUCTP(r->out.handle);
1576 return WERR_ACCESS_DENIED;
1579 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1580 and not a printer admin, then fail */
1582 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1583 !user_has_privileges(p->server_info->ptok,
1585 !token_contains_name_in_list(
1586 uidtoname(p->server_info->utok.uid),
1587 p->server_info->info3->base.domain.string,
1589 p->server_info->ptok,
1590 lp_printer_admin(snum))) {
1591 close_printer_handle(p, r->out.handle);
1592 ZERO_STRUCTP(r->out.handle);
1593 return WERR_ACCESS_DENIED;
1596 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1600 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1603 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1604 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1606 /* We fall through to return WERR_OK */
1609 case SPLHND_PRINTER:
1610 /* NT doesn't let us connect to a printer if the connecting user
1611 doesn't have print permission. */
1613 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1614 close_printer_handle(p, r->out.handle);
1615 ZERO_STRUCTP(r->out.handle);
1619 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1620 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1623 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1625 /* map an empty access mask to the minimum access mask */
1626 if (r->in.access_mask == 0x0)
1627 r->in.access_mask = PRINTER_ACCESS_USE;
1630 * If we are not serving the printer driver for this printer,
1631 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1632 * will keep NT clients happy --jerry
1635 if (lp_use_client_driver(snum)
1636 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1638 r->in.access_mask = PRINTER_ACCESS_USE;
1641 /* check smb.conf parameters and the the sec_desc */
1643 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1644 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1645 ZERO_STRUCTP(r->out.handle);
1646 return WERR_ACCESS_DENIED;
1649 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1650 p->server_info->ptok, snum) ||
1651 !print_access_check(p->server_info, snum,
1652 r->in.access_mask)) {
1653 DEBUG(3, ("access DENIED for printer open\n"));
1654 close_printer_handle(p, r->out.handle);
1655 ZERO_STRUCTP(r->out.handle);
1656 return WERR_ACCESS_DENIED;
1659 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1660 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1661 close_printer_handle(p, r->out.handle);
1662 ZERO_STRUCTP(r->out.handle);
1663 return WERR_ACCESS_DENIED;
1666 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1667 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1669 r->in.access_mask = PRINTER_ACCESS_USE;
1671 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1672 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1674 winreg_create_printer(p->mem_ctx,
1677 Printer->servername,
1678 lp_const_servicename(snum));
1683 /* sanity check to prevent programmer error */
1684 ZERO_STRUCTP(r->out.handle);
1688 Printer->access_granted = r->in.access_mask;
1691 * If the client sent a devmode in the OpenPrinter() call, then
1692 * save it here in case we get a job submission on this handle
1695 if ((Printer->printer_type != SPLHND_SERVER) &&
1696 r->in.devmode_ctr.devmode) {
1697 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1701 #if 0 /* JERRY -- I'm doubtful this is really effective */
1702 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1703 optimization in Windows 2000 clients --jerry */
1705 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1706 && (RA_WIN2K == get_remote_arch()) )
1708 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1709 sys_usleep( 500000 );
1716 /****************************************************************
1717 _spoolss_ClosePrinter
1718 ****************************************************************/
1720 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1721 struct spoolss_ClosePrinter *r)
1723 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1725 if (Printer && Printer->document_started) {
1726 struct spoolss_EndDocPrinter e;
1728 e.in.handle = r->in.handle;
1730 _spoolss_EndDocPrinter(p, &e);
1733 if (!close_printer_handle(p, r->in.handle))
1736 /* clear the returned printer handle. Observed behavior
1737 from Win2k server. Don't think this really matters.
1738 Previous code just copied the value of the closed
1741 ZERO_STRUCTP(r->out.handle);
1746 /****************************************************************
1747 _spoolss_DeletePrinter
1748 ****************************************************************/
1750 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1751 struct spoolss_DeletePrinter *r)
1753 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1757 if (Printer && Printer->document_started) {
1758 struct spoolss_EndDocPrinter e;
1760 e.in.handle = r->in.handle;
1762 _spoolss_EndDocPrinter(p, &e);
1765 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1766 winreg_delete_printer_key(p->mem_ctx,
1769 lp_const_servicename(snum),
1773 result = delete_printer_handle(p, r->in.handle);
1778 /*******************************************************************
1779 * static function to lookup the version id corresponding to an
1780 * long architecture string
1781 ******************************************************************/
1783 static const struct print_architecture_table_node archi_table[]= {
1785 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1786 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1787 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1788 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1789 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1790 {"Windows IA64", SPL_ARCH_IA64, 3 },
1791 {"Windows x64", SPL_ARCH_X64, 3 },
1795 static int get_version_id(const char *arch)
1799 for (i=0; archi_table[i].long_archi != NULL; i++)
1801 if (strcmp(arch, archi_table[i].long_archi) == 0)
1802 return (archi_table[i].version);
1808 /****************************************************************
1809 _spoolss_DeletePrinterDriver
1810 ****************************************************************/
1812 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1813 struct spoolss_DeletePrinterDriver *r)
1816 struct spoolss_DriverInfo8 *info = NULL;
1817 struct spoolss_DriverInfo8 *info_win2k = NULL;
1820 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1822 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1823 and not a printer admin, then fail */
1825 if ( (p->server_info->utok.uid != sec_initial_uid())
1826 && !user_has_privileges(p->server_info->ptok, &se_printop )
1827 && !token_contains_name_in_list(
1828 uidtoname(p->server_info->utok.uid),
1829 p->server_info->info3->base.domain.string,
1831 p->server_info->ptok,
1832 lp_printer_admin(-1)) )
1834 return WERR_ACCESS_DENIED;
1837 /* check that we have a valid driver name first */
1839 if ((version = get_version_id(r->in.architecture)) == -1)
1840 return WERR_INVALID_ENVIRONMENT;
1842 status = winreg_get_driver(p->mem_ctx, p->server_info, p->msg_ctx,
1843 r->in.architecture, r->in.driver,
1845 if (!W_ERROR_IS_OK(status)) {
1846 /* try for Win2k driver if "Windows NT x86" */
1848 if ( version == 2 ) {
1851 status = winreg_get_driver(p->mem_ctx, p->server_info,
1856 if (!W_ERROR_IS_OK(status)) {
1857 status = WERR_UNKNOWN_PRINTER_DRIVER;
1861 /* otherwise it was a failure */
1863 status = WERR_UNKNOWN_PRINTER_DRIVER;
1869 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1870 status = WERR_PRINTER_DRIVER_IN_USE;
1875 status = winreg_get_driver(p->mem_ctx, p->server_info,
1878 r->in.driver, 3, &info_win2k);
1879 if (W_ERROR_IS_OK(status)) {
1880 /* if we get to here, we now have 2 driver info structures to remove */
1881 /* remove the Win2k driver first*/
1883 status = winreg_del_driver(p->mem_ctx,
1887 talloc_free(info_win2k);
1889 /* this should not have failed---if it did, report to client */
1890 if (!W_ERROR_IS_OK(status)) {
1896 status = winreg_del_driver(p->mem_ctx, p->server_info, p->msg_ctx,
1905 /****************************************************************
1906 _spoolss_DeletePrinterDriverEx
1907 ****************************************************************/
1909 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1910 struct spoolss_DeletePrinterDriverEx *r)
1912 struct spoolss_DriverInfo8 *info = NULL;
1913 struct spoolss_DriverInfo8 *info_win2k = NULL;
1917 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1919 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1920 and not a printer admin, then fail */
1922 if ( (p->server_info->utok.uid != sec_initial_uid())
1923 && !user_has_privileges(p->server_info->ptok, &se_printop )
1924 && !token_contains_name_in_list(
1925 uidtoname(p->server_info->utok.uid),
1926 p->server_info->info3->base.domain.string,
1928 p->server_info->ptok, lp_printer_admin(-1)) )
1930 return WERR_ACCESS_DENIED;
1933 /* check that we have a valid driver name first */
1934 if ((version = get_version_id(r->in.architecture)) == -1) {
1935 /* this is what NT returns */
1936 return WERR_INVALID_ENVIRONMENT;
1939 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1940 version = r->in.version;
1942 status = winreg_get_driver(p->mem_ctx, p->server_info,
1943 p->msg_ctx, r->in.architecture,
1944 r->in.driver, version, &info);
1945 if (!W_ERROR_IS_OK(status)) {
1946 status = WERR_UNKNOWN_PRINTER_DRIVER;
1949 * if the client asked for a specific version,
1950 * or this is something other than Windows NT x86,
1954 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1957 /* try for Win2k driver if "Windows NT x86" */
1960 status = winreg_get_driver(info, p->server_info, p->msg_ctx,
1964 if (!W_ERROR_IS_OK(status)) {
1965 status = WERR_UNKNOWN_PRINTER_DRIVER;
1970 if (printer_driver_in_use(info, p->server_info, info)) {
1971 status = WERR_PRINTER_DRIVER_IN_USE;
1976 * we have a couple of cases to consider.
1977 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1978 * then the delete should fail if **any** files overlap with
1980 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1981 * non-overlapping files
1982 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1983 * is set, the do not delete any files
1984 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1987 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1989 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1992 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1993 printer_driver_files_in_use(info, p->server_info, info)) {
1994 /* no idea of the correct error here */
1995 status = WERR_ACCESS_DENIED;
2000 /* also check for W32X86/3 if necessary; maybe we already have? */
2002 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2003 status = winreg_get_driver(info, p->server_info, p->msg_ctx,
2005 r->in.driver, 3, &info_win2k);
2006 if (W_ERROR_IS_OK(status)) {
2009 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2010 printer_driver_files_in_use(info, p->server_info,
2012 /* no idea of the correct error here */
2013 talloc_free(info_win2k);
2014 status = WERR_ACCESS_DENIED;
2018 /* if we get to here, we now have 2 driver info structures to remove */
2019 /* remove the Win2k driver first*/
2021 status = winreg_del_driver(info, p->server_info,
2022 p->msg_ctx, info_win2k, 3);
2024 /* this should not have failed---if it did, report to client */
2026 if (!W_ERROR_IS_OK(status)) {
2031 * now delete any associated files if delete_files is
2032 * true. Even if this part failes, we return succes
2033 * because the driver doesn not exist any more
2036 delete_driver_files(p->server_info,
2042 status = winreg_del_driver(info, p->server_info, p->msg_ctx, info,
2044 if (!W_ERROR_IS_OK(status)) {
2049 * now delete any associated files if delete_files is
2050 * true. Even if this part failes, we return succes
2051 * because the driver doesn not exist any more
2054 delete_driver_files(p->server_info, info);
2063 /********************************************************************
2064 GetPrinterData on a printer server Handle.
2065 ********************************************************************/
2067 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2069 enum winreg_Type *type,
2070 union spoolss_PrinterData *data)
2072 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2074 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2080 if (!StrCaseCmp(value, "BeepEnabled")) {
2086 if (!StrCaseCmp(value, "EventLog")) {
2088 /* formally was 0x1b */
2093 if (!StrCaseCmp(value, "NetPopup")) {
2099 if (!StrCaseCmp(value, "MajorVersion")) {
2102 /* Windows NT 4.0 seems to not allow uploading of drivers
2103 to a server that reports 0x3 as the MajorVersion.
2104 need to investigate more how Win2k gets around this .
2107 if (RA_WINNT == get_remote_arch()) {
2116 if (!StrCaseCmp(value, "MinorVersion")) {
2123 * uint32_t size = 0x114
2124 * uint32_t major = 5
2125 * uint32_t minor = [0|1]
2126 * uint32_t build = [2195|2600]
2127 * extra unicode string = e.g. "Service Pack 3"
2129 if (!StrCaseCmp(value, "OSVersion")) {
2131 enum ndr_err_code ndr_err;
2132 struct spoolss_OSVersion os;
2134 os.major = 5; /* Windows 2000 == 5.0 */
2136 os.build = 2195; /* build */
2137 os.extra_string = ""; /* leave extra string empty */
2139 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2140 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2141 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2142 return WERR_GENERAL_FAILURE;
2146 data->binary = blob;
2152 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2155 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2156 W_ERROR_HAVE_NO_MEMORY(data->string);
2161 if (!StrCaseCmp(value, "Architecture")) {
2163 data->string = talloc_strdup(mem_ctx,
2164 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2165 W_ERROR_HAVE_NO_MEMORY(data->string);
2170 if (!StrCaseCmp(value, "DsPresent")) {
2173 /* only show the publish check box if we are a
2174 member of a AD domain */
2176 if (lp_security() == SEC_ADS) {
2184 if (!StrCaseCmp(value, "DNSMachineName")) {
2185 const char *hostname = get_mydnsfullname();
2188 return WERR_BADFILE;
2192 data->string = talloc_strdup(mem_ctx, hostname);
2193 W_ERROR_HAVE_NO_MEMORY(data->string);
2200 return WERR_INVALID_PARAM;
2203 /****************************************************************
2204 _spoolss_GetPrinterData
2205 ****************************************************************/
2207 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2208 struct spoolss_GetPrinterData *r)
2210 struct spoolss_GetPrinterDataEx r2;
2212 r2.in.handle = r->in.handle;
2213 r2.in.key_name = "PrinterDriverData";
2214 r2.in.value_name = r->in.value_name;
2215 r2.in.offered = r->in.offered;
2216 r2.out.type = r->out.type;
2217 r2.out.data = r->out.data;
2218 r2.out.needed = r->out.needed;
2220 return _spoolss_GetPrinterDataEx(p, &r2);
2223 /*********************************************************
2224 Connect to the client machine.
2225 **********************************************************/
2227 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2228 struct sockaddr_storage *client_ss, const char *remote_machine)
2231 struct cli_state *the_cli;
2232 struct sockaddr_storage rm_addr;
2233 char addr[INET6_ADDRSTRLEN];
2235 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2236 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2238 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2239 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2242 print_sockaddr(addr, sizeof(addr), &rm_addr);
2244 rm_addr = *client_ss;
2245 print_sockaddr(addr, sizeof(addr), &rm_addr);
2246 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2250 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2251 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2256 /* setup the connection */
2257 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2258 &rm_addr, 0, "IPC$", "IPC",
2262 0, lp_client_signing(), NULL );
2264 if ( !NT_STATUS_IS_OK( ret ) ) {
2265 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2270 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2271 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2272 cli_shutdown(the_cli);
2277 * Ok - we have an anonymous connection to the IPC$ share.
2278 * Now start the NT Domain stuff :-).
2281 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2282 if (!NT_STATUS_IS_OK(ret)) {
2283 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2284 remote_machine, nt_errstr(ret)));
2285 cli_shutdown(the_cli);
2292 /***************************************************************************
2293 Connect to the client.
2294 ****************************************************************************/
2296 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2297 uint32_t localprinter, uint32_t type,
2298 struct policy_handle *handle,
2299 struct sockaddr_storage *client_ss,
2300 struct messaging_context *msg_ctx)
2306 * If it's the first connection, contact the client
2307 * and connect to the IPC$ share anonymously
2309 if (smb_connections==0) {
2310 fstring unix_printer;
2312 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2314 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2317 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2318 receive_notify2_message_list);
2319 /* Tell the connections db we're now interested in printer
2320 * notify messages. */
2321 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2322 true, FLAG_MSG_PRINT_NOTIFY);
2326 * Tell the specific printing tdb we want messages for this printer
2327 * by registering our PID.
2330 if (!print_notify_register_pid(snum))
2331 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2335 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2343 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2344 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2345 win_errstr(result)));
2347 return (W_ERROR_IS_OK(result));
2350 /****************************************************************
2351 ****************************************************************/
2353 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2354 const struct spoolss_NotifyOption *r)
2356 struct spoolss_NotifyOption *option;
2363 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2370 if (!option->count) {
2374 option->types = talloc_zero_array(option,
2375 struct spoolss_NotifyOptionType, option->count);
2376 if (!option->types) {
2377 talloc_free(option);
2381 for (i=0; i < option->count; i++) {
2382 option->types[i] = r->types[i];
2384 if (option->types[i].count) {
2385 option->types[i].fields = talloc_zero_array(option,
2386 union spoolss_Field, option->types[i].count);
2387 if (!option->types[i].fields) {
2388 talloc_free(option);
2391 for (k=0; k<option->types[i].count; k++) {
2392 option->types[i].fields[k] =
2393 r->types[i].fields[k];
2401 /****************************************************************
2402 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2404 * before replying OK: status=0 a rpc call is made to the workstation
2405 * asking ReplyOpenPrinter
2407 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2408 * called from api_spoolss_rffpcnex
2409 ****************************************************************/
2411 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2412 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2415 struct spoolss_NotifyOption *option = r->in.notify_options;
2416 struct sockaddr_storage client_ss;
2418 /* store the notify value in the printer struct */
2420 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2423 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2424 "Invalid handle (%s:%u:%u).\n",
2425 OUR_HANDLE(r->in.handle)));
2429 Printer->notify.flags = r->in.flags;
2430 Printer->notify.options = r->in.options;
2431 Printer->notify.printerlocal = r->in.printer_local;
2432 Printer->notify.msg_ctx = p->msg_ctx;
2434 TALLOC_FREE(Printer->notify.option);
2435 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2437 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2439 /* Connect to the client machine and send a ReplyOpenPrinter */
2441 if ( Printer->printer_type == SPLHND_SERVER)
2443 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2444 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2447 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2448 "client_address is %s\n", p->client_address));
2450 if (!interpret_string_addr(&client_ss, p->client_address,
2452 return WERR_SERVER_UNAVAILABLE;
2455 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2456 Printer->notify.printerlocal, 1,
2457 &Printer->notify.client_hnd,
2458 &client_ss, p->msg_ctx))
2459 return WERR_SERVER_UNAVAILABLE;
2461 Printer->notify.client_connected = true;
2466 /*******************************************************************
2467 * fill a notify_info_data with the servername
2468 ********************************************************************/
2470 static void spoolss_notify_server_name(int snum,
2471 struct spoolss_Notify *data,
2472 print_queue_struct *queue,
2473 struct spoolss_PrinterInfo2 *pinfo2,
2474 TALLOC_CTX *mem_ctx)
2476 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2479 /*******************************************************************
2480 * fill a notify_info_data with the printername (not including the servername).
2481 ********************************************************************/
2483 static void spoolss_notify_printer_name(int snum,
2484 struct spoolss_Notify *data,
2485 print_queue_struct *queue,
2486 struct spoolss_PrinterInfo2 *pinfo2,
2487 TALLOC_CTX *mem_ctx)
2489 /* the notify name should not contain the \\server\ part */
2490 const char *p = strrchr(pinfo2->printername, '\\');
2493 p = pinfo2->printername;
2498 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2501 /*******************************************************************
2502 * fill a notify_info_data with the servicename
2503 ********************************************************************/
2505 static void spoolss_notify_share_name(int snum,
2506 struct spoolss_Notify *data,
2507 print_queue_struct *queue,
2508 struct spoolss_PrinterInfo2 *pinfo2,
2509 TALLOC_CTX *mem_ctx)
2511 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2514 /*******************************************************************
2515 * fill a notify_info_data with the port name
2516 ********************************************************************/
2518 static void spoolss_notify_port_name(int snum,
2519 struct spoolss_Notify *data,
2520 print_queue_struct *queue,
2521 struct spoolss_PrinterInfo2 *pinfo2,
2522 TALLOC_CTX *mem_ctx)
2524 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2527 /*******************************************************************
2528 * fill a notify_info_data with the printername
2529 * but it doesn't exist, have to see what to do
2530 ********************************************************************/
2532 static void spoolss_notify_driver_name(int snum,
2533 struct spoolss_Notify *data,
2534 print_queue_struct *queue,
2535 struct spoolss_PrinterInfo2 *pinfo2,
2536 TALLOC_CTX *mem_ctx)
2538 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2541 /*******************************************************************
2542 * fill a notify_info_data with the comment
2543 ********************************************************************/
2545 static void spoolss_notify_comment(int snum,
2546 struct spoolss_Notify *data,
2547 print_queue_struct *queue,
2548 struct spoolss_PrinterInfo2 *pinfo2,
2549 TALLOC_CTX *mem_ctx)
2553 if (*pinfo2->comment == '\0') {
2554 p = lp_comment(snum);
2556 p = pinfo2->comment;
2559 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2562 /*******************************************************************
2563 * fill a notify_info_data with the comment
2564 * location = "Room 1, floor 2, building 3"
2565 ********************************************************************/
2567 static void spoolss_notify_location(int snum,
2568 struct spoolss_Notify *data,
2569 print_queue_struct *queue,
2570 struct spoolss_PrinterInfo2 *pinfo2,
2571 TALLOC_CTX *mem_ctx)
2573 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2576 /*******************************************************************
2577 * fill a notify_info_data with the device mode
2578 * jfm:xxxx don't to it for know but that's a real problem !!!
2579 ********************************************************************/
2581 static void spoolss_notify_devmode(int snum,
2582 struct spoolss_Notify *data,
2583 print_queue_struct *queue,
2584 struct spoolss_PrinterInfo2 *pinfo2,
2585 TALLOC_CTX *mem_ctx)
2587 /* for a dummy implementation we have to zero the fields */
2588 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2591 /*******************************************************************
2592 * fill a notify_info_data with the separator file name
2593 ********************************************************************/
2595 static void spoolss_notify_sepfile(int snum,
2596 struct spoolss_Notify *data,
2597 print_queue_struct *queue,
2598 struct spoolss_PrinterInfo2 *pinfo2,
2599 TALLOC_CTX *mem_ctx)
2601 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2604 /*******************************************************************
2605 * fill a notify_info_data with the print processor
2606 * jfm:xxxx return always winprint to indicate we don't do anything to it
2607 ********************************************************************/
2609 static void spoolss_notify_print_processor(int snum,
2610 struct spoolss_Notify *data,
2611 print_queue_struct *queue,
2612 struct spoolss_PrinterInfo2 *pinfo2,
2613 TALLOC_CTX *mem_ctx)
2615 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2618 /*******************************************************************
2619 * fill a notify_info_data with the print processor options
2620 * jfm:xxxx send an empty string
2621 ********************************************************************/
2623 static void spoolss_notify_parameters(int snum,
2624 struct spoolss_Notify *data,
2625 print_queue_struct *queue,
2626 struct spoolss_PrinterInfo2 *pinfo2,
2627 TALLOC_CTX *mem_ctx)
2629 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2632 /*******************************************************************
2633 * fill a notify_info_data with the data type
2634 * jfm:xxxx always send RAW as data type
2635 ********************************************************************/
2637 static void spoolss_notify_datatype(int snum,
2638 struct spoolss_Notify *data,
2639 print_queue_struct *queue,
2640 struct spoolss_PrinterInfo2 *pinfo2,
2641 TALLOC_CTX *mem_ctx)
2643 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2646 /*******************************************************************
2647 * fill a notify_info_data with the security descriptor
2648 * jfm:xxxx send an null pointer to say no security desc
2649 * have to implement security before !
2650 ********************************************************************/
2652 static void spoolss_notify_security_desc(int snum,
2653 struct spoolss_Notify *data,
2654 print_queue_struct *queue,
2655 struct spoolss_PrinterInfo2 *pinfo2,
2656 TALLOC_CTX *mem_ctx)
2658 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2661 /*******************************************************************
2662 * fill a notify_info_data with the attributes
2663 * jfm:xxxx a samba printer is always shared
2664 ********************************************************************/
2666 static void spoolss_notify_attributes(int snum,
2667 struct spoolss_Notify *data,
2668 print_queue_struct *queue,
2669 struct spoolss_PrinterInfo2 *pinfo2,
2670 TALLOC_CTX *mem_ctx)
2672 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2675 /*******************************************************************
2676 * fill a notify_info_data with the priority
2677 ********************************************************************/
2679 static void spoolss_notify_priority(int snum,
2680 struct spoolss_Notify *data,
2681 print_queue_struct *queue,
2682 struct spoolss_PrinterInfo2 *pinfo2,
2683 TALLOC_CTX *mem_ctx)
2685 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2688 /*******************************************************************
2689 * fill a notify_info_data with the default priority
2690 ********************************************************************/
2692 static void spoolss_notify_default_priority(int snum,
2693 struct spoolss_Notify *data,
2694 print_queue_struct *queue,
2695 struct spoolss_PrinterInfo2 *pinfo2,
2696 TALLOC_CTX *mem_ctx)
2698 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2701 /*******************************************************************
2702 * fill a notify_info_data with the start time
2703 ********************************************************************/
2705 static void spoolss_notify_start_time(int snum,
2706 struct spoolss_Notify *data,
2707 print_queue_struct *queue,
2708 struct spoolss_PrinterInfo2 *pinfo2,
2709 TALLOC_CTX *mem_ctx)
2711 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2714 /*******************************************************************
2715 * fill a notify_info_data with the until time
2716 ********************************************************************/
2718 static void spoolss_notify_until_time(int snum,
2719 struct spoolss_Notify *data,
2720 print_queue_struct *queue,
2721 struct spoolss_PrinterInfo2 *pinfo2,
2722 TALLOC_CTX *mem_ctx)
2724 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2727 /*******************************************************************
2728 * fill a notify_info_data with the status
2729 ********************************************************************/
2731 static void spoolss_notify_status(int snum,
2732 struct spoolss_Notify *data,
2733 print_queue_struct *queue,
2734 struct spoolss_PrinterInfo2 *pinfo2,
2735 TALLOC_CTX *mem_ctx)
2737 print_status_struct status;
2739 print_queue_length(snum, &status);
2740 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2743 /*******************************************************************
2744 * fill a notify_info_data with the number of jobs queued
2745 ********************************************************************/
2747 static void spoolss_notify_cjobs(int snum,
2748 struct spoolss_Notify *data,
2749 print_queue_struct *queue,
2750 struct spoolss_PrinterInfo2 *pinfo2,
2751 TALLOC_CTX *mem_ctx)
2753 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2756 /*******************************************************************
2757 * fill a notify_info_data with the average ppm
2758 ********************************************************************/
2760 static void spoolss_notify_average_ppm(int snum,
2761 struct spoolss_Notify *data,
2762 print_queue_struct *queue,
2763 struct spoolss_PrinterInfo2 *pinfo2,
2764 TALLOC_CTX *mem_ctx)
2766 /* always respond 8 pages per minutes */
2767 /* a little hard ! */
2768 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2771 /*******************************************************************
2772 * fill a notify_info_data with username
2773 ********************************************************************/
2775 static void spoolss_notify_username(int snum,
2776 struct spoolss_Notify *data,
2777 print_queue_struct *queue,
2778 struct spoolss_PrinterInfo2 *pinfo2,
2779 TALLOC_CTX *mem_ctx)
2781 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2784 /*******************************************************************
2785 * fill a notify_info_data with job status
2786 ********************************************************************/
2788 static void spoolss_notify_job_status(int snum,
2789 struct spoolss_Notify *data,
2790 print_queue_struct *queue,
2791 struct spoolss_PrinterInfo2 *pinfo2,
2792 TALLOC_CTX *mem_ctx)
2794 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2797 /*******************************************************************
2798 * fill a notify_info_data with job name
2799 ********************************************************************/
2801 static void spoolss_notify_job_name(int snum,
2802 struct spoolss_Notify *data,
2803 print_queue_struct *queue,
2804 struct spoolss_PrinterInfo2 *pinfo2,
2805 TALLOC_CTX *mem_ctx)
2807 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2810 /*******************************************************************
2811 * fill a notify_info_data with job status
2812 ********************************************************************/
2814 static void spoolss_notify_job_status_string(int snum,
2815 struct spoolss_Notify *data,
2816 print_queue_struct *queue,
2817 struct spoolss_PrinterInfo2 *pinfo2,
2818 TALLOC_CTX *mem_ctx)
2821 * Now we're returning job status codes we just return a "" here. JRA.
2826 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2829 switch (queue->status) {
2834 p = ""; /* NT provides the paused string */
2843 #endif /* NO LONGER NEEDED. */
2845 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2848 /*******************************************************************
2849 * fill a notify_info_data with job time
2850 ********************************************************************/
2852 static void spoolss_notify_job_time(int snum,
2853 struct spoolss_Notify *data,
2854 print_queue_struct *queue,
2855 struct spoolss_PrinterInfo2 *pinfo2,
2856 TALLOC_CTX *mem_ctx)
2858 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2861 /*******************************************************************
2862 * fill a notify_info_data with job size
2863 ********************************************************************/
2865 static void spoolss_notify_job_size(int snum,
2866 struct spoolss_Notify *data,
2867 print_queue_struct *queue,
2868 struct spoolss_PrinterInfo2 *pinfo2,
2869 TALLOC_CTX *mem_ctx)
2871 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2874 /*******************************************************************
2875 * fill a notify_info_data with page info
2876 ********************************************************************/
2877 static void spoolss_notify_total_pages(int snum,
2878 struct spoolss_Notify *data,
2879 print_queue_struct *queue,
2880 struct spoolss_PrinterInfo2 *pinfo2,
2881 TALLOC_CTX *mem_ctx)
2883 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2886 /*******************************************************************
2887 * fill a notify_info_data with pages printed info.
2888 ********************************************************************/
2889 static void spoolss_notify_pages_printed(int snum,
2890 struct spoolss_Notify *data,
2891 print_queue_struct *queue,
2892 struct spoolss_PrinterInfo2 *pinfo2,
2893 TALLOC_CTX *mem_ctx)
2895 /* Add code when back-end tracks this */
2896 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2899 /*******************************************************************
2900 Fill a notify_info_data with job position.
2901 ********************************************************************/
2903 static void spoolss_notify_job_position(int snum,
2904 struct spoolss_Notify *data,
2905 print_queue_struct *queue,
2906 struct spoolss_PrinterInfo2 *pinfo2,
2907 TALLOC_CTX *mem_ctx)
2909 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2912 /*******************************************************************
2913 Fill a notify_info_data with submitted time.
2914 ********************************************************************/
2916 static void spoolss_notify_submitted_time(int snum,
2917 struct spoolss_Notify *data,
2918 print_queue_struct *queue,
2919 struct spoolss_PrinterInfo2 *pinfo2,
2920 TALLOC_CTX *mem_ctx)
2922 data->data.string.string = NULL;
2923 data->data.string.size = 0;
2925 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2926 &data->data.string.string,
2927 &data->data.string.size);
2931 struct s_notify_info_data_table
2933 enum spoolss_NotifyType type;
2936 enum spoolss_NotifyTable variable_type;
2937 void (*fn) (int snum, struct spoolss_Notify *data,
2938 print_queue_struct *queue,
2939 struct spoolss_PrinterInfo2 *pinfo2,
2940 TALLOC_CTX *mem_ctx);
2943 /* A table describing the various print notification constants and
2944 whether the notification data is a pointer to a variable sized
2945 buffer, a one value uint32_t or a two value uint32_t. */
2947 static const struct s_notify_info_data_table notify_info_data_table[] =
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2950 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2951 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2952 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2953 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2954 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2955 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2956 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2957 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2958 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2959 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2960 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2961 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2962 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2963 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2964 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2965 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2966 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2967 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2968 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2969 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2970 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2971 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2972 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2973 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2974 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2975 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2976 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2977 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2978 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2979 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2980 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2981 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2982 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2983 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2984 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2985 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2986 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2987 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2988 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2989 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2990 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2991 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2992 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2993 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2994 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2995 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2996 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2997 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3000 /*******************************************************************
3001 Return the variable_type of info_data structure.
3002 ********************************************************************/
3004 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3009 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3010 if ( (notify_info_data_table[i].type == type) &&
3011 (notify_info_data_table[i].field == field) ) {
3012 return notify_info_data_table[i].variable_type;
3016 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3021 /****************************************************************************
3022 ****************************************************************************/
3024 static bool search_notify(enum spoolss_NotifyType type,
3030 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3031 if (notify_info_data_table[i].type == type &&
3032 notify_info_data_table[i].field == field &&
3033 notify_info_data_table[i].fn != NULL) {
3042 /****************************************************************************
3043 ****************************************************************************/
3045 static void construct_info_data(struct spoolss_Notify *info_data,
3046 enum spoolss_NotifyType type,
3047 uint16_t field, int id)
3049 info_data->type = type;
3050 info_data->field.field = field;
3051 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3052 info_data->job_id = id;
3055 /*******************************************************************
3057 * fill a notify_info struct with info asked
3059 ********************************************************************/
3061 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3062 struct spoolss_NotifyInfo *info,
3063 struct spoolss_PrinterInfo2 *pinfo2,
3065 const struct spoolss_NotifyOptionType *option_type,
3067 TALLOC_CTX *mem_ctx)
3070 enum spoolss_NotifyType type;
3073 struct spoolss_Notify *current_data;
3074 print_queue_struct *queue=NULL;
3076 type = option_type->type;
3078 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3079 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3080 option_type->count, lp_servicename(snum)));
3082 for(field_num=0; field_num < option_type->count; field_num++) {
3083 field = option_type->fields[field_num].field;
3085 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3087 if (!search_notify(type, field, &j) )
3090 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3091 struct spoolss_Notify,
3093 if (info->notifies == NULL) {
3094 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3098 current_data = &info->notifies[info->count];
3100 construct_info_data(current_data, type, field, id);
3102 DEBUG(10, ("construct_notify_printer_info: "
3103 "calling [%s] snum=%d printername=[%s])\n",
3104 notify_info_data_table[j].name, snum,
3105 pinfo2->printername));
3107 notify_info_data_table[j].fn(snum, current_data, queue,
3116 /*******************************************************************
3118 * fill a notify_info struct with info asked
3120 ********************************************************************/
3122 static bool construct_notify_jobs_info(print_queue_struct *queue,
3123 struct spoolss_NotifyInfo *info,
3124 struct spoolss_PrinterInfo2 *pinfo2,
3126 const struct spoolss_NotifyOptionType *option_type,
3128 TALLOC_CTX *mem_ctx)
3131 enum spoolss_NotifyType type;
3133 struct spoolss_Notify *current_data;
3135 DEBUG(4,("construct_notify_jobs_info\n"));
3137 type = option_type->type;
3139 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3140 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3141 option_type->count));
3143 for(field_num=0; field_num<option_type->count; field_num++) {
3144 field = option_type->fields[field_num].field;
3146 if (!search_notify(type, field, &j) )
3149 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3150 struct spoolss_Notify,
3152 if (info->notifies == NULL) {
3153 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3157 current_data=&(info->notifies[info->count]);
3159 construct_info_data(current_data, type, field, id);
3160 notify_info_data_table[j].fn(snum, current_data, queue,
3169 * JFM: The enumeration is not that simple, it's even non obvious.
3171 * let's take an example: I want to monitor the PRINTER SERVER for
3172 * the printer's name and the number of jobs currently queued.
3173 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3174 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3176 * I have 3 printers on the back of my server.
3178 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3181 * 1 printer 1 name 1
3182 * 2 printer 1 cjob 1
3183 * 3 printer 2 name 2
3184 * 4 printer 2 cjob 2
3185 * 5 printer 3 name 3
3186 * 6 printer 3 name 3
3188 * that's the print server case, the printer case is even worse.
3191 /*******************************************************************
3193 * enumerate all printers on the printserver
3194 * fill a notify_info struct with info asked
3196 ********************************************************************/
3198 static WERROR printserver_notify_info(struct pipes_struct *p,
3199 struct policy_handle *hnd,
3200 struct spoolss_NotifyInfo *info,
3201 TALLOC_CTX *mem_ctx)
3204 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3205 int n_services=lp_numservices();
3207 struct spoolss_NotifyOption *option;
3208 struct spoolss_NotifyOptionType option_type;
3209 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3212 DEBUG(4,("printserver_notify_info\n"));
3217 option = Printer->notify.option;
3220 info->notifies = NULL;
3223 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3224 sending a ffpcn() request first */
3229 for (i=0; i<option->count; i++) {
3230 option_type = option->types[i];
3232 if (option_type.type != PRINTER_NOTIFY_TYPE)
3235 for (snum = 0; snum < n_services; snum++) {
3236 if (!lp_browseable(snum) ||
3237 !lp_snum_ok(snum) ||
3238 !lp_print_ok(snum)) {
3239 continue; /* skip */
3242 /* Maybe we should use the SYSTEM server_info here... */
3243 result = winreg_get_printer(mem_ctx, p->server_info,
3245 Printer->servername,
3246 lp_servicename(snum),
3248 if (!W_ERROR_IS_OK(result)) {
3249 DEBUG(4, ("printserver_notify_info: "
3250 "Failed to get printer [%s]\n",
3251 lp_servicename(snum)));
3256 construct_notify_printer_info(Printer, info,
3261 TALLOC_FREE(pinfo2);
3267 * Debugging information, don't delete.
3270 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3271 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3272 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3274 for (i=0; i<info->count; i++) {
3275 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3276 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3277 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3284 /*******************************************************************
3286 * fill a notify_info struct with info asked
3288 ********************************************************************/
3290 static WERROR printer_notify_info(struct pipes_struct *p,
3291 struct policy_handle *hnd,
3292 struct spoolss_NotifyInfo *info,
3293 TALLOC_CTX *mem_ctx)
3296 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3299 struct spoolss_NotifyOption *option;
3300 struct spoolss_NotifyOptionType option_type;
3302 print_queue_struct *queue=NULL;
3303 print_status_struct status;
3304 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3307 DEBUG(4,("printer_notify_info\n"));
3312 option = Printer->notify.option;
3316 info->notifies = NULL;
3319 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3320 sending a ffpcn() request first */
3325 get_printer_snum(p, hnd, &snum, NULL);
3327 /* Maybe we should use the SYSTEM server_info here... */
3328 result = winreg_get_printer(mem_ctx, p->server_info, p->msg_ctx,
3329 Printer->servername,
3330 lp_servicename(snum), &pinfo2);
3331 if (!W_ERROR_IS_OK(result)) {
3335 for (i=0; i<option->count; i++) {
3336 option_type = option->types[i];
3338 switch (option_type.type) {
3339 case PRINTER_NOTIFY_TYPE:
3340 if (construct_notify_printer_info(Printer, info,
3348 case JOB_NOTIFY_TYPE:
3350 count = print_queue_status(snum, &queue, &status);
3352 for (j=0; j<count; j++) {
3353 construct_notify_jobs_info(&queue[j], info,
3366 * Debugging information, don't delete.
3369 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3370 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3371 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3373 for (i=0; i<info->count; i++) {
3374 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3375 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3376 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3380 talloc_free(pinfo2);
3384 /****************************************************************
3385 _spoolss_RouterRefreshPrinterChangeNotify
3386 ****************************************************************/
3388 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3389 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3391 struct spoolss_NotifyInfo *info;
3393 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3394 WERROR result = WERR_BADFID;
3396 /* we always have a spoolss_NotifyInfo struct */
3397 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3399 result = WERR_NOMEM;
3403 *r->out.info = info;
3406 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3407 "Invalid handle (%s:%u:%u).\n",
3408 OUR_HANDLE(r->in.handle)));
3412 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3415 * We are now using the change value, and
3416 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3417 * I don't have a global notification system, I'm sending back all the
3418 * informations even when _NOTHING_ has changed.
3421 /* We need to keep track of the change value to send back in
3422 RRPCN replies otherwise our updates are ignored. */
3424 Printer->notify.fnpcn = true;
3426 if (Printer->notify.client_connected) {
3427 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3428 "Saving change value in request [%x]\n",
3430 Printer->notify.change = r->in.change_low;
3433 /* just ignore the spoolss_NotifyOption */
3435 switch (Printer->printer_type) {
3437 result = printserver_notify_info(p, r->in.handle,
3441 case SPLHND_PRINTER:
3442 result = printer_notify_info(p, r->in.handle,
3447 Printer->notify.fnpcn = false;
3453 /********************************************************************
3454 * construct_printer_info_0
3455 * fill a printer_info_0 struct
3456 ********************************************************************/
3458 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3459 struct auth_serversupplied_info *server_info,
3460 struct spoolss_PrinterInfo2 *info2,
3461 struct spoolss_PrinterInfo0 *r,
3465 counter_printer_0 *session_counter;
3466 struct timeval setuptime;
3467 print_status_struct status;
3469 r->printername = talloc_strdup(mem_ctx, info2->printername);
3470 W_ERROR_HAVE_NO_MEMORY(r->printername);
3472 r->servername = talloc_strdup(mem_ctx, info2->servername);
3473 W_ERROR_HAVE_NO_MEMORY(r->servername);
3475 count = print_queue_length(snum, &status);
3477 /* check if we already have a counter for this printer */
3478 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3479 if (session_counter->snum == snum)
3483 /* it's the first time, add it to the list */
3484 if (session_counter == NULL) {
3485 session_counter = SMB_MALLOC_P(counter_printer_0);
3486 W_ERROR_HAVE_NO_MEMORY(session_counter);
3487 ZERO_STRUCTP(session_counter);
3488 session_counter->snum = snum;
3489 session_counter->counter = 0;
3490 DLIST_ADD(counter_list, session_counter);
3494 session_counter->counter++;
3500 get_startup_time(&setuptime);
3501 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3504 * the global_counter should be stored in a TDB as it's common to all the clients
3505 * and should be zeroed on samba startup
3507 r->global_counter = session_counter->counter;
3509 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3510 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3511 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3512 r->free_build = SPOOLSS_RELEASE_BUILD;
3514 r->max_spooling = 0;
3515 r->session_counter = session_counter->counter;
3516 r->num_error_out_of_paper = 0x0;
3517 r->num_error_not_ready = 0x0; /* number of print failure */
3519 r->number_of_processors = 0x1;
3520 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3521 r->high_part_total_bytes = 0x0;
3523 /* ChangeID in milliseconds*/
3524 winreg_printer_get_changeid(mem_ctx, server_info,
3525 smbd_messaging_context(),
3526 info2->sharename, &r->change_id);
3528 r->last_error = WERR_OK;
3529 r->status = nt_printq_status(status.status);
3530 r->enumerate_network_printers = 0x0;
3531 r->c_setprinter = 0x0;
3532 r->processor_architecture = 0x0;
3533 r->processor_level = 0x6; /* 6 ???*/
3542 /********************************************************************
3543 * construct_printer_info1
3544 * fill a spoolss_PrinterInfo1 struct
3545 ********************************************************************/
3547 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3548 const struct spoolss_PrinterInfo2 *info2,
3550 struct spoolss_PrinterInfo1 *r,
3555 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3559 W_ERROR_HAVE_NO_MEMORY(r->description);
3561 if (info2->comment == NULL || info2->comment[0] == '\0') {
3562 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3564 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3566 W_ERROR_HAVE_NO_MEMORY(r->comment);
3568 r->name = talloc_strdup(mem_ctx, info2->printername);
3569 W_ERROR_HAVE_NO_MEMORY(r->name);
3574 /********************************************************************
3575 * construct_printer_info2
3576 * fill a spoolss_PrinterInfo2 struct
3577 ********************************************************************/
3579 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3580 const struct spoolss_PrinterInfo2 *info2,
3581 struct spoolss_PrinterInfo2 *r,
3585 print_status_struct status;
3587 count = print_queue_length(snum, &status);
3589 r->servername = talloc_strdup(mem_ctx, info2->servername);
3590 W_ERROR_HAVE_NO_MEMORY(r->servername);
3591 r->printername = talloc_strdup(mem_ctx, info2->printername);
3592 W_ERROR_HAVE_NO_MEMORY(r->printername);
3593 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3594 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3595 r->portname = talloc_strdup(mem_ctx, info2->portname);
3596 W_ERROR_HAVE_NO_MEMORY(r->portname);
3597 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3598 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3600 if (info2->comment[0] == '\0') {
3601 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3603 r->comment = talloc_strdup(mem_ctx, info2->comment);
3605 W_ERROR_HAVE_NO_MEMORY(r->comment);
3607 r->location = talloc_strdup(mem_ctx, info2->location);
3608 W_ERROR_HAVE_NO_MEMORY(r->location);
3609 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3610 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3611 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3612 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3613 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3614 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3615 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3616 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3618 r->attributes = info2->attributes;
3620 r->priority = info2->priority;
3621 r->defaultpriority = info2->defaultpriority;
3622 r->starttime = info2->starttime;
3623 r->untiltime = info2->untiltime;
3624 r->status = nt_printq_status(status.status);
3626 r->averageppm = info2->averageppm;
3628 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3630 DEBUG(8,("Returning NULL Devicemode!\n"));
3635 if (info2->secdesc != NULL) {
3636 /* don't use talloc_steal() here unless you do a deep steal of all
3637 the SEC_DESC members */
3639 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3645 /********************************************************************
3646 * construct_printer_info3
3647 * fill a spoolss_PrinterInfo3 struct
3648 ********************************************************************/
3650 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3651 const struct spoolss_PrinterInfo2 *info2,
3652 struct spoolss_PrinterInfo3 *r,
3655 /* These are the components of the SD we are returning. */
3657 if (info2->secdesc != NULL) {
3658 /* don't use talloc_steal() here unless you do a deep steal of all
3659 the SEC_DESC members */
3661 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3662 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3668 /********************************************************************
3669 * construct_printer_info4
3670 * fill a spoolss_PrinterInfo4 struct
3671 ********************************************************************/
3673 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3674 const struct spoolss_PrinterInfo2 *info2,
3675 struct spoolss_PrinterInfo4 *r,
3678 r->printername = talloc_strdup(mem_ctx, info2->printername);
3679 W_ERROR_HAVE_NO_MEMORY(r->printername);
3680 r->servername = talloc_strdup(mem_ctx, info2->servername);
3681 W_ERROR_HAVE_NO_MEMORY(r->servername);
3683 r->attributes = info2->attributes;
3688 /********************************************************************
3689 * construct_printer_info5
3690 * fill a spoolss_PrinterInfo5 struct
3691 ********************************************************************/
3693 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3694 const struct spoolss_PrinterInfo2 *info2,
3695 struct spoolss_PrinterInfo5 *r,
3698 r->printername = talloc_strdup(mem_ctx, info2->printername);
3699 W_ERROR_HAVE_NO_MEMORY(r->printername);
3700 r->portname = talloc_strdup(mem_ctx, info2->portname);
3701 W_ERROR_HAVE_NO_MEMORY(r->portname);
3703 r->attributes = info2->attributes;
3705 /* these two are not used by NT+ according to MSDN */
3706 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3707 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3712 /********************************************************************
3713 * construct_printer_info_6
3714 * fill a spoolss_PrinterInfo6 struct
3715 ********************************************************************/
3717 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3718 const struct spoolss_PrinterInfo2 *info2,
3719 struct spoolss_PrinterInfo6 *r,
3723 print_status_struct status;
3725 count = print_queue_length(snum, &status);
3727 r->status = nt_printq_status(status.status);
3732 /********************************************************************
3733 * construct_printer_info7
3734 * fill a spoolss_PrinterInfo7 struct
3735 ********************************************************************/
3737 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3738 Printer_entry *print_hnd,
3739 struct spoolss_PrinterInfo7 *r,
3742 struct auth_serversupplied_info *server_info;
3746 status = make_server_info_system(mem_ctx, &server_info);
3747 if (!NT_STATUS_IS_OK(status)) {
3748 DEBUG(0, ("construct_printer_info7: "
3749 "Could not create system server_info\n"));
3753 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3754 lp_servicename(snum), &guid, NULL)) {
3755 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3756 r->action = DSPRINT_PUBLISH;
3758 r->guid = talloc_strdup(mem_ctx, "");
3759 r->action = DSPRINT_UNPUBLISH;
3761 W_ERROR_HAVE_NO_MEMORY(r->guid);
3763 TALLOC_FREE(server_info);
3767 /********************************************************************
3768 * construct_printer_info8
3769 * fill a spoolss_PrinterInfo8 struct
3770 ********************************************************************/
3772 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3773 const struct spoolss_PrinterInfo2 *info2,
3774 struct spoolss_DeviceModeInfo *r,
3777 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3779 DEBUG(8,("Returning NULL Devicemode!\n"));
3786 /********************************************************************
3787 ********************************************************************/
3789 static bool snum_is_shared_printer(int snum)
3791 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3794 /********************************************************************
3795 Spoolss_enumprinters.
3796 ********************************************************************/
3798 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3799 struct auth_serversupplied_info *server_info,
3802 union spoolss_PrinterInfo **info_p,
3806 int n_services = lp_numservices();
3807 union spoolss_PrinterInfo *info = NULL;
3809 WERROR result = WERR_OK;
3814 for (snum = 0; snum < n_services; snum++) {
3816 const char *printer;
3817 struct spoolss_PrinterInfo2 *info2;
3819 if (!snum_is_shared_printer(snum)) {
3823 printer = lp_const_servicename(snum);
3825 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3828 result = winreg_create_printer(mem_ctx,
3830 smbd_messaging_context(),
3833 if (!W_ERROR_IS_OK(result)) {
3837 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3838 union spoolss_PrinterInfo,
3841 result = WERR_NOMEM;
3845 result = winreg_get_printer(mem_ctx, server_info,
3846 smbd_messaging_context(),
3847 NULL, printer, &info2);
3848 if (!W_ERROR_IS_OK(result)) {
3854 result = construct_printer_info0(info, server_info, info2,
3855 &info[count].info0, snum);
3858 result = construct_printer_info1(info, info2, flags,
3859 &info[count].info1, snum);
3862 result = construct_printer_info2(info, info2,
3863 &info[count].info2, snum);
3866 result = construct_printer_info4(info, info2,
3867 &info[count].info4, snum);
3870 result = construct_printer_info5(info, info2,
3871 &info[count].info5, snum);
3875 result = WERR_UNKNOWN_LEVEL;
3879 if (!W_ERROR_IS_OK(result)) {
3890 if (!W_ERROR_IS_OK(result)) {
3900 /********************************************************************
3901 * handle enumeration of printers at level 0
3902 ********************************************************************/
3904 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3905 struct auth_serversupplied_info *server_info,
3907 const char *servername,
3908 union spoolss_PrinterInfo **info,
3911 DEBUG(4,("enum_all_printers_info_0\n"));
3913 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3917 /********************************************************************
3918 ********************************************************************/
3920 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3921 struct auth_serversupplied_info *server_info,
3923 union spoolss_PrinterInfo **info,
3926 DEBUG(4,("enum_all_printers_info_1\n"));
3928 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3931 /********************************************************************
3932 enum_all_printers_info_1_local.
3933 *********************************************************************/
3935 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3936 struct auth_serversupplied_info *server_info,
3937 union spoolss_PrinterInfo **info,
3940 DEBUG(4,("enum_all_printers_info_1_local\n"));
3942 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3945 /********************************************************************
3946 enum_all_printers_info_1_name.
3947 *********************************************************************/
3949 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3950 struct auth_serversupplied_info *server_info,
3952 union spoolss_PrinterInfo **info,
3955 const char *s = name;
3957 DEBUG(4,("enum_all_printers_info_1_name\n"));
3959 if ((name[0] == '\\') && (name[1] == '\\')) {
3963 if (!is_myname_or_ipaddr(s)) {
3964 return WERR_INVALID_NAME;
3967 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3970 /********************************************************************
3971 enum_all_printers_info_1_network.
3972 *********************************************************************/
3974 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3975 struct auth_serversupplied_info *server_info,
3977 union spoolss_PrinterInfo **info,
3980 const char *s = name;
3982 DEBUG(4,("enum_all_printers_info_1_network\n"));
3984 /* If we respond to a enum_printers level 1 on our name with flags
3985 set to PRINTER_ENUM_REMOTE with a list of printers then these
3986 printers incorrectly appear in the APW browse list.
3987 Specifically the printers for the server appear at the workgroup
3988 level where all the other servers in the domain are
3989 listed. Windows responds to this call with a
3990 WERR_CAN_NOT_COMPLETE so we should do the same. */
3992 if (name[0] == '\\' && name[1] == '\\') {
3996 if (is_myname_or_ipaddr(s)) {
3997 return WERR_CAN_NOT_COMPLETE;
4000 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
4003 /********************************************************************
4004 * api_spoolss_enumprinters
4006 * called from api_spoolss_enumprinters (see this to understand)
4007 ********************************************************************/
4009 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4010 struct auth_serversupplied_info *server_info,
4011 union spoolss_PrinterInfo **info,
4014 DEBUG(4,("enum_all_printers_info_2\n"));
4016 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
4019 /********************************************************************
4020 * handle enumeration of printers at level 1
4021 ********************************************************************/
4023 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4024 struct auth_serversupplied_info *server_info,
4027 union spoolss_PrinterInfo **info,
4030 /* Not all the flags are equals */
4032 if (flags & PRINTER_ENUM_LOCAL) {
4033 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4036 if (flags & PRINTER_ENUM_NAME) {
4037 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4040 if (flags & PRINTER_ENUM_NETWORK) {
4041 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4044 return WERR_OK; /* NT4sp5 does that */
4047 /********************************************************************
4048 * handle enumeration of printers at level 2
4049 ********************************************************************/
4051 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4052 struct auth_serversupplied_info *server_info,
4054 const char *servername,
4055 union spoolss_PrinterInfo **info,
4058 if (flags & PRINTER_ENUM_LOCAL) {
4059 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4062 if (flags & PRINTER_ENUM_NAME) {
4063 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4064 return WERR_INVALID_NAME;
4067 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4070 if (flags & PRINTER_ENUM_REMOTE) {
4071 return WERR_UNKNOWN_LEVEL;
4077 /********************************************************************
4078 * handle enumeration of printers at level 4
4079 ********************************************************************/
4081 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4082 struct auth_serversupplied_info *server_info,
4084 const char *servername,
4085 union spoolss_PrinterInfo **info,
4088 DEBUG(4,("enum_all_printers_info_4\n"));
4090 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4094 /********************************************************************
4095 * handle enumeration of printers at level 5
4096 ********************************************************************/
4098 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4099 struct auth_serversupplied_info *server_info,
4101 const char *servername,
4102 union spoolss_PrinterInfo **info,
4105 DEBUG(4,("enum_all_printers_info_5\n"));
4107 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4110 /****************************************************************
4111 _spoolss_EnumPrinters
4112 ****************************************************************/
4114 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4115 struct spoolss_EnumPrinters *r)
4117 const char *name = NULL;
4120 /* that's an [in out] buffer */
4122 if (!r->in.buffer && (r->in.offered != 0)) {
4123 return WERR_INVALID_PARAM;
4126 DEBUG(4,("_spoolss_EnumPrinters\n"));
4130 *r->out.info = NULL;
4134 * flags==PRINTER_ENUM_NAME
4135 * if name=="" then enumerates all printers
4136 * if name!="" then enumerate the printer
4137 * flags==PRINTER_ENUM_REMOTE
4138 * name is NULL, enumerate printers
4139 * Level 2: name!="" enumerates printers, name can't be NULL
4140 * Level 3: doesn't exist
4141 * Level 4: does a local registry lookup
4142 * Level 5: same as Level 2
4146 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4147 W_ERROR_HAVE_NO_MEMORY(name);
4150 switch (r->in.level) {
4152 result = enumprinters_level0(p->mem_ctx, p->server_info,
4154 r->out.info, r->out.count);
4157 result = enumprinters_level1(p->mem_ctx, p->server_info,
4159 r->out.info, r->out.count);
4162 result = enumprinters_level2(p->mem_ctx, p->server_info,
4164 r->out.info, r->out.count);
4167 result = enumprinters_level4(p->mem_ctx, p->server_info,
4169 r->out.info, r->out.count);
4172 result = enumprinters_level5(p->mem_ctx, p->server_info,
4174 r->out.info, r->out.count);
4177 return WERR_UNKNOWN_LEVEL;
4180 if (!W_ERROR_IS_OK(result)) {
4184 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4185 spoolss_EnumPrinters,
4186 *r->out.info, r->in.level,
4188 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4189 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4191 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4194 /****************************************************************
4196 ****************************************************************/
4198 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4199 struct spoolss_GetPrinter *r)
4201 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4202 struct spoolss_PrinterInfo2 *info2 = NULL;
4203 WERROR result = WERR_OK;
4204 const char *servername = NULL;
4207 /* that's an [in out] buffer */
4209 if (!r->in.buffer && (r->in.offered != 0)) {
4210 return WERR_INVALID_PARAM;
4215 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4219 if (Printer != NULL || Printer->servername != NULL) {
4220 servername = Printer->servername;
4223 result = winreg_get_printer(p->mem_ctx,
4227 lp_const_servicename(snum),
4229 if (!W_ERROR_IS_OK(result)) {
4233 switch (r->in.level) {
4235 result = construct_printer_info0(p->mem_ctx, p->server_info,
4237 &r->out.info->info0, snum);
4240 result = construct_printer_info1(p->mem_ctx, info2,
4242 &r->out.info->info1, snum);
4245 result = construct_printer_info2(p->mem_ctx, info2,
4246 &r->out.info->info2, snum);
4249 result = construct_printer_info3(p->mem_ctx, info2,
4250 &r->out.info->info3, snum);
4253 result = construct_printer_info4(p->mem_ctx, info2,
4254 &r->out.info->info4, snum);
4257 result = construct_printer_info5(p->mem_ctx, info2,
4258 &r->out.info->info5, snum);
4261 result = construct_printer_info6(p->mem_ctx, info2,
4262 &r->out.info->info6, snum);
4265 result = construct_printer_info7(p->mem_ctx, Printer,
4266 &r->out.info->info7, snum);
4269 result = construct_printer_info8(p->mem_ctx, info2,
4270 &r->out.info->info8, snum);
4273 result = WERR_UNKNOWN_LEVEL;
4277 if (!W_ERROR_IS_OK(result)) {
4278 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4279 r->in.level, win_errstr(result)));
4280 TALLOC_FREE(r->out.info);
4284 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4285 r->out.info, r->in.level);
4286 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4288 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4291 /********************************************************************
4292 ********************************************************************/
4294 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4296 if (in && strlen(in)) { \
4297 out = talloc_strdup(mem_ctx, in); \
4299 out = talloc_strdup(mem_ctx, ""); \
4301 W_ERROR_HAVE_NO_MEMORY(out); \
4304 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4306 if (in && strlen(in)) { \
4307 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4309 out = talloc_strdup(mem_ctx, ""); \
4311 W_ERROR_HAVE_NO_MEMORY(out); \
4314 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4315 const char **string_array,
4316 const char ***presult,
4317 const char *cservername,
4321 int i, num_strings = 0;
4322 const char **array = NULL;
4324 if (string_array == NULL) {
4325 return WERR_INVALID_PARAMETER;;
4328 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4329 const char *str = NULL;
4331 if (cservername == NULL || arch == NULL) {
4332 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4334 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4337 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4344 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4345 &array, &num_strings);
4355 /********************************************************************
4356 * fill a spoolss_DriverInfo1 struct
4357 ********************************************************************/
4359 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4360 struct spoolss_DriverInfo1 *r,
4361 const struct spoolss_DriverInfo8 *driver,
4362 const char *servername)
4364 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4365 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4370 /********************************************************************
4371 * fill a spoolss_DriverInfo2 struct
4372 ********************************************************************/
4374 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4375 struct spoolss_DriverInfo2 *r,
4376 const struct spoolss_DriverInfo8 *driver,
4377 const char *servername)
4380 const char *cservername = canon_servername(servername);
4382 r->version = driver->version;
4384 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4385 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4386 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4387 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4389 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4390 driver->architecture,
4392 driver->driver_path,
4395 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4396 driver->architecture,
4401 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4402 driver->architecture,
4404 driver->config_file,
4410 /********************************************************************
4411 * fill a spoolss_DriverInfo3 struct
4412 ********************************************************************/
4414 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4415 struct spoolss_DriverInfo3 *r,
4416 const struct spoolss_DriverInfo8 *driver,
4417 const char *servername)
4419 const char *cservername = canon_servername(servername);
4421 r->version = driver->version;
4423 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4424 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4425 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4426 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4428 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4429 driver->architecture,
4431 driver->driver_path,
4434 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4435 driver->architecture,
4440 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4441 driver->architecture,
4443 driver->config_file,
4446 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4447 driver->architecture,
4452 FILL_DRIVER_STRING(mem_ctx,
4453 driver->monitor_name,
4456 FILL_DRIVER_STRING(mem_ctx,
4457 driver->default_datatype,
4458 r->default_datatype);
4460 return string_array_from_driver_info(mem_ctx,
4461 driver->dependent_files,
4462 &r->dependent_files,
4464 driver->architecture,
4468 /********************************************************************
4469 * fill a spoolss_DriverInfo4 struct
4470 ********************************************************************/
4472 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4473 struct spoolss_DriverInfo4 *r,
4474 const struct spoolss_DriverInfo8 *driver,
4475 const char *servername)
4477 const char *cservername = canon_servername(servername);
4480 r->version = driver->version;
4482 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4483 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4484 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4485 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4487 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4488 driver->architecture,
4490 driver->driver_path,
4493 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4494 driver->architecture,
4499 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4500 driver->architecture,
4502 driver->config_file,
4505 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4506 driver->architecture,
4511 result = string_array_from_driver_info(mem_ctx,
4512 driver->dependent_files,
4513 &r->dependent_files,
4515 driver->architecture,
4517 if (!W_ERROR_IS_OK(result)) {
4521 FILL_DRIVER_STRING(mem_ctx,
4522 driver->monitor_name,
4525 FILL_DRIVER_STRING(mem_ctx,
4526 driver->default_datatype,
4527 r->default_datatype);
4530 result = string_array_from_driver_info(mem_ctx,
4531 driver->previous_names,
4538 /********************************************************************
4539 * fill a spoolss_DriverInfo5 struct
4540 ********************************************************************/
4542 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4543 struct spoolss_DriverInfo5 *r,
4544 const struct spoolss_DriverInfo8 *driver,
4545 const char *servername)
4547 const char *cservername = canon_servername(servername);
4549 r->version = driver->version;
4551 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4552 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4553 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4554 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4556 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4557 driver->architecture,
4559 driver->driver_path,
4562 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4563 driver->architecture,
4568 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4569 driver->architecture,
4571 driver->config_file,
4574 r->driver_attributes = 0;
4575 r->config_version = 0;
4576 r->driver_version = 0;
4580 /********************************************************************
4581 * fill a spoolss_DriverInfo6 struct
4582 ********************************************************************/
4584 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4585 struct spoolss_DriverInfo6 *r,
4586 const struct spoolss_DriverInfo8 *driver,
4587 const char *servername)
4589 const char *cservername = canon_servername(servername);
4592 r->version = driver->version;
4594 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4595 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4596 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4597 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4599 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4600 driver->architecture,
4602 driver->driver_path,
4605 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4606 driver->architecture,
4611 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4612 driver->architecture,
4614 driver->config_file,
4617 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4618 driver->architecture,
4623 FILL_DRIVER_STRING(mem_ctx,
4624 driver->monitor_name,
4627 FILL_DRIVER_STRING(mem_ctx,
4628 driver->default_datatype,
4629 r->default_datatype);
4631 result = string_array_from_driver_info(mem_ctx,
4632 driver->dependent_files,
4633 &r->dependent_files,
4635 driver->architecture,
4637 if (!W_ERROR_IS_OK(result)) {
4641 result = string_array_from_driver_info(mem_ctx,
4642 driver->previous_names,
4645 if (!W_ERROR_IS_OK(result)) {
4649 r->driver_date = driver->driver_date;
4650 r->driver_version = driver->driver_version;
4652 FILL_DRIVER_STRING(mem_ctx,
4653 driver->manufacturer_name,
4654 r->manufacturer_name);
4655 FILL_DRIVER_STRING(mem_ctx,
4656 driver->manufacturer_url,
4657 r->manufacturer_url);
4658 FILL_DRIVER_STRING(mem_ctx,
4659 driver->hardware_id,
4661 FILL_DRIVER_STRING(mem_ctx,
4668 /********************************************************************
4669 * fill a spoolss_DriverInfo8 struct
4670 ********************************************************************/
4672 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4673 struct spoolss_DriverInfo8 *r,
4674 const struct spoolss_DriverInfo8 *driver,
4675 const char *servername)
4677 const char *cservername = canon_servername(servername);
4680 r->version = driver->version;
4682 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4683 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4684 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4685 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4687 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4688 driver->architecture,
4690 driver->driver_path,
4693 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4694 driver->architecture,
4699 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4700 driver->architecture,
4702 driver->config_file,
4705 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4706 driver->architecture,
4711 FILL_DRIVER_STRING(mem_ctx,
4712 driver->monitor_name,
4715 FILL_DRIVER_STRING(mem_ctx,
4716 driver->default_datatype,
4717 r->default_datatype);
4719 result = string_array_from_driver_info(mem_ctx,
4720 driver->dependent_files,
4721 &r->dependent_files,
4723 driver->architecture,
4725 if (!W_ERROR_IS_OK(result)) {
4729 result = string_array_from_driver_info(mem_ctx,
4730 driver->previous_names,
4733 if (!W_ERROR_IS_OK(result)) {
4737 r->driver_date = driver->driver_date;
4738 r->driver_version = driver->driver_version;
4740 FILL_DRIVER_STRING(mem_ctx,
4741 driver->manufacturer_name,
4742 r->manufacturer_name);
4743 FILL_DRIVER_STRING(mem_ctx,
4744 driver->manufacturer_url,
4745 r->manufacturer_url);
4746 FILL_DRIVER_STRING(mem_ctx,
4747 driver->hardware_id,
4749 FILL_DRIVER_STRING(mem_ctx,
4753 FILL_DRIVER_STRING(mem_ctx,
4754 driver->print_processor,
4755 r->print_processor);
4756 FILL_DRIVER_STRING(mem_ctx,
4757 driver->vendor_setup,
4760 result = string_array_from_driver_info(mem_ctx,
4761 driver->color_profiles,
4764 if (!W_ERROR_IS_OK(result)) {
4768 FILL_DRIVER_STRING(mem_ctx,
4772 r->printer_driver_attributes = driver->printer_driver_attributes;
4774 result = string_array_from_driver_info(mem_ctx,
4775 driver->core_driver_dependencies,
4776 &r->core_driver_dependencies,
4778 if (!W_ERROR_IS_OK(result)) {
4782 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4783 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4788 #if 0 /* disabled until marshalling issues are resolved - gd */
4789 /********************************************************************
4790 ********************************************************************/
4792 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4793 struct spoolss_DriverFileInfo *r,
4794 const char *cservername,
4795 const char *file_name,
4796 enum spoolss_DriverFileType file_type,
4797 uint32_t file_version)
4799 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4800 cservername, file_name);
4801 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4802 r->file_type = file_type;
4803 r->file_version = file_version;
4808 /********************************************************************
4809 ********************************************************************/
4811 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4812 const struct spoolss_DriverInfo8 *driver,
4813 const char *cservername,
4814 struct spoolss_DriverFileInfo **info_p,
4817 struct spoolss_DriverFileInfo *info = NULL;
4825 if (strlen(driver->driver_path)) {
4826 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4827 struct spoolss_DriverFileInfo,
4829 W_ERROR_HAVE_NO_MEMORY(info);
4830 result = fill_spoolss_DriverFileInfo(info,
4833 driver->driver_path,
4834 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4836 W_ERROR_NOT_OK_RETURN(result);
4840 if (strlen(driver->config_file)) {
4841 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4842 struct spoolss_DriverFileInfo,
4844 W_ERROR_HAVE_NO_MEMORY(info);
4845 result = fill_spoolss_DriverFileInfo(info,
4848 driver->config_file,
4849 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4851 W_ERROR_NOT_OK_RETURN(result);
4855 if (strlen(driver->data_file)) {
4856 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4857 struct spoolss_DriverFileInfo,
4859 W_ERROR_HAVE_NO_MEMORY(info);
4860 result = fill_spoolss_DriverFileInfo(info,
4864 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4866 W_ERROR_NOT_OK_RETURN(result);
4870 if (strlen(driver->help_file)) {
4871 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4872 struct spoolss_DriverFileInfo,
4874 W_ERROR_HAVE_NO_MEMORY(info);
4875 result = fill_spoolss_DriverFileInfo(info,
4879 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4881 W_ERROR_NOT_OK_RETURN(result);
4885 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4886 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4887 struct spoolss_DriverFileInfo,
4889 W_ERROR_HAVE_NO_MEMORY(info);
4890 result = fill_spoolss_DriverFileInfo(info,
4893 driver->dependent_files[i],
4894 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4896 W_ERROR_NOT_OK_RETURN(result);
4906 /********************************************************************
4907 * fill a spoolss_DriverInfo101 struct
4908 ********************************************************************/
4910 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4911 struct spoolss_DriverInfo101 *r,
4912 const struct spoolss_DriverInfo8 *driver,
4913 const char *servername)
4915 const char *cservername = canon_servername(servername);
4918 r->version = driver->version;
4920 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4921 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4922 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4923 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4925 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4929 if (!W_ERROR_IS_OK(result)) {
4933 FILL_DRIVER_STRING(mem_ctx,
4934 driver->monitor_name,
4937 FILL_DRIVER_STRING(mem_ctx,
4938 driver->default_datatype,
4939 r->default_datatype);
4941 result = string_array_from_driver_info(mem_ctx,
4942 driver->previous_names,
4945 if (!W_ERROR_IS_OK(result)) {
4949 r->driver_date = driver->driver_date;
4950 r->driver_version = driver->driver_version;
4952 FILL_DRIVER_STRING(mem_ctx,
4953 driver->manufacturer_name,
4954 r->manufacturer_name);
4955 FILL_DRIVER_STRING(mem_ctx,
4956 driver->manufacturer_url,
4957 r->manufacturer_url);
4958 FILL_DRIVER_STRING(mem_ctx,
4959 driver->hardware_id,
4961 FILL_DRIVER_STRING(mem_ctx,
4968 /********************************************************************
4969 ********************************************************************/
4971 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4972 struct auth_serversupplied_info *server_info,
4974 union spoolss_DriverInfo *r,
4976 const char *servername,
4977 const char *architecture,
4980 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4981 struct spoolss_DriverInfo8 *driver;
4984 result = winreg_get_printer(mem_ctx,
4986 smbd_messaging_context(),
4988 lp_const_servicename(snum),
4991 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4992 win_errstr(result)));
4994 if (!W_ERROR_IS_OK(result)) {
4995 return WERR_INVALID_PRINTER_NAME;
4998 result = winreg_get_driver(mem_ctx, server_info,
4999 smbd_messaging_context(),
5001 pinfo2->drivername, version, &driver);
5003 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5004 win_errstr(result)));
5006 if (!W_ERROR_IS_OK(result)) {
5008 * Is this a W2k client ?
5012 talloc_free(pinfo2);
5013 return WERR_UNKNOWN_PRINTER_DRIVER;
5016 /* Yes - try again with a WinNT driver. */
5018 result = winreg_get_driver(mem_ctx, server_info,
5019 smbd_messaging_context(),
5023 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5024 win_errstr(result)));
5025 if (!W_ERROR_IS_OK(result)) {
5026 talloc_free(pinfo2);
5027 return WERR_UNKNOWN_PRINTER_DRIVER;
5033 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5036 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5039 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5042 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5045 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5048 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5051 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5053 #if 0 /* disabled until marshalling issues are resolved - gd */
5055 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5059 result = WERR_UNKNOWN_LEVEL;
5063 talloc_free(pinfo2);
5064 talloc_free(driver);
5069 /****************************************************************
5070 _spoolss_GetPrinterDriver2
5071 ****************************************************************/
5073 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5074 struct spoolss_GetPrinterDriver2 *r)
5076 Printer_entry *printer;
5081 /* that's an [in out] buffer */
5083 if (!r->in.buffer && (r->in.offered != 0)) {
5084 return WERR_INVALID_PARAM;
5087 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5089 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5090 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5091 return WERR_INVALID_PRINTER_NAME;
5095 *r->out.server_major_version = 0;
5096 *r->out.server_minor_version = 0;
5098 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5102 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5103 r->in.level, r->out.info,
5104 snum, printer->servername,
5106 r->in.client_major_version);
5107 if (!W_ERROR_IS_OK(result)) {
5108 TALLOC_FREE(r->out.info);
5112 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5113 r->out.info, r->in.level);
5114 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5116 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5120 /****************************************************************
5121 _spoolss_StartPagePrinter
5122 ****************************************************************/
5124 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5125 struct spoolss_StartPagePrinter *r)
5127 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5130 DEBUG(3,("_spoolss_StartPagePrinter: "
5131 "Error in startpageprinter printer handle\n"));
5135 Printer->page_started = true;
5139 /****************************************************************
5140 _spoolss_EndPagePrinter
5141 ****************************************************************/
5143 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5144 struct spoolss_EndPagePrinter *r)
5148 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5151 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5152 OUR_HANDLE(r->in.handle)));
5156 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5159 Printer->page_started = false;
5160 print_job_endpage(snum, Printer->jobid);
5165 /****************************************************************
5166 _spoolss_StartDocPrinter
5167 ****************************************************************/
5169 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5170 struct spoolss_StartDocPrinter *r)
5172 struct spoolss_DocumentInfo1 *info_1;
5174 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5178 DEBUG(2,("_spoolss_StartDocPrinter: "
5179 "Invalid handle (%s:%u:%u)\n",
5180 OUR_HANDLE(r->in.handle)));
5184 if (Printer->jobid) {
5185 DEBUG(2, ("_spoolss_StartDocPrinter: "
5186 "StartDocPrinter called twice! "
5187 "(existing jobid = %d)\n", Printer->jobid));
5188 return WERR_INVALID_HANDLE;
5191 if (r->in.level != 1) {
5192 return WERR_UNKNOWN_LEVEL;
5195 info_1 = r->in.info.info1;
5198 * a nice thing with NT is it doesn't listen to what you tell it.
5199 * when asked to send _only_ RAW datas, it tries to send datas
5202 * So I add checks like in NT Server ...
5205 if (info_1->datatype) {
5206 if (strcmp(info_1->datatype, "RAW") != 0) {
5208 return WERR_INVALID_DATATYPE;
5212 /* get the share number of the printer */
5213 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5217 werr = print_job_start(p->server_info, snum,
5218 info_1->document_name, info_1->output_file,
5219 Printer->devmode, &Printer->jobid);
5221 /* An error occured in print_job_start() so return an appropriate
5224 if (!W_ERROR_IS_OK(werr)) {
5228 Printer->document_started = true;
5229 *r->out.job_id = Printer->jobid;
5234 /****************************************************************
5235 _spoolss_EndDocPrinter
5236 ****************************************************************/
5238 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5239 struct spoolss_EndDocPrinter *r)
5241 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5246 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5247 OUR_HANDLE(r->in.handle)));
5251 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5255 Printer->document_started = false;
5256 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5257 if (!NT_STATUS_IS_OK(status)) {
5258 DEBUG(2, ("_spoolss_EndDocPrinter: "
5259 "print_job_end failed [%s]\n",
5260 nt_errstr(status)));
5264 return ntstatus_to_werror(status);
5267 /****************************************************************
5268 _spoolss_WritePrinter
5269 ****************************************************************/
5271 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5272 struct spoolss_WritePrinter *r)
5274 ssize_t buffer_written;
5276 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5279 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5280 OUR_HANDLE(r->in.handle)));
5281 *r->out.num_written = r->in._data_size;
5285 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5288 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5289 buffer_written = print_job_write(snum, Printer->jobid,
5290 (const char *)r->in.data.data,
5292 (size_t)r->in._data_size);
5293 if (buffer_written == (ssize_t)-1) {
5294 *r->out.num_written = 0;
5295 if (errno == ENOSPC)
5296 return WERR_NO_SPOOL_SPACE;
5298 return WERR_ACCESS_DENIED;
5301 *r->out.num_written = r->in._data_size;
5306 /********************************************************************
5307 * api_spoolss_getprinter
5308 * called from the spoolss dispatcher
5310 ********************************************************************/
5312 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5313 struct pipes_struct *p)
5316 WERROR errcode = WERR_BADFUNC;
5317 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5320 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5321 OUR_HANDLE(handle)));
5325 if (!get_printer_snum(p, handle, &snum, NULL))
5329 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5330 errcode = print_queue_pause(p->server_info, snum);
5332 case SPOOLSS_PRINTER_CONTROL_RESUME:
5333 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5334 errcode = print_queue_resume(p->server_info, snum);
5336 case SPOOLSS_PRINTER_CONTROL_PURGE:
5337 errcode = print_queue_purge(p->server_info, snum);
5340 return WERR_UNKNOWN_LEVEL;
5347 /****************************************************************
5348 _spoolss_AbortPrinter
5349 * From MSDN: "Deletes printer's spool file if printer is configured
5351 ****************************************************************/
5353 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5354 struct spoolss_AbortPrinter *r)
5356 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5358 WERROR errcode = WERR_OK;
5361 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5362 OUR_HANDLE(r->in.handle)));
5366 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5369 if (!Printer->document_started) {
5370 return WERR_SPL_NO_STARTDOC;
5373 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5378 /********************************************************************
5379 * called by spoolss_api_setprinter
5380 * when updating a printer description
5381 ********************************************************************/
5383 static WERROR update_printer_sec(struct policy_handle *handle,
5384 struct pipes_struct *p,
5385 struct sec_desc_buf *secdesc_ctr)
5387 struct spoolss_security_descriptor *new_secdesc = NULL;
5388 struct spoolss_security_descriptor *old_secdesc = NULL;
5389 const char *printer;
5393 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5395 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5396 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5397 OUR_HANDLE(handle)));
5399 result = WERR_BADFID;
5403 if (secdesc_ctr == NULL) {
5404 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5405 result = WERR_INVALID_PARAM;
5408 printer = lp_const_servicename(snum);
5410 /* Check the user has permissions to change the security
5411 descriptor. By experimentation with two NT machines, the user
5412 requires Full Access to the printer to change security
5415 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5416 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5417 result = WERR_ACCESS_DENIED;
5421 /* NT seems to like setting the security descriptor even though
5422 nothing may have actually changed. */
5423 result = winreg_get_printer_secdesc(p->mem_ctx,
5428 if (!W_ERROR_IS_OK(result)) {
5429 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5430 result = WERR_BADFID;
5434 if (DEBUGLEVEL >= 10) {
5435 struct security_acl *the_acl;
5438 the_acl = old_secdesc->dacl;
5439 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5440 printer, the_acl->num_aces));
5442 for (i = 0; i < the_acl->num_aces; i++) {
5443 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5444 &the_acl->aces[i].trustee),
5445 the_acl->aces[i].access_mask));
5448 the_acl = secdesc_ctr->sd->dacl;
5451 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5452 printer, the_acl->num_aces));
5454 for (i = 0; i < the_acl->num_aces; i++) {
5455 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5456 &the_acl->aces[i].trustee),
5457 the_acl->aces[i].access_mask));
5460 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5464 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5465 if (new_secdesc == NULL) {
5466 result = WERR_NOMEM;
5470 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5475 result = winreg_set_printer_secdesc(p->mem_ctx,
5485 /********************************************************************
5486 Canonicalize printer info from a client
5487 ********************************************************************/
5489 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5490 struct spoolss_SetPrinterInfo2 *info2,
5493 fstring printername;
5496 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5497 "portname=%s drivername=%s comment=%s location=%s\n",
5498 info2->servername, info2->printername, info2->sharename,
5499 info2->portname, info2->drivername, info2->comment,
5502 /* we force some elements to "correct" values */
5503 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5504 if (info2->servername == NULL) {
5507 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5508 if (info2->sharename == NULL) {
5512 /* check to see if we allow printername != sharename */
5513 if (lp_force_printername(snum)) {
5514 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5515 global_myname(), info2->sharename);
5517 /* make sure printername is in \\server\printername format */
5518 fstrcpy(printername, info2->printername);
5520 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5521 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5525 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5526 global_myname(), p);
5528 if (info2->printername == NULL) {
5532 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5533 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5538 /****************************************************************************
5539 ****************************************************************************/
5541 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5543 char *cmd = lp_addport_cmd();
5544 char *command = NULL;
5546 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5547 bool is_print_op = false;
5550 return WERR_ACCESS_DENIED;
5553 command = talloc_asprintf(ctx,
5554 "%s \"%s\" \"%s\"", cmd, portname, uri );
5560 is_print_op = user_has_privileges( token, &se_printop );
5562 DEBUG(10,("Running [%s]\n", command));
5564 /********* BEGIN SePrintOperatorPrivilege **********/
5569 ret = smbrun(command, NULL);
5574 /********* END SePrintOperatorPrivilege **********/
5576 DEBUGADD(10,("returned [%d]\n", ret));
5578 TALLOC_FREE(command);
5581 return WERR_ACCESS_DENIED;
5587 /****************************************************************************
5588 ****************************************************************************/
5590 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5591 struct spoolss_SetPrinterInfo2 *info2,
5592 const char *remote_machine,
5593 struct messaging_context *msg_ctx)
5595 char *cmd = lp_addprinter_cmd();
5597 char *command = NULL;
5601 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5602 bool is_print_op = false;
5604 if (!remote_machine) {
5608 command = talloc_asprintf(ctx,
5609 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5610 cmd, info2->printername, info2->sharename,
5611 info2->portname, info2->drivername,
5612 info2->location, info2->comment, remote_machine);
5618 is_print_op = user_has_privileges( token, &se_printop );
5620 DEBUG(10,("Running [%s]\n", command));
5622 /********* BEGIN SePrintOperatorPrivilege **********/
5627 if ( (ret = smbrun(command, &fd)) == 0 ) {
5628 /* Tell everyone we updated smb.conf. */
5629 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5635 /********* END SePrintOperatorPrivilege **********/
5637 DEBUGADD(10,("returned [%d]\n", ret));
5639 TALLOC_FREE(command);
5647 /* reload our services immediately */
5649 reload_services(false);
5653 /* Get lines and convert them back to dos-codepage */
5654 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5655 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5658 /* Set the portname to what the script says the portname should be. */
5659 /* but don't require anything to be return from the script exit a good error code */
5662 /* Set the portname to what the script says the portname should be. */
5663 info2->portname = talloc_strdup(ctx, qlines[0]);
5664 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5667 TALLOC_FREE(qlines);
5671 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5672 struct auth_serversupplied_info *server_info,
5674 struct spoolss_SetPrinterInfo2 *printer,
5675 struct spoolss_PrinterInfo2 *old_printer)
5677 bool force_update = (old_printer == NULL);
5678 const char *dnsdomname;
5679 const char *longname;
5680 const char *uncname;
5681 const char *spooling;
5683 WERROR result = WERR_OK;
5685 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5686 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5687 winreg_set_printer_dataex(mem_ctx,
5689 smbd_messaging_context(),
5691 SPOOL_DSSPOOLER_KEY,
5692 SPOOL_REG_DRIVERNAME,
5697 if (!force_update) {
5698 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5699 printer->drivername));
5701 notify_printer_driver(snum, printer->drivername);
5705 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5706 push_reg_sz(mem_ctx, &buffer, printer->comment);
5707 winreg_set_printer_dataex(mem_ctx,
5709 smbd_messaging_context(),
5711 SPOOL_DSSPOOLER_KEY,
5712 SPOOL_REG_DESCRIPTION,
5717 if (!force_update) {
5718 notify_printer_comment(snum, printer->comment);
5722 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5723 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5724 winreg_set_printer_dataex(mem_ctx,
5726 smbd_messaging_context(),
5728 SPOOL_DSSPOOLER_KEY,
5729 SPOOL_REG_PRINTSHARENAME,
5734 if (!force_update) {
5735 notify_printer_sharename(snum, printer->sharename);
5739 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5742 p = strrchr(printer->printername, '\\' );
5746 p = printer->printername;
5749 push_reg_sz(mem_ctx, &buffer, p);
5750 winreg_set_printer_dataex(mem_ctx,
5752 smbd_messaging_context(),
5754 SPOOL_DSSPOOLER_KEY,
5755 SPOOL_REG_PRINTERNAME,
5760 if (!force_update) {
5761 notify_printer_printername(snum, p);
5765 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5766 push_reg_sz(mem_ctx, &buffer, printer->portname);
5767 winreg_set_printer_dataex(mem_ctx,
5769 smbd_messaging_context(),
5771 SPOOL_DSSPOOLER_KEY,
5777 if (!force_update) {
5778 notify_printer_port(snum, printer->portname);
5782 if (force_update || !strequal(printer->location, old_printer->location)) {
5783 push_reg_sz(mem_ctx, &buffer, printer->location);
5784 winreg_set_printer_dataex(mem_ctx,
5786 smbd_messaging_context(),
5788 SPOOL_DSSPOOLER_KEY,
5794 if (!force_update) {
5795 notify_printer_location(snum, printer->location);
5799 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5800 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5801 winreg_set_printer_dataex(mem_ctx,
5803 smbd_messaging_context(),
5805 SPOOL_DSSPOOLER_KEY,
5806 SPOOL_REG_PRINTSEPARATORFILE,
5811 if (!force_update) {
5812 notify_printer_location(snum, printer->location);
5816 if (force_update || printer->starttime != old_printer->starttime) {
5817 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5818 SIVAL(buffer.data, 0, printer->starttime);
5819 winreg_set_printer_dataex(mem_ctx,
5821 smbd_messaging_context(),
5823 SPOOL_DSSPOOLER_KEY,
5824 SPOOL_REG_PRINTSTARTTIME,
5830 if (force_update || printer->untiltime != old_printer->untiltime) {
5831 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5832 SIVAL(buffer.data, 0, printer->untiltime);
5833 winreg_set_printer_dataex(mem_ctx,
5835 smbd_messaging_context(),
5837 SPOOL_DSSPOOLER_KEY,
5838 SPOOL_REG_PRINTENDTIME,
5844 if (force_update || printer->priority != old_printer->priority) {
5845 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5846 SIVAL(buffer.data, 0, printer->priority);
5847 winreg_set_printer_dataex(mem_ctx,
5849 smbd_messaging_context(),
5851 SPOOL_DSSPOOLER_KEY,
5858 if (force_update || printer->attributes != old_printer->attributes) {
5859 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5860 SIVAL(buffer.data, 0, (printer->attributes &
5861 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5862 winreg_set_printer_dataex(mem_ctx,
5864 smbd_messaging_context(),
5866 SPOOL_DSSPOOLER_KEY,
5867 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5872 switch (printer->attributes & 0x3) {
5874 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5877 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5880 spooling = SPOOL_REGVAL_PRINTDIRECT;
5883 spooling = "unknown";
5885 push_reg_sz(mem_ctx, &buffer, spooling);
5886 winreg_set_printer_dataex(mem_ctx,
5888 smbd_messaging_context(),
5890 SPOOL_DSSPOOLER_KEY,
5891 SPOOL_REG_PRINTSPOOLING,
5897 push_reg_sz(mem_ctx, &buffer, global_myname());
5898 winreg_set_printer_dataex(mem_ctx,
5900 smbd_messaging_context(),
5902 SPOOL_DSSPOOLER_KEY,
5903 SPOOL_REG_SHORTSERVERNAME,
5908 dnsdomname = get_mydnsfullname();
5909 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5910 longname = talloc_strdup(mem_ctx, dnsdomname);
5912 longname = talloc_strdup(mem_ctx, global_myname());
5914 if (longname == NULL) {
5915 result = WERR_NOMEM;
5919 push_reg_sz(mem_ctx, &buffer, longname);
5920 winreg_set_printer_dataex(mem_ctx,
5922 smbd_messaging_context(),
5924 SPOOL_DSSPOOLER_KEY,
5925 SPOOL_REG_SERVERNAME,
5930 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5931 global_myname(), printer->sharename);
5932 push_reg_sz(mem_ctx, &buffer, uncname);
5933 winreg_set_printer_dataex(mem_ctx,
5935 smbd_messaging_context(),
5937 SPOOL_DSSPOOLER_KEY,
5947 /********************************************************************
5948 * Called by spoolss_api_setprinter
5949 * when updating a printer description.
5950 ********************************************************************/
5952 static WERROR update_printer(struct pipes_struct *p,
5953 struct policy_handle *handle,
5954 struct spoolss_SetPrinterInfoCtr *info_ctr,
5955 struct spoolss_DeviceMode *devmode)
5957 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5958 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5959 struct spoolss_PrinterInfo2 *old_printer;
5960 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5961 const char *servername = NULL;
5963 WERROR result = WERR_OK;
5964 TALLOC_CTX *tmp_ctx;
5966 DEBUG(8,("update_printer\n"));
5968 tmp_ctx = talloc_new(p->mem_ctx);
5969 if (tmp_ctx == NULL) {
5974 result = WERR_BADFID;
5978 if (!get_printer_snum(p, handle, &snum, NULL)) {
5979 result = WERR_BADFID;
5983 if (Printer != NULL || Printer->servername != NULL) {
5984 servername = Printer->servername;
5987 result = winreg_get_printer(tmp_ctx,
5991 lp_const_servicename(snum),
5993 if (!W_ERROR_IS_OK(result)) {
5994 result = WERR_BADFID;
5998 /* Do sanity check on the requested changes for Samba */
5999 if (!check_printer_ok(tmp_ctx, printer, snum)) {
6000 result = WERR_INVALID_PARAM;
6004 /* FIXME!!! If the driver has changed we really should verify that
6005 it is installed before doing much else --jerry */
6007 /* Check calling user has permission to update printer description */
6008 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6009 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6010 result = WERR_ACCESS_DENIED;
6014 /* Call addprinter hook */
6015 /* Check changes to see if this is really needed */
6017 if (*lp_addprinter_cmd() &&
6018 (!strequal(printer->drivername, old_printer->drivername) ||
6019 !strequal(printer->comment, old_printer->comment) ||
6020 !strequal(printer->portname, old_printer->portname) ||
6021 !strequal(printer->location, old_printer->location)) )
6023 /* add_printer_hook() will call reload_services() */
6024 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6025 printer, p->client_address,
6027 result = WERR_ACCESS_DENIED;
6032 update_dsspooler(tmp_ctx,
6038 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6040 if (devmode == NULL) {
6041 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6043 result = winreg_update_printer(tmp_ctx,
6053 talloc_free(tmp_ctx);
6058 /****************************************************************************
6059 ****************************************************************************/
6060 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6061 struct policy_handle *handle,
6062 struct spoolss_SetPrinterInfo7 *info7)
6065 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6068 Printer_entry *Printer;
6070 if ( lp_security() != SEC_ADS ) {
6071 return WERR_UNKNOWN_LEVEL;
6074 Printer = find_printer_index_by_hnd(p, handle);
6076 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6081 if (!get_printer_snum(p, handle, &snum, NULL))
6084 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6085 Printer->servername,
6086 lp_servicename(snum), &pinfo2);
6087 if (!W_ERROR_IS_OK(result)) {
6091 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6093 TALLOC_FREE(pinfo2);
6096 return WERR_UNKNOWN_LEVEL;
6100 /********************************************************************
6101 ********************************************************************/
6103 static WERROR update_printer_devmode(struct pipes_struct *p,
6104 struct policy_handle *handle,
6105 struct spoolss_DeviceMode *devmode)
6108 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6109 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6111 DEBUG(8,("update_printer_devmode\n"));
6117 if (!get_printer_snum(p, handle, &snum, NULL)) {
6121 /* Check calling user has permission to update printer description */
6122 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6123 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6124 return WERR_ACCESS_DENIED;
6127 return winreg_update_printer(p->mem_ctx,
6130 lp_const_servicename(snum),
6138 /****************************************************************
6140 ****************************************************************/
6142 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6143 struct spoolss_SetPrinter *r)
6147 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6150 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6151 OUR_HANDLE(r->in.handle)));
6155 /* check the level */
6156 switch (r->in.info_ctr->level) {
6158 return control_printer(r->in.handle, r->in.command, p);
6160 result = update_printer(p, r->in.handle,
6162 r->in.devmode_ctr->devmode);
6163 if (!W_ERROR_IS_OK(result))
6165 if (r->in.secdesc_ctr->sd)
6166 result = update_printer_sec(r->in.handle, p,
6170 return update_printer_sec(r->in.handle, p,
6173 return publish_or_unpublish_printer(p, r->in.handle,
6174 r->in.info_ctr->info.info7);
6176 return update_printer_devmode(p, r->in.handle,
6177 r->in.devmode_ctr->devmode);
6179 return WERR_UNKNOWN_LEVEL;
6183 /****************************************************************
6184 _spoolss_FindClosePrinterNotify
6185 ****************************************************************/
6187 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6188 struct spoolss_FindClosePrinterNotify *r)
6190 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6193 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6194 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6198 if (Printer->notify.client_connected == true) {
6201 if ( Printer->printer_type == SPLHND_SERVER)
6203 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6204 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6207 srv_spoolss_replycloseprinter(
6208 snum, &Printer->notify.client_hnd, p->msg_ctx);
6211 Printer->notify.flags=0;
6212 Printer->notify.options=0;
6213 Printer->notify.localmachine[0]='\0';
6214 Printer->notify.printerlocal=0;
6215 TALLOC_FREE(Printer->notify.option);
6216 Printer->notify.client_connected = false;
6221 /****************************************************************
6223 ****************************************************************/
6225 WERROR _spoolss_AddJob(struct pipes_struct *p,
6226 struct spoolss_AddJob *r)
6228 if (!r->in.buffer && (r->in.offered != 0)) {
6229 return WERR_INVALID_PARAM;
6232 /* this is what a NT server returns for AddJob. AddJob must fail on
6233 * non-local printers */
6235 if (r->in.level != 1) {
6236 return WERR_UNKNOWN_LEVEL;
6239 return WERR_INVALID_PARAM;
6242 /****************************************************************************
6244 ****************************************************************************/
6246 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6247 struct spoolss_JobInfo1 *r,
6248 const print_queue_struct *queue,
6249 int position, int snum,
6250 struct spoolss_PrinterInfo2 *pinfo2)
6254 t = gmtime(&queue->time);
6256 r->job_id = queue->job;
6258 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6259 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6260 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6261 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6262 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6263 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6264 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6265 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6266 r->data_type = talloc_strdup(mem_ctx, "RAW");
6267 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6268 r->text_status = talloc_strdup(mem_ctx, "");
6269 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6271 r->status = nt_printj_status(queue->status);
6272 r->priority = queue->priority;
6273 r->position = position;
6274 r->total_pages = queue->page_count;
6275 r->pages_printed = 0; /* ??? */
6277 init_systemtime(&r->submitted, t);
6282 /****************************************************************************
6284 ****************************************************************************/
6286 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6287 struct spoolss_JobInfo2 *r,
6288 const print_queue_struct *queue,
6289 int position, int snum,
6290 struct spoolss_PrinterInfo2 *pinfo2,
6291 struct spoolss_DeviceMode *devmode)
6295 t = gmtime(&queue->time);
6297 r->job_id = queue->job;
6299 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6300 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6301 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6302 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6303 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6304 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6305 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6306 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6307 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6308 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6309 r->data_type = talloc_strdup(mem_ctx, "RAW");
6310 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6311 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6312 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6313 r->parameters = talloc_strdup(mem_ctx, "");
6314 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6315 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6316 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6318 r->devmode = devmode;
6320 r->text_status = talloc_strdup(mem_ctx, "");
6321 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6325 r->status = nt_printj_status(queue->status);
6326 r->priority = queue->priority;
6327 r->position = position;
6330 r->total_pages = queue->page_count;
6331 r->size = queue->size;
6332 init_systemtime(&r->submitted, t);
6334 r->pages_printed = 0; /* ??? */
6339 /****************************************************************************
6341 ****************************************************************************/
6343 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6344 struct spoolss_JobInfo3 *r,
6345 const print_queue_struct *queue,
6346 const print_queue_struct *next_queue,
6347 int position, int snum,
6348 struct spoolss_PrinterInfo2 *pinfo2)
6350 r->job_id = queue->job;
6353 r->next_job_id = next_queue->job;
6360 /****************************************************************************
6361 Enumjobs at level 1.
6362 ****************************************************************************/
6364 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6365 const print_queue_struct *queue,
6366 uint32_t num_queues, int snum,
6367 struct spoolss_PrinterInfo2 *pinfo2,
6368 union spoolss_JobInfo **info_p,
6371 union spoolss_JobInfo *info;
6373 WERROR result = WERR_OK;
6375 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6376 W_ERROR_HAVE_NO_MEMORY(info);
6378 *count = num_queues;
6380 for (i=0; i<*count; i++) {
6381 result = fill_job_info1(info,
6387 if (!W_ERROR_IS_OK(result)) {
6393 if (!W_ERROR_IS_OK(result)) {
6404 /****************************************************************************
6405 Enumjobs at level 2.
6406 ****************************************************************************/
6408 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6409 const print_queue_struct *queue,
6410 uint32_t num_queues, int snum,
6411 struct spoolss_PrinterInfo2 *pinfo2,
6412 union spoolss_JobInfo **info_p,
6415 union spoolss_JobInfo *info;
6417 WERROR result = WERR_OK;
6419 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6420 W_ERROR_HAVE_NO_MEMORY(info);
6422 *count = num_queues;
6424 for (i=0; i<*count; i++) {
6425 struct spoolss_DeviceMode *devmode;
6427 result = spoolss_create_default_devmode(info,
6428 pinfo2->printername,
6430 if (!W_ERROR_IS_OK(result)) {
6431 DEBUG(3, ("Can't proceed w/o a devmode!"));
6435 result = fill_job_info2(info,
6442 if (!W_ERROR_IS_OK(result)) {
6448 if (!W_ERROR_IS_OK(result)) {
6459 /****************************************************************************
6460 Enumjobs at level 3.
6461 ****************************************************************************/
6463 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6464 const print_queue_struct *queue,
6465 uint32_t num_queues, int snum,
6466 struct spoolss_PrinterInfo2 *pinfo2,
6467 union spoolss_JobInfo **info_p,
6470 union spoolss_JobInfo *info;
6472 WERROR result = WERR_OK;
6474 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6475 W_ERROR_HAVE_NO_MEMORY(info);
6477 *count = num_queues;
6479 for (i=0; i<*count; i++) {
6480 const print_queue_struct *next_queue = NULL;
6483 next_queue = &queue[i+1];
6486 result = fill_job_info3(info,
6493 if (!W_ERROR_IS_OK(result)) {
6499 if (!W_ERROR_IS_OK(result)) {
6510 /****************************************************************
6512 ****************************************************************/
6514 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6515 struct spoolss_EnumJobs *r)
6518 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6520 print_status_struct prt_status;
6521 print_queue_struct *queue = NULL;
6524 /* that's an [in out] buffer */
6526 if (!r->in.buffer && (r->in.offered != 0)) {
6527 return WERR_INVALID_PARAM;
6530 DEBUG(4,("_spoolss_EnumJobs\n"));
6534 *r->out.info = NULL;
6536 /* lookup the printer snum and tdb entry */
6538 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6542 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6543 NULL, lp_servicename(snum), &pinfo2);
6544 if (!W_ERROR_IS_OK(result)) {
6548 count = print_queue_status(snum, &queue, &prt_status);
6549 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6550 count, prt_status.status, prt_status.message));
6554 TALLOC_FREE(pinfo2);
6558 switch (r->in.level) {
6560 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6561 pinfo2, r->out.info, r->out.count);
6564 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6565 pinfo2, r->out.info, r->out.count);
6568 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6569 pinfo2, r->out.info, r->out.count);
6572 result = WERR_UNKNOWN_LEVEL;
6577 TALLOC_FREE(pinfo2);
6579 if (!W_ERROR_IS_OK(result)) {
6583 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6585 *r->out.info, r->in.level,
6587 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6588 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6590 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6593 /****************************************************************
6594 _spoolss_ScheduleJob
6595 ****************************************************************/
6597 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6598 struct spoolss_ScheduleJob *r)
6603 /****************************************************************
6604 ****************************************************************/
6606 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6607 const char *printer_name,
6609 struct spoolss_SetJobInfo1 *r)
6613 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6617 if (strequal(old_doc_name, r->document_name)) {
6621 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6628 /****************************************************************
6630 ****************************************************************/
6632 WERROR _spoolss_SetJob(struct pipes_struct *p,
6633 struct spoolss_SetJob *r)
6636 WERROR errcode = WERR_BADFUNC;
6638 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6642 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6643 return WERR_INVALID_PRINTER_NAME;
6646 switch (r->in.command) {
6647 case SPOOLSS_JOB_CONTROL_CANCEL:
6648 case SPOOLSS_JOB_CONTROL_DELETE:
6649 errcode = print_job_delete(p->server_info,
6650 snum, r->in.job_id);
6651 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6655 case SPOOLSS_JOB_CONTROL_PAUSE:
6656 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6660 case SPOOLSS_JOB_CONTROL_RESTART:
6661 case SPOOLSS_JOB_CONTROL_RESUME:
6662 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6670 return WERR_UNKNOWN_LEVEL;
6673 if (!W_ERROR_IS_OK(errcode)) {
6677 if (r->in.ctr == NULL) {
6681 switch (r->in.ctr->level) {
6683 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6685 r->in.ctr->info.info1);
6691 return WERR_UNKNOWN_LEVEL;
6697 /****************************************************************************
6698 Enumerates all printer drivers by level and architecture.
6699 ****************************************************************************/
6701 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6702 struct auth_serversupplied_info *server_info,
6703 const char *servername,
6704 const char *architecture,
6706 union spoolss_DriverInfo **info_p,
6711 struct spoolss_DriverInfo8 *driver;
6712 union spoolss_DriverInfo *info = NULL;
6714 WERROR result = WERR_OK;
6715 uint32_t num_drivers;
6716 const char **drivers;
6721 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6722 result = winreg_get_driver_list(mem_ctx, server_info,
6723 smbd_messaging_context(),
6724 architecture, version,
6725 &num_drivers, &drivers);
6726 if (!W_ERROR_IS_OK(result)) {
6729 DEBUG(4, ("we have:[%d] drivers in environment"
6730 " [%s] and version [%d]\n",
6731 num_drivers, architecture, version));
6733 if (num_drivers != 0) {
6734 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6735 union spoolss_DriverInfo,
6736 count + num_drivers);
6738 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6739 "failed to enlarge driver info buffer!\n"));
6740 result = WERR_NOMEM;
6745 for (i = 0; i < num_drivers; i++) {
6746 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6748 result = winreg_get_driver(mem_ctx, server_info,
6749 smbd_messaging_context(),
6750 architecture, drivers[i],
6752 if (!W_ERROR_IS_OK(result)) {
6758 result = fill_printer_driver_info1(info, &info[count+i].info1,
6759 driver, servername);
6762 result = fill_printer_driver_info2(info, &info[count+i].info2,
6763 driver, servername);
6766 result = fill_printer_driver_info3(info, &info[count+i].info3,
6767 driver, servername);
6770 result = fill_printer_driver_info4(info, &info[count+i].info4,
6771 driver, servername);
6774 result = fill_printer_driver_info5(info, &info[count+i].info5,
6775 driver, servername);
6778 result = fill_printer_driver_info6(info, &info[count+i].info6,
6779 driver, servername);
6782 result = fill_printer_driver_info8(info, &info[count+i].info8,
6783 driver, servername);
6786 result = WERR_UNKNOWN_LEVEL;
6790 TALLOC_FREE(driver);
6792 if (!W_ERROR_IS_OK(result)) {
6797 count += num_drivers;
6798 TALLOC_FREE(drivers);
6802 TALLOC_FREE(drivers);
6804 if (!W_ERROR_IS_OK(result)) {
6815 /****************************************************************************
6816 Enumerates all printer drivers by level.
6817 ****************************************************************************/
6819 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6820 struct auth_serversupplied_info *server_info,
6821 const char *servername,
6822 const char *architecture,
6824 union spoolss_DriverInfo **info_p,
6828 WERROR result = WERR_OK;
6830 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6832 for (a=0; archi_table[a].long_archi != NULL; a++) {
6834 union spoolss_DriverInfo *info = NULL;
6837 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6840 archi_table[a].long_archi,
6844 if (!W_ERROR_IS_OK(result)) {
6848 for (i=0; i < count; i++) {
6849 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6850 info[i], info_p, count_p);
6857 return enumprinterdrivers_level_by_architecture(mem_ctx,
6866 /****************************************************************
6867 _spoolss_EnumPrinterDrivers
6868 ****************************************************************/
6870 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6871 struct spoolss_EnumPrinterDrivers *r)
6873 const char *cservername;
6876 /* that's an [in out] buffer */
6878 if (!r->in.buffer && (r->in.offered != 0)) {
6879 return WERR_INVALID_PARAM;
6882 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6886 *r->out.info = NULL;
6888 cservername = canon_servername(r->in.server);
6890 if (!is_myname_or_ipaddr(cservername)) {
6891 return WERR_UNKNOWN_PRINTER_DRIVER;
6894 result = enumprinterdrivers_level(p->mem_ctx,
6901 if (!W_ERROR_IS_OK(result)) {
6905 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6906 spoolss_EnumPrinterDrivers,
6907 *r->out.info, r->in.level,
6909 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6910 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6912 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6915 /****************************************************************
6917 ****************************************************************/
6919 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6920 struct spoolss_EnumForms *r)
6926 *r->out.info = NULL;
6928 /* that's an [in out] buffer */
6930 if (!r->in.buffer && (r->in.offered != 0) ) {
6931 return WERR_INVALID_PARAM;
6934 DEBUG(4,("_spoolss_EnumForms\n"));
6935 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6936 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6938 switch (r->in.level) {
6940 result = winreg_printer_enumforms1(p->mem_ctx,
6947 result = WERR_UNKNOWN_LEVEL;
6951 if (!W_ERROR_IS_OK(result)) {
6955 if (*r->out.count == 0) {
6956 return WERR_NO_MORE_ITEMS;
6959 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6961 *r->out.info, r->in.level,
6963 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6964 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6966 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6969 /****************************************************************
6971 ****************************************************************/
6973 WERROR _spoolss_GetForm(struct pipes_struct *p,
6974 struct spoolss_GetForm *r)
6978 /* that's an [in out] buffer */
6980 if (!r->in.buffer && (r->in.offered != 0)) {
6981 return WERR_INVALID_PARAM;
6984 DEBUG(4,("_spoolss_GetForm\n"));
6985 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6986 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6988 switch (r->in.level) {
6990 result = winreg_printer_getform1(p->mem_ctx,
6994 &r->out.info->info1);
6997 result = WERR_UNKNOWN_LEVEL;
7001 if (!W_ERROR_IS_OK(result)) {
7002 TALLOC_FREE(r->out.info);
7006 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
7007 r->out.info, r->in.level);
7008 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7010 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7013 /****************************************************************************
7014 ****************************************************************************/
7016 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
7017 struct spoolss_PortInfo1 *r,
7020 r->port_name = talloc_strdup(mem_ctx, name);
7021 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7026 /****************************************************************************
7027 TODO: This probably needs distinguish between TCP/IP and Local ports
7029 ****************************************************************************/
7031 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7032 struct spoolss_PortInfo2 *r,
7035 r->port_name = talloc_strdup(mem_ctx, name);
7036 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7038 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7039 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7041 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7042 W_ERROR_HAVE_NO_MEMORY(r->description);
7044 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7051 /****************************************************************************
7052 wrapper around the enumer ports command
7053 ****************************************************************************/
7055 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7057 char *cmd = lp_enumports_cmd();
7058 char **qlines = NULL;
7059 char *command = NULL;
7067 /* if no hook then just fill in the default port */
7070 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7073 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7074 TALLOC_FREE(qlines);
7081 /* we have a valid enumport command */
7083 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7088 DEBUG(10,("Running [%s]\n", command));
7089 ret = smbrun(command, &fd);
7090 DEBUG(10,("Returned [%d]\n", ret));
7091 TALLOC_FREE(command);
7096 return WERR_ACCESS_DENIED;
7100 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7101 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7111 /****************************************************************************
7113 ****************************************************************************/
7115 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7116 union spoolss_PortInfo **info_p,
7119 union spoolss_PortInfo *info = NULL;
7121 WERROR result = WERR_OK;
7122 char **qlines = NULL;
7125 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7126 if (!W_ERROR_IS_OK(result)) {
7131 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7133 DEBUG(10,("Returning WERR_NOMEM\n"));
7134 result = WERR_NOMEM;
7138 for (i=0; i<numlines; i++) {
7139 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7140 result = fill_port_1(info, &info[i].info1, qlines[i]);
7141 if (!W_ERROR_IS_OK(result)) {
7146 TALLOC_FREE(qlines);
7149 if (!W_ERROR_IS_OK(result)) {
7151 TALLOC_FREE(qlines);
7163 /****************************************************************************
7165 ****************************************************************************/
7167 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7168 union spoolss_PortInfo **info_p,
7171 union spoolss_PortInfo *info = NULL;
7173 WERROR result = WERR_OK;
7174 char **qlines = NULL;
7177 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7178 if (!W_ERROR_IS_OK(result)) {
7183 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7185 DEBUG(10,("Returning WERR_NOMEM\n"));
7186 result = WERR_NOMEM;
7190 for (i=0; i<numlines; i++) {
7191 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7192 result = fill_port_2(info, &info[i].info2, qlines[i]);
7193 if (!W_ERROR_IS_OK(result)) {
7198 TALLOC_FREE(qlines);
7201 if (!W_ERROR_IS_OK(result)) {
7203 TALLOC_FREE(qlines);
7215 /****************************************************************
7217 ****************************************************************/
7219 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7220 struct spoolss_EnumPorts *r)
7224 /* that's an [in out] buffer */
7226 if (!r->in.buffer && (r->in.offered != 0)) {
7227 return WERR_INVALID_PARAM;
7230 DEBUG(4,("_spoolss_EnumPorts\n"));
7234 *r->out.info = NULL;
7236 switch (r->in.level) {
7238 result = enumports_level_1(p->mem_ctx, r->out.info,
7242 result = enumports_level_2(p->mem_ctx, r->out.info,
7246 return WERR_UNKNOWN_LEVEL;
7249 if (!W_ERROR_IS_OK(result)) {
7253 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7255 *r->out.info, r->in.level,
7257 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7258 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7260 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7263 /****************************************************************************
7264 ****************************************************************************/
7266 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7268 struct spoolss_SetPrinterInfoCtr *info_ctr,
7269 struct spoolss_DeviceMode *devmode,
7270 struct security_descriptor *secdesc,
7271 struct spoolss_UserLevelCtr *user_ctr,
7272 struct policy_handle *handle)
7274 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7275 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7277 WERROR err = WERR_OK;
7279 /* samba does not have a concept of local, non-shared printers yet, so
7280 * make sure we always setup sharename - gd */
7281 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7282 (info2->printername != NULL && info2->printername[0] != '\0')) {
7283 DEBUG(5, ("spoolss_addprinterex_level_2: "
7284 "no sharename has been set, setting printername %s as sharename\n",
7285 info2->printername));
7286 info2->sharename = info2->printername;
7289 /* check to see if the printer already exists */
7290 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7291 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7293 return WERR_PRINTER_ALREADY_EXISTS;
7296 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7297 if ((snum = print_queue_snum(info2->printername)) != -1) {
7298 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7299 info2->printername));
7300 return WERR_PRINTER_ALREADY_EXISTS;
7304 /* validate printer info struct */
7305 if (!info2->printername || strlen(info2->printername) == 0) {
7306 return WERR_INVALID_PRINTER_NAME;
7308 if (!info2->portname || strlen(info2->portname) == 0) {
7309 return WERR_UNKNOWN_PORT;
7311 if (!info2->drivername || strlen(info2->drivername) == 0) {
7312 return WERR_UNKNOWN_PRINTER_DRIVER;
7314 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7315 return WERR_UNKNOWN_PRINTPROCESSOR;
7318 /* FIXME!!! smbd should check to see if the driver is installed before
7319 trying to add a printer like this --jerry */
7321 if (*lp_addprinter_cmd() ) {
7322 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7323 info2, p->client_address,
7325 return WERR_ACCESS_DENIED;
7328 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7329 "smb.conf parameter \"addprinter command\" is defined. This"
7330 "parameter must exist for this call to succeed\n",
7331 info2->sharename ));
7334 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7335 return WERR_ACCESS_DENIED;
7338 /* you must be a printer admin to add a new printer */
7339 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7340 return WERR_ACCESS_DENIED;
7344 * Do sanity check on the requested changes for Samba.
7347 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7348 return WERR_INVALID_PARAM;
7351 if (devmode == NULL) {
7352 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7355 update_dsspooler(p->mem_ctx,
7361 err = winreg_update_printer(p->mem_ctx,
7369 if (!W_ERROR_IS_OK(err)) {
7373 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7374 /* Handle open failed - remove addition. */
7375 ZERO_STRUCTP(handle);
7376 return WERR_ACCESS_DENIED;
7382 /****************************************************************
7383 _spoolss_AddPrinterEx
7384 ****************************************************************/
7386 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7387 struct spoolss_AddPrinterEx *r)
7389 switch (r->in.info_ctr->level) {
7391 /* we don't handle yet */
7392 /* but I know what to do ... */
7393 return WERR_UNKNOWN_LEVEL;
7395 return spoolss_addprinterex_level_2(p, r->in.server,
7397 r->in.devmode_ctr->devmode,
7398 r->in.secdesc_ctr->sd,
7399 r->in.userlevel_ctr,
7402 return WERR_UNKNOWN_LEVEL;
7406 /****************************************************************
7408 ****************************************************************/
7410 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7411 struct spoolss_AddPrinter *r)
7413 struct spoolss_AddPrinterEx a;
7414 struct spoolss_UserLevelCtr userlevel_ctr;
7416 ZERO_STRUCT(userlevel_ctr);
7418 userlevel_ctr.level = 1;
7420 a.in.server = r->in.server;
7421 a.in.info_ctr = r->in.info_ctr;
7422 a.in.devmode_ctr = r->in.devmode_ctr;
7423 a.in.secdesc_ctr = r->in.secdesc_ctr;
7424 a.in.userlevel_ctr = &userlevel_ctr;
7425 a.out.handle = r->out.handle;
7427 return _spoolss_AddPrinterEx(p, &a);
7430 /****************************************************************
7431 _spoolss_AddPrinterDriverEx
7432 ****************************************************************/
7434 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7435 struct spoolss_AddPrinterDriverEx *r)
7437 WERROR err = WERR_OK;
7438 const char *driver_name = NULL;
7443 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7444 fn = "_spoolss_AddPrinterDriver";
7446 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7447 fn = "_spoolss_AddPrinterDriverEx";
7450 return WERR_INVALID_PARAM;
7454 * we only support the semantics of AddPrinterDriver()
7455 * i.e. only copy files that are newer than existing ones
7458 if (r->in.flags == 0) {
7459 return WERR_INVALID_PARAM;
7462 if (r->in.flags != APD_COPY_NEW_FILES) {
7463 return WERR_ACCESS_DENIED;
7467 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7468 /* Clever hack from Martin Zielinski <mz@seh.de>
7469 * to allow downgrade from level 8 (Vista).
7471 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7472 r->in.info_ctr->level));
7473 return WERR_UNKNOWN_LEVEL;
7476 DEBUG(5,("Cleaning driver's information\n"));
7477 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7478 if (!W_ERROR_IS_OK(err))
7481 DEBUG(5,("Moving driver to final destination\n"));
7482 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7487 err = winreg_add_driver(p->mem_ctx, p->server_info, p->msg_ctx,
7488 r->in.info_ctr, &driver_name, &version);
7489 if (!W_ERROR_IS_OK(err)) {
7494 * I think this is where he DrvUpgradePrinter() hook would be
7495 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7496 * server. Right now, we just need to send ourselves a message
7497 * to update each printer bound to this driver. --jerry
7500 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7501 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7509 /****************************************************************
7510 _spoolss_AddPrinterDriver
7511 ****************************************************************/
7513 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7514 struct spoolss_AddPrinterDriver *r)
7516 struct spoolss_AddPrinterDriverEx a;
7518 switch (r->in.info_ctr->level) {
7525 return WERR_UNKNOWN_LEVEL;
7528 a.in.servername = r->in.servername;
7529 a.in.info_ctr = r->in.info_ctr;
7530 a.in.flags = APD_COPY_NEW_FILES;
7532 return _spoolss_AddPrinterDriverEx(p, &a);
7535 /****************************************************************************
7536 ****************************************************************************/
7538 struct _spoolss_paths {
7544 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7546 static const struct _spoolss_paths spoolss_paths[]= {
7547 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7548 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7551 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7552 const char *servername,
7553 const char *environment,
7557 const char *pservername = NULL;
7558 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7559 const char *short_archi;
7563 /* environment may be empty */
7564 if (environment && strlen(environment)) {
7565 long_archi = environment;
7568 /* servername may be empty */
7569 if (servername && strlen(servername)) {
7570 pservername = canon_servername(servername);
7572 if (!is_myname_or_ipaddr(pservername)) {
7573 return WERR_INVALID_PARAM;
7577 if (!(short_archi = get_short_archi(long_archi))) {
7578 return WERR_INVALID_ENVIRONMENT;
7581 switch (component) {
7582 case SPOOLSS_PRTPROCS_PATH:
7583 case SPOOLSS_DRIVER_PATH:
7585 *path = talloc_asprintf(mem_ctx,
7588 spoolss_paths[component].share,
7591 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7592 SPOOLSS_DEFAULT_SERVER_PATH,
7593 spoolss_paths[component].dir,
7598 return WERR_INVALID_PARAM;
7608 /****************************************************************************
7609 ****************************************************************************/
7611 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7612 const char *servername,
7613 const char *environment,
7614 struct spoolss_DriverDirectoryInfo1 *r)
7619 werr = compose_spoolss_server_path(mem_ctx,
7622 SPOOLSS_DRIVER_PATH,
7624 if (!W_ERROR_IS_OK(werr)) {
7628 DEBUG(4,("printer driver directory: [%s]\n", path));
7630 r->directory_name = path;
7635 /****************************************************************
7636 _spoolss_GetPrinterDriverDirectory
7637 ****************************************************************/
7639 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7640 struct spoolss_GetPrinterDriverDirectory *r)
7644 /* that's an [in out] buffer */
7646 if (!r->in.buffer && (r->in.offered != 0)) {
7647 return WERR_INVALID_PARAM;
7650 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7655 /* r->in.level is ignored */
7657 werror = getprinterdriverdir_level_1(p->mem_ctx,
7660 &r->out.info->info1);
7661 if (!W_ERROR_IS_OK(werror)) {
7662 TALLOC_FREE(r->out.info);
7666 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7667 r->out.info, r->in.level);
7668 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7670 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7673 /****************************************************************
7674 _spoolss_EnumPrinterData
7675 ****************************************************************/
7677 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7678 struct spoolss_EnumPrinterData *r)
7681 struct spoolss_EnumPrinterDataEx r2;
7683 struct spoolss_PrinterEnumValues *info, *val = NULL;
7686 r2.in.handle = r->in.handle;
7687 r2.in.key_name = "PrinterDriverData";
7689 r2.out.count = &count;
7690 r2.out.info = &info;
7691 r2.out.needed = &needed;
7693 result = _spoolss_EnumPrinterDataEx(p, &r2);
7694 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7695 r2.in.offered = needed;
7696 result = _spoolss_EnumPrinterDataEx(p, &r2);
7698 if (!W_ERROR_IS_OK(result)) {
7703 * The NT machine wants to know the biggest size of value and data
7705 * cf: MSDN EnumPrinterData remark section
7708 if (!r->in.value_offered && !r->in.data_offered) {
7709 uint32_t biggest_valuesize = 0;
7710 uint32_t biggest_datasize = 0;
7713 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7715 for (i=0; i<count; i++) {
7717 name_length = strlen(info[i].value_name);
7718 if (strlen(info[i].value_name) > biggest_valuesize) {
7719 biggest_valuesize = name_length;
7722 if (info[i].data_length > biggest_datasize) {
7723 biggest_datasize = info[i].data_length;
7726 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7730 /* the value is an UNICODE string but real_value_size is the length
7731 in bytes including the trailing 0 */
7733 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7734 *r->out.data_needed = biggest_datasize;
7736 DEBUG(6,("final values: [%d], [%d]\n",
7737 *r->out.value_needed, *r->out.data_needed));
7742 if (r->in.enum_index < count) {
7743 val = &info[r->in.enum_index];
7747 /* out_value should default to "" or else NT4 has
7748 problems unmarshalling the response */
7750 if (r->in.value_offered) {
7751 *r->out.value_needed = 1;
7752 r->out.value_name = talloc_strdup(r, "");
7753 if (!r->out.value_name) {
7757 r->out.value_name = NULL;
7758 *r->out.value_needed = 0;
7761 /* the data is counted in bytes */
7763 *r->out.data_needed = r->in.data_offered;
7765 result = WERR_NO_MORE_ITEMS;
7769 * - counted in bytes in the request
7770 * - counted in UNICODE chars in the max reply
7771 * - counted in bytes in the real size
7773 * take a pause *before* coding not *during* coding
7777 if (r->in.value_offered) {
7778 r->out.value_name = talloc_strdup(r, val->value_name);
7779 if (!r->out.value_name) {
7782 *r->out.value_needed = val->value_name_len;
7784 r->out.value_name = NULL;
7785 *r->out.value_needed = 0;
7790 *r->out.type = val->type;
7792 /* data - counted in bytes */
7795 * See the section "Dynamically Typed Query Parameters"
7799 if (r->out.data && val->data && val->data->data &&
7800 val->data_length && r->in.data_offered) {
7801 memcpy(r->out.data, val->data->data,
7802 MIN(val->data_length,r->in.data_offered));
7805 *r->out.data_needed = val->data_length;
7813 /****************************************************************
7814 _spoolss_SetPrinterData
7815 ****************************************************************/
7817 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7818 struct spoolss_SetPrinterData *r)
7820 struct spoolss_SetPrinterDataEx r2;
7822 r2.in.handle = r->in.handle;
7823 r2.in.key_name = "PrinterDriverData";
7824 r2.in.value_name = r->in.value_name;
7825 r2.in.type = r->in.type;
7826 r2.in.data = r->in.data;
7827 r2.in.offered = r->in.offered;
7829 return _spoolss_SetPrinterDataEx(p, &r2);
7832 /****************************************************************
7833 _spoolss_ResetPrinter
7834 ****************************************************************/
7836 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7837 struct spoolss_ResetPrinter *r)
7839 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7842 DEBUG(5,("_spoolss_ResetPrinter\n"));
7845 * All we do is to check to see if the handle and queue is valid.
7846 * This call really doesn't mean anything to us because we only
7847 * support RAW printing. --jerry
7851 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7852 OUR_HANDLE(r->in.handle)));
7856 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7860 /* blindly return success */
7864 /****************************************************************
7865 _spoolss_DeletePrinterData
7866 ****************************************************************/
7868 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7869 struct spoolss_DeletePrinterData *r)
7871 struct spoolss_DeletePrinterDataEx r2;
7873 r2.in.handle = r->in.handle;
7874 r2.in.key_name = "PrinterDriverData";
7875 r2.in.value_name = r->in.value_name;
7877 return _spoolss_DeletePrinterDataEx(p, &r2);
7880 /****************************************************************
7882 ****************************************************************/
7884 WERROR _spoolss_AddForm(struct pipes_struct *p,
7885 struct spoolss_AddForm *r)
7887 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7889 WERROR status = WERR_OK;
7890 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7892 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7894 DEBUG(5,("_spoolss_AddForm\n"));
7897 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7898 OUR_HANDLE(r->in.handle)));
7902 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7903 and not a printer admin, then fail */
7905 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7906 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7907 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7908 p->server_info->info3->base.domain.string,
7910 p->server_info->ptok,
7911 lp_printer_admin(snum))) {
7912 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7913 return WERR_ACCESS_DENIED;
7916 switch (form->flags) {
7917 case SPOOLSS_FORM_USER:
7918 case SPOOLSS_FORM_BUILTIN:
7919 case SPOOLSS_FORM_PRINTER:
7922 return WERR_INVALID_PARAM;
7925 status = winreg_printer_addform1(p->mem_ctx, p->server_info,
7927 if (!W_ERROR_IS_OK(status)) {
7932 * ChangeID must always be set if this is a printer
7934 if (Printer->printer_type == SPLHND_PRINTER) {
7935 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7939 status = winreg_printer_update_changeid(p->mem_ctx,
7942 lp_const_servicename(snum));
7943 if (!W_ERROR_IS_OK(status)) {
7951 /****************************************************************
7953 ****************************************************************/
7955 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7956 struct spoolss_DeleteForm *r)
7958 const char *form_name = r->in.form_name;
7959 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7961 WERROR status = WERR_OK;
7962 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7964 DEBUG(5,("_spoolss_DeleteForm\n"));
7967 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7968 OUR_HANDLE(r->in.handle)));
7972 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7973 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7974 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7975 p->server_info->info3->base.domain.string,
7977 p->server_info->ptok,
7978 lp_printer_admin(snum))) {
7979 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7980 return WERR_ACCESS_DENIED;
7983 status = winreg_printer_deleteform1(p->mem_ctx,
7987 if (!W_ERROR_IS_OK(status)) {
7992 * ChangeID must always be set if this is a printer
7994 if (Printer->printer_type == SPLHND_PRINTER) {
7995 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7999 status = winreg_printer_update_changeid(p->mem_ctx,
8002 lp_const_servicename(snum));
8003 if (!W_ERROR_IS_OK(status)) {
8011 /****************************************************************
8013 ****************************************************************/
8015 WERROR _spoolss_SetForm(struct pipes_struct *p,
8016 struct spoolss_SetForm *r)
8018 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8019 const char *form_name = r->in.form_name;
8021 WERROR status = WERR_OK;
8022 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8024 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8026 DEBUG(5,("_spoolss_SetForm\n"));
8029 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8030 OUR_HANDLE(r->in.handle)));
8034 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8035 and not a printer admin, then fail */
8037 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8038 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8039 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8040 p->server_info->info3->base.domain.string,
8042 p->server_info->ptok,
8043 lp_printer_admin(snum))) {
8044 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8045 return WERR_ACCESS_DENIED;
8048 status = winreg_printer_setform1(p->mem_ctx,
8053 if (!W_ERROR_IS_OK(status)) {
8058 * ChangeID must always be set if this is a printer
8060 if (Printer->printer_type == SPLHND_PRINTER) {
8061 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8065 status = winreg_printer_update_changeid(p->mem_ctx,
8068 lp_const_servicename(snum));
8069 if (!W_ERROR_IS_OK(status)) {
8077 /****************************************************************************
8078 fill_print_processor1
8079 ****************************************************************************/
8081 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8082 struct spoolss_PrintProcessorInfo1 *r,
8083 const char *print_processor_name)
8085 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8086 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8091 /****************************************************************************
8092 enumprintprocessors level 1.
8093 ****************************************************************************/
8095 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8096 union spoolss_PrintProcessorInfo **info_p,
8099 union spoolss_PrintProcessorInfo *info;
8102 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8103 W_ERROR_HAVE_NO_MEMORY(info);
8107 result = fill_print_processor1(info, &info[0].info1, "winprint");
8108 if (!W_ERROR_IS_OK(result)) {
8113 if (!W_ERROR_IS_OK(result)) {
8124 /****************************************************************
8125 _spoolss_EnumPrintProcessors
8126 ****************************************************************/
8128 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8129 struct spoolss_EnumPrintProcessors *r)
8133 /* that's an [in out] buffer */
8135 if (!r->in.buffer && (r->in.offered != 0)) {
8136 return WERR_INVALID_PARAM;
8139 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8142 * Enumerate the print processors ...
8144 * Just reply with "winprint", to keep NT happy
8145 * and I can use my nice printer checker.
8150 *r->out.info = NULL;
8152 switch (r->in.level) {
8154 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8158 return WERR_UNKNOWN_LEVEL;
8161 if (!W_ERROR_IS_OK(result)) {
8165 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8166 spoolss_EnumPrintProcessors,
8167 *r->out.info, r->in.level,
8169 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8170 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8172 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8175 /****************************************************************************
8176 fill_printprocdatatype1
8177 ****************************************************************************/
8179 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8180 struct spoolss_PrintProcDataTypesInfo1 *r,
8181 const char *name_array)
8183 r->name_array = talloc_strdup(mem_ctx, name_array);
8184 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8189 /****************************************************************************
8190 enumprintprocdatatypes level 1.
8191 ****************************************************************************/
8193 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8194 union spoolss_PrintProcDataTypesInfo **info_p,
8198 union spoolss_PrintProcDataTypesInfo *info;
8200 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8201 W_ERROR_HAVE_NO_MEMORY(info);
8205 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8206 if (!W_ERROR_IS_OK(result)) {
8211 if (!W_ERROR_IS_OK(result)) {
8222 /****************************************************************
8223 _spoolss_EnumPrintProcDataTypes
8224 ****************************************************************/
8226 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8227 struct spoolss_EnumPrintProcDataTypes *r)
8231 /* that's an [in out] buffer */
8233 if (!r->in.buffer && (r->in.offered != 0)) {
8234 return WERR_INVALID_PARAM;
8237 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8241 *r->out.info = NULL;
8243 switch (r->in.level) {
8245 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8249 return WERR_UNKNOWN_LEVEL;
8252 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8253 spoolss_EnumPrintProcDataTypes,
8254 *r->out.info, r->in.level,
8256 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8257 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8259 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8262 /****************************************************************************
8264 ****************************************************************************/
8266 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8267 struct spoolss_MonitorInfo1 *r,
8268 const char *monitor_name)
8270 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8271 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8276 /****************************************************************************
8278 ****************************************************************************/
8280 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8281 struct spoolss_MonitorInfo2 *r,
8282 const char *monitor_name,
8283 const char *environment,
8284 const char *dll_name)
8286 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8287 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8288 r->environment = talloc_strdup(mem_ctx, environment);
8289 W_ERROR_HAVE_NO_MEMORY(r->environment);
8290 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8291 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8296 /****************************************************************************
8297 enumprintmonitors level 1.
8298 ****************************************************************************/
8300 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8301 union spoolss_MonitorInfo **info_p,
8304 union spoolss_MonitorInfo *info;
8305 WERROR result = WERR_OK;
8307 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8308 W_ERROR_HAVE_NO_MEMORY(info);
8312 result = fill_monitor_1(info, &info[0].info1,
8314 if (!W_ERROR_IS_OK(result)) {
8318 result = fill_monitor_1(info, &info[1].info1,
8320 if (!W_ERROR_IS_OK(result)) {
8325 if (!W_ERROR_IS_OK(result)) {
8336 /****************************************************************************
8337 enumprintmonitors level 2.
8338 ****************************************************************************/
8340 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8341 union spoolss_MonitorInfo **info_p,
8344 union spoolss_MonitorInfo *info;
8345 WERROR result = WERR_OK;
8347 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8348 W_ERROR_HAVE_NO_MEMORY(info);
8352 result = fill_monitor_2(info, &info[0].info2,
8354 "Windows NT X86", /* FIXME */
8356 if (!W_ERROR_IS_OK(result)) {
8360 result = fill_monitor_2(info, &info[1].info2,
8362 "Windows NT X86", /* FIXME */
8364 if (!W_ERROR_IS_OK(result)) {
8369 if (!W_ERROR_IS_OK(result)) {
8380 /****************************************************************
8381 _spoolss_EnumMonitors
8382 ****************************************************************/
8384 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8385 struct spoolss_EnumMonitors *r)
8389 /* that's an [in out] buffer */
8391 if (!r->in.buffer && (r->in.offered != 0)) {
8392 return WERR_INVALID_PARAM;
8395 DEBUG(5,("_spoolss_EnumMonitors\n"));
8398 * Enumerate the print monitors ...
8400 * Just reply with "Local Port", to keep NT happy
8401 * and I can use my nice printer checker.
8406 *r->out.info = NULL;
8408 switch (r->in.level) {
8410 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8414 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8418 return WERR_UNKNOWN_LEVEL;
8421 if (!W_ERROR_IS_OK(result)) {
8425 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8426 spoolss_EnumMonitors,
8427 *r->out.info, r->in.level,
8429 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8430 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8432 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8435 /****************************************************************************
8436 ****************************************************************************/
8438 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8439 const print_queue_struct *queue,
8440 int count, int snum,
8441 struct spoolss_PrinterInfo2 *pinfo2,
8443 struct spoolss_JobInfo1 *r)
8448 for (i=0; i<count; i++) {
8449 if (queue[i].job == (int)jobid) {
8455 if (found == false) {
8456 /* NT treats not found as bad param... yet another bad choice */
8457 return WERR_INVALID_PARAM;
8460 return fill_job_info1(mem_ctx,
8468 /****************************************************************************
8469 ****************************************************************************/
8471 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8472 const print_queue_struct *queue,
8473 int count, int snum,
8474 struct spoolss_PrinterInfo2 *pinfo2,
8476 struct spoolss_JobInfo2 *r)
8480 struct spoolss_DeviceMode *devmode;
8483 for (i=0; i<count; i++) {
8484 if (queue[i].job == (int)jobid) {
8490 if (found == false) {
8491 /* NT treats not found as bad param... yet another bad
8493 return WERR_INVALID_PARAM;
8497 * if the print job does not have a DEVMODE associated with it,
8498 * just use the one for the printer. A NULL devicemode is not
8499 * a failure condition
8502 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8504 result = spoolss_create_default_devmode(mem_ctx,
8505 pinfo2->printername,
8507 if (!W_ERROR_IS_OK(result)) {
8508 DEBUG(3, ("Can't proceed w/o a devmode!"));
8513 return fill_job_info2(mem_ctx,
8522 /****************************************************************
8524 ****************************************************************/
8526 WERROR _spoolss_GetJob(struct pipes_struct *p,
8527 struct spoolss_GetJob *r)
8529 WERROR result = WERR_OK;
8530 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8533 print_queue_struct *queue = NULL;
8534 print_status_struct prt_status;
8536 /* that's an [in out] buffer */
8538 if (!r->in.buffer && (r->in.offered != 0)) {
8539 return WERR_INVALID_PARAM;
8542 DEBUG(5,("_spoolss_GetJob\n"));
8546 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8550 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
8551 NULL, lp_servicename(snum), &pinfo2);
8552 if (!W_ERROR_IS_OK(result)) {
8556 count = print_queue_status(snum, &queue, &prt_status);
8558 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8559 count, prt_status.status, prt_status.message));
8561 switch (r->in.level) {
8563 result = getjob_level_1(p->mem_ctx,
8564 queue, count, snum, pinfo2,
8565 r->in.job_id, &r->out.info->info1);
8568 result = getjob_level_2(p->mem_ctx,
8569 queue, count, snum, pinfo2,
8570 r->in.job_id, &r->out.info->info2);
8573 result = WERR_UNKNOWN_LEVEL;
8578 TALLOC_FREE(pinfo2);
8580 if (!W_ERROR_IS_OK(result)) {
8581 TALLOC_FREE(r->out.info);
8585 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8587 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8589 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8592 /****************************************************************
8593 _spoolss_GetPrinterDataEx
8594 ****************************************************************/
8596 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8597 struct spoolss_GetPrinterDataEx *r)
8600 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8601 const char *printer;
8603 WERROR result = WERR_OK;
8605 enum winreg_Type val_type;
8610 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8612 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8613 r->in.key_name, r->in.value_name));
8615 /* in case of problem, return some default values */
8618 *r->out.type = REG_NONE;
8621 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8622 OUR_HANDLE(r->in.handle)));
8623 result = WERR_BADFID;
8627 /* Is the handle to a printer or to the server? */
8629 if (Printer->printer_type == SPLHND_SERVER) {
8631 union spoolss_PrinterData data;
8633 result = getprinterdata_printer_server(p->mem_ctx,
8637 if (!W_ERROR_IS_OK(result)) {
8641 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8642 *r->out.type, &data);
8643 if (!W_ERROR_IS_OK(result)) {
8647 *r->out.needed = blob.length;
8649 if (r->in.offered >= *r->out.needed) {
8650 memcpy(r->out.data, blob.data, blob.length);
8653 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8656 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8659 printer = lp_const_servicename(snum);
8661 /* check to see if the keyname is valid */
8662 if (!strlen(r->in.key_name)) {
8663 return WERR_INVALID_PARAM;
8666 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8667 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8668 strequal(r->in.value_name, "ChangeId")) {
8669 *r->out.type = REG_DWORD;
8671 if (r->in.offered >= *r->out.needed) {
8672 uint32_t changeid = 0;
8674 result = winreg_printer_get_changeid(p->mem_ctx,
8679 if (!W_ERROR_IS_OK(result)) {
8683 SIVAL(r->out.data, 0, changeid);
8689 result = winreg_get_printer_dataex(p->mem_ctx,
8698 if (!W_ERROR_IS_OK(result)) {
8702 *r->out.needed = val_size;
8703 *r->out.type = val_type;
8705 if (r->in.offered >= *r->out.needed) {
8706 memcpy(r->out.data, val_data, val_size);
8710 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8711 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8713 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8716 /****************************************************************
8717 _spoolss_SetPrinterDataEx
8718 ****************************************************************/
8720 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8721 struct spoolss_SetPrinterDataEx *r)
8723 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8725 WERROR result = WERR_OK;
8726 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8729 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8731 /* From MSDN documentation of SetPrinterDataEx: pass request to
8732 SetPrinterData if key is "PrinterDriverData" */
8735 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8736 OUR_HANDLE(r->in.handle)));
8740 if (Printer->printer_type == SPLHND_SERVER) {
8741 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8742 "Not implemented for server handles yet\n"));
8743 return WERR_INVALID_PARAM;
8746 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8751 * Access check : NT returns "access denied" if you make a
8752 * SetPrinterData call without the necessary privildge.
8753 * we were originally returning OK if nothing changed
8754 * which made Win2k issue **a lot** of SetPrinterData
8755 * when connecting to a printer --jerry
8758 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8759 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8760 "change denied by handle access permissions\n"));
8761 return WERR_ACCESS_DENIED;
8764 result = winreg_get_printer(Printer, p->server_info, p->msg_ctx,
8765 Printer->servername,
8766 lp_servicename(snum),
8768 if (!W_ERROR_IS_OK(result)) {
8772 /* check for OID in valuename */
8774 oid_string = strchr(r->in.value_name, ',');
8780 /* save the registry data */
8782 result = winreg_set_printer_dataex(p->mem_ctx,
8792 if (W_ERROR_IS_OK(result)) {
8793 /* save the OID if one was specified */
8795 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8796 r->in.key_name, SPOOL_OID_KEY);
8798 result = WERR_NOMEM;
8803 * I'm not checking the status here on purpose. Don't know
8804 * if this is right, but I'm returning the status from the
8805 * previous set_printer_dataex() call. I have no idea if
8806 * this is right. --jerry
8808 winreg_set_printer_dataex(p->mem_ctx,
8815 (uint8_t *) oid_string,
8816 strlen(oid_string) + 1);
8819 result = winreg_printer_update_changeid(p->mem_ctx,
8822 lp_const_servicename(snum));
8827 talloc_free(pinfo2);
8831 /****************************************************************
8832 _spoolss_DeletePrinterDataEx
8833 ****************************************************************/
8835 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8836 struct spoolss_DeletePrinterDataEx *r)
8838 const char *printer;
8840 WERROR status = WERR_OK;
8841 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8843 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8846 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8847 "Invalid handle (%s:%u:%u).\n",
8848 OUR_HANDLE(r->in.handle)));
8852 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8853 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8854 "printer properties change denied by handle\n"));
8855 return WERR_ACCESS_DENIED;
8858 if (!r->in.value_name || !r->in.key_name) {
8862 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8865 printer = lp_const_servicename(snum);
8867 status = winreg_delete_printer_dataex(p->mem_ctx,
8873 if (W_ERROR_IS_OK(status)) {
8874 status = winreg_printer_update_changeid(p->mem_ctx,
8883 /****************************************************************
8884 _spoolss_EnumPrinterKey
8885 ****************************************************************/
8887 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8888 struct spoolss_EnumPrinterKey *r)
8891 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8893 WERROR result = WERR_BADFILE;
8894 const char **array = NULL;
8897 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8900 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8901 OUR_HANDLE(r->in.handle)));
8905 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8909 result = winreg_enum_printer_key(p->mem_ctx,
8912 lp_const_servicename(snum),
8916 if (!W_ERROR_IS_OK(result)) {
8920 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8921 result = WERR_NOMEM;
8925 *r->out._ndr_size = r->in.offered / 2;
8926 *r->out.needed = blob.length;
8928 if (r->in.offered < *r->out.needed) {
8929 result = WERR_MORE_DATA;
8932 r->out.key_buffer->string_array = array;
8936 if (!W_ERROR_IS_OK(result)) {
8938 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8946 /****************************************************************
8947 _spoolss_DeletePrinterKey
8948 ****************************************************************/
8950 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8951 struct spoolss_DeletePrinterKey *r)
8953 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8956 const char *printer;
8958 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8961 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8962 OUR_HANDLE(r->in.handle)));
8966 /* if keyname == NULL, return error */
8967 if ( !r->in.key_name )
8968 return WERR_INVALID_PARAM;
8970 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8974 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8975 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8976 "printer properties change denied by handle\n"));
8977 return WERR_ACCESS_DENIED;
8980 printer = lp_const_servicename(snum);
8982 /* delete the key and all subkeys */
8983 status = winreg_delete_printer_key(p->mem_ctx,
8988 if (W_ERROR_IS_OK(status)) {
8989 status = winreg_printer_update_changeid(p->mem_ctx,
8998 /****************************************************************
8999 _spoolss_EnumPrinterDataEx
9000 ****************************************************************/
9002 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
9003 struct spoolss_EnumPrinterDataEx *r)
9006 struct spoolss_PrinterEnumValues *info = NULL;
9007 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9011 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9015 *r->out.info = NULL;
9018 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9019 OUR_HANDLE(r->in.handle)));
9024 * first check for a keyname of NULL or "". Win2k seems to send
9025 * this a lot and we should send back WERR_INVALID_PARAM
9026 * no need to spend time looking up the printer in this case.
9030 if (!strlen(r->in.key_name)) {
9031 result = WERR_INVALID_PARAM;
9035 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9039 /* now look for a match on the key name */
9040 result = winreg_enum_printer_dataex(p->mem_ctx,
9043 lp_const_servicename(snum),
9047 if (!W_ERROR_IS_OK(result)) {
9051 #if 0 /* FIXME - gd */
9052 /* housekeeping information in the reply */
9054 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9055 * the hand marshalled container size is a multiple
9056 * of 4 bytes for RPC alignment.
9060 needed += 4-(needed % 4);
9063 *r->out.count = count;
9064 *r->out.info = info;
9067 if (!W_ERROR_IS_OK(result)) {
9071 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9072 spoolss_EnumPrinterDataEx,
9075 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9076 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9078 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9081 /****************************************************************************
9082 ****************************************************************************/
9084 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9085 const char *servername,
9086 const char *environment,
9087 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9092 werr = compose_spoolss_server_path(mem_ctx,
9095 SPOOLSS_PRTPROCS_PATH,
9097 if (!W_ERROR_IS_OK(werr)) {
9101 DEBUG(4,("print processor directory: [%s]\n", path));
9103 r->directory_name = path;
9108 /****************************************************************
9109 _spoolss_GetPrintProcessorDirectory
9110 ****************************************************************/
9112 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9113 struct spoolss_GetPrintProcessorDirectory *r)
9117 /* that's an [in out] buffer */
9119 if (!r->in.buffer && (r->in.offered != 0)) {
9120 return WERR_INVALID_PARAM;
9123 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9128 /* r->in.level is ignored */
9130 /* We always should reply with a local print processor directory so that
9131 * users are not forced to have a [prnproc$] share on the Samba spoolss
9132 * server - Guenther */
9134 result = getprintprocessordirectory_level_1(p->mem_ctx,
9135 NULL, /* r->in.server */
9137 &r->out.info->info1);
9138 if (!W_ERROR_IS_OK(result)) {
9139 TALLOC_FREE(r->out.info);
9143 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9144 r->out.info, r->in.level);
9145 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9147 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9150 /*******************************************************************
9151 ********************************************************************/
9153 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9154 const char *dllname)
9156 enum ndr_err_code ndr_err;
9157 struct spoolss_MonitorUi ui;
9159 ui.dll_name = dllname;
9161 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9162 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9163 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9164 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9166 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9169 /*******************************************************************
9170 Streams the monitor UI DLL name in UNICODE
9171 *******************************************************************/
9173 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9174 NT_USER_TOKEN *token, DATA_BLOB *in,
9175 DATA_BLOB *out, uint32_t *needed)
9177 const char *dllname = "tcpmonui.dll";
9179 *needed = (strlen(dllname)+1) * 2;
9181 if (out->length < *needed) {
9182 return WERR_INSUFFICIENT_BUFFER;
9185 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9192 /*******************************************************************
9193 ********************************************************************/
9195 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9196 struct spoolss_PortData1 *port1,
9197 const DATA_BLOB *buf)
9199 enum ndr_err_code ndr_err;
9200 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9201 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9202 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9203 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9205 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9208 /*******************************************************************
9209 ********************************************************************/
9211 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9212 struct spoolss_PortData2 *port2,
9213 const DATA_BLOB *buf)
9215 enum ndr_err_code ndr_err;
9216 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9217 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9218 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9219 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9221 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9224 /*******************************************************************
9225 Create a new TCP/IP port
9226 *******************************************************************/
9228 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9229 NT_USER_TOKEN *token, DATA_BLOB *in,
9230 DATA_BLOB *out, uint32_t *needed)
9232 struct spoolss_PortData1 port1;
9233 struct spoolss_PortData2 port2;
9234 char *device_uri = NULL;
9237 const char *portname;
9238 const char *hostaddress;
9240 uint32_t port_number;
9243 /* peek for spoolss_PortData version */
9245 if (!in || (in->length < (128 + 4))) {
9246 return WERR_GENERAL_FAILURE;
9249 version = IVAL(in->data, 128);
9255 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9259 portname = port1.portname;
9260 hostaddress = port1.hostaddress;
9261 queue = port1.queue;
9262 protocol = port1.protocol;
9263 port_number = port1.port_number;
9269 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9273 portname = port2.portname;
9274 hostaddress = port2.hostaddress;
9275 queue = port2.queue;
9276 protocol = port2.protocol;
9277 port_number = port2.port_number;
9281 DEBUG(1,("xcvtcp_addport: "
9282 "unknown version of port_data: %d\n", version));
9283 return WERR_UNKNOWN_PORT;
9286 /* create the device URI and call the add_port_hook() */
9289 case PROTOCOL_RAWTCP_TYPE:
9290 device_uri = talloc_asprintf(mem_ctx,
9291 "socket://%s:%d/", hostaddress,
9295 case PROTOCOL_LPR_TYPE:
9296 device_uri = talloc_asprintf(mem_ctx,
9297 "lpr://%s/%s", hostaddress, queue );
9301 return WERR_UNKNOWN_PORT;
9308 return add_port_hook(mem_ctx, token, portname, device_uri);
9311 /*******************************************************************
9312 *******************************************************************/
9314 struct xcv_api_table xcvtcp_cmds[] = {
9315 { "MonitorUI", xcvtcp_monitorui },
9316 { "AddPort", xcvtcp_addport},
9320 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9321 NT_USER_TOKEN *token, const char *command,
9328 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9330 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9331 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9332 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9335 return WERR_BADFUNC;
9338 /*******************************************************************
9339 *******************************************************************/
9340 #if 0 /* don't support management using the "Local Port" monitor */
9342 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9343 NT_USER_TOKEN *token, DATA_BLOB *in,
9344 DATA_BLOB *out, uint32_t *needed)
9346 const char *dllname = "localui.dll";
9348 *needed = (strlen(dllname)+1) * 2;
9350 if (out->length < *needed) {
9351 return WERR_INSUFFICIENT_BUFFER;
9354 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9361 /*******************************************************************
9362 *******************************************************************/
9364 struct xcv_api_table xcvlocal_cmds[] = {
9365 { "MonitorUI", xcvlocal_monitorui },
9369 struct xcv_api_table xcvlocal_cmds[] = {
9376 /*******************************************************************
9377 *******************************************************************/
9379 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9380 NT_USER_TOKEN *token, const char *command,
9381 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9386 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9388 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9389 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9390 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9392 return WERR_BADFUNC;
9395 /****************************************************************
9397 ****************************************************************/
9399 WERROR _spoolss_XcvData(struct pipes_struct *p,
9400 struct spoolss_XcvData *r)
9402 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9403 DATA_BLOB out_data = data_blob_null;
9407 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9408 OUR_HANDLE(r->in.handle)));
9412 /* Has to be a handle to the TCP/IP port monitor */
9414 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9415 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9419 /* requires administrative access to the server */
9421 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9422 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9423 return WERR_ACCESS_DENIED;
9426 /* Allocate the outgoing buffer */
9428 if (r->in.out_data_size) {
9429 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9430 if (out_data.data == NULL) {
9435 switch ( Printer->printer_type ) {
9436 case SPLHND_PORTMON_TCP:
9437 werror = process_xcvtcp_command(p->mem_ctx,
9438 p->server_info->ptok,
9439 r->in.function_name,
9440 &r->in.in_data, &out_data,
9443 case SPLHND_PORTMON_LOCAL:
9444 werror = process_xcvlocal_command(p->mem_ctx,
9445 p->server_info->ptok,
9446 r->in.function_name,
9447 &r->in.in_data, &out_data,
9451 werror = WERR_INVALID_PRINT_MONITOR;
9454 if (!W_ERROR_IS_OK(werror)) {
9458 *r->out.status_code = 0;
9460 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9461 memcpy(r->out.out_data, out_data.data,
9462 MIN(r->in.out_data_size, out_data.length));
9468 /****************************************************************
9469 _spoolss_AddPrintProcessor
9470 ****************************************************************/
9472 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9473 struct spoolss_AddPrintProcessor *r)
9475 /* for now, just indicate success and ignore the add. We'll
9476 automatically set the winprint processor for printer
9477 entries later. Used to debug the LexMark Optra S 1855 PCL
9483 /****************************************************************
9485 ****************************************************************/
9487 WERROR _spoolss_AddPort(struct pipes_struct *p,
9488 struct spoolss_AddPort *r)
9490 /* do what w2k3 does */
9492 return WERR_NOT_SUPPORTED;
9495 /****************************************************************
9496 _spoolss_GetPrinterDriver
9497 ****************************************************************/
9499 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9500 struct spoolss_GetPrinterDriver *r)
9502 p->rng_fault_state = true;
9503 return WERR_NOT_SUPPORTED;
9506 /****************************************************************
9507 _spoolss_ReadPrinter
9508 ****************************************************************/
9510 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9511 struct spoolss_ReadPrinter *r)
9513 p->rng_fault_state = true;
9514 return WERR_NOT_SUPPORTED;
9517 /****************************************************************
9518 _spoolss_WaitForPrinterChange
9519 ****************************************************************/
9521 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9522 struct spoolss_WaitForPrinterChange *r)
9524 p->rng_fault_state = true;
9525 return WERR_NOT_SUPPORTED;
9528 /****************************************************************
9529 _spoolss_ConfigurePort
9530 ****************************************************************/
9532 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9533 struct spoolss_ConfigurePort *r)
9535 p->rng_fault_state = true;
9536 return WERR_NOT_SUPPORTED;
9539 /****************************************************************
9541 ****************************************************************/
9543 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9544 struct spoolss_DeletePort *r)
9546 p->rng_fault_state = true;
9547 return WERR_NOT_SUPPORTED;
9550 /****************************************************************
9551 _spoolss_CreatePrinterIC
9552 ****************************************************************/
9554 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9555 struct spoolss_CreatePrinterIC *r)
9557 p->rng_fault_state = true;
9558 return WERR_NOT_SUPPORTED;
9561 /****************************************************************
9562 _spoolss_PlayGDIScriptOnPrinterIC
9563 ****************************************************************/
9565 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9566 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9568 p->rng_fault_state = true;
9569 return WERR_NOT_SUPPORTED;
9572 /****************************************************************
9573 _spoolss_DeletePrinterIC
9574 ****************************************************************/
9576 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9577 struct spoolss_DeletePrinterIC *r)
9579 p->rng_fault_state = true;
9580 return WERR_NOT_SUPPORTED;
9583 /****************************************************************
9584 _spoolss_AddPrinterConnection
9585 ****************************************************************/
9587 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9588 struct spoolss_AddPrinterConnection *r)
9590 p->rng_fault_state = true;
9591 return WERR_NOT_SUPPORTED;
9594 /****************************************************************
9595 _spoolss_DeletePrinterConnection
9596 ****************************************************************/
9598 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9599 struct spoolss_DeletePrinterConnection *r)
9601 p->rng_fault_state = true;
9602 return WERR_NOT_SUPPORTED;
9605 /****************************************************************
9606 _spoolss_PrinterMessageBox
9607 ****************************************************************/
9609 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9610 struct spoolss_PrinterMessageBox *r)
9612 p->rng_fault_state = true;
9613 return WERR_NOT_SUPPORTED;
9616 /****************************************************************
9618 ****************************************************************/
9620 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9621 struct spoolss_AddMonitor *r)
9623 p->rng_fault_state = true;
9624 return WERR_NOT_SUPPORTED;
9627 /****************************************************************
9628 _spoolss_DeleteMonitor
9629 ****************************************************************/
9631 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9632 struct spoolss_DeleteMonitor *r)
9634 p->rng_fault_state = true;
9635 return WERR_NOT_SUPPORTED;
9638 /****************************************************************
9639 _spoolss_DeletePrintProcessor
9640 ****************************************************************/
9642 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9643 struct spoolss_DeletePrintProcessor *r)
9645 p->rng_fault_state = true;
9646 return WERR_NOT_SUPPORTED;
9649 /****************************************************************
9650 _spoolss_AddPrintProvidor
9651 ****************************************************************/
9653 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9654 struct spoolss_AddPrintProvidor *r)
9656 p->rng_fault_state = true;
9657 return WERR_NOT_SUPPORTED;
9660 /****************************************************************
9661 _spoolss_DeletePrintProvidor
9662 ****************************************************************/
9664 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9665 struct spoolss_DeletePrintProvidor *r)
9667 p->rng_fault_state = true;
9668 return WERR_NOT_SUPPORTED;
9671 /****************************************************************
9672 _spoolss_FindFirstPrinterChangeNotification
9673 ****************************************************************/
9675 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9676 struct spoolss_FindFirstPrinterChangeNotification *r)
9678 p->rng_fault_state = true;
9679 return WERR_NOT_SUPPORTED;
9682 /****************************************************************
9683 _spoolss_FindNextPrinterChangeNotification
9684 ****************************************************************/
9686 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9687 struct spoolss_FindNextPrinterChangeNotification *r)
9689 p->rng_fault_state = true;
9690 return WERR_NOT_SUPPORTED;
9693 /****************************************************************
9694 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9695 ****************************************************************/
9697 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9698 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9700 p->rng_fault_state = true;
9701 return WERR_NOT_SUPPORTED;
9704 /****************************************************************
9705 _spoolss_ReplyOpenPrinter
9706 ****************************************************************/
9708 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9709 struct spoolss_ReplyOpenPrinter *r)
9711 p->rng_fault_state = true;
9712 return WERR_NOT_SUPPORTED;
9715 /****************************************************************
9716 _spoolss_RouterReplyPrinter
9717 ****************************************************************/
9719 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9720 struct spoolss_RouterReplyPrinter *r)
9722 p->rng_fault_state = true;
9723 return WERR_NOT_SUPPORTED;
9726 /****************************************************************
9727 _spoolss_ReplyClosePrinter
9728 ****************************************************************/
9730 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9731 struct spoolss_ReplyClosePrinter *r)
9733 p->rng_fault_state = true;
9734 return WERR_NOT_SUPPORTED;
9737 /****************************************************************
9739 ****************************************************************/
9741 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9742 struct spoolss_AddPortEx *r)
9744 p->rng_fault_state = true;
9745 return WERR_NOT_SUPPORTED;
9748 /****************************************************************
9749 _spoolss_RouterFindFirstPrinterChangeNotification
9750 ****************************************************************/
9752 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9753 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9755 p->rng_fault_state = true;
9756 return WERR_NOT_SUPPORTED;
9759 /****************************************************************
9760 _spoolss_SpoolerInit
9761 ****************************************************************/
9763 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9764 struct spoolss_SpoolerInit *r)
9766 p->rng_fault_state = true;
9767 return WERR_NOT_SUPPORTED;
9770 /****************************************************************
9771 _spoolss_ResetPrinterEx
9772 ****************************************************************/
9774 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9775 struct spoolss_ResetPrinterEx *r)
9777 p->rng_fault_state = true;
9778 return WERR_NOT_SUPPORTED;
9781 /****************************************************************
9782 _spoolss_RouterReplyPrinterEx
9783 ****************************************************************/
9785 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9786 struct spoolss_RouterReplyPrinterEx *r)
9788 p->rng_fault_state = true;
9789 return WERR_NOT_SUPPORTED;
9792 /****************************************************************
9794 ****************************************************************/
9796 WERROR _spoolss_44(struct pipes_struct *p,
9797 struct spoolss_44 *r)
9799 p->rng_fault_state = true;
9800 return WERR_NOT_SUPPORTED;
9803 /****************************************************************
9805 ****************************************************************/
9807 WERROR _spoolss_47(struct pipes_struct *p,
9808 struct spoolss_47 *r)
9810 p->rng_fault_state = true;
9811 return WERR_NOT_SUPPORTED;
9814 /****************************************************************
9816 ****************************************************************/
9818 WERROR _spoolss_4a(struct pipes_struct *p,
9819 struct spoolss_4a *r)
9821 p->rng_fault_state = true;
9822 return WERR_NOT_SUPPORTED;
9825 /****************************************************************
9827 ****************************************************************/
9829 WERROR _spoolss_4b(struct pipes_struct *p,
9830 struct spoolss_4b *r)
9832 p->rng_fault_state = true;
9833 return WERR_NOT_SUPPORTED;
9836 /****************************************************************
9838 ****************************************************************/
9840 WERROR _spoolss_4c(struct pipes_struct *p,
9841 struct spoolss_4c *r)
9843 p->rng_fault_state = true;
9844 return WERR_NOT_SUPPORTED;
9847 /****************************************************************
9849 ****************************************************************/
9851 WERROR _spoolss_53(struct pipes_struct *p,
9852 struct spoolss_53 *r)
9854 p->rng_fault_state = true;
9855 return WERR_NOT_SUPPORTED;
9858 /****************************************************************
9860 ****************************************************************/
9862 WERROR _spoolss_55(struct pipes_struct *p,
9863 struct spoolss_55 *r)
9865 p->rng_fault_state = true;
9866 return WERR_NOT_SUPPORTED;
9869 /****************************************************************
9871 ****************************************************************/
9873 WERROR _spoolss_56(struct pipes_struct *p,
9874 struct spoolss_56 *r)
9876 p->rng_fault_state = true;
9877 return WERR_NOT_SUPPORTED;
9880 /****************************************************************
9882 ****************************************************************/
9884 WERROR _spoolss_57(struct pipes_struct *p,
9885 struct spoolss_57 *r)
9887 p->rng_fault_state = true;
9888 return WERR_NOT_SUPPORTED;
9891 /****************************************************************
9893 ****************************************************************/
9895 WERROR _spoolss_5a(struct pipes_struct *p,
9896 struct spoolss_5a *r)
9898 p->rng_fault_state = true;
9899 return WERR_NOT_SUPPORTED;
9902 /****************************************************************
9904 ****************************************************************/
9906 WERROR _spoolss_5b(struct pipes_struct *p,
9907 struct spoolss_5b *r)
9909 p->rng_fault_state = true;
9910 return WERR_NOT_SUPPORTED;
9913 /****************************************************************
9915 ****************************************************************/
9917 WERROR _spoolss_5c(struct pipes_struct *p,
9918 struct spoolss_5c *r)
9920 p->rng_fault_state = true;
9921 return WERR_NOT_SUPPORTED;
9924 /****************************************************************
9926 ****************************************************************/
9928 WERROR _spoolss_5d(struct pipes_struct *p,
9929 struct spoolss_5d *r)
9931 p->rng_fault_state = true;
9932 return WERR_NOT_SUPPORTED;
9935 /****************************************************************
9937 ****************************************************************/
9939 WERROR _spoolss_5e(struct pipes_struct *p,
9940 struct spoolss_5e *r)
9942 p->rng_fault_state = true;
9943 return WERR_NOT_SUPPORTED;
9946 /****************************************************************
9948 ****************************************************************/
9950 WERROR _spoolss_5f(struct pipes_struct *p,
9951 struct spoolss_5f *r)
9953 p->rng_fault_state = true;
9954 return WERR_NOT_SUPPORTED;
9957 /****************************************************************
9959 ****************************************************************/
9961 WERROR _spoolss_60(struct pipes_struct *p,
9962 struct spoolss_60 *r)
9964 p->rng_fault_state = true;
9965 return WERR_NOT_SUPPORTED;
9968 /****************************************************************
9970 ****************************************************************/
9972 WERROR _spoolss_61(struct pipes_struct *p,
9973 struct spoolss_61 *r)
9975 p->rng_fault_state = true;
9976 return WERR_NOT_SUPPORTED;
9979 /****************************************************************
9981 ****************************************************************/
9983 WERROR _spoolss_62(struct pipes_struct *p,
9984 struct spoolss_62 *r)
9986 p->rng_fault_state = true;
9987 return WERR_NOT_SUPPORTED;
9990 /****************************************************************
9992 ****************************************************************/
9994 WERROR _spoolss_63(struct pipes_struct *p,
9995 struct spoolss_63 *r)
9997 p->rng_fault_state = true;
9998 return WERR_NOT_SUPPORTED;
10001 /****************************************************************
10003 ****************************************************************/
10005 WERROR _spoolss_64(struct pipes_struct *p,
10006 struct spoolss_64 *r)
10008 p->rng_fault_state = true;
10009 return WERR_NOT_SUPPORTED;
10012 /****************************************************************
10014 ****************************************************************/
10016 WERROR _spoolss_65(struct pipes_struct *p,
10017 struct spoolss_65 *r)
10019 p->rng_fault_state = true;
10020 return WERR_NOT_SUPPORTED;
10023 /****************************************************************
10024 _spoolss_GetCorePrinterDrivers
10025 ****************************************************************/
10027 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
10028 struct spoolss_GetCorePrinterDrivers *r)
10030 p->rng_fault_state = true;
10031 return WERR_NOT_SUPPORTED;
10034 /****************************************************************
10036 ****************************************************************/
10038 WERROR _spoolss_67(struct pipes_struct *p,
10039 struct spoolss_67 *r)
10041 p->rng_fault_state = true;
10042 return WERR_NOT_SUPPORTED;
10045 /****************************************************************
10046 _spoolss_GetPrinterDriverPackagePath
10047 ****************************************************************/
10049 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10050 struct spoolss_GetPrinterDriverPackagePath *r)
10052 p->rng_fault_state = true;
10053 return WERR_NOT_SUPPORTED;
10056 /****************************************************************
10058 ****************************************************************/
10060 WERROR _spoolss_69(struct pipes_struct *p,
10061 struct spoolss_69 *r)
10063 p->rng_fault_state = true;
10064 return WERR_NOT_SUPPORTED;
10067 /****************************************************************
10069 ****************************************************************/
10071 WERROR _spoolss_6a(struct pipes_struct *p,
10072 struct spoolss_6a *r)
10074 p->rng_fault_state = true;
10075 return WERR_NOT_SUPPORTED;
10078 /****************************************************************
10080 ****************************************************************/
10082 WERROR _spoolss_6b(struct pipes_struct *p,
10083 struct spoolss_6b *r)
10085 p->rng_fault_state = true;
10086 return WERR_NOT_SUPPORTED;
10089 /****************************************************************
10091 ****************************************************************/
10093 WERROR _spoolss_6c(struct pipes_struct *p,
10094 struct spoolss_6c *r)
10096 p->rng_fault_state = true;
10097 return WERR_NOT_SUPPORTED;
10100 /****************************************************************
10102 ****************************************************************/
10104 WERROR _spoolss_6d(struct pipes_struct *p,
10105 struct spoolss_6d *r)
10107 p->rng_fault_state = true;
10108 return WERR_NOT_SUPPORTED;