2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009-2010.
11 * Copyright (C) Andreas Schneider 2010.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
39 #include "registry/reg_objects.h"
40 #include "include/printing.h"
42 #include "../librpc/gen_ndr/netlogon.h"
44 /* macros stolen from s4 spoolss server */
45 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
46 ((info)?ndr_size_##fn(info, level, 0):0)
48 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
49 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
51 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
52 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
54 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
57 #define DBGC_CLASS DBGC_RPC_SRV
59 static Printer_entry *printers_list;
61 typedef struct _counter_printer_0 {
62 struct _counter_printer_0 *next;
63 struct _counter_printer_0 *prev;
69 static counter_printer_0 *counter_list;
71 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
72 static uint32_t smb_connections = 0;
75 /* Map generic permissions to printer object specific permissions */
77 const struct standard_mapping printer_std_mapping = {
84 /* Map generic permissions to print server object specific permissions */
86 const struct standard_mapping printserver_std_mapping = {
93 /* API table for Xcv Monitor functions */
95 struct xcv_api_table {
97 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
100 /********************************************************************
101 * Canonicalize servername.
102 ********************************************************************/
104 static const char *canon_servername(const char *servername)
106 const char *pservername = servername;
107 while (*pservername == '\\') {
113 /* translate between internal status numbers and NT status numbers */
114 static int nt_printj_status(int v)
120 return JOB_STATUS_PAUSED;
122 return JOB_STATUS_SPOOLING;
124 return JOB_STATUS_PRINTING;
126 return JOB_STATUS_ERROR;
128 return JOB_STATUS_DELETING;
130 return JOB_STATUS_OFFLINE;
132 return JOB_STATUS_PAPEROUT;
134 return JOB_STATUS_PRINTED;
136 return JOB_STATUS_DELETED;
138 return JOB_STATUS_BLOCKED_DEVQ;
139 case LPQ_USER_INTERVENTION:
140 return JOB_STATUS_USER_INTERVENTION;
145 static int nt_printq_status(int v)
149 return PRINTER_STATUS_PAUSED;
158 /***************************************************************************
159 Disconnect from the client
160 ****************************************************************************/
162 static void srv_spoolss_replycloseprinter(
163 int snum, struct policy_handle *handle,
164 struct messaging_context *msg_ctx)
170 * Tell the specific printing tdb we no longer want messages for this printer
171 * by deregistering our PID.
174 if (!print_notify_deregister_pid(snum))
175 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
177 /* weird if the test succeeds !!! */
178 if (smb_connections==0) {
179 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
183 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
186 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
187 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
188 win_errstr(result)));
190 /* if it's the last connection, deconnect the IPC$ share */
191 if (smb_connections==1) {
193 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
195 * The above call shuts down the pipe also.
197 notify_cli_pipe = NULL;
199 if (msg_ctx != NULL) {
200 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
204 * Tell the serverid.tdb we're no longer
205 * interested in printer notify messages.
208 serverid_register_msg_flags(
209 messaging_server_id(msg_ctx),
210 false, FLAG_MSG_PRINT_NOTIFY);
217 /****************************************************************************
218 Functions to free a printer entry datastruct.
219 ****************************************************************************/
221 static int printer_entry_destructor(Printer_entry *Printer)
223 if (Printer->notify.client_connected == true) {
226 if ( Printer->printer_type == SPLHND_SERVER) {
228 srv_spoolss_replycloseprinter(
229 snum, &Printer->notify.client_hnd,
230 Printer->notify.msg_ctx);
231 } else if (Printer->printer_type == SPLHND_PRINTER) {
232 snum = print_queue_snum(Printer->sharename);
234 srv_spoolss_replycloseprinter(
235 snum, &Printer->notify.client_hnd,
236 Printer->notify.msg_ctx);
240 Printer->notify.flags=0;
241 Printer->notify.options=0;
242 Printer->notify.localmachine[0]='\0';
243 Printer->notify.printerlocal=0;
244 TALLOC_FREE(Printer->notify.option);
245 Printer->notify.client_connected = false;
247 TALLOC_FREE(Printer->devmode);
249 /* Remove from the internal list. */
250 DLIST_REMOVE(printers_list, Printer);
254 /****************************************************************************
255 find printer index by handle
256 ****************************************************************************/
258 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
259 struct policy_handle *hnd)
261 Printer_entry *find_printer = NULL;
263 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
264 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
271 /****************************************************************************
272 Close printer index by handle.
273 ****************************************************************************/
275 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
277 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
280 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
285 close_policy_hnd(p, hnd);
290 /****************************************************************************
291 Delete a printer given a handle.
292 ****************************************************************************/
294 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
295 const char *sharename,
296 struct messaging_context *msg_ctx)
298 char *cmd = lp_deleteprinter_cmd();
299 char *command = NULL;
301 SE_PRIV se_printop = SE_PRINT_OPERATOR;
302 bool is_print_op = false;
304 /* can't fail if we don't try */
309 command = talloc_asprintf(ctx,
316 is_print_op = user_has_privileges( token, &se_printop );
318 DEBUG(10,("Running [%s]\n", command));
320 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
325 if ( (ret = smbrun(command, NULL)) == 0 ) {
326 /* Tell everyone we updated smb.conf. */
327 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
333 /********** END SePrintOperatorPrivlege BLOCK **********/
335 DEBUGADD(10,("returned [%d]\n", ret));
337 TALLOC_FREE(command);
340 return WERR_BADFID; /* What to return here? */
342 /* go ahead and re-read the services immediately */
344 reload_services(false);
347 if ( lp_servicenumber( sharename ) > 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
363 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
369 * It turns out that Windows allows delete printer on a handle
370 * opened by an admin user, then used on a pipe handle created
371 * by an anonymous user..... but they're working on security.... riiight !
375 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
376 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
377 return WERR_ACCESS_DENIED;
380 /* this does not need a become root since the access check has been
381 done on the handle already */
383 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
384 Printer->sharename, "");
385 if (!W_ERROR_IS_OK(result)) {
386 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
390 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
391 Printer->sharename, p->msg_ctx);
394 /****************************************************************************
395 Return the snum of a printer corresponding to an handle.
396 ****************************************************************************/
398 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
399 int *number, struct share_params **params)
401 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
404 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
409 switch (Printer->printer_type) {
411 DEBUG(4,("short name:%s\n", Printer->sharename));
412 *number = print_queue_snum(Printer->sharename);
413 return (*number != -1);
421 /****************************************************************************
422 Set printer handle type.
423 Check if it's \\server or \\server\printer
424 ****************************************************************************/
426 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
428 DEBUG(3,("Setting printer type=%s\n", handlename));
430 if ( strlen(handlename) < 3 ) {
431 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
435 /* it's a print server */
436 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
437 DEBUGADD(4,("Printer is a print server\n"));
438 Printer->printer_type = SPLHND_SERVER;
440 /* it's a printer (set_printer_hnd_name() will handle port monitors */
442 DEBUGADD(4,("Printer is a printer\n"));
443 Printer->printer_type = SPLHND_PRINTER;
449 /****************************************************************************
450 Set printer handle name.. Accept names like \\server, \\server\printer,
451 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
452 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
453 XcvDataPort() interface.
454 ****************************************************************************/
456 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
457 struct auth_serversupplied_info *server_info,
458 Printer_entry *Printer,
459 const char *handlename)
462 int n_services=lp_numservices();
464 const char *printername;
465 const char *servername = NULL;
468 struct spoolss_PrinterInfo2 *info2 = NULL;
471 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
472 (unsigned long)strlen(handlename)));
474 aprinter = CONST_DISCARD(char *, handlename);
475 if ( *handlename == '\\' ) {
476 servername = canon_servername(handlename);
477 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
481 if (!is_myname_or_ipaddr(servername)) {
485 fstrcpy(Printer->servername, servername);
488 if (Printer->printer_type == SPLHND_SERVER) {
492 if (Printer->printer_type != SPLHND_PRINTER) {
496 DEBUGADD(5, ("searching for [%s]\n", aprinter));
498 /* check for the Port Monitor Interface */
499 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
500 Printer->printer_type = SPLHND_PORTMON_TCP;
501 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
504 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
505 Printer->printer_type = SPLHND_PORTMON_LOCAL;
506 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
510 /* Search all sharenames first as this is easier than pulling
511 the printer_info_2 off of disk. Don't use find_service() since
512 that calls out to map_username() */
514 /* do another loop to look for printernames */
515 for (snum = 0; !found && snum < n_services; snum++) {
516 const char *printer = lp_const_servicename(snum);
518 /* no point going on if this is not a printer */
519 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
523 /* ignore [printers] share */
524 if (strequal(printer, "printers")) {
528 fstrcpy(sname, printer);
529 if (strequal(aprinter, printer)) {
534 /* no point looking up the printer object if
535 we aren't allowing printername != sharename */
536 if (lp_force_printername(snum)) {
540 result = winreg_get_printer(mem_ctx,
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,
1371 pinfo2->printername);
1373 if (!W_ERROR_IS_OK(result)) {
1374 DEBUG(3, ("do_drv_upgrade_printer: "
1375 "Failed to update changeid [%s]\n",
1376 win_errstr(result)));
1382 talloc_free(tmp_ctx);
1385 /********************************************************************
1386 Update the cache for all printq's with a registered client
1388 ********************************************************************/
1390 void update_monitored_printq_cache( void )
1392 Printer_entry *printer = printers_list;
1395 /* loop through all printers and update the cache where
1396 client_connected == true */
1399 if ( (printer->printer_type == SPLHND_PRINTER)
1400 && printer->notify.client_connected )
1402 snum = print_queue_snum(printer->sharename);
1403 print_queue_status( snum, NULL, NULL );
1406 printer = printer->next;
1412 /****************************************************************
1413 _spoolss_OpenPrinter
1414 ****************************************************************/
1416 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1417 struct spoolss_OpenPrinter *r)
1419 struct spoolss_OpenPrinterEx e;
1422 ZERO_STRUCT(e.in.userlevel);
1424 e.in.printername = r->in.printername;
1425 e.in.datatype = r->in.datatype;
1426 e.in.devmode_ctr = r->in.devmode_ctr;
1427 e.in.access_mask = r->in.access_mask;
1430 e.out.handle = r->out.handle;
1432 werr = _spoolss_OpenPrinterEx(p, &e);
1434 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1435 /* OpenPrinterEx returns this for a bad
1436 * printer name. We must return WERR_INVALID_PRINTER_NAME
1439 werr = WERR_INVALID_PRINTER_NAME;
1445 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1446 struct spoolss_DeviceMode *orig,
1447 struct spoolss_DeviceMode **dest)
1449 struct spoolss_DeviceMode *dm;
1451 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1456 /* copy all values, then duplicate strings and structs */
1459 dm->devicename = talloc_strdup(dm, orig->devicename);
1460 if (!dm->devicename) {
1463 dm->formname = talloc_strdup(dm, orig->formname);
1464 if (!dm->formname) {
1467 if (orig->driverextra_data.data) {
1468 dm->driverextra_data.data =
1469 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1470 orig->driverextra_data.length);
1471 if (!dm->driverextra_data.data) {
1480 /****************************************************************
1481 _spoolss_OpenPrinterEx
1482 ****************************************************************/
1484 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1485 struct spoolss_OpenPrinterEx *r)
1488 Printer_entry *Printer=NULL;
1490 if (!r->in.printername) {
1491 return WERR_INVALID_PARAM;
1494 /* some sanity check because you can open a printer or a print server */
1495 /* aka: \\server\printer or \\server */
1497 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1499 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1500 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1501 " for printer %s\n", r->in.printername));
1502 ZERO_STRUCTP(r->out.handle);
1503 return WERR_INVALID_PARAM;
1506 Printer = find_printer_index_by_hnd(p, r->out.handle);
1508 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1509 "handle we created for printer %s\n", r->in.printername));
1510 close_printer_handle(p, r->out.handle);
1511 ZERO_STRUCTP(r->out.handle);
1512 return WERR_INVALID_PARAM;
1516 * First case: the user is opening the print server:
1518 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1519 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1521 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1522 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1523 * or if the user is listed in the smb.conf printer admin parameter.
1525 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1526 * client view printer folder, but does not show the MSAPW.
1528 * Note: this test needs code to check access rights here too. Jeremy
1529 * could you look at this?
1531 * Second case: the user is opening a printer:
1532 * NT doesn't let us connect to a printer if the connecting user
1533 * doesn't have print permission.
1535 * Third case: user is opening a Port Monitor
1536 * access checks same as opening a handle to the print server.
1539 switch (Printer->printer_type )
1542 case SPLHND_PORTMON_TCP:
1543 case SPLHND_PORTMON_LOCAL:
1544 /* Printserver handles use global struct... */
1548 /* Map standard access rights to object specific access rights */
1550 se_map_standard(&r->in.access_mask,
1551 &printserver_std_mapping);
1553 /* Deny any object specific bits that don't apply to print
1554 servers (i.e printer and job specific bits) */
1556 r->in.access_mask &= SEC_MASK_SPECIFIC;
1558 if (r->in.access_mask &
1559 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1560 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1561 close_printer_handle(p, r->out.handle);
1562 ZERO_STRUCTP(r->out.handle);
1563 return WERR_ACCESS_DENIED;
1566 /* Allow admin access */
1568 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1570 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1572 if (!lp_ms_add_printer_wizard()) {
1573 close_printer_handle(p, r->out.handle);
1574 ZERO_STRUCTP(r->out.handle);
1575 return WERR_ACCESS_DENIED;
1578 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1579 and not a printer admin, then fail */
1581 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1582 !user_has_privileges(p->server_info->ptok,
1584 !token_contains_name_in_list(
1585 uidtoname(p->server_info->utok.uid),
1586 p->server_info->info3->base.domain.string,
1588 p->server_info->ptok,
1589 lp_printer_admin(snum))) {
1590 close_printer_handle(p, r->out.handle);
1591 ZERO_STRUCTP(r->out.handle);
1592 return WERR_ACCESS_DENIED;
1595 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1599 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1602 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1603 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1605 /* We fall through to return WERR_OK */
1608 case SPLHND_PRINTER:
1609 /* NT doesn't let us connect to a printer if the connecting user
1610 doesn't have print permission. */
1612 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1613 close_printer_handle(p, r->out.handle);
1614 ZERO_STRUCTP(r->out.handle);
1618 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1619 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1622 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1624 /* map an empty access mask to the minimum access mask */
1625 if (r->in.access_mask == 0x0)
1626 r->in.access_mask = PRINTER_ACCESS_USE;
1629 * If we are not serving the printer driver for this printer,
1630 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1631 * will keep NT clients happy --jerry
1634 if (lp_use_client_driver(snum)
1635 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1637 r->in.access_mask = PRINTER_ACCESS_USE;
1640 /* check smb.conf parameters and the the sec_desc */
1642 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1643 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1644 ZERO_STRUCTP(r->out.handle);
1645 return WERR_ACCESS_DENIED;
1648 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1649 p->server_info->ptok, snum) ||
1650 !print_access_check(p->server_info, snum,
1651 r->in.access_mask)) {
1652 DEBUG(3, ("access DENIED for printer open\n"));
1653 close_printer_handle(p, r->out.handle);
1654 ZERO_STRUCTP(r->out.handle);
1655 return WERR_ACCESS_DENIED;
1658 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1659 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1660 close_printer_handle(p, r->out.handle);
1661 ZERO_STRUCTP(r->out.handle);
1662 return WERR_ACCESS_DENIED;
1665 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1666 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1668 r->in.access_mask = PRINTER_ACCESS_USE;
1670 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1671 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1673 winreg_create_printer(p->mem_ctx,
1676 Printer->servername,
1677 lp_const_servicename(snum));
1682 /* sanity check to prevent programmer error */
1683 ZERO_STRUCTP(r->out.handle);
1687 Printer->access_granted = r->in.access_mask;
1690 * If the client sent a devmode in the OpenPrinter() call, then
1691 * save it here in case we get a job submission on this handle
1694 if ((Printer->printer_type != SPLHND_SERVER) &&
1695 r->in.devmode_ctr.devmode) {
1696 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1700 #if 0 /* JERRY -- I'm doubtful this is really effective */
1701 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1702 optimization in Windows 2000 clients --jerry */
1704 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1705 && (RA_WIN2K == get_remote_arch()) )
1707 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1708 sys_usleep( 500000 );
1715 /****************************************************************
1716 _spoolss_ClosePrinter
1717 ****************************************************************/
1719 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1720 struct spoolss_ClosePrinter *r)
1722 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1724 if (Printer && Printer->document_started) {
1725 struct spoolss_EndDocPrinter e;
1727 e.in.handle = r->in.handle;
1729 _spoolss_EndDocPrinter(p, &e);
1732 if (!close_printer_handle(p, r->in.handle))
1735 /* clear the returned printer handle. Observed behavior
1736 from Win2k server. Don't think this really matters.
1737 Previous code just copied the value of the closed
1740 ZERO_STRUCTP(r->out.handle);
1745 /****************************************************************
1746 _spoolss_DeletePrinter
1747 ****************************************************************/
1749 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1750 struct spoolss_DeletePrinter *r)
1752 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1756 if (Printer && Printer->document_started) {
1757 struct spoolss_EndDocPrinter e;
1759 e.in.handle = r->in.handle;
1761 _spoolss_EndDocPrinter(p, &e);
1764 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1765 winreg_delete_printer_key(p->mem_ctx,
1767 lp_const_servicename(snum),
1771 result = delete_printer_handle(p, r->in.handle);
1776 /*******************************************************************
1777 * static function to lookup the version id corresponding to an
1778 * long architecture string
1779 ******************************************************************/
1781 static const struct print_architecture_table_node archi_table[]= {
1783 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1784 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1785 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1786 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1787 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1788 {"Windows IA64", SPL_ARCH_IA64, 3 },
1789 {"Windows x64", SPL_ARCH_X64, 3 },
1793 static int get_version_id(const char *arch)
1797 for (i=0; archi_table[i].long_archi != NULL; i++)
1799 if (strcmp(arch, archi_table[i].long_archi) == 0)
1800 return (archi_table[i].version);
1806 /****************************************************************
1807 _spoolss_DeletePrinterDriver
1808 ****************************************************************/
1810 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1811 struct spoolss_DeletePrinterDriver *r)
1814 struct spoolss_DriverInfo8 *info = NULL;
1815 struct spoolss_DriverInfo8 *info_win2k = NULL;
1818 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1820 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1821 and not a printer admin, then fail */
1823 if ( (p->server_info->utok.uid != sec_initial_uid())
1824 && !user_has_privileges(p->server_info->ptok, &se_printop )
1825 && !token_contains_name_in_list(
1826 uidtoname(p->server_info->utok.uid),
1827 p->server_info->info3->base.domain.string,
1829 p->server_info->ptok,
1830 lp_printer_admin(-1)) )
1832 return WERR_ACCESS_DENIED;
1835 /* check that we have a valid driver name first */
1837 if ((version = get_version_id(r->in.architecture)) == -1)
1838 return WERR_INVALID_ENVIRONMENT;
1840 status = winreg_get_driver(p->mem_ctx, p->server_info,
1841 r->in.architecture, r->in.driver,
1843 if (!W_ERROR_IS_OK(status)) {
1844 /* try for Win2k driver if "Windows NT x86" */
1846 if ( version == 2 ) {
1849 status = winreg_get_driver(p->mem_ctx, p->server_info,
1853 if (!W_ERROR_IS_OK(status)) {
1854 status = WERR_UNKNOWN_PRINTER_DRIVER;
1858 /* otherwise it was a failure */
1860 status = WERR_UNKNOWN_PRINTER_DRIVER;
1866 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1867 status = WERR_PRINTER_DRIVER_IN_USE;
1872 status = winreg_get_driver(p->mem_ctx, p->server_info,
1874 r->in.driver, 3, &info_win2k);
1875 if (W_ERROR_IS_OK(status)) {
1876 /* if we get to here, we now have 2 driver info structures to remove */
1877 /* remove the Win2k driver first*/
1879 status = winreg_del_driver(p->mem_ctx,
1882 talloc_free(info_win2k);
1884 /* this should not have failed---if it did, report to client */
1885 if (!W_ERROR_IS_OK(status)) {
1891 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1899 /****************************************************************
1900 _spoolss_DeletePrinterDriverEx
1901 ****************************************************************/
1903 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1904 struct spoolss_DeletePrinterDriverEx *r)
1906 struct spoolss_DriverInfo8 *info = NULL;
1907 struct spoolss_DriverInfo8 *info_win2k = NULL;
1911 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1913 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1914 and not a printer admin, then fail */
1916 if ( (p->server_info->utok.uid != sec_initial_uid())
1917 && !user_has_privileges(p->server_info->ptok, &se_printop )
1918 && !token_contains_name_in_list(
1919 uidtoname(p->server_info->utok.uid),
1920 p->server_info->info3->base.domain.string,
1922 p->server_info->ptok, lp_printer_admin(-1)) )
1924 return WERR_ACCESS_DENIED;
1927 /* check that we have a valid driver name first */
1928 if ((version = get_version_id(r->in.architecture)) == -1) {
1929 /* this is what NT returns */
1930 return WERR_INVALID_ENVIRONMENT;
1933 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1934 version = r->in.version;
1936 status = winreg_get_driver(p->mem_ctx, p->server_info,
1937 r->in.architecture, r->in.driver,
1939 if (!W_ERROR_IS_OK(status)) {
1940 status = WERR_UNKNOWN_PRINTER_DRIVER;
1943 * if the client asked for a specific version,
1944 * or this is something other than Windows NT x86,
1948 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1951 /* try for Win2k driver if "Windows NT x86" */
1954 status = winreg_get_driver(info, p->server_info,
1958 if (!W_ERROR_IS_OK(status)) {
1959 status = WERR_UNKNOWN_PRINTER_DRIVER;
1964 if (printer_driver_in_use(info, p->server_info, info)) {
1965 status = WERR_PRINTER_DRIVER_IN_USE;
1970 * we have a couple of cases to consider.
1971 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1972 * then the delete should fail if **any** files overlap with
1974 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1975 * non-overlapping files
1976 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1977 * is set, the do not delete any files
1978 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1981 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1983 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1986 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1987 printer_driver_files_in_use(info, p->server_info, info)) {
1988 /* no idea of the correct error here */
1989 status = WERR_ACCESS_DENIED;
1994 /* also check for W32X86/3 if necessary; maybe we already have? */
1996 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1997 status = winreg_get_driver(info, p->server_info,
1999 r->in.driver, 3, &info_win2k);
2000 if (W_ERROR_IS_OK(status)) {
2003 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2004 printer_driver_files_in_use(info, p->server_info,
2006 /* no idea of the correct error here */
2007 talloc_free(info_win2k);
2008 status = WERR_ACCESS_DENIED;
2012 /* if we get to here, we now have 2 driver info structures to remove */
2013 /* remove the Win2k driver first*/
2015 status = winreg_del_driver(info, p->server_info,
2018 /* this should not have failed---if it did, report to client */
2020 if (!W_ERROR_IS_OK(status)) {
2025 * now delete any associated files if delete_files is
2026 * true. Even if this part failes, we return succes
2027 * because the driver doesn not exist any more
2030 delete_driver_files(p->server_info,
2036 status = winreg_del_driver(info, p->server_info, info, version);
2037 if (!W_ERROR_IS_OK(status)) {
2042 * now delete any associated files if delete_files is
2043 * true. Even if this part failes, we return succes
2044 * because the driver doesn not exist any more
2047 delete_driver_files(p->server_info, info);
2056 /********************************************************************
2057 GetPrinterData on a printer server Handle.
2058 ********************************************************************/
2060 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2062 enum winreg_Type *type,
2063 union spoolss_PrinterData *data)
2065 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2067 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2073 if (!StrCaseCmp(value, "BeepEnabled")) {
2079 if (!StrCaseCmp(value, "EventLog")) {
2081 /* formally was 0x1b */
2086 if (!StrCaseCmp(value, "NetPopup")) {
2092 if (!StrCaseCmp(value, "MajorVersion")) {
2095 /* Windows NT 4.0 seems to not allow uploading of drivers
2096 to a server that reports 0x3 as the MajorVersion.
2097 need to investigate more how Win2k gets around this .
2100 if (RA_WINNT == get_remote_arch()) {
2109 if (!StrCaseCmp(value, "MinorVersion")) {
2116 * uint32_t size = 0x114
2117 * uint32_t major = 5
2118 * uint32_t minor = [0|1]
2119 * uint32_t build = [2195|2600]
2120 * extra unicode string = e.g. "Service Pack 3"
2122 if (!StrCaseCmp(value, "OSVersion")) {
2124 enum ndr_err_code ndr_err;
2125 struct spoolss_OSVersion os;
2127 os.major = 5; /* Windows 2000 == 5.0 */
2129 os.build = 2195; /* build */
2130 os.extra_string = ""; /* leave extra string empty */
2132 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2133 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2134 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2135 return WERR_GENERAL_FAILURE;
2139 data->binary = blob;
2145 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2148 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2149 W_ERROR_HAVE_NO_MEMORY(data->string);
2154 if (!StrCaseCmp(value, "Architecture")) {
2156 data->string = talloc_strdup(mem_ctx,
2157 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2158 W_ERROR_HAVE_NO_MEMORY(data->string);
2163 if (!StrCaseCmp(value, "DsPresent")) {
2166 /* only show the publish check box if we are a
2167 member of a AD domain */
2169 if (lp_security() == SEC_ADS) {
2177 if (!StrCaseCmp(value, "DNSMachineName")) {
2178 const char *hostname = get_mydnsfullname();
2181 return WERR_BADFILE;
2185 data->string = talloc_strdup(mem_ctx, hostname);
2186 W_ERROR_HAVE_NO_MEMORY(data->string);
2193 return WERR_INVALID_PARAM;
2196 /****************************************************************
2197 _spoolss_GetPrinterData
2198 ****************************************************************/
2200 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2201 struct spoolss_GetPrinterData *r)
2203 struct spoolss_GetPrinterDataEx r2;
2205 r2.in.handle = r->in.handle;
2206 r2.in.key_name = "PrinterDriverData";
2207 r2.in.value_name = r->in.value_name;
2208 r2.in.offered = r->in.offered;
2209 r2.out.type = r->out.type;
2210 r2.out.data = r->out.data;
2211 r2.out.needed = r->out.needed;
2213 return _spoolss_GetPrinterDataEx(p, &r2);
2216 /*********************************************************
2217 Connect to the client machine.
2218 **********************************************************/
2220 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2221 struct sockaddr_storage *client_ss, const char *remote_machine)
2224 struct cli_state *the_cli;
2225 struct sockaddr_storage rm_addr;
2226 char addr[INET6_ADDRSTRLEN];
2228 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2229 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2231 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2232 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2235 print_sockaddr(addr, sizeof(addr), &rm_addr);
2237 rm_addr = *client_ss;
2238 print_sockaddr(addr, sizeof(addr), &rm_addr);
2239 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2243 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2244 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2249 /* setup the connection */
2250 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2251 &rm_addr, 0, "IPC$", "IPC",
2255 0, lp_client_signing(), NULL );
2257 if ( !NT_STATUS_IS_OK( ret ) ) {
2258 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2263 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2264 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2265 cli_shutdown(the_cli);
2270 * Ok - we have an anonymous connection to the IPC$ share.
2271 * Now start the NT Domain stuff :-).
2274 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2275 if (!NT_STATUS_IS_OK(ret)) {
2276 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2277 remote_machine, nt_errstr(ret)));
2278 cli_shutdown(the_cli);
2285 /***************************************************************************
2286 Connect to the client.
2287 ****************************************************************************/
2289 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2290 uint32_t localprinter, uint32_t type,
2291 struct policy_handle *handle,
2292 struct sockaddr_storage *client_ss,
2293 struct messaging_context *msg_ctx)
2299 * If it's the first connection, contact the client
2300 * and connect to the IPC$ share anonymously
2302 if (smb_connections==0) {
2303 fstring unix_printer;
2305 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2307 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2310 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2311 receive_notify2_message_list);
2312 /* Tell the connections db we're now interested in printer
2313 * notify messages. */
2314 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2315 true, FLAG_MSG_PRINT_NOTIFY);
2319 * Tell the specific printing tdb we want messages for this printer
2320 * by registering our PID.
2323 if (!print_notify_register_pid(snum))
2324 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2328 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2336 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2337 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2338 win_errstr(result)));
2340 return (W_ERROR_IS_OK(result));
2343 /****************************************************************
2344 ****************************************************************/
2346 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2347 const struct spoolss_NotifyOption *r)
2349 struct spoolss_NotifyOption *option;
2356 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2363 if (!option->count) {
2367 option->types = talloc_zero_array(option,
2368 struct spoolss_NotifyOptionType, option->count);
2369 if (!option->types) {
2370 talloc_free(option);
2374 for (i=0; i < option->count; i++) {
2375 option->types[i] = r->types[i];
2377 if (option->types[i].count) {
2378 option->types[i].fields = talloc_zero_array(option,
2379 union spoolss_Field, option->types[i].count);
2380 if (!option->types[i].fields) {
2381 talloc_free(option);
2384 for (k=0; k<option->types[i].count; k++) {
2385 option->types[i].fields[k] =
2386 r->types[i].fields[k];
2394 /****************************************************************
2395 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2397 * before replying OK: status=0 a rpc call is made to the workstation
2398 * asking ReplyOpenPrinter
2400 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2401 * called from api_spoolss_rffpcnex
2402 ****************************************************************/
2404 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2405 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2408 struct spoolss_NotifyOption *option = r->in.notify_options;
2409 struct sockaddr_storage client_ss;
2411 /* store the notify value in the printer struct */
2413 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2416 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2417 "Invalid handle (%s:%u:%u).\n",
2418 OUR_HANDLE(r->in.handle)));
2422 Printer->notify.flags = r->in.flags;
2423 Printer->notify.options = r->in.options;
2424 Printer->notify.printerlocal = r->in.printer_local;
2425 Printer->notify.msg_ctx = p->msg_ctx;
2427 TALLOC_FREE(Printer->notify.option);
2428 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2430 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2432 /* Connect to the client machine and send a ReplyOpenPrinter */
2434 if ( Printer->printer_type == SPLHND_SERVER)
2436 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2437 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2440 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2441 "client_address is %s\n", p->client_address));
2443 if (!interpret_string_addr(&client_ss, p->client_address,
2445 return WERR_SERVER_UNAVAILABLE;
2448 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2449 Printer->notify.printerlocal, 1,
2450 &Printer->notify.client_hnd,
2451 &client_ss, p->msg_ctx))
2452 return WERR_SERVER_UNAVAILABLE;
2454 Printer->notify.client_connected = true;
2459 /*******************************************************************
2460 * fill a notify_info_data with the servername
2461 ********************************************************************/
2463 static void spoolss_notify_server_name(int snum,
2464 struct spoolss_Notify *data,
2465 print_queue_struct *queue,
2466 struct spoolss_PrinterInfo2 *pinfo2,
2467 TALLOC_CTX *mem_ctx)
2469 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2472 /*******************************************************************
2473 * fill a notify_info_data with the printername (not including the servername).
2474 ********************************************************************/
2476 static void spoolss_notify_printer_name(int snum,
2477 struct spoolss_Notify *data,
2478 print_queue_struct *queue,
2479 struct spoolss_PrinterInfo2 *pinfo2,
2480 TALLOC_CTX *mem_ctx)
2482 /* the notify name should not contain the \\server\ part */
2483 const char *p = strrchr(pinfo2->printername, '\\');
2486 p = pinfo2->printername;
2491 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2494 /*******************************************************************
2495 * fill a notify_info_data with the servicename
2496 ********************************************************************/
2498 static void spoolss_notify_share_name(int snum,
2499 struct spoolss_Notify *data,
2500 print_queue_struct *queue,
2501 struct spoolss_PrinterInfo2 *pinfo2,
2502 TALLOC_CTX *mem_ctx)
2504 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2507 /*******************************************************************
2508 * fill a notify_info_data with the port name
2509 ********************************************************************/
2511 static void spoolss_notify_port_name(int snum,
2512 struct spoolss_Notify *data,
2513 print_queue_struct *queue,
2514 struct spoolss_PrinterInfo2 *pinfo2,
2515 TALLOC_CTX *mem_ctx)
2517 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2520 /*******************************************************************
2521 * fill a notify_info_data with the printername
2522 * but it doesn't exist, have to see what to do
2523 ********************************************************************/
2525 static void spoolss_notify_driver_name(int snum,
2526 struct spoolss_Notify *data,
2527 print_queue_struct *queue,
2528 struct spoolss_PrinterInfo2 *pinfo2,
2529 TALLOC_CTX *mem_ctx)
2531 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2534 /*******************************************************************
2535 * fill a notify_info_data with the comment
2536 ********************************************************************/
2538 static void spoolss_notify_comment(int snum,
2539 struct spoolss_Notify *data,
2540 print_queue_struct *queue,
2541 struct spoolss_PrinterInfo2 *pinfo2,
2542 TALLOC_CTX *mem_ctx)
2546 if (*pinfo2->comment == '\0') {
2547 p = lp_comment(snum);
2549 p = pinfo2->comment;
2552 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2555 /*******************************************************************
2556 * fill a notify_info_data with the comment
2557 * location = "Room 1, floor 2, building 3"
2558 ********************************************************************/
2560 static void spoolss_notify_location(int snum,
2561 struct spoolss_Notify *data,
2562 print_queue_struct *queue,
2563 struct spoolss_PrinterInfo2 *pinfo2,
2564 TALLOC_CTX *mem_ctx)
2566 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2569 /*******************************************************************
2570 * fill a notify_info_data with the device mode
2571 * jfm:xxxx don't to it for know but that's a real problem !!!
2572 ********************************************************************/
2574 static void spoolss_notify_devmode(int snum,
2575 struct spoolss_Notify *data,
2576 print_queue_struct *queue,
2577 struct spoolss_PrinterInfo2 *pinfo2,
2578 TALLOC_CTX *mem_ctx)
2580 /* for a dummy implementation we have to zero the fields */
2581 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2584 /*******************************************************************
2585 * fill a notify_info_data with the separator file name
2586 ********************************************************************/
2588 static void spoolss_notify_sepfile(int snum,
2589 struct spoolss_Notify *data,
2590 print_queue_struct *queue,
2591 struct spoolss_PrinterInfo2 *pinfo2,
2592 TALLOC_CTX *mem_ctx)
2594 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2597 /*******************************************************************
2598 * fill a notify_info_data with the print processor
2599 * jfm:xxxx return always winprint to indicate we don't do anything to it
2600 ********************************************************************/
2602 static void spoolss_notify_print_processor(int snum,
2603 struct spoolss_Notify *data,
2604 print_queue_struct *queue,
2605 struct spoolss_PrinterInfo2 *pinfo2,
2606 TALLOC_CTX *mem_ctx)
2608 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2611 /*******************************************************************
2612 * fill a notify_info_data with the print processor options
2613 * jfm:xxxx send an empty string
2614 ********************************************************************/
2616 static void spoolss_notify_parameters(int snum,
2617 struct spoolss_Notify *data,
2618 print_queue_struct *queue,
2619 struct spoolss_PrinterInfo2 *pinfo2,
2620 TALLOC_CTX *mem_ctx)
2622 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2625 /*******************************************************************
2626 * fill a notify_info_data with the data type
2627 * jfm:xxxx always send RAW as data type
2628 ********************************************************************/
2630 static void spoolss_notify_datatype(int snum,
2631 struct spoolss_Notify *data,
2632 print_queue_struct *queue,
2633 struct spoolss_PrinterInfo2 *pinfo2,
2634 TALLOC_CTX *mem_ctx)
2636 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2639 /*******************************************************************
2640 * fill a notify_info_data with the security descriptor
2641 * jfm:xxxx send an null pointer to say no security desc
2642 * have to implement security before !
2643 ********************************************************************/
2645 static void spoolss_notify_security_desc(int snum,
2646 struct spoolss_Notify *data,
2647 print_queue_struct *queue,
2648 struct spoolss_PrinterInfo2 *pinfo2,
2649 TALLOC_CTX *mem_ctx)
2651 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2654 /*******************************************************************
2655 * fill a notify_info_data with the attributes
2656 * jfm:xxxx a samba printer is always shared
2657 ********************************************************************/
2659 static void spoolss_notify_attributes(int snum,
2660 struct spoolss_Notify *data,
2661 print_queue_struct *queue,
2662 struct spoolss_PrinterInfo2 *pinfo2,
2663 TALLOC_CTX *mem_ctx)
2665 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2668 /*******************************************************************
2669 * fill a notify_info_data with the priority
2670 ********************************************************************/
2672 static void spoolss_notify_priority(int snum,
2673 struct spoolss_Notify *data,
2674 print_queue_struct *queue,
2675 struct spoolss_PrinterInfo2 *pinfo2,
2676 TALLOC_CTX *mem_ctx)
2678 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2681 /*******************************************************************
2682 * fill a notify_info_data with the default priority
2683 ********************************************************************/
2685 static void spoolss_notify_default_priority(int snum,
2686 struct spoolss_Notify *data,
2687 print_queue_struct *queue,
2688 struct spoolss_PrinterInfo2 *pinfo2,
2689 TALLOC_CTX *mem_ctx)
2691 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2694 /*******************************************************************
2695 * fill a notify_info_data with the start time
2696 ********************************************************************/
2698 static void spoolss_notify_start_time(int snum,
2699 struct spoolss_Notify *data,
2700 print_queue_struct *queue,
2701 struct spoolss_PrinterInfo2 *pinfo2,
2702 TALLOC_CTX *mem_ctx)
2704 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2707 /*******************************************************************
2708 * fill a notify_info_data with the until time
2709 ********************************************************************/
2711 static void spoolss_notify_until_time(int snum,
2712 struct spoolss_Notify *data,
2713 print_queue_struct *queue,
2714 struct spoolss_PrinterInfo2 *pinfo2,
2715 TALLOC_CTX *mem_ctx)
2717 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2720 /*******************************************************************
2721 * fill a notify_info_data with the status
2722 ********************************************************************/
2724 static void spoolss_notify_status(int snum,
2725 struct spoolss_Notify *data,
2726 print_queue_struct *queue,
2727 struct spoolss_PrinterInfo2 *pinfo2,
2728 TALLOC_CTX *mem_ctx)
2730 print_status_struct status;
2732 print_queue_length(snum, &status);
2733 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2736 /*******************************************************************
2737 * fill a notify_info_data with the number of jobs queued
2738 ********************************************************************/
2740 static void spoolss_notify_cjobs(int snum,
2741 struct spoolss_Notify *data,
2742 print_queue_struct *queue,
2743 struct spoolss_PrinterInfo2 *pinfo2,
2744 TALLOC_CTX *mem_ctx)
2746 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2749 /*******************************************************************
2750 * fill a notify_info_data with the average ppm
2751 ********************************************************************/
2753 static void spoolss_notify_average_ppm(int snum,
2754 struct spoolss_Notify *data,
2755 print_queue_struct *queue,
2756 struct spoolss_PrinterInfo2 *pinfo2,
2757 TALLOC_CTX *mem_ctx)
2759 /* always respond 8 pages per minutes */
2760 /* a little hard ! */
2761 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2764 /*******************************************************************
2765 * fill a notify_info_data with username
2766 ********************************************************************/
2768 static void spoolss_notify_username(int snum,
2769 struct spoolss_Notify *data,
2770 print_queue_struct *queue,
2771 struct spoolss_PrinterInfo2 *pinfo2,
2772 TALLOC_CTX *mem_ctx)
2774 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2777 /*******************************************************************
2778 * fill a notify_info_data with job status
2779 ********************************************************************/
2781 static void spoolss_notify_job_status(int snum,
2782 struct spoolss_Notify *data,
2783 print_queue_struct *queue,
2784 struct spoolss_PrinterInfo2 *pinfo2,
2785 TALLOC_CTX *mem_ctx)
2787 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2790 /*******************************************************************
2791 * fill a notify_info_data with job name
2792 ********************************************************************/
2794 static void spoolss_notify_job_name(int snum,
2795 struct spoolss_Notify *data,
2796 print_queue_struct *queue,
2797 struct spoolss_PrinterInfo2 *pinfo2,
2798 TALLOC_CTX *mem_ctx)
2800 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2803 /*******************************************************************
2804 * fill a notify_info_data with job status
2805 ********************************************************************/
2807 static void spoolss_notify_job_status_string(int snum,
2808 struct spoolss_Notify *data,
2809 print_queue_struct *queue,
2810 struct spoolss_PrinterInfo2 *pinfo2,
2811 TALLOC_CTX *mem_ctx)
2814 * Now we're returning job status codes we just return a "" here. JRA.
2819 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2822 switch (queue->status) {
2827 p = ""; /* NT provides the paused string */
2836 #endif /* NO LONGER NEEDED. */
2838 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2841 /*******************************************************************
2842 * fill a notify_info_data with job time
2843 ********************************************************************/
2845 static void spoolss_notify_job_time(int snum,
2846 struct spoolss_Notify *data,
2847 print_queue_struct *queue,
2848 struct spoolss_PrinterInfo2 *pinfo2,
2849 TALLOC_CTX *mem_ctx)
2851 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2854 /*******************************************************************
2855 * fill a notify_info_data with job size
2856 ********************************************************************/
2858 static void spoolss_notify_job_size(int snum,
2859 struct spoolss_Notify *data,
2860 print_queue_struct *queue,
2861 struct spoolss_PrinterInfo2 *pinfo2,
2862 TALLOC_CTX *mem_ctx)
2864 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2867 /*******************************************************************
2868 * fill a notify_info_data with page info
2869 ********************************************************************/
2870 static void spoolss_notify_total_pages(int snum,
2871 struct spoolss_Notify *data,
2872 print_queue_struct *queue,
2873 struct spoolss_PrinterInfo2 *pinfo2,
2874 TALLOC_CTX *mem_ctx)
2876 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2879 /*******************************************************************
2880 * fill a notify_info_data with pages printed info.
2881 ********************************************************************/
2882 static void spoolss_notify_pages_printed(int snum,
2883 struct spoolss_Notify *data,
2884 print_queue_struct *queue,
2885 struct spoolss_PrinterInfo2 *pinfo2,
2886 TALLOC_CTX *mem_ctx)
2888 /* Add code when back-end tracks this */
2889 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2892 /*******************************************************************
2893 Fill a notify_info_data with job position.
2894 ********************************************************************/
2896 static void spoolss_notify_job_position(int snum,
2897 struct spoolss_Notify *data,
2898 print_queue_struct *queue,
2899 struct spoolss_PrinterInfo2 *pinfo2,
2900 TALLOC_CTX *mem_ctx)
2902 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2905 /*******************************************************************
2906 Fill a notify_info_data with submitted time.
2907 ********************************************************************/
2909 static void spoolss_notify_submitted_time(int snum,
2910 struct spoolss_Notify *data,
2911 print_queue_struct *queue,
2912 struct spoolss_PrinterInfo2 *pinfo2,
2913 TALLOC_CTX *mem_ctx)
2915 data->data.string.string = NULL;
2916 data->data.string.size = 0;
2918 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2919 &data->data.string.string,
2920 &data->data.string.size);
2924 struct s_notify_info_data_table
2926 enum spoolss_NotifyType type;
2929 enum spoolss_NotifyTable variable_type;
2930 void (*fn) (int snum, struct spoolss_Notify *data,
2931 print_queue_struct *queue,
2932 struct spoolss_PrinterInfo2 *pinfo2,
2933 TALLOC_CTX *mem_ctx);
2936 /* A table describing the various print notification constants and
2937 whether the notification data is a pointer to a variable sized
2938 buffer, a one value uint32_t or a two value uint32_t. */
2940 static const struct s_notify_info_data_table notify_info_data_table[] =
2942 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2943 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2950 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2951 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2952 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2953 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2954 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2955 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2956 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2957 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2958 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2959 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2960 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2961 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2962 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2963 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2964 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2965 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2966 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2967 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2968 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2969 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2970 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2971 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2972 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2973 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2974 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2975 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2976 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2977 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2978 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2979 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2980 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2981 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2982 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2983 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2984 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2985 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2986 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2987 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2988 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2989 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2990 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2993 /*******************************************************************
2994 Return the variable_type of info_data structure.
2995 ********************************************************************/
2997 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3002 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3003 if ( (notify_info_data_table[i].type == type) &&
3004 (notify_info_data_table[i].field == field) ) {
3005 return notify_info_data_table[i].variable_type;
3009 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3014 /****************************************************************************
3015 ****************************************************************************/
3017 static bool search_notify(enum spoolss_NotifyType type,
3023 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3024 if (notify_info_data_table[i].type == type &&
3025 notify_info_data_table[i].field == field &&
3026 notify_info_data_table[i].fn != NULL) {
3035 /****************************************************************************
3036 ****************************************************************************/
3038 static void construct_info_data(struct spoolss_Notify *info_data,
3039 enum spoolss_NotifyType type,
3040 uint16_t field, int id)
3042 info_data->type = type;
3043 info_data->field.field = field;
3044 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3045 info_data->job_id = id;
3048 /*******************************************************************
3050 * fill a notify_info struct with info asked
3052 ********************************************************************/
3054 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3055 struct spoolss_NotifyInfo *info,
3056 struct spoolss_PrinterInfo2 *pinfo2,
3058 const struct spoolss_NotifyOptionType *option_type,
3060 TALLOC_CTX *mem_ctx)
3063 enum spoolss_NotifyType type;
3066 struct spoolss_Notify *current_data;
3067 print_queue_struct *queue=NULL;
3069 type = option_type->type;
3071 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3072 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3073 option_type->count, lp_servicename(snum)));
3075 for(field_num=0; field_num < option_type->count; field_num++) {
3076 field = option_type->fields[field_num].field;
3078 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3080 if (!search_notify(type, field, &j) )
3083 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3084 struct spoolss_Notify,
3086 if (info->notifies == NULL) {
3087 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3091 current_data = &info->notifies[info->count];
3093 construct_info_data(current_data, type, field, id);
3095 DEBUG(10, ("construct_notify_printer_info: "
3096 "calling [%s] snum=%d printername=[%s])\n",
3097 notify_info_data_table[j].name, snum,
3098 pinfo2->printername));
3100 notify_info_data_table[j].fn(snum, current_data, queue,
3109 /*******************************************************************
3111 * fill a notify_info struct with info asked
3113 ********************************************************************/
3115 static bool construct_notify_jobs_info(print_queue_struct *queue,
3116 struct spoolss_NotifyInfo *info,
3117 struct spoolss_PrinterInfo2 *pinfo2,
3119 const struct spoolss_NotifyOptionType *option_type,
3121 TALLOC_CTX *mem_ctx)
3124 enum spoolss_NotifyType type;
3126 struct spoolss_Notify *current_data;
3128 DEBUG(4,("construct_notify_jobs_info\n"));
3130 type = option_type->type;
3132 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3133 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3134 option_type->count));
3136 for(field_num=0; field_num<option_type->count; field_num++) {
3137 field = option_type->fields[field_num].field;
3139 if (!search_notify(type, field, &j) )
3142 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3143 struct spoolss_Notify,
3145 if (info->notifies == NULL) {
3146 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3150 current_data=&(info->notifies[info->count]);
3152 construct_info_data(current_data, type, field, id);
3153 notify_info_data_table[j].fn(snum, current_data, queue,
3162 * JFM: The enumeration is not that simple, it's even non obvious.
3164 * let's take an example: I want to monitor the PRINTER SERVER for
3165 * the printer's name and the number of jobs currently queued.
3166 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3167 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3169 * I have 3 printers on the back of my server.
3171 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3174 * 1 printer 1 name 1
3175 * 2 printer 1 cjob 1
3176 * 3 printer 2 name 2
3177 * 4 printer 2 cjob 2
3178 * 5 printer 3 name 3
3179 * 6 printer 3 name 3
3181 * that's the print server case, the printer case is even worse.
3184 /*******************************************************************
3186 * enumerate all printers on the printserver
3187 * fill a notify_info struct with info asked
3189 ********************************************************************/
3191 static WERROR printserver_notify_info(struct pipes_struct *p,
3192 struct policy_handle *hnd,
3193 struct spoolss_NotifyInfo *info,
3194 TALLOC_CTX *mem_ctx)
3197 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3198 int n_services=lp_numservices();
3200 struct spoolss_NotifyOption *option;
3201 struct spoolss_NotifyOptionType option_type;
3202 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3205 DEBUG(4,("printserver_notify_info\n"));
3210 option = Printer->notify.option;
3213 info->notifies = NULL;
3216 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3217 sending a ffpcn() request first */
3222 for (i=0; i<option->count; i++) {
3223 option_type = option->types[i];
3225 if (option_type.type != PRINTER_NOTIFY_TYPE)
3228 for (snum = 0; snum < n_services; snum++) {
3229 if (!lp_browseable(snum) ||
3230 !lp_snum_ok(snum) ||
3231 !lp_print_ok(snum)) {
3232 continue; /* skip */
3235 /* Maybe we should use the SYSTEM server_info here... */
3236 result = winreg_get_printer(mem_ctx, p->server_info,
3238 Printer->servername,
3239 lp_servicename(snum),
3241 if (!W_ERROR_IS_OK(result)) {
3242 DEBUG(4, ("printserver_notify_info: "
3243 "Failed to get printer [%s]\n",
3244 lp_servicename(snum)));
3249 construct_notify_printer_info(Printer, info,
3254 TALLOC_FREE(pinfo2);
3260 * Debugging information, don't delete.
3263 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3264 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3265 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3267 for (i=0; i<info->count; i++) {
3268 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3269 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3270 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3277 /*******************************************************************
3279 * fill a notify_info struct with info asked
3281 ********************************************************************/
3283 static WERROR printer_notify_info(struct pipes_struct *p,
3284 struct policy_handle *hnd,
3285 struct spoolss_NotifyInfo *info,
3286 TALLOC_CTX *mem_ctx)
3289 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3292 struct spoolss_NotifyOption *option;
3293 struct spoolss_NotifyOptionType option_type;
3295 print_queue_struct *queue=NULL;
3296 print_status_struct status;
3297 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3300 DEBUG(4,("printer_notify_info\n"));
3305 option = Printer->notify.option;
3309 info->notifies = NULL;
3312 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3313 sending a ffpcn() request first */
3318 get_printer_snum(p, hnd, &snum, NULL);
3320 /* Maybe we should use the SYSTEM server_info here... */
3321 result = winreg_get_printer(mem_ctx, p->server_info, p->msg_ctx,
3322 Printer->servername,
3323 lp_servicename(snum), &pinfo2);
3324 if (!W_ERROR_IS_OK(result)) {
3328 for (i=0; i<option->count; i++) {
3329 option_type = option->types[i];
3331 switch (option_type.type) {
3332 case PRINTER_NOTIFY_TYPE:
3333 if (construct_notify_printer_info(Printer, info,
3341 case JOB_NOTIFY_TYPE:
3343 count = print_queue_status(snum, &queue, &status);
3345 for (j=0; j<count; j++) {
3346 construct_notify_jobs_info(&queue[j], info,
3359 * Debugging information, don't delete.
3362 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3363 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3364 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3366 for (i=0; i<info->count; i++) {
3367 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3368 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3369 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3373 talloc_free(pinfo2);
3377 /****************************************************************
3378 _spoolss_RouterRefreshPrinterChangeNotify
3379 ****************************************************************/
3381 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3382 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3384 struct spoolss_NotifyInfo *info;
3386 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3387 WERROR result = WERR_BADFID;
3389 /* we always have a spoolss_NotifyInfo struct */
3390 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3392 result = WERR_NOMEM;
3396 *r->out.info = info;
3399 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3400 "Invalid handle (%s:%u:%u).\n",
3401 OUR_HANDLE(r->in.handle)));
3405 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3408 * We are now using the change value, and
3409 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3410 * I don't have a global notification system, I'm sending back all the
3411 * informations even when _NOTHING_ has changed.
3414 /* We need to keep track of the change value to send back in
3415 RRPCN replies otherwise our updates are ignored. */
3417 Printer->notify.fnpcn = true;
3419 if (Printer->notify.client_connected) {
3420 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3421 "Saving change value in request [%x]\n",
3423 Printer->notify.change = r->in.change_low;
3426 /* just ignore the spoolss_NotifyOption */
3428 switch (Printer->printer_type) {
3430 result = printserver_notify_info(p, r->in.handle,
3434 case SPLHND_PRINTER:
3435 result = printer_notify_info(p, r->in.handle,
3440 Printer->notify.fnpcn = false;
3446 /********************************************************************
3447 * construct_printer_info_0
3448 * fill a printer_info_0 struct
3449 ********************************************************************/
3451 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3452 struct auth_serversupplied_info *server_info,
3453 struct spoolss_PrinterInfo2 *info2,
3454 struct spoolss_PrinterInfo0 *r,
3458 counter_printer_0 *session_counter;
3459 struct timeval setuptime;
3460 print_status_struct status;
3462 r->printername = talloc_strdup(mem_ctx, info2->printername);
3463 W_ERROR_HAVE_NO_MEMORY(r->printername);
3465 r->servername = talloc_strdup(mem_ctx, info2->servername);
3466 W_ERROR_HAVE_NO_MEMORY(r->servername);
3468 count = print_queue_length(snum, &status);
3470 /* check if we already have a counter for this printer */
3471 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3472 if (session_counter->snum == snum)
3476 /* it's the first time, add it to the list */
3477 if (session_counter == NULL) {
3478 session_counter = SMB_MALLOC_P(counter_printer_0);
3479 W_ERROR_HAVE_NO_MEMORY(session_counter);
3480 ZERO_STRUCTP(session_counter);
3481 session_counter->snum = snum;
3482 session_counter->counter = 0;
3483 DLIST_ADD(counter_list, session_counter);
3487 session_counter->counter++;
3493 get_startup_time(&setuptime);
3494 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3497 * the global_counter should be stored in a TDB as it's common to all the clients
3498 * and should be zeroed on samba startup
3500 r->global_counter = session_counter->counter;
3502 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3503 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3504 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3505 r->free_build = SPOOLSS_RELEASE_BUILD;
3507 r->max_spooling = 0;
3508 r->session_counter = session_counter->counter;
3509 r->num_error_out_of_paper = 0x0;
3510 r->num_error_not_ready = 0x0; /* number of print failure */
3512 r->number_of_processors = 0x1;
3513 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3514 r->high_part_total_bytes = 0x0;
3515 winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3516 r->last_error = WERR_OK;
3517 r->status = nt_printq_status(status.status);
3518 r->enumerate_network_printers = 0x0;
3519 r->c_setprinter = 0x0;
3520 r->processor_architecture = 0x0;
3521 r->processor_level = 0x6; /* 6 ???*/
3530 /********************************************************************
3531 * construct_printer_info1
3532 * fill a spoolss_PrinterInfo1 struct
3533 ********************************************************************/
3535 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3536 const struct spoolss_PrinterInfo2 *info2,
3538 struct spoolss_PrinterInfo1 *r,
3543 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3547 W_ERROR_HAVE_NO_MEMORY(r->description);
3549 if (info2->comment == NULL || info2->comment[0] == '\0') {
3550 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3552 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3554 W_ERROR_HAVE_NO_MEMORY(r->comment);
3556 r->name = talloc_strdup(mem_ctx, info2->printername);
3557 W_ERROR_HAVE_NO_MEMORY(r->name);
3562 /********************************************************************
3563 * construct_printer_info2
3564 * fill a spoolss_PrinterInfo2 struct
3565 ********************************************************************/
3567 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3568 const struct spoolss_PrinterInfo2 *info2,
3569 struct spoolss_PrinterInfo2 *r,
3573 print_status_struct status;
3575 count = print_queue_length(snum, &status);
3577 r->servername = talloc_strdup(mem_ctx, info2->servername);
3578 W_ERROR_HAVE_NO_MEMORY(r->servername);
3579 r->printername = talloc_strdup(mem_ctx, info2->printername);
3580 W_ERROR_HAVE_NO_MEMORY(r->printername);
3581 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3582 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3583 r->portname = talloc_strdup(mem_ctx, info2->portname);
3584 W_ERROR_HAVE_NO_MEMORY(r->portname);
3585 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3586 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3588 if (info2->comment[0] == '\0') {
3589 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3591 r->comment = talloc_strdup(mem_ctx, info2->comment);
3593 W_ERROR_HAVE_NO_MEMORY(r->comment);
3595 r->location = talloc_strdup(mem_ctx, info2->location);
3596 W_ERROR_HAVE_NO_MEMORY(r->location);
3597 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3598 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3599 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3600 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3601 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3602 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3603 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3604 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3606 r->attributes = info2->attributes;
3608 r->priority = info2->priority;
3609 r->defaultpriority = info2->defaultpriority;
3610 r->starttime = info2->starttime;
3611 r->untiltime = info2->untiltime;
3612 r->status = nt_printq_status(status.status);
3614 r->averageppm = info2->averageppm;
3616 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3618 DEBUG(8,("Returning NULL Devicemode!\n"));
3623 if (info2->secdesc != NULL) {
3624 /* don't use talloc_steal() here unless you do a deep steal of all
3625 the SEC_DESC members */
3627 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3633 /********************************************************************
3634 * construct_printer_info3
3635 * fill a spoolss_PrinterInfo3 struct
3636 ********************************************************************/
3638 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3639 const struct spoolss_PrinterInfo2 *info2,
3640 struct spoolss_PrinterInfo3 *r,
3643 /* These are the components of the SD we are returning. */
3645 if (info2->secdesc != NULL) {
3646 /* don't use talloc_steal() here unless you do a deep steal of all
3647 the SEC_DESC members */
3649 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3650 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3656 /********************************************************************
3657 * construct_printer_info4
3658 * fill a spoolss_PrinterInfo4 struct
3659 ********************************************************************/
3661 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3662 const struct spoolss_PrinterInfo2 *info2,
3663 struct spoolss_PrinterInfo4 *r,
3666 r->printername = talloc_strdup(mem_ctx, info2->printername);
3667 W_ERROR_HAVE_NO_MEMORY(r->printername);
3668 r->servername = talloc_strdup(mem_ctx, info2->servername);
3669 W_ERROR_HAVE_NO_MEMORY(r->servername);
3671 r->attributes = info2->attributes;
3676 /********************************************************************
3677 * construct_printer_info5
3678 * fill a spoolss_PrinterInfo5 struct
3679 ********************************************************************/
3681 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3682 const struct spoolss_PrinterInfo2 *info2,
3683 struct spoolss_PrinterInfo5 *r,
3686 r->printername = talloc_strdup(mem_ctx, info2->printername);
3687 W_ERROR_HAVE_NO_MEMORY(r->printername);
3688 r->portname = talloc_strdup(mem_ctx, info2->portname);
3689 W_ERROR_HAVE_NO_MEMORY(r->portname);
3691 r->attributes = info2->attributes;
3693 /* these two are not used by NT+ according to MSDN */
3694 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3695 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3700 /********************************************************************
3701 * construct_printer_info_6
3702 * fill a spoolss_PrinterInfo6 struct
3703 ********************************************************************/
3705 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3706 const struct spoolss_PrinterInfo2 *info2,
3707 struct spoolss_PrinterInfo6 *r,
3711 print_status_struct status;
3713 count = print_queue_length(snum, &status);
3715 r->status = nt_printq_status(status.status);
3720 /********************************************************************
3721 * construct_printer_info7
3722 * fill a spoolss_PrinterInfo7 struct
3723 ********************************************************************/
3725 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3726 Printer_entry *print_hnd,
3727 struct spoolss_PrinterInfo7 *r,
3730 struct auth_serversupplied_info *server_info;
3734 status = make_server_info_system(mem_ctx, &server_info);
3735 if (!NT_STATUS_IS_OK(status)) {
3736 DEBUG(0, ("construct_printer_info7: "
3737 "Could not create system server_info\n"));
3741 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3742 lp_servicename(snum), &guid, NULL)) {
3743 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3744 r->action = DSPRINT_PUBLISH;
3746 r->guid = talloc_strdup(mem_ctx, "");
3747 r->action = DSPRINT_UNPUBLISH;
3749 W_ERROR_HAVE_NO_MEMORY(r->guid);
3751 TALLOC_FREE(server_info);
3755 /********************************************************************
3756 * construct_printer_info8
3757 * fill a spoolss_PrinterInfo8 struct
3758 ********************************************************************/
3760 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3761 const struct spoolss_PrinterInfo2 *info2,
3762 struct spoolss_DeviceModeInfo *r,
3765 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3767 DEBUG(8,("Returning NULL Devicemode!\n"));
3774 /********************************************************************
3775 ********************************************************************/
3777 static bool snum_is_shared_printer(int snum)
3779 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3782 /********************************************************************
3783 Spoolss_enumprinters.
3784 ********************************************************************/
3786 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3787 struct auth_serversupplied_info *server_info,
3790 union spoolss_PrinterInfo **info_p,
3794 int n_services = lp_numservices();
3795 union spoolss_PrinterInfo *info = NULL;
3797 WERROR result = WERR_OK;
3802 for (snum = 0; snum < n_services; snum++) {
3804 const char *printer;
3805 struct spoolss_PrinterInfo2 *info2;
3807 if (!snum_is_shared_printer(snum)) {
3811 printer = lp_const_servicename(snum);
3813 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3816 result = winreg_create_printer(mem_ctx,
3818 smbd_messaging_context(),
3821 if (!W_ERROR_IS_OK(result)) {
3825 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3826 union spoolss_PrinterInfo,
3829 result = WERR_NOMEM;
3833 result = winreg_get_printer(mem_ctx, server_info,
3834 smbd_messaging_context(),
3835 NULL, printer, &info2);
3836 if (!W_ERROR_IS_OK(result)) {
3842 result = construct_printer_info0(info, server_info, info2,
3843 &info[count].info0, snum);
3846 result = construct_printer_info1(info, info2, flags,
3847 &info[count].info1, snum);
3850 result = construct_printer_info2(info, info2,
3851 &info[count].info2, snum);
3854 result = construct_printer_info4(info, info2,
3855 &info[count].info4, snum);
3858 result = construct_printer_info5(info, info2,
3859 &info[count].info5, snum);
3863 result = WERR_UNKNOWN_LEVEL;
3867 if (!W_ERROR_IS_OK(result)) {
3878 if (!W_ERROR_IS_OK(result)) {
3888 /********************************************************************
3889 * handle enumeration of printers at level 0
3890 ********************************************************************/
3892 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3893 struct auth_serversupplied_info *server_info,
3895 const char *servername,
3896 union spoolss_PrinterInfo **info,
3899 DEBUG(4,("enum_all_printers_info_0\n"));
3901 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3905 /********************************************************************
3906 ********************************************************************/
3908 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3909 struct auth_serversupplied_info *server_info,
3911 union spoolss_PrinterInfo **info,
3914 DEBUG(4,("enum_all_printers_info_1\n"));
3916 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3919 /********************************************************************
3920 enum_all_printers_info_1_local.
3921 *********************************************************************/
3923 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3924 struct auth_serversupplied_info *server_info,
3925 union spoolss_PrinterInfo **info,
3928 DEBUG(4,("enum_all_printers_info_1_local\n"));
3930 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3933 /********************************************************************
3934 enum_all_printers_info_1_name.
3935 *********************************************************************/
3937 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3938 struct auth_serversupplied_info *server_info,
3940 union spoolss_PrinterInfo **info,
3943 const char *s = name;
3945 DEBUG(4,("enum_all_printers_info_1_name\n"));
3947 if ((name[0] == '\\') && (name[1] == '\\')) {
3951 if (!is_myname_or_ipaddr(s)) {
3952 return WERR_INVALID_NAME;
3955 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3958 /********************************************************************
3959 enum_all_printers_info_1_network.
3960 *********************************************************************/
3962 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3963 struct auth_serversupplied_info *server_info,
3965 union spoolss_PrinterInfo **info,
3968 const char *s = name;
3970 DEBUG(4,("enum_all_printers_info_1_network\n"));
3972 /* If we respond to a enum_printers level 1 on our name with flags
3973 set to PRINTER_ENUM_REMOTE with a list of printers then these
3974 printers incorrectly appear in the APW browse list.
3975 Specifically the printers for the server appear at the workgroup
3976 level where all the other servers in the domain are
3977 listed. Windows responds to this call with a
3978 WERR_CAN_NOT_COMPLETE so we should do the same. */
3980 if (name[0] == '\\' && name[1] == '\\') {
3984 if (is_myname_or_ipaddr(s)) {
3985 return WERR_CAN_NOT_COMPLETE;
3988 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3991 /********************************************************************
3992 * api_spoolss_enumprinters
3994 * called from api_spoolss_enumprinters (see this to understand)
3995 ********************************************************************/
3997 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3998 struct auth_serversupplied_info *server_info,
3999 union spoolss_PrinterInfo **info,
4002 DEBUG(4,("enum_all_printers_info_2\n"));
4004 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
4007 /********************************************************************
4008 * handle enumeration of printers at level 1
4009 ********************************************************************/
4011 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4012 struct auth_serversupplied_info *server_info,
4015 union spoolss_PrinterInfo **info,
4018 /* Not all the flags are equals */
4020 if (flags & PRINTER_ENUM_LOCAL) {
4021 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4024 if (flags & PRINTER_ENUM_NAME) {
4025 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4028 if (flags & PRINTER_ENUM_NETWORK) {
4029 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4032 return WERR_OK; /* NT4sp5 does that */
4035 /********************************************************************
4036 * handle enumeration of printers at level 2
4037 ********************************************************************/
4039 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4040 struct auth_serversupplied_info *server_info,
4042 const char *servername,
4043 union spoolss_PrinterInfo **info,
4046 if (flags & PRINTER_ENUM_LOCAL) {
4047 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4050 if (flags & PRINTER_ENUM_NAME) {
4051 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4052 return WERR_INVALID_NAME;
4055 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4058 if (flags & PRINTER_ENUM_REMOTE) {
4059 return WERR_UNKNOWN_LEVEL;
4065 /********************************************************************
4066 * handle enumeration of printers at level 4
4067 ********************************************************************/
4069 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4070 struct auth_serversupplied_info *server_info,
4072 const char *servername,
4073 union spoolss_PrinterInfo **info,
4076 DEBUG(4,("enum_all_printers_info_4\n"));
4078 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4082 /********************************************************************
4083 * handle enumeration of printers at level 5
4084 ********************************************************************/
4086 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4087 struct auth_serversupplied_info *server_info,
4089 const char *servername,
4090 union spoolss_PrinterInfo **info,
4093 DEBUG(4,("enum_all_printers_info_5\n"));
4095 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4098 /****************************************************************
4099 _spoolss_EnumPrinters
4100 ****************************************************************/
4102 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4103 struct spoolss_EnumPrinters *r)
4105 const char *name = NULL;
4108 /* that's an [in out] buffer */
4110 if (!r->in.buffer && (r->in.offered != 0)) {
4111 return WERR_INVALID_PARAM;
4114 DEBUG(4,("_spoolss_EnumPrinters\n"));
4118 *r->out.info = NULL;
4122 * flags==PRINTER_ENUM_NAME
4123 * if name=="" then enumerates all printers
4124 * if name!="" then enumerate the printer
4125 * flags==PRINTER_ENUM_REMOTE
4126 * name is NULL, enumerate printers
4127 * Level 2: name!="" enumerates printers, name can't be NULL
4128 * Level 3: doesn't exist
4129 * Level 4: does a local registry lookup
4130 * Level 5: same as Level 2
4134 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4135 W_ERROR_HAVE_NO_MEMORY(name);
4138 switch (r->in.level) {
4140 result = enumprinters_level0(p->mem_ctx, p->server_info,
4142 r->out.info, r->out.count);
4145 result = enumprinters_level1(p->mem_ctx, p->server_info,
4147 r->out.info, r->out.count);
4150 result = enumprinters_level2(p->mem_ctx, p->server_info,
4152 r->out.info, r->out.count);
4155 result = enumprinters_level4(p->mem_ctx, p->server_info,
4157 r->out.info, r->out.count);
4160 result = enumprinters_level5(p->mem_ctx, p->server_info,
4162 r->out.info, r->out.count);
4165 return WERR_UNKNOWN_LEVEL;
4168 if (!W_ERROR_IS_OK(result)) {
4172 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4173 spoolss_EnumPrinters,
4174 *r->out.info, r->in.level,
4176 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4177 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4179 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4182 /****************************************************************
4184 ****************************************************************/
4186 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4187 struct spoolss_GetPrinter *r)
4189 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4190 struct spoolss_PrinterInfo2 *info2 = NULL;
4191 WERROR result = WERR_OK;
4192 const char *servername = NULL;
4195 /* that's an [in out] buffer */
4197 if (!r->in.buffer && (r->in.offered != 0)) {
4198 return WERR_INVALID_PARAM;
4203 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4207 if (Printer != NULL || Printer->servername != NULL) {
4208 servername = Printer->servername;
4211 result = winreg_get_printer(p->mem_ctx,
4215 lp_const_servicename(snum),
4217 if (!W_ERROR_IS_OK(result)) {
4221 switch (r->in.level) {
4223 result = construct_printer_info0(p->mem_ctx, p->server_info,
4225 &r->out.info->info0, snum);
4228 result = construct_printer_info1(p->mem_ctx, info2,
4230 &r->out.info->info1, snum);
4233 result = construct_printer_info2(p->mem_ctx, info2,
4234 &r->out.info->info2, snum);
4237 result = construct_printer_info3(p->mem_ctx, info2,
4238 &r->out.info->info3, snum);
4241 result = construct_printer_info4(p->mem_ctx, info2,
4242 &r->out.info->info4, snum);
4245 result = construct_printer_info5(p->mem_ctx, info2,
4246 &r->out.info->info5, snum);
4249 result = construct_printer_info6(p->mem_ctx, info2,
4250 &r->out.info->info6, snum);
4253 result = construct_printer_info7(p->mem_ctx, Printer,
4254 &r->out.info->info7, snum);
4257 result = construct_printer_info8(p->mem_ctx, info2,
4258 &r->out.info->info8, snum);
4261 result = WERR_UNKNOWN_LEVEL;
4265 if (!W_ERROR_IS_OK(result)) {
4266 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4267 r->in.level, win_errstr(result)));
4268 TALLOC_FREE(r->out.info);
4272 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4273 r->out.info, r->in.level);
4274 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4276 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4279 /********************************************************************
4280 ********************************************************************/
4282 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4284 if (in && strlen(in)) { \
4285 out = talloc_strdup(mem_ctx, in); \
4287 out = talloc_strdup(mem_ctx, ""); \
4289 W_ERROR_HAVE_NO_MEMORY(out); \
4292 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4294 if (in && strlen(in)) { \
4295 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4297 out = talloc_strdup(mem_ctx, ""); \
4299 W_ERROR_HAVE_NO_MEMORY(out); \
4302 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4303 const char **string_array,
4304 const char ***presult,
4305 const char *cservername,
4309 int i, num_strings = 0;
4310 const char **array = NULL;
4312 if (string_array == NULL) {
4313 return WERR_INVALID_PARAMETER;;
4316 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4317 const char *str = NULL;
4319 if (cservername == NULL || arch == NULL) {
4320 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4322 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4325 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4332 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4333 &array, &num_strings);
4343 /********************************************************************
4344 * fill a spoolss_DriverInfo1 struct
4345 ********************************************************************/
4347 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4348 struct spoolss_DriverInfo1 *r,
4349 const struct spoolss_DriverInfo8 *driver,
4350 const char *servername)
4352 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4353 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4358 /********************************************************************
4359 * fill a spoolss_DriverInfo2 struct
4360 ********************************************************************/
4362 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4363 struct spoolss_DriverInfo2 *r,
4364 const struct spoolss_DriverInfo8 *driver,
4365 const char *servername)
4368 const char *cservername = canon_servername(servername);
4370 r->version = driver->version;
4372 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4373 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4374 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4375 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4377 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4378 driver->architecture,
4380 driver->driver_path,
4383 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4384 driver->architecture,
4389 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4390 driver->architecture,
4392 driver->config_file,
4398 /********************************************************************
4399 * fill a spoolss_DriverInfo3 struct
4400 ********************************************************************/
4402 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4403 struct spoolss_DriverInfo3 *r,
4404 const struct spoolss_DriverInfo8 *driver,
4405 const char *servername)
4407 const char *cservername = canon_servername(servername);
4409 r->version = driver->version;
4411 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4412 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4413 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4414 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4416 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4417 driver->architecture,
4419 driver->driver_path,
4422 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4423 driver->architecture,
4428 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4429 driver->architecture,
4431 driver->config_file,
4434 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4435 driver->architecture,
4440 FILL_DRIVER_STRING(mem_ctx,
4441 driver->monitor_name,
4444 FILL_DRIVER_STRING(mem_ctx,
4445 driver->default_datatype,
4446 r->default_datatype);
4448 return string_array_from_driver_info(mem_ctx,
4449 driver->dependent_files,
4450 &r->dependent_files,
4452 driver->architecture,
4456 /********************************************************************
4457 * fill a spoolss_DriverInfo4 struct
4458 ********************************************************************/
4460 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4461 struct spoolss_DriverInfo4 *r,
4462 const struct spoolss_DriverInfo8 *driver,
4463 const char *servername)
4465 const char *cservername = canon_servername(servername);
4468 r->version = driver->version;
4470 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4471 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4472 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4473 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4475 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4476 driver->architecture,
4478 driver->driver_path,
4481 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4482 driver->architecture,
4487 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4488 driver->architecture,
4490 driver->config_file,
4493 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4494 driver->architecture,
4499 result = string_array_from_driver_info(mem_ctx,
4500 driver->dependent_files,
4501 &r->dependent_files,
4503 driver->architecture,
4505 if (!W_ERROR_IS_OK(result)) {
4509 FILL_DRIVER_STRING(mem_ctx,
4510 driver->monitor_name,
4513 FILL_DRIVER_STRING(mem_ctx,
4514 driver->default_datatype,
4515 r->default_datatype);
4518 result = string_array_from_driver_info(mem_ctx,
4519 driver->previous_names,
4526 /********************************************************************
4527 * fill a spoolss_DriverInfo5 struct
4528 ********************************************************************/
4530 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4531 struct spoolss_DriverInfo5 *r,
4532 const struct spoolss_DriverInfo8 *driver,
4533 const char *servername)
4535 const char *cservername = canon_servername(servername);
4537 r->version = driver->version;
4539 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4540 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4541 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4542 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4544 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4545 driver->architecture,
4547 driver->driver_path,
4550 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4551 driver->architecture,
4556 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4557 driver->architecture,
4559 driver->config_file,
4562 r->driver_attributes = 0;
4563 r->config_version = 0;
4564 r->driver_version = 0;
4568 /********************************************************************
4569 * fill a spoolss_DriverInfo6 struct
4570 ********************************************************************/
4572 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4573 struct spoolss_DriverInfo6 *r,
4574 const struct spoolss_DriverInfo8 *driver,
4575 const char *servername)
4577 const char *cservername = canon_servername(servername);
4580 r->version = driver->version;
4582 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4583 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4584 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4585 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4587 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4588 driver->architecture,
4590 driver->driver_path,
4593 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4594 driver->architecture,
4599 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4600 driver->architecture,
4602 driver->config_file,
4605 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4606 driver->architecture,
4611 FILL_DRIVER_STRING(mem_ctx,
4612 driver->monitor_name,
4615 FILL_DRIVER_STRING(mem_ctx,
4616 driver->default_datatype,
4617 r->default_datatype);
4619 result = string_array_from_driver_info(mem_ctx,
4620 driver->dependent_files,
4621 &r->dependent_files,
4623 driver->architecture,
4625 if (!W_ERROR_IS_OK(result)) {
4629 result = string_array_from_driver_info(mem_ctx,
4630 driver->previous_names,
4633 if (!W_ERROR_IS_OK(result)) {
4637 r->driver_date = driver->driver_date;
4638 r->driver_version = driver->driver_version;
4640 FILL_DRIVER_STRING(mem_ctx,
4641 driver->manufacturer_name,
4642 r->manufacturer_name);
4643 FILL_DRIVER_STRING(mem_ctx,
4644 driver->manufacturer_url,
4645 r->manufacturer_url);
4646 FILL_DRIVER_STRING(mem_ctx,
4647 driver->hardware_id,
4649 FILL_DRIVER_STRING(mem_ctx,
4656 /********************************************************************
4657 * fill a spoolss_DriverInfo8 struct
4658 ********************************************************************/
4660 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4661 struct spoolss_DriverInfo8 *r,
4662 const struct spoolss_DriverInfo8 *driver,
4663 const char *servername)
4665 const char *cservername = canon_servername(servername);
4668 r->version = driver->version;
4670 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4671 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4672 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4673 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4675 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4676 driver->architecture,
4678 driver->driver_path,
4681 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4682 driver->architecture,
4687 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4688 driver->architecture,
4690 driver->config_file,
4693 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4694 driver->architecture,
4699 FILL_DRIVER_STRING(mem_ctx,
4700 driver->monitor_name,
4703 FILL_DRIVER_STRING(mem_ctx,
4704 driver->default_datatype,
4705 r->default_datatype);
4707 result = string_array_from_driver_info(mem_ctx,
4708 driver->dependent_files,
4709 &r->dependent_files,
4711 driver->architecture,
4713 if (!W_ERROR_IS_OK(result)) {
4717 result = string_array_from_driver_info(mem_ctx,
4718 driver->previous_names,
4721 if (!W_ERROR_IS_OK(result)) {
4725 r->driver_date = driver->driver_date;
4726 r->driver_version = driver->driver_version;
4728 FILL_DRIVER_STRING(mem_ctx,
4729 driver->manufacturer_name,
4730 r->manufacturer_name);
4731 FILL_DRIVER_STRING(mem_ctx,
4732 driver->manufacturer_url,
4733 r->manufacturer_url);
4734 FILL_DRIVER_STRING(mem_ctx,
4735 driver->hardware_id,
4737 FILL_DRIVER_STRING(mem_ctx,
4741 FILL_DRIVER_STRING(mem_ctx,
4742 driver->print_processor,
4743 r->print_processor);
4744 FILL_DRIVER_STRING(mem_ctx,
4745 driver->vendor_setup,
4748 result = string_array_from_driver_info(mem_ctx,
4749 driver->color_profiles,
4752 if (!W_ERROR_IS_OK(result)) {
4756 FILL_DRIVER_STRING(mem_ctx,
4760 r->printer_driver_attributes = driver->printer_driver_attributes;
4762 result = string_array_from_driver_info(mem_ctx,
4763 driver->core_driver_dependencies,
4764 &r->core_driver_dependencies,
4766 if (!W_ERROR_IS_OK(result)) {
4770 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4771 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4776 #if 0 /* disabled until marshalling issues are resolved - gd */
4777 /********************************************************************
4778 ********************************************************************/
4780 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4781 struct spoolss_DriverFileInfo *r,
4782 const char *cservername,
4783 const char *file_name,
4784 enum spoolss_DriverFileType file_type,
4785 uint32_t file_version)
4787 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4788 cservername, file_name);
4789 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4790 r->file_type = file_type;
4791 r->file_version = file_version;
4796 /********************************************************************
4797 ********************************************************************/
4799 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4800 const struct spoolss_DriverInfo8 *driver,
4801 const char *cservername,
4802 struct spoolss_DriverFileInfo **info_p,
4805 struct spoolss_DriverFileInfo *info = NULL;
4813 if (strlen(driver->driver_path)) {
4814 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4815 struct spoolss_DriverFileInfo,
4817 W_ERROR_HAVE_NO_MEMORY(info);
4818 result = fill_spoolss_DriverFileInfo(info,
4821 driver->driver_path,
4822 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4824 W_ERROR_NOT_OK_RETURN(result);
4828 if (strlen(driver->config_file)) {
4829 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4830 struct spoolss_DriverFileInfo,
4832 W_ERROR_HAVE_NO_MEMORY(info);
4833 result = fill_spoolss_DriverFileInfo(info,
4836 driver->config_file,
4837 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4839 W_ERROR_NOT_OK_RETURN(result);
4843 if (strlen(driver->data_file)) {
4844 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4845 struct spoolss_DriverFileInfo,
4847 W_ERROR_HAVE_NO_MEMORY(info);
4848 result = fill_spoolss_DriverFileInfo(info,
4852 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4854 W_ERROR_NOT_OK_RETURN(result);
4858 if (strlen(driver->help_file)) {
4859 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4860 struct spoolss_DriverFileInfo,
4862 W_ERROR_HAVE_NO_MEMORY(info);
4863 result = fill_spoolss_DriverFileInfo(info,
4867 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4869 W_ERROR_NOT_OK_RETURN(result);
4873 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4874 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4875 struct spoolss_DriverFileInfo,
4877 W_ERROR_HAVE_NO_MEMORY(info);
4878 result = fill_spoolss_DriverFileInfo(info,
4881 driver->dependent_files[i],
4882 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4884 W_ERROR_NOT_OK_RETURN(result);
4894 /********************************************************************
4895 * fill a spoolss_DriverInfo101 struct
4896 ********************************************************************/
4898 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4899 struct spoolss_DriverInfo101 *r,
4900 const struct spoolss_DriverInfo8 *driver,
4901 const char *servername)
4903 const char *cservername = canon_servername(servername);
4906 r->version = driver->version;
4908 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4909 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4910 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4911 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4913 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4917 if (!W_ERROR_IS_OK(result)) {
4921 FILL_DRIVER_STRING(mem_ctx,
4922 driver->monitor_name,
4925 FILL_DRIVER_STRING(mem_ctx,
4926 driver->default_datatype,
4927 r->default_datatype);
4929 result = string_array_from_driver_info(mem_ctx,
4930 driver->previous_names,
4933 if (!W_ERROR_IS_OK(result)) {
4937 r->driver_date = driver->driver_date;
4938 r->driver_version = driver->driver_version;
4940 FILL_DRIVER_STRING(mem_ctx,
4941 driver->manufacturer_name,
4942 r->manufacturer_name);
4943 FILL_DRIVER_STRING(mem_ctx,
4944 driver->manufacturer_url,
4945 r->manufacturer_url);
4946 FILL_DRIVER_STRING(mem_ctx,
4947 driver->hardware_id,
4949 FILL_DRIVER_STRING(mem_ctx,
4956 /********************************************************************
4957 ********************************************************************/
4959 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4960 struct auth_serversupplied_info *server_info,
4962 union spoolss_DriverInfo *r,
4964 const char *servername,
4965 const char *architecture,
4968 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4969 struct spoolss_DriverInfo8 *driver;
4972 result = winreg_get_printer(mem_ctx,
4974 smbd_messaging_context(),
4976 lp_const_servicename(snum),
4979 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4980 win_errstr(result)));
4982 if (!W_ERROR_IS_OK(result)) {
4983 return WERR_INVALID_PRINTER_NAME;
4986 result = winreg_get_driver(mem_ctx, server_info, architecture,
4987 pinfo2->drivername, version, &driver);
4989 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4990 win_errstr(result)));
4992 if (!W_ERROR_IS_OK(result)) {
4994 * Is this a W2k client ?
4998 talloc_free(pinfo2);
4999 return WERR_UNKNOWN_PRINTER_DRIVER;
5002 /* Yes - try again with a WinNT driver. */
5004 result = winreg_get_driver(mem_ctx, server_info, architecture,
5007 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5008 win_errstr(result)));
5009 if (!W_ERROR_IS_OK(result)) {
5010 talloc_free(pinfo2);
5011 return WERR_UNKNOWN_PRINTER_DRIVER;
5017 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5020 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5023 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5026 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5029 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5032 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5035 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5037 #if 0 /* disabled until marshalling issues are resolved - gd */
5039 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5043 result = WERR_UNKNOWN_LEVEL;
5047 talloc_free(pinfo2);
5048 talloc_free(driver);
5053 /****************************************************************
5054 _spoolss_GetPrinterDriver2
5055 ****************************************************************/
5057 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5058 struct spoolss_GetPrinterDriver2 *r)
5060 Printer_entry *printer;
5065 /* that's an [in out] buffer */
5067 if (!r->in.buffer && (r->in.offered != 0)) {
5068 return WERR_INVALID_PARAM;
5071 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5073 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5074 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5075 return WERR_INVALID_PRINTER_NAME;
5079 *r->out.server_major_version = 0;
5080 *r->out.server_minor_version = 0;
5082 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5086 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5087 r->in.level, r->out.info,
5088 snum, printer->servername,
5090 r->in.client_major_version);
5091 if (!W_ERROR_IS_OK(result)) {
5092 TALLOC_FREE(r->out.info);
5096 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5097 r->out.info, r->in.level);
5098 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5100 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5104 /****************************************************************
5105 _spoolss_StartPagePrinter
5106 ****************************************************************/
5108 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5109 struct spoolss_StartPagePrinter *r)
5111 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5114 DEBUG(3,("_spoolss_StartPagePrinter: "
5115 "Error in startpageprinter printer handle\n"));
5119 Printer->page_started = true;
5123 /****************************************************************
5124 _spoolss_EndPagePrinter
5125 ****************************************************************/
5127 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5128 struct spoolss_EndPagePrinter *r)
5132 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5135 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5136 OUR_HANDLE(r->in.handle)));
5140 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5143 Printer->page_started = false;
5144 print_job_endpage(snum, Printer->jobid);
5149 /****************************************************************
5150 _spoolss_StartDocPrinter
5151 ****************************************************************/
5153 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5154 struct spoolss_StartDocPrinter *r)
5156 struct spoolss_DocumentInfo1 *info_1;
5158 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5162 DEBUG(2,("_spoolss_StartDocPrinter: "
5163 "Invalid handle (%s:%u:%u)\n",
5164 OUR_HANDLE(r->in.handle)));
5168 if (Printer->jobid) {
5169 DEBUG(2, ("_spoolss_StartDocPrinter: "
5170 "StartDocPrinter called twice! "
5171 "(existing jobid = %d)\n", Printer->jobid));
5172 return WERR_INVALID_HANDLE;
5175 if (r->in.level != 1) {
5176 return WERR_UNKNOWN_LEVEL;
5179 info_1 = r->in.info.info1;
5182 * a nice thing with NT is it doesn't listen to what you tell it.
5183 * when asked to send _only_ RAW datas, it tries to send datas
5186 * So I add checks like in NT Server ...
5189 if (info_1->datatype) {
5190 if (strcmp(info_1->datatype, "RAW") != 0) {
5192 return WERR_INVALID_DATATYPE;
5196 /* get the share number of the printer */
5197 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5201 werr = print_job_start(p->server_info, snum,
5202 info_1->document_name, info_1->output_file,
5203 Printer->devmode, &Printer->jobid);
5205 /* An error occured in print_job_start() so return an appropriate
5208 if (!W_ERROR_IS_OK(werr)) {
5212 Printer->document_started = true;
5213 *r->out.job_id = Printer->jobid;
5218 /****************************************************************
5219 _spoolss_EndDocPrinter
5220 ****************************************************************/
5222 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5223 struct spoolss_EndDocPrinter *r)
5225 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5230 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5231 OUR_HANDLE(r->in.handle)));
5235 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5239 Printer->document_started = false;
5240 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5241 if (!NT_STATUS_IS_OK(status)) {
5242 DEBUG(2, ("_spoolss_EndDocPrinter: "
5243 "print_job_end failed [%s]\n",
5244 nt_errstr(status)));
5248 return ntstatus_to_werror(status);
5251 /****************************************************************
5252 _spoolss_WritePrinter
5253 ****************************************************************/
5255 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5256 struct spoolss_WritePrinter *r)
5258 ssize_t buffer_written;
5260 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5263 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5264 OUR_HANDLE(r->in.handle)));
5265 *r->out.num_written = r->in._data_size;
5269 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5272 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5273 buffer_written = print_job_write(snum, Printer->jobid,
5274 (const char *)r->in.data.data,
5276 (size_t)r->in._data_size);
5277 if (buffer_written == (ssize_t)-1) {
5278 *r->out.num_written = 0;
5279 if (errno == ENOSPC)
5280 return WERR_NO_SPOOL_SPACE;
5282 return WERR_ACCESS_DENIED;
5285 *r->out.num_written = r->in._data_size;
5290 /********************************************************************
5291 * api_spoolss_getprinter
5292 * called from the spoolss dispatcher
5294 ********************************************************************/
5296 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5297 struct pipes_struct *p)
5300 WERROR errcode = WERR_BADFUNC;
5301 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5304 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5305 OUR_HANDLE(handle)));
5309 if (!get_printer_snum(p, handle, &snum, NULL))
5313 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5314 errcode = print_queue_pause(p->server_info, snum);
5316 case SPOOLSS_PRINTER_CONTROL_RESUME:
5317 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5318 errcode = print_queue_resume(p->server_info, snum);
5320 case SPOOLSS_PRINTER_CONTROL_PURGE:
5321 errcode = print_queue_purge(p->server_info, snum);
5324 return WERR_UNKNOWN_LEVEL;
5331 /****************************************************************
5332 _spoolss_AbortPrinter
5333 * From MSDN: "Deletes printer's spool file if printer is configured
5335 ****************************************************************/
5337 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5338 struct spoolss_AbortPrinter *r)
5340 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5342 WERROR errcode = WERR_OK;
5345 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5346 OUR_HANDLE(r->in.handle)));
5350 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5353 if (!Printer->document_started) {
5354 return WERR_SPL_NO_STARTDOC;
5357 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5362 /********************************************************************
5363 * called by spoolss_api_setprinter
5364 * when updating a printer description
5365 ********************************************************************/
5367 static WERROR update_printer_sec(struct policy_handle *handle,
5368 struct pipes_struct *p,
5369 struct sec_desc_buf *secdesc_ctr)
5371 struct spoolss_security_descriptor *new_secdesc = NULL;
5372 struct spoolss_security_descriptor *old_secdesc = NULL;
5373 const char *printer;
5377 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5379 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5380 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5381 OUR_HANDLE(handle)));
5383 result = WERR_BADFID;
5387 if (secdesc_ctr == NULL) {
5388 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5389 result = WERR_INVALID_PARAM;
5392 printer = lp_const_servicename(snum);
5394 /* Check the user has permissions to change the security
5395 descriptor. By experimentation with two NT machines, the user
5396 requires Full Access to the printer to change security
5399 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5400 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5401 result = WERR_ACCESS_DENIED;
5405 /* NT seems to like setting the security descriptor even though
5406 nothing may have actually changed. */
5407 result = winreg_get_printer_secdesc(p->mem_ctx,
5412 if (!W_ERROR_IS_OK(result)) {
5413 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5414 result = WERR_BADFID;
5418 if (DEBUGLEVEL >= 10) {
5419 struct security_acl *the_acl;
5422 the_acl = old_secdesc->dacl;
5423 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5424 printer, the_acl->num_aces));
5426 for (i = 0; i < the_acl->num_aces; i++) {
5427 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5428 &the_acl->aces[i].trustee),
5429 the_acl->aces[i].access_mask));
5432 the_acl = secdesc_ctr->sd->dacl;
5435 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5436 printer, the_acl->num_aces));
5438 for (i = 0; i < the_acl->num_aces; i++) {
5439 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5440 &the_acl->aces[i].trustee),
5441 the_acl->aces[i].access_mask));
5444 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5448 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5449 if (new_secdesc == NULL) {
5450 result = WERR_NOMEM;
5454 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5459 result = winreg_set_printer_secdesc(p->mem_ctx,
5469 /********************************************************************
5470 Canonicalize printer info from a client
5471 ********************************************************************/
5473 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5474 struct spoolss_SetPrinterInfo2 *info2,
5477 fstring printername;
5480 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5481 "portname=%s drivername=%s comment=%s location=%s\n",
5482 info2->servername, info2->printername, info2->sharename,
5483 info2->portname, info2->drivername, info2->comment,
5486 /* we force some elements to "correct" values */
5487 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5488 if (info2->servername == NULL) {
5491 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5492 if (info2->sharename == NULL) {
5496 /* check to see if we allow printername != sharename */
5497 if (lp_force_printername(snum)) {
5498 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5499 global_myname(), info2->sharename);
5501 /* make sure printername is in \\server\printername format */
5502 fstrcpy(printername, info2->printername);
5504 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5505 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5509 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5510 global_myname(), p);
5512 if (info2->printername == NULL) {
5516 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5517 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5522 /****************************************************************************
5523 ****************************************************************************/
5525 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5527 char *cmd = lp_addport_cmd();
5528 char *command = NULL;
5530 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5531 bool is_print_op = false;
5534 return WERR_ACCESS_DENIED;
5537 command = talloc_asprintf(ctx,
5538 "%s \"%s\" \"%s\"", cmd, portname, uri );
5544 is_print_op = user_has_privileges( token, &se_printop );
5546 DEBUG(10,("Running [%s]\n", command));
5548 /********* BEGIN SePrintOperatorPrivilege **********/
5553 ret = smbrun(command, NULL);
5558 /********* END SePrintOperatorPrivilege **********/
5560 DEBUGADD(10,("returned [%d]\n", ret));
5562 TALLOC_FREE(command);
5565 return WERR_ACCESS_DENIED;
5571 /****************************************************************************
5572 ****************************************************************************/
5574 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5575 struct spoolss_SetPrinterInfo2 *info2,
5576 const char *remote_machine,
5577 struct messaging_context *msg_ctx)
5579 char *cmd = lp_addprinter_cmd();
5581 char *command = NULL;
5585 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5586 bool is_print_op = false;
5588 if (!remote_machine) {
5592 command = talloc_asprintf(ctx,
5593 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5594 cmd, info2->printername, info2->sharename,
5595 info2->portname, info2->drivername,
5596 info2->location, info2->comment, remote_machine);
5602 is_print_op = user_has_privileges( token, &se_printop );
5604 DEBUG(10,("Running [%s]\n", command));
5606 /********* BEGIN SePrintOperatorPrivilege **********/
5611 if ( (ret = smbrun(command, &fd)) == 0 ) {
5612 /* Tell everyone we updated smb.conf. */
5613 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5619 /********* END SePrintOperatorPrivilege **********/
5621 DEBUGADD(10,("returned [%d]\n", ret));
5623 TALLOC_FREE(command);
5631 /* reload our services immediately */
5633 reload_services(false);
5637 /* Get lines and convert them back to dos-codepage */
5638 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5639 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5642 /* Set the portname to what the script says the portname should be. */
5643 /* but don't require anything to be return from the script exit a good error code */
5646 /* Set the portname to what the script says the portname should be. */
5647 info2->portname = talloc_strdup(ctx, qlines[0]);
5648 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5651 TALLOC_FREE(qlines);
5655 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5656 struct auth_serversupplied_info *server_info,
5658 struct spoolss_SetPrinterInfo2 *printer,
5659 struct spoolss_PrinterInfo2 *old_printer)
5661 bool force_update = (old_printer == NULL);
5662 const char *dnsdomname;
5663 const char *longname;
5664 const char *uncname;
5665 const char *spooling;
5667 WERROR result = WERR_OK;
5669 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5670 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5671 winreg_set_printer_dataex(mem_ctx,
5673 smbd_messaging_context(),
5675 SPOOL_DSSPOOLER_KEY,
5676 SPOOL_REG_DRIVERNAME,
5681 if (!force_update) {
5682 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5683 printer->drivername));
5685 notify_printer_driver(snum, printer->drivername);
5689 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5690 push_reg_sz(mem_ctx, &buffer, printer->comment);
5691 winreg_set_printer_dataex(mem_ctx,
5693 smbd_messaging_context(),
5695 SPOOL_DSSPOOLER_KEY,
5696 SPOOL_REG_DESCRIPTION,
5701 if (!force_update) {
5702 notify_printer_comment(snum, printer->comment);
5706 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5707 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5708 winreg_set_printer_dataex(mem_ctx,
5710 smbd_messaging_context(),
5712 SPOOL_DSSPOOLER_KEY,
5713 SPOOL_REG_PRINTSHARENAME,
5718 if (!force_update) {
5719 notify_printer_sharename(snum, printer->sharename);
5723 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5726 p = strrchr(printer->printername, '\\' );
5730 p = printer->printername;
5733 push_reg_sz(mem_ctx, &buffer, p);
5734 winreg_set_printer_dataex(mem_ctx,
5736 smbd_messaging_context(),
5738 SPOOL_DSSPOOLER_KEY,
5739 SPOOL_REG_PRINTERNAME,
5744 if (!force_update) {
5745 notify_printer_printername(snum, p);
5749 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5750 push_reg_sz(mem_ctx, &buffer, printer->portname);
5751 winreg_set_printer_dataex(mem_ctx,
5753 smbd_messaging_context(),
5755 SPOOL_DSSPOOLER_KEY,
5761 if (!force_update) {
5762 notify_printer_port(snum, printer->portname);
5766 if (force_update || !strequal(printer->location, old_printer->location)) {
5767 push_reg_sz(mem_ctx, &buffer, printer->location);
5768 winreg_set_printer_dataex(mem_ctx,
5770 smbd_messaging_context(),
5772 SPOOL_DSSPOOLER_KEY,
5778 if (!force_update) {
5779 notify_printer_location(snum, printer->location);
5783 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5784 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5785 winreg_set_printer_dataex(mem_ctx,
5787 smbd_messaging_context(),
5789 SPOOL_DSSPOOLER_KEY,
5790 SPOOL_REG_PRINTSEPARATORFILE,
5795 if (!force_update) {
5796 notify_printer_location(snum, printer->location);
5800 if (force_update || printer->starttime != old_printer->starttime) {
5801 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5802 SIVAL(buffer.data, 0, printer->starttime);
5803 winreg_set_printer_dataex(mem_ctx,
5805 smbd_messaging_context(),
5807 SPOOL_DSSPOOLER_KEY,
5808 SPOOL_REG_PRINTSTARTTIME,
5814 if (force_update || printer->untiltime != old_printer->untiltime) {
5815 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5816 SIVAL(buffer.data, 0, printer->untiltime);
5817 winreg_set_printer_dataex(mem_ctx,
5819 smbd_messaging_context(),
5821 SPOOL_DSSPOOLER_KEY,
5822 SPOOL_REG_PRINTENDTIME,
5828 if (force_update || printer->priority != old_printer->priority) {
5829 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5830 SIVAL(buffer.data, 0, printer->priority);
5831 winreg_set_printer_dataex(mem_ctx,
5833 smbd_messaging_context(),
5835 SPOOL_DSSPOOLER_KEY,
5842 if (force_update || printer->attributes != old_printer->attributes) {
5843 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5844 SIVAL(buffer.data, 0, (printer->attributes &
5845 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5846 winreg_set_printer_dataex(mem_ctx,
5848 smbd_messaging_context(),
5850 SPOOL_DSSPOOLER_KEY,
5851 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5856 switch (printer->attributes & 0x3) {
5858 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5861 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5864 spooling = SPOOL_REGVAL_PRINTDIRECT;
5867 spooling = "unknown";
5869 push_reg_sz(mem_ctx, &buffer, spooling);
5870 winreg_set_printer_dataex(mem_ctx,
5872 smbd_messaging_context(),
5874 SPOOL_DSSPOOLER_KEY,
5875 SPOOL_REG_PRINTSPOOLING,
5881 push_reg_sz(mem_ctx, &buffer, global_myname());
5882 winreg_set_printer_dataex(mem_ctx,
5884 smbd_messaging_context(),
5886 SPOOL_DSSPOOLER_KEY,
5887 SPOOL_REG_SHORTSERVERNAME,
5892 dnsdomname = get_mydnsfullname();
5893 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5894 longname = talloc_strdup(mem_ctx, dnsdomname);
5896 longname = talloc_strdup(mem_ctx, global_myname());
5898 if (longname == NULL) {
5899 result = WERR_NOMEM;
5903 push_reg_sz(mem_ctx, &buffer, longname);
5904 winreg_set_printer_dataex(mem_ctx,
5906 smbd_messaging_context(),
5908 SPOOL_DSSPOOLER_KEY,
5909 SPOOL_REG_SERVERNAME,
5914 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5915 global_myname(), printer->sharename);
5916 push_reg_sz(mem_ctx, &buffer, uncname);
5917 winreg_set_printer_dataex(mem_ctx,
5919 smbd_messaging_context(),
5921 SPOOL_DSSPOOLER_KEY,
5931 /********************************************************************
5932 * Called by spoolss_api_setprinter
5933 * when updating a printer description.
5934 ********************************************************************/
5936 static WERROR update_printer(struct pipes_struct *p,
5937 struct policy_handle *handle,
5938 struct spoolss_SetPrinterInfoCtr *info_ctr,
5939 struct spoolss_DeviceMode *devmode)
5941 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5942 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5943 struct spoolss_PrinterInfo2 *old_printer;
5944 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5945 const char *servername = NULL;
5947 WERROR result = WERR_OK;
5948 TALLOC_CTX *tmp_ctx;
5950 DEBUG(8,("update_printer\n"));
5952 tmp_ctx = talloc_new(p->mem_ctx);
5953 if (tmp_ctx == NULL) {
5958 result = WERR_BADFID;
5962 if (!get_printer_snum(p, handle, &snum, NULL)) {
5963 result = WERR_BADFID;
5967 if (Printer != NULL || Printer->servername != NULL) {
5968 servername = Printer->servername;
5971 result = winreg_get_printer(tmp_ctx,
5975 lp_const_servicename(snum),
5977 if (!W_ERROR_IS_OK(result)) {
5978 result = WERR_BADFID;
5982 /* Do sanity check on the requested changes for Samba */
5983 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5984 result = WERR_INVALID_PARAM;
5988 /* FIXME!!! If the driver has changed we really should verify that
5989 it is installed before doing much else --jerry */
5991 /* Check calling user has permission to update printer description */
5992 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5993 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5994 result = WERR_ACCESS_DENIED;
5998 /* Call addprinter hook */
5999 /* Check changes to see if this is really needed */
6001 if (*lp_addprinter_cmd() &&
6002 (!strequal(printer->drivername, old_printer->drivername) ||
6003 !strequal(printer->comment, old_printer->comment) ||
6004 !strequal(printer->portname, old_printer->portname) ||
6005 !strequal(printer->location, old_printer->location)) )
6007 /* add_printer_hook() will call reload_services() */
6008 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6009 printer, p->client_address,
6011 result = WERR_ACCESS_DENIED;
6016 update_dsspooler(tmp_ctx,
6022 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6024 if (devmode == NULL) {
6025 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6027 result = winreg_update_printer(tmp_ctx,
6037 talloc_free(tmp_ctx);
6042 /****************************************************************************
6043 ****************************************************************************/
6044 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6045 struct policy_handle *handle,
6046 struct spoolss_SetPrinterInfo7 *info7)
6049 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6052 Printer_entry *Printer;
6054 if ( lp_security() != SEC_ADS ) {
6055 return WERR_UNKNOWN_LEVEL;
6058 Printer = find_printer_index_by_hnd(p, handle);
6060 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6065 if (!get_printer_snum(p, handle, &snum, NULL))
6068 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6069 Printer->servername,
6070 lp_servicename(snum), &pinfo2);
6071 if (!W_ERROR_IS_OK(result)) {
6075 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6077 TALLOC_FREE(pinfo2);
6080 return WERR_UNKNOWN_LEVEL;
6084 /********************************************************************
6085 ********************************************************************/
6087 static WERROR update_printer_devmode(struct pipes_struct *p,
6088 struct policy_handle *handle,
6089 struct spoolss_DeviceMode *devmode)
6092 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6093 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6095 DEBUG(8,("update_printer_devmode\n"));
6101 if (!get_printer_snum(p, handle, &snum, NULL)) {
6105 /* Check calling user has permission to update printer description */
6106 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6107 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6108 return WERR_ACCESS_DENIED;
6111 return winreg_update_printer(p->mem_ctx,
6114 lp_const_servicename(snum),
6122 /****************************************************************
6124 ****************************************************************/
6126 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6127 struct spoolss_SetPrinter *r)
6131 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6134 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6135 OUR_HANDLE(r->in.handle)));
6139 /* check the level */
6140 switch (r->in.info_ctr->level) {
6142 return control_printer(r->in.handle, r->in.command, p);
6144 result = update_printer(p, r->in.handle,
6146 r->in.devmode_ctr->devmode);
6147 if (!W_ERROR_IS_OK(result))
6149 if (r->in.secdesc_ctr->sd)
6150 result = update_printer_sec(r->in.handle, p,
6154 return update_printer_sec(r->in.handle, p,
6157 return publish_or_unpublish_printer(p, r->in.handle,
6158 r->in.info_ctr->info.info7);
6160 return update_printer_devmode(p, r->in.handle,
6161 r->in.devmode_ctr->devmode);
6163 return WERR_UNKNOWN_LEVEL;
6167 /****************************************************************
6168 _spoolss_FindClosePrinterNotify
6169 ****************************************************************/
6171 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6172 struct spoolss_FindClosePrinterNotify *r)
6174 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6177 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6178 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6182 if (Printer->notify.client_connected == true) {
6185 if ( Printer->printer_type == SPLHND_SERVER)
6187 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6188 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6191 srv_spoolss_replycloseprinter(
6192 snum, &Printer->notify.client_hnd, p->msg_ctx);
6195 Printer->notify.flags=0;
6196 Printer->notify.options=0;
6197 Printer->notify.localmachine[0]='\0';
6198 Printer->notify.printerlocal=0;
6199 TALLOC_FREE(Printer->notify.option);
6200 Printer->notify.client_connected = false;
6205 /****************************************************************
6207 ****************************************************************/
6209 WERROR _spoolss_AddJob(struct pipes_struct *p,
6210 struct spoolss_AddJob *r)
6212 if (!r->in.buffer && (r->in.offered != 0)) {
6213 return WERR_INVALID_PARAM;
6216 /* this is what a NT server returns for AddJob. AddJob must fail on
6217 * non-local printers */
6219 if (r->in.level != 1) {
6220 return WERR_UNKNOWN_LEVEL;
6223 return WERR_INVALID_PARAM;
6226 /****************************************************************************
6228 ****************************************************************************/
6230 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6231 struct spoolss_JobInfo1 *r,
6232 const print_queue_struct *queue,
6233 int position, int snum,
6234 struct spoolss_PrinterInfo2 *pinfo2)
6238 t = gmtime(&queue->time);
6240 r->job_id = queue->job;
6242 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6243 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6244 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6245 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6246 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6247 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6248 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6249 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6250 r->data_type = talloc_strdup(mem_ctx, "RAW");
6251 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6252 r->text_status = talloc_strdup(mem_ctx, "");
6253 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6255 r->status = nt_printj_status(queue->status);
6256 r->priority = queue->priority;
6257 r->position = position;
6258 r->total_pages = queue->page_count;
6259 r->pages_printed = 0; /* ??? */
6261 init_systemtime(&r->submitted, t);
6266 /****************************************************************************
6268 ****************************************************************************/
6270 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6271 struct spoolss_JobInfo2 *r,
6272 const print_queue_struct *queue,
6273 int position, int snum,
6274 struct spoolss_PrinterInfo2 *pinfo2,
6275 struct spoolss_DeviceMode *devmode)
6279 t = gmtime(&queue->time);
6281 r->job_id = queue->job;
6283 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6284 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6285 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6286 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6287 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6288 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6289 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6290 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6291 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6292 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6293 r->data_type = talloc_strdup(mem_ctx, "RAW");
6294 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6295 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6296 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6297 r->parameters = talloc_strdup(mem_ctx, "");
6298 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6299 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6300 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6302 r->devmode = devmode;
6304 r->text_status = talloc_strdup(mem_ctx, "");
6305 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6309 r->status = nt_printj_status(queue->status);
6310 r->priority = queue->priority;
6311 r->position = position;
6314 r->total_pages = queue->page_count;
6315 r->size = queue->size;
6316 init_systemtime(&r->submitted, t);
6318 r->pages_printed = 0; /* ??? */
6323 /****************************************************************************
6325 ****************************************************************************/
6327 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6328 struct spoolss_JobInfo3 *r,
6329 const print_queue_struct *queue,
6330 const print_queue_struct *next_queue,
6331 int position, int snum,
6332 struct spoolss_PrinterInfo2 *pinfo2)
6334 r->job_id = queue->job;
6337 r->next_job_id = next_queue->job;
6344 /****************************************************************************
6345 Enumjobs at level 1.
6346 ****************************************************************************/
6348 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6349 const print_queue_struct *queue,
6350 uint32_t num_queues, int snum,
6351 struct spoolss_PrinterInfo2 *pinfo2,
6352 union spoolss_JobInfo **info_p,
6355 union spoolss_JobInfo *info;
6357 WERROR result = WERR_OK;
6359 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6360 W_ERROR_HAVE_NO_MEMORY(info);
6362 *count = num_queues;
6364 for (i=0; i<*count; i++) {
6365 result = fill_job_info1(info,
6371 if (!W_ERROR_IS_OK(result)) {
6377 if (!W_ERROR_IS_OK(result)) {
6388 /****************************************************************************
6389 Enumjobs at level 2.
6390 ****************************************************************************/
6392 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6393 const print_queue_struct *queue,
6394 uint32_t num_queues, int snum,
6395 struct spoolss_PrinterInfo2 *pinfo2,
6396 union spoolss_JobInfo **info_p,
6399 union spoolss_JobInfo *info;
6401 WERROR result = WERR_OK;
6403 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6404 W_ERROR_HAVE_NO_MEMORY(info);
6406 *count = num_queues;
6408 for (i=0; i<*count; i++) {
6409 struct spoolss_DeviceMode *devmode;
6411 result = spoolss_create_default_devmode(info,
6412 pinfo2->printername,
6414 if (!W_ERROR_IS_OK(result)) {
6415 DEBUG(3, ("Can't proceed w/o a devmode!"));
6419 result = fill_job_info2(info,
6426 if (!W_ERROR_IS_OK(result)) {
6432 if (!W_ERROR_IS_OK(result)) {
6443 /****************************************************************************
6444 Enumjobs at level 3.
6445 ****************************************************************************/
6447 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6448 const print_queue_struct *queue,
6449 uint32_t num_queues, int snum,
6450 struct spoolss_PrinterInfo2 *pinfo2,
6451 union spoolss_JobInfo **info_p,
6454 union spoolss_JobInfo *info;
6456 WERROR result = WERR_OK;
6458 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6459 W_ERROR_HAVE_NO_MEMORY(info);
6461 *count = num_queues;
6463 for (i=0; i<*count; i++) {
6464 const print_queue_struct *next_queue = NULL;
6467 next_queue = &queue[i+1];
6470 result = fill_job_info3(info,
6477 if (!W_ERROR_IS_OK(result)) {
6483 if (!W_ERROR_IS_OK(result)) {
6494 /****************************************************************
6496 ****************************************************************/
6498 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6499 struct spoolss_EnumJobs *r)
6502 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6504 print_status_struct prt_status;
6505 print_queue_struct *queue = NULL;
6508 /* that's an [in out] buffer */
6510 if (!r->in.buffer && (r->in.offered != 0)) {
6511 return WERR_INVALID_PARAM;
6514 DEBUG(4,("_spoolss_EnumJobs\n"));
6518 *r->out.info = NULL;
6520 /* lookup the printer snum and tdb entry */
6522 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6526 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6527 NULL, lp_servicename(snum), &pinfo2);
6528 if (!W_ERROR_IS_OK(result)) {
6532 count = print_queue_status(snum, &queue, &prt_status);
6533 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6534 count, prt_status.status, prt_status.message));
6538 TALLOC_FREE(pinfo2);
6542 switch (r->in.level) {
6544 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6545 pinfo2, r->out.info, r->out.count);
6548 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6549 pinfo2, r->out.info, r->out.count);
6552 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6553 pinfo2, r->out.info, r->out.count);
6556 result = WERR_UNKNOWN_LEVEL;
6561 TALLOC_FREE(pinfo2);
6563 if (!W_ERROR_IS_OK(result)) {
6567 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6569 *r->out.info, r->in.level,
6571 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6572 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6574 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6577 /****************************************************************
6578 _spoolss_ScheduleJob
6579 ****************************************************************/
6581 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6582 struct spoolss_ScheduleJob *r)
6587 /****************************************************************
6588 ****************************************************************/
6590 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6591 const char *printer_name,
6593 struct spoolss_SetJobInfo1 *r)
6597 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6601 if (strequal(old_doc_name, r->document_name)) {
6605 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6612 /****************************************************************
6614 ****************************************************************/
6616 WERROR _spoolss_SetJob(struct pipes_struct *p,
6617 struct spoolss_SetJob *r)
6620 WERROR errcode = WERR_BADFUNC;
6622 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6626 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6627 return WERR_INVALID_PRINTER_NAME;
6630 switch (r->in.command) {
6631 case SPOOLSS_JOB_CONTROL_CANCEL:
6632 case SPOOLSS_JOB_CONTROL_DELETE:
6633 errcode = print_job_delete(p->server_info,
6634 snum, r->in.job_id);
6635 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6639 case SPOOLSS_JOB_CONTROL_PAUSE:
6640 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6644 case SPOOLSS_JOB_CONTROL_RESTART:
6645 case SPOOLSS_JOB_CONTROL_RESUME:
6646 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6654 return WERR_UNKNOWN_LEVEL;
6657 if (!W_ERROR_IS_OK(errcode)) {
6661 if (r->in.ctr == NULL) {
6665 switch (r->in.ctr->level) {
6667 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6669 r->in.ctr->info.info1);
6675 return WERR_UNKNOWN_LEVEL;
6681 /****************************************************************************
6682 Enumerates all printer drivers by level and architecture.
6683 ****************************************************************************/
6685 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6686 struct auth_serversupplied_info *server_info,
6687 const char *servername,
6688 const char *architecture,
6690 union spoolss_DriverInfo **info_p,
6695 struct spoolss_DriverInfo8 *driver;
6696 union spoolss_DriverInfo *info = NULL;
6698 WERROR result = WERR_OK;
6699 uint32_t num_drivers;
6700 const char **drivers;
6705 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6706 result = winreg_get_driver_list(mem_ctx, server_info,
6707 architecture, version,
6708 &num_drivers, &drivers);
6709 if (!W_ERROR_IS_OK(result)) {
6712 DEBUG(4, ("we have:[%d] drivers in environment"
6713 " [%s] and version [%d]\n",
6714 num_drivers, architecture, version));
6716 if (num_drivers != 0) {
6717 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6718 union spoolss_DriverInfo,
6719 count + num_drivers);
6721 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6722 "failed to enlarge driver info buffer!\n"));
6723 result = WERR_NOMEM;
6728 for (i = 0; i < num_drivers; i++) {
6729 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6731 result = winreg_get_driver(mem_ctx, server_info,
6732 architecture, drivers[i],
6734 if (!W_ERROR_IS_OK(result)) {
6740 result = fill_printer_driver_info1(info, &info[count+i].info1,
6741 driver, servername);
6744 result = fill_printer_driver_info2(info, &info[count+i].info2,
6745 driver, servername);
6748 result = fill_printer_driver_info3(info, &info[count+i].info3,
6749 driver, servername);
6752 result = fill_printer_driver_info4(info, &info[count+i].info4,
6753 driver, servername);
6756 result = fill_printer_driver_info5(info, &info[count+i].info5,
6757 driver, servername);
6760 result = fill_printer_driver_info6(info, &info[count+i].info6,
6761 driver, servername);
6764 result = fill_printer_driver_info8(info, &info[count+i].info8,
6765 driver, servername);
6768 result = WERR_UNKNOWN_LEVEL;
6772 TALLOC_FREE(driver);
6774 if (!W_ERROR_IS_OK(result)) {
6779 count += num_drivers;
6780 TALLOC_FREE(drivers);
6784 TALLOC_FREE(drivers);
6786 if (!W_ERROR_IS_OK(result)) {
6797 /****************************************************************************
6798 Enumerates all printer drivers by level.
6799 ****************************************************************************/
6801 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6802 struct auth_serversupplied_info *server_info,
6803 const char *servername,
6804 const char *architecture,
6806 union spoolss_DriverInfo **info_p,
6810 WERROR result = WERR_OK;
6812 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6814 for (a=0; archi_table[a].long_archi != NULL; a++) {
6816 union spoolss_DriverInfo *info = NULL;
6819 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6822 archi_table[a].long_archi,
6826 if (!W_ERROR_IS_OK(result)) {
6830 for (i=0; i < count; i++) {
6831 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6832 info[i], info_p, count_p);
6839 return enumprinterdrivers_level_by_architecture(mem_ctx,
6848 /****************************************************************
6849 _spoolss_EnumPrinterDrivers
6850 ****************************************************************/
6852 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6853 struct spoolss_EnumPrinterDrivers *r)
6855 const char *cservername;
6858 /* that's an [in out] buffer */
6860 if (!r->in.buffer && (r->in.offered != 0)) {
6861 return WERR_INVALID_PARAM;
6864 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6868 *r->out.info = NULL;
6870 cservername = canon_servername(r->in.server);
6872 if (!is_myname_or_ipaddr(cservername)) {
6873 return WERR_UNKNOWN_PRINTER_DRIVER;
6876 result = enumprinterdrivers_level(p->mem_ctx,
6883 if (!W_ERROR_IS_OK(result)) {
6887 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6888 spoolss_EnumPrinterDrivers,
6889 *r->out.info, r->in.level,
6891 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6892 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6894 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6897 /****************************************************************
6899 ****************************************************************/
6901 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6902 struct spoolss_EnumForms *r)
6908 *r->out.info = NULL;
6910 /* that's an [in out] buffer */
6912 if (!r->in.buffer && (r->in.offered != 0) ) {
6913 return WERR_INVALID_PARAM;
6916 DEBUG(4,("_spoolss_EnumForms\n"));
6917 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6918 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6920 switch (r->in.level) {
6922 result = winreg_printer_enumforms1(p->mem_ctx,
6928 result = WERR_UNKNOWN_LEVEL;
6932 if (!W_ERROR_IS_OK(result)) {
6936 if (*r->out.count == 0) {
6937 return WERR_NO_MORE_ITEMS;
6940 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6942 *r->out.info, r->in.level,
6944 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6945 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6947 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6950 /****************************************************************
6952 ****************************************************************/
6954 WERROR _spoolss_GetForm(struct pipes_struct *p,
6955 struct spoolss_GetForm *r)
6959 /* that's an [in out] buffer */
6961 if (!r->in.buffer && (r->in.offered != 0)) {
6962 return WERR_INVALID_PARAM;
6965 DEBUG(4,("_spoolss_GetForm\n"));
6966 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6967 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6969 switch (r->in.level) {
6971 result = winreg_printer_getform1(p->mem_ctx,
6974 &r->out.info->info1);
6977 result = WERR_UNKNOWN_LEVEL;
6981 if (!W_ERROR_IS_OK(result)) {
6982 TALLOC_FREE(r->out.info);
6986 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6987 r->out.info, r->in.level);
6988 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6990 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6993 /****************************************************************************
6994 ****************************************************************************/
6996 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6997 struct spoolss_PortInfo1 *r,
7000 r->port_name = talloc_strdup(mem_ctx, name);
7001 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7006 /****************************************************************************
7007 TODO: This probably needs distinguish between TCP/IP and Local ports
7009 ****************************************************************************/
7011 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7012 struct spoolss_PortInfo2 *r,
7015 r->port_name = talloc_strdup(mem_ctx, name);
7016 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7018 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7019 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7021 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7022 W_ERROR_HAVE_NO_MEMORY(r->description);
7024 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7031 /****************************************************************************
7032 wrapper around the enumer ports command
7033 ****************************************************************************/
7035 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7037 char *cmd = lp_enumports_cmd();
7038 char **qlines = NULL;
7039 char *command = NULL;
7047 /* if no hook then just fill in the default port */
7050 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7053 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7054 TALLOC_FREE(qlines);
7061 /* we have a valid enumport command */
7063 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7068 DEBUG(10,("Running [%s]\n", command));
7069 ret = smbrun(command, &fd);
7070 DEBUG(10,("Returned [%d]\n", ret));
7071 TALLOC_FREE(command);
7076 return WERR_ACCESS_DENIED;
7080 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7081 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7091 /****************************************************************************
7093 ****************************************************************************/
7095 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7096 union spoolss_PortInfo **info_p,
7099 union spoolss_PortInfo *info = NULL;
7101 WERROR result = WERR_OK;
7102 char **qlines = NULL;
7105 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7106 if (!W_ERROR_IS_OK(result)) {
7111 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7113 DEBUG(10,("Returning WERR_NOMEM\n"));
7114 result = WERR_NOMEM;
7118 for (i=0; i<numlines; i++) {
7119 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7120 result = fill_port_1(info, &info[i].info1, qlines[i]);
7121 if (!W_ERROR_IS_OK(result)) {
7126 TALLOC_FREE(qlines);
7129 if (!W_ERROR_IS_OK(result)) {
7131 TALLOC_FREE(qlines);
7143 /****************************************************************************
7145 ****************************************************************************/
7147 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7148 union spoolss_PortInfo **info_p,
7151 union spoolss_PortInfo *info = NULL;
7153 WERROR result = WERR_OK;
7154 char **qlines = NULL;
7157 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7158 if (!W_ERROR_IS_OK(result)) {
7163 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7165 DEBUG(10,("Returning WERR_NOMEM\n"));
7166 result = WERR_NOMEM;
7170 for (i=0; i<numlines; i++) {
7171 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7172 result = fill_port_2(info, &info[i].info2, qlines[i]);
7173 if (!W_ERROR_IS_OK(result)) {
7178 TALLOC_FREE(qlines);
7181 if (!W_ERROR_IS_OK(result)) {
7183 TALLOC_FREE(qlines);
7195 /****************************************************************
7197 ****************************************************************/
7199 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7200 struct spoolss_EnumPorts *r)
7204 /* that's an [in out] buffer */
7206 if (!r->in.buffer && (r->in.offered != 0)) {
7207 return WERR_INVALID_PARAM;
7210 DEBUG(4,("_spoolss_EnumPorts\n"));
7214 *r->out.info = NULL;
7216 switch (r->in.level) {
7218 result = enumports_level_1(p->mem_ctx, r->out.info,
7222 result = enumports_level_2(p->mem_ctx, r->out.info,
7226 return WERR_UNKNOWN_LEVEL;
7229 if (!W_ERROR_IS_OK(result)) {
7233 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7235 *r->out.info, r->in.level,
7237 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7238 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7240 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7243 /****************************************************************************
7244 ****************************************************************************/
7246 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7248 struct spoolss_SetPrinterInfoCtr *info_ctr,
7249 struct spoolss_DeviceMode *devmode,
7250 struct security_descriptor *secdesc,
7251 struct spoolss_UserLevelCtr *user_ctr,
7252 struct policy_handle *handle)
7254 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7255 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7257 WERROR err = WERR_OK;
7259 /* samba does not have a concept of local, non-shared printers yet, so
7260 * make sure we always setup sharename - gd */
7261 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7262 (info2->printername != NULL && info2->printername[0] != '\0')) {
7263 DEBUG(5, ("spoolss_addprinterex_level_2: "
7264 "no sharename has been set, setting printername %s as sharename\n",
7265 info2->printername));
7266 info2->sharename = info2->printername;
7269 /* check to see if the printer already exists */
7270 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7271 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7273 return WERR_PRINTER_ALREADY_EXISTS;
7276 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7277 if ((snum = print_queue_snum(info2->printername)) != -1) {
7278 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7279 info2->printername));
7280 return WERR_PRINTER_ALREADY_EXISTS;
7284 /* validate printer info struct */
7285 if (!info2->printername || strlen(info2->printername) == 0) {
7286 return WERR_INVALID_PRINTER_NAME;
7288 if (!info2->portname || strlen(info2->portname) == 0) {
7289 return WERR_UNKNOWN_PORT;
7291 if (!info2->drivername || strlen(info2->drivername) == 0) {
7292 return WERR_UNKNOWN_PRINTER_DRIVER;
7294 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7295 return WERR_UNKNOWN_PRINTPROCESSOR;
7298 /* FIXME!!! smbd should check to see if the driver is installed before
7299 trying to add a printer like this --jerry */
7301 if (*lp_addprinter_cmd() ) {
7302 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7303 info2, p->client_address,
7305 return WERR_ACCESS_DENIED;
7308 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7309 "smb.conf parameter \"addprinter command\" is defined. This"
7310 "parameter must exist for this call to succeed\n",
7311 info2->sharename ));
7314 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7315 return WERR_ACCESS_DENIED;
7318 /* you must be a printer admin to add a new printer */
7319 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7320 return WERR_ACCESS_DENIED;
7324 * Do sanity check on the requested changes for Samba.
7327 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7328 return WERR_INVALID_PARAM;
7331 if (devmode == NULL) {
7332 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7335 update_dsspooler(p->mem_ctx,
7341 err = winreg_update_printer(p->mem_ctx,
7349 if (!W_ERROR_IS_OK(err)) {
7353 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7354 /* Handle open failed - remove addition. */
7355 ZERO_STRUCTP(handle);
7356 return WERR_ACCESS_DENIED;
7362 /****************************************************************
7363 _spoolss_AddPrinterEx
7364 ****************************************************************/
7366 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7367 struct spoolss_AddPrinterEx *r)
7369 switch (r->in.info_ctr->level) {
7371 /* we don't handle yet */
7372 /* but I know what to do ... */
7373 return WERR_UNKNOWN_LEVEL;
7375 return spoolss_addprinterex_level_2(p, r->in.server,
7377 r->in.devmode_ctr->devmode,
7378 r->in.secdesc_ctr->sd,
7379 r->in.userlevel_ctr,
7382 return WERR_UNKNOWN_LEVEL;
7386 /****************************************************************
7388 ****************************************************************/
7390 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7391 struct spoolss_AddPrinter *r)
7393 struct spoolss_AddPrinterEx a;
7394 struct spoolss_UserLevelCtr userlevel_ctr;
7396 ZERO_STRUCT(userlevel_ctr);
7398 userlevel_ctr.level = 1;
7400 a.in.server = r->in.server;
7401 a.in.info_ctr = r->in.info_ctr;
7402 a.in.devmode_ctr = r->in.devmode_ctr;
7403 a.in.secdesc_ctr = r->in.secdesc_ctr;
7404 a.in.userlevel_ctr = &userlevel_ctr;
7405 a.out.handle = r->out.handle;
7407 return _spoolss_AddPrinterEx(p, &a);
7410 /****************************************************************
7411 _spoolss_AddPrinterDriverEx
7412 ****************************************************************/
7414 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7415 struct spoolss_AddPrinterDriverEx *r)
7417 WERROR err = WERR_OK;
7418 const char *driver_name = NULL;
7423 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7424 fn = "_spoolss_AddPrinterDriver";
7426 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7427 fn = "_spoolss_AddPrinterDriverEx";
7430 return WERR_INVALID_PARAM;
7434 * we only support the semantics of AddPrinterDriver()
7435 * i.e. only copy files that are newer than existing ones
7438 if (r->in.flags == 0) {
7439 return WERR_INVALID_PARAM;
7442 if (r->in.flags != APD_COPY_NEW_FILES) {
7443 return WERR_ACCESS_DENIED;
7447 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7448 /* Clever hack from Martin Zielinski <mz@seh.de>
7449 * to allow downgrade from level 8 (Vista).
7451 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7452 r->in.info_ctr->level));
7453 return WERR_UNKNOWN_LEVEL;
7456 DEBUG(5,("Cleaning driver's information\n"));
7457 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7458 if (!W_ERROR_IS_OK(err))
7461 DEBUG(5,("Moving driver to final destination\n"));
7462 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7467 err = winreg_add_driver(p->mem_ctx, p->server_info,
7468 r->in.info_ctr, &driver_name, &version);
7469 if (!W_ERROR_IS_OK(err)) {
7474 * I think this is where he DrvUpgradePrinter() hook would be
7475 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7476 * server. Right now, we just need to send ourselves a message
7477 * to update each printer bound to this driver. --jerry
7480 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7481 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7489 /****************************************************************
7490 _spoolss_AddPrinterDriver
7491 ****************************************************************/
7493 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7494 struct spoolss_AddPrinterDriver *r)
7496 struct spoolss_AddPrinterDriverEx a;
7498 switch (r->in.info_ctr->level) {
7505 return WERR_UNKNOWN_LEVEL;
7508 a.in.servername = r->in.servername;
7509 a.in.info_ctr = r->in.info_ctr;
7510 a.in.flags = APD_COPY_NEW_FILES;
7512 return _spoolss_AddPrinterDriverEx(p, &a);
7515 /****************************************************************************
7516 ****************************************************************************/
7518 struct _spoolss_paths {
7524 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7526 static const struct _spoolss_paths spoolss_paths[]= {
7527 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7528 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7531 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7532 const char *servername,
7533 const char *environment,
7537 const char *pservername = NULL;
7538 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7539 const char *short_archi;
7543 /* environment may be empty */
7544 if (environment && strlen(environment)) {
7545 long_archi = environment;
7548 /* servername may be empty */
7549 if (servername && strlen(servername)) {
7550 pservername = canon_servername(servername);
7552 if (!is_myname_or_ipaddr(pservername)) {
7553 return WERR_INVALID_PARAM;
7557 if (!(short_archi = get_short_archi(long_archi))) {
7558 return WERR_INVALID_ENVIRONMENT;
7561 switch (component) {
7562 case SPOOLSS_PRTPROCS_PATH:
7563 case SPOOLSS_DRIVER_PATH:
7565 *path = talloc_asprintf(mem_ctx,
7568 spoolss_paths[component].share,
7571 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7572 SPOOLSS_DEFAULT_SERVER_PATH,
7573 spoolss_paths[component].dir,
7578 return WERR_INVALID_PARAM;
7588 /****************************************************************************
7589 ****************************************************************************/
7591 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7592 const char *servername,
7593 const char *environment,
7594 struct spoolss_DriverDirectoryInfo1 *r)
7599 werr = compose_spoolss_server_path(mem_ctx,
7602 SPOOLSS_DRIVER_PATH,
7604 if (!W_ERROR_IS_OK(werr)) {
7608 DEBUG(4,("printer driver directory: [%s]\n", path));
7610 r->directory_name = path;
7615 /****************************************************************
7616 _spoolss_GetPrinterDriverDirectory
7617 ****************************************************************/
7619 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7620 struct spoolss_GetPrinterDriverDirectory *r)
7624 /* that's an [in out] buffer */
7626 if (!r->in.buffer && (r->in.offered != 0)) {
7627 return WERR_INVALID_PARAM;
7630 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7635 /* r->in.level is ignored */
7637 werror = getprinterdriverdir_level_1(p->mem_ctx,
7640 &r->out.info->info1);
7641 if (!W_ERROR_IS_OK(werror)) {
7642 TALLOC_FREE(r->out.info);
7646 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7647 r->out.info, r->in.level);
7648 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7650 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7653 /****************************************************************
7654 _spoolss_EnumPrinterData
7655 ****************************************************************/
7657 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7658 struct spoolss_EnumPrinterData *r)
7661 struct spoolss_EnumPrinterDataEx r2;
7663 struct spoolss_PrinterEnumValues *info, *val = NULL;
7666 r2.in.handle = r->in.handle;
7667 r2.in.key_name = "PrinterDriverData";
7669 r2.out.count = &count;
7670 r2.out.info = &info;
7671 r2.out.needed = &needed;
7673 result = _spoolss_EnumPrinterDataEx(p, &r2);
7674 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7675 r2.in.offered = needed;
7676 result = _spoolss_EnumPrinterDataEx(p, &r2);
7678 if (!W_ERROR_IS_OK(result)) {
7683 * The NT machine wants to know the biggest size of value and data
7685 * cf: MSDN EnumPrinterData remark section
7688 if (!r->in.value_offered && !r->in.data_offered) {
7689 uint32_t biggest_valuesize = 0;
7690 uint32_t biggest_datasize = 0;
7693 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7695 for (i=0; i<count; i++) {
7697 name_length = strlen(info[i].value_name);
7698 if (strlen(info[i].value_name) > biggest_valuesize) {
7699 biggest_valuesize = name_length;
7702 if (info[i].data_length > biggest_datasize) {
7703 biggest_datasize = info[i].data_length;
7706 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7710 /* the value is an UNICODE string but real_value_size is the length
7711 in bytes including the trailing 0 */
7713 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7714 *r->out.data_needed = biggest_datasize;
7716 DEBUG(6,("final values: [%d], [%d]\n",
7717 *r->out.value_needed, *r->out.data_needed));
7722 if (r->in.enum_index < count) {
7723 val = &info[r->in.enum_index];
7727 /* out_value should default to "" or else NT4 has
7728 problems unmarshalling the response */
7730 if (r->in.value_offered) {
7731 *r->out.value_needed = 1;
7732 r->out.value_name = talloc_strdup(r, "");
7733 if (!r->out.value_name) {
7737 r->out.value_name = NULL;
7738 *r->out.value_needed = 0;
7741 /* the data is counted in bytes */
7743 *r->out.data_needed = r->in.data_offered;
7745 result = WERR_NO_MORE_ITEMS;
7749 * - counted in bytes in the request
7750 * - counted in UNICODE chars in the max reply
7751 * - counted in bytes in the real size
7753 * take a pause *before* coding not *during* coding
7757 if (r->in.value_offered) {
7758 r->out.value_name = talloc_strdup(r, val->value_name);
7759 if (!r->out.value_name) {
7762 *r->out.value_needed = val->value_name_len;
7764 r->out.value_name = NULL;
7765 *r->out.value_needed = 0;
7770 *r->out.type = val->type;
7772 /* data - counted in bytes */
7775 * See the section "Dynamically Typed Query Parameters"
7779 if (r->out.data && val->data && val->data->data &&
7780 val->data_length && r->in.data_offered) {
7781 memcpy(r->out.data, val->data->data,
7782 MIN(val->data_length,r->in.data_offered));
7785 *r->out.data_needed = val->data_length;
7793 /****************************************************************
7794 _spoolss_SetPrinterData
7795 ****************************************************************/
7797 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7798 struct spoolss_SetPrinterData *r)
7800 struct spoolss_SetPrinterDataEx r2;
7802 r2.in.handle = r->in.handle;
7803 r2.in.key_name = "PrinterDriverData";
7804 r2.in.value_name = r->in.value_name;
7805 r2.in.type = r->in.type;
7806 r2.in.data = r->in.data;
7807 r2.in.offered = r->in.offered;
7809 return _spoolss_SetPrinterDataEx(p, &r2);
7812 /****************************************************************
7813 _spoolss_ResetPrinter
7814 ****************************************************************/
7816 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7817 struct spoolss_ResetPrinter *r)
7819 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7822 DEBUG(5,("_spoolss_ResetPrinter\n"));
7825 * All we do is to check to see if the handle and queue is valid.
7826 * This call really doesn't mean anything to us because we only
7827 * support RAW printing. --jerry
7831 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7832 OUR_HANDLE(r->in.handle)));
7836 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7840 /* blindly return success */
7844 /****************************************************************
7845 _spoolss_DeletePrinterData
7846 ****************************************************************/
7848 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7849 struct spoolss_DeletePrinterData *r)
7851 struct spoolss_DeletePrinterDataEx r2;
7853 r2.in.handle = r->in.handle;
7854 r2.in.key_name = "PrinterDriverData";
7855 r2.in.value_name = r->in.value_name;
7857 return _spoolss_DeletePrinterDataEx(p, &r2);
7860 /****************************************************************
7862 ****************************************************************/
7864 WERROR _spoolss_AddForm(struct pipes_struct *p,
7865 struct spoolss_AddForm *r)
7867 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7869 WERROR status = WERR_OK;
7870 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7872 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7874 DEBUG(5,("_spoolss_AddForm\n"));
7877 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7878 OUR_HANDLE(r->in.handle)));
7882 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7883 and not a printer admin, then fail */
7885 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7886 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7887 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7888 p->server_info->info3->base.domain.string,
7890 p->server_info->ptok,
7891 lp_printer_admin(snum))) {
7892 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7893 return WERR_ACCESS_DENIED;
7896 switch (form->flags) {
7897 case SPOOLSS_FORM_USER:
7898 case SPOOLSS_FORM_BUILTIN:
7899 case SPOOLSS_FORM_PRINTER:
7902 return WERR_INVALID_PARAM;
7905 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7906 if (!W_ERROR_IS_OK(status)) {
7911 * ChangeID must always be set if this is a printer
7913 if (Printer->printer_type == SPLHND_PRINTER) {
7914 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7918 status = winreg_printer_update_changeid(p->mem_ctx,
7920 lp_const_servicename(snum));
7921 if (!W_ERROR_IS_OK(status)) {
7929 /****************************************************************
7931 ****************************************************************/
7933 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7934 struct spoolss_DeleteForm *r)
7936 const char *form_name = r->in.form_name;
7937 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7939 WERROR status = WERR_OK;
7940 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7942 DEBUG(5,("_spoolss_DeleteForm\n"));
7945 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7946 OUR_HANDLE(r->in.handle)));
7950 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7951 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7952 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7953 p->server_info->info3->base.domain.string,
7955 p->server_info->ptok,
7956 lp_printer_admin(snum))) {
7957 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7958 return WERR_ACCESS_DENIED;
7961 status = winreg_printer_deleteform1(p->mem_ctx,
7964 if (!W_ERROR_IS_OK(status)) {
7969 * ChangeID must always be set if this is a printer
7971 if (Printer->printer_type == SPLHND_PRINTER) {
7972 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7976 status = winreg_printer_update_changeid(p->mem_ctx,
7978 lp_const_servicename(snum));
7979 if (!W_ERROR_IS_OK(status)) {
7987 /****************************************************************
7989 ****************************************************************/
7991 WERROR _spoolss_SetForm(struct pipes_struct *p,
7992 struct spoolss_SetForm *r)
7994 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7995 const char *form_name = r->in.form_name;
7997 WERROR status = WERR_OK;
7998 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8000 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8002 DEBUG(5,("_spoolss_SetForm\n"));
8005 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8006 OUR_HANDLE(r->in.handle)));
8010 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8011 and not a printer admin, then fail */
8013 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8014 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8015 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8016 p->server_info->info3->base.domain.string,
8018 p->server_info->ptok,
8019 lp_printer_admin(snum))) {
8020 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8021 return WERR_ACCESS_DENIED;
8024 status = winreg_printer_setform1(p->mem_ctx,
8028 if (!W_ERROR_IS_OK(status)) {
8033 * ChangeID must always be set if this is a printer
8035 if (Printer->printer_type == SPLHND_PRINTER) {
8036 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8040 status = winreg_printer_update_changeid(p->mem_ctx,
8042 lp_const_servicename(snum));
8043 if (!W_ERROR_IS_OK(status)) {
8051 /****************************************************************************
8052 fill_print_processor1
8053 ****************************************************************************/
8055 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8056 struct spoolss_PrintProcessorInfo1 *r,
8057 const char *print_processor_name)
8059 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8060 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8065 /****************************************************************************
8066 enumprintprocessors level 1.
8067 ****************************************************************************/
8069 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8070 union spoolss_PrintProcessorInfo **info_p,
8073 union spoolss_PrintProcessorInfo *info;
8076 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8077 W_ERROR_HAVE_NO_MEMORY(info);
8081 result = fill_print_processor1(info, &info[0].info1, "winprint");
8082 if (!W_ERROR_IS_OK(result)) {
8087 if (!W_ERROR_IS_OK(result)) {
8098 /****************************************************************
8099 _spoolss_EnumPrintProcessors
8100 ****************************************************************/
8102 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8103 struct spoolss_EnumPrintProcessors *r)
8107 /* that's an [in out] buffer */
8109 if (!r->in.buffer && (r->in.offered != 0)) {
8110 return WERR_INVALID_PARAM;
8113 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8116 * Enumerate the print processors ...
8118 * Just reply with "winprint", to keep NT happy
8119 * and I can use my nice printer checker.
8124 *r->out.info = NULL;
8126 switch (r->in.level) {
8128 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8132 return WERR_UNKNOWN_LEVEL;
8135 if (!W_ERROR_IS_OK(result)) {
8139 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8140 spoolss_EnumPrintProcessors,
8141 *r->out.info, r->in.level,
8143 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8144 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8146 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8149 /****************************************************************************
8150 fill_printprocdatatype1
8151 ****************************************************************************/
8153 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8154 struct spoolss_PrintProcDataTypesInfo1 *r,
8155 const char *name_array)
8157 r->name_array = talloc_strdup(mem_ctx, name_array);
8158 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8163 /****************************************************************************
8164 enumprintprocdatatypes level 1.
8165 ****************************************************************************/
8167 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8168 union spoolss_PrintProcDataTypesInfo **info_p,
8172 union spoolss_PrintProcDataTypesInfo *info;
8174 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8175 W_ERROR_HAVE_NO_MEMORY(info);
8179 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8180 if (!W_ERROR_IS_OK(result)) {
8185 if (!W_ERROR_IS_OK(result)) {
8196 /****************************************************************
8197 _spoolss_EnumPrintProcDataTypes
8198 ****************************************************************/
8200 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8201 struct spoolss_EnumPrintProcDataTypes *r)
8205 /* that's an [in out] buffer */
8207 if (!r->in.buffer && (r->in.offered != 0)) {
8208 return WERR_INVALID_PARAM;
8211 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8215 *r->out.info = NULL;
8217 switch (r->in.level) {
8219 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8223 return WERR_UNKNOWN_LEVEL;
8226 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8227 spoolss_EnumPrintProcDataTypes,
8228 *r->out.info, r->in.level,
8230 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8231 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8233 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8236 /****************************************************************************
8238 ****************************************************************************/
8240 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8241 struct spoolss_MonitorInfo1 *r,
8242 const char *monitor_name)
8244 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8245 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8250 /****************************************************************************
8252 ****************************************************************************/
8254 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8255 struct spoolss_MonitorInfo2 *r,
8256 const char *monitor_name,
8257 const char *environment,
8258 const char *dll_name)
8260 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8261 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8262 r->environment = talloc_strdup(mem_ctx, environment);
8263 W_ERROR_HAVE_NO_MEMORY(r->environment);
8264 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8265 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8270 /****************************************************************************
8271 enumprintmonitors level 1.
8272 ****************************************************************************/
8274 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8275 union spoolss_MonitorInfo **info_p,
8278 union spoolss_MonitorInfo *info;
8279 WERROR result = WERR_OK;
8281 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8282 W_ERROR_HAVE_NO_MEMORY(info);
8286 result = fill_monitor_1(info, &info[0].info1,
8288 if (!W_ERROR_IS_OK(result)) {
8292 result = fill_monitor_1(info, &info[1].info1,
8294 if (!W_ERROR_IS_OK(result)) {
8299 if (!W_ERROR_IS_OK(result)) {
8310 /****************************************************************************
8311 enumprintmonitors level 2.
8312 ****************************************************************************/
8314 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8315 union spoolss_MonitorInfo **info_p,
8318 union spoolss_MonitorInfo *info;
8319 WERROR result = WERR_OK;
8321 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8322 W_ERROR_HAVE_NO_MEMORY(info);
8326 result = fill_monitor_2(info, &info[0].info2,
8328 "Windows NT X86", /* FIXME */
8330 if (!W_ERROR_IS_OK(result)) {
8334 result = fill_monitor_2(info, &info[1].info2,
8336 "Windows NT X86", /* FIXME */
8338 if (!W_ERROR_IS_OK(result)) {
8343 if (!W_ERROR_IS_OK(result)) {
8354 /****************************************************************
8355 _spoolss_EnumMonitors
8356 ****************************************************************/
8358 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8359 struct spoolss_EnumMonitors *r)
8363 /* that's an [in out] buffer */
8365 if (!r->in.buffer && (r->in.offered != 0)) {
8366 return WERR_INVALID_PARAM;
8369 DEBUG(5,("_spoolss_EnumMonitors\n"));
8372 * Enumerate the print monitors ...
8374 * Just reply with "Local Port", to keep NT happy
8375 * and I can use my nice printer checker.
8380 *r->out.info = NULL;
8382 switch (r->in.level) {
8384 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8388 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8392 return WERR_UNKNOWN_LEVEL;
8395 if (!W_ERROR_IS_OK(result)) {
8399 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8400 spoolss_EnumMonitors,
8401 *r->out.info, r->in.level,
8403 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8404 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8406 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8409 /****************************************************************************
8410 ****************************************************************************/
8412 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8413 const print_queue_struct *queue,
8414 int count, int snum,
8415 struct spoolss_PrinterInfo2 *pinfo2,
8417 struct spoolss_JobInfo1 *r)
8422 for (i=0; i<count; i++) {
8423 if (queue[i].job == (int)jobid) {
8429 if (found == false) {
8430 /* NT treats not found as bad param... yet another bad choice */
8431 return WERR_INVALID_PARAM;
8434 return fill_job_info1(mem_ctx,
8442 /****************************************************************************
8443 ****************************************************************************/
8445 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8446 const print_queue_struct *queue,
8447 int count, int snum,
8448 struct spoolss_PrinterInfo2 *pinfo2,
8450 struct spoolss_JobInfo2 *r)
8454 struct spoolss_DeviceMode *devmode;
8457 for (i=0; i<count; i++) {
8458 if (queue[i].job == (int)jobid) {
8464 if (found == false) {
8465 /* NT treats not found as bad param... yet another bad
8467 return WERR_INVALID_PARAM;
8471 * if the print job does not have a DEVMODE associated with it,
8472 * just use the one for the printer. A NULL devicemode is not
8473 * a failure condition
8476 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8478 result = spoolss_create_default_devmode(mem_ctx,
8479 pinfo2->printername,
8481 if (!W_ERROR_IS_OK(result)) {
8482 DEBUG(3, ("Can't proceed w/o a devmode!"));
8487 return fill_job_info2(mem_ctx,
8496 /****************************************************************
8498 ****************************************************************/
8500 WERROR _spoolss_GetJob(struct pipes_struct *p,
8501 struct spoolss_GetJob *r)
8503 WERROR result = WERR_OK;
8504 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8507 print_queue_struct *queue = NULL;
8508 print_status_struct prt_status;
8510 /* that's an [in out] buffer */
8512 if (!r->in.buffer && (r->in.offered != 0)) {
8513 return WERR_INVALID_PARAM;
8516 DEBUG(5,("_spoolss_GetJob\n"));
8520 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8524 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
8525 NULL, lp_servicename(snum), &pinfo2);
8526 if (!W_ERROR_IS_OK(result)) {
8530 count = print_queue_status(snum, &queue, &prt_status);
8532 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8533 count, prt_status.status, prt_status.message));
8535 switch (r->in.level) {
8537 result = getjob_level_1(p->mem_ctx,
8538 queue, count, snum, pinfo2,
8539 r->in.job_id, &r->out.info->info1);
8542 result = getjob_level_2(p->mem_ctx,
8543 queue, count, snum, pinfo2,
8544 r->in.job_id, &r->out.info->info2);
8547 result = WERR_UNKNOWN_LEVEL;
8552 TALLOC_FREE(pinfo2);
8554 if (!W_ERROR_IS_OK(result)) {
8555 TALLOC_FREE(r->out.info);
8559 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8561 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8563 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8566 /****************************************************************
8567 _spoolss_GetPrinterDataEx
8568 ****************************************************************/
8570 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8571 struct spoolss_GetPrinterDataEx *r)
8574 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8575 const char *printer;
8577 WERROR result = WERR_OK;
8579 enum winreg_Type val_type;
8584 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8586 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8587 r->in.key_name, r->in.value_name));
8589 /* in case of problem, return some default values */
8592 *r->out.type = REG_NONE;
8595 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8596 OUR_HANDLE(r->in.handle)));
8597 result = WERR_BADFID;
8601 /* Is the handle to a printer or to the server? */
8603 if (Printer->printer_type == SPLHND_SERVER) {
8605 union spoolss_PrinterData data;
8607 result = getprinterdata_printer_server(p->mem_ctx,
8611 if (!W_ERROR_IS_OK(result)) {
8615 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8616 *r->out.type, &data);
8617 if (!W_ERROR_IS_OK(result)) {
8621 *r->out.needed = blob.length;
8623 if (r->in.offered >= *r->out.needed) {
8624 memcpy(r->out.data, blob.data, blob.length);
8627 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8630 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8633 printer = lp_const_servicename(snum);
8635 /* check to see if the keyname is valid */
8636 if (!strlen(r->in.key_name)) {
8637 return WERR_INVALID_PARAM;
8640 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8641 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8642 strequal(r->in.value_name, "ChangeId")) {
8643 *r->out.type = REG_DWORD;
8645 if (r->in.offered >= *r->out.needed) {
8646 uint32_t changeid = 0;
8648 result = winreg_printer_get_changeid(p->mem_ctx,
8652 if (!W_ERROR_IS_OK(result)) {
8656 SIVAL(r->out.data, 0, changeid);
8662 result = winreg_get_printer_dataex(p->mem_ctx,
8670 if (!W_ERROR_IS_OK(result)) {
8674 *r->out.needed = val_size;
8675 *r->out.type = val_type;
8677 if (r->in.offered >= *r->out.needed) {
8678 memcpy(r->out.data, val_data, val_size);
8682 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8683 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8685 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8688 /****************************************************************
8689 _spoolss_SetPrinterDataEx
8690 ****************************************************************/
8692 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8693 struct spoolss_SetPrinterDataEx *r)
8695 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8697 WERROR result = WERR_OK;
8698 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8701 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8703 /* From MSDN documentation of SetPrinterDataEx: pass request to
8704 SetPrinterData if key is "PrinterDriverData" */
8707 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8708 OUR_HANDLE(r->in.handle)));
8712 if (Printer->printer_type == SPLHND_SERVER) {
8713 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8714 "Not implemented for server handles yet\n"));
8715 return WERR_INVALID_PARAM;
8718 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8723 * Access check : NT returns "access denied" if you make a
8724 * SetPrinterData call without the necessary privildge.
8725 * we were originally returning OK if nothing changed
8726 * which made Win2k issue **a lot** of SetPrinterData
8727 * when connecting to a printer --jerry
8730 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8731 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8732 "change denied by handle access permissions\n"));
8733 return WERR_ACCESS_DENIED;
8736 result = winreg_get_printer(Printer, p->server_info, p->msg_ctx,
8737 Printer->servername,
8738 lp_servicename(snum),
8740 if (!W_ERROR_IS_OK(result)) {
8744 /* check for OID in valuename */
8746 oid_string = strchr(r->in.value_name, ',');
8752 /* save the registry data */
8754 result = winreg_set_printer_dataex(p->mem_ctx,
8764 if (W_ERROR_IS_OK(result)) {
8765 /* save the OID if one was specified */
8767 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8768 r->in.key_name, SPOOL_OID_KEY);
8770 result = WERR_NOMEM;
8775 * I'm not checking the status here on purpose. Don't know
8776 * if this is right, but I'm returning the status from the
8777 * previous set_printer_dataex() call. I have no idea if
8778 * this is right. --jerry
8780 winreg_set_printer_dataex(p->mem_ctx,
8787 (uint8_t *) oid_string,
8788 strlen(oid_string) + 1);
8791 result = winreg_printer_update_changeid(p->mem_ctx,
8793 lp_const_servicename(snum));
8798 talloc_free(pinfo2);
8802 /****************************************************************
8803 _spoolss_DeletePrinterDataEx
8804 ****************************************************************/
8806 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8807 struct spoolss_DeletePrinterDataEx *r)
8809 const char *printer;
8811 WERROR status = WERR_OK;
8812 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8814 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8817 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8818 "Invalid handle (%s:%u:%u).\n",
8819 OUR_HANDLE(r->in.handle)));
8823 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8824 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8825 "printer properties change denied by handle\n"));
8826 return WERR_ACCESS_DENIED;
8829 if (!r->in.value_name || !r->in.key_name) {
8833 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8836 printer = lp_const_servicename(snum);
8838 status = winreg_delete_printer_dataex(p->mem_ctx,
8843 if (W_ERROR_IS_OK(status)) {
8844 status = winreg_printer_update_changeid(p->mem_ctx,
8852 /****************************************************************
8853 _spoolss_EnumPrinterKey
8854 ****************************************************************/
8856 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8857 struct spoolss_EnumPrinterKey *r)
8860 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8862 WERROR result = WERR_BADFILE;
8863 const char **array = NULL;
8866 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8869 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8870 OUR_HANDLE(r->in.handle)));
8874 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8878 result = winreg_enum_printer_key(p->mem_ctx,
8880 lp_const_servicename(snum),
8884 if (!W_ERROR_IS_OK(result)) {
8888 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8889 result = WERR_NOMEM;
8893 *r->out._ndr_size = r->in.offered / 2;
8894 *r->out.needed = blob.length;
8896 if (r->in.offered < *r->out.needed) {
8897 result = WERR_MORE_DATA;
8900 r->out.key_buffer->string_array = array;
8904 if (!W_ERROR_IS_OK(result)) {
8906 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8914 /****************************************************************
8915 _spoolss_DeletePrinterKey
8916 ****************************************************************/
8918 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8919 struct spoolss_DeletePrinterKey *r)
8921 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8924 const char *printer;
8926 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8929 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8930 OUR_HANDLE(r->in.handle)));
8934 /* if keyname == NULL, return error */
8935 if ( !r->in.key_name )
8936 return WERR_INVALID_PARAM;
8938 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8942 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8943 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8944 "printer properties change denied by handle\n"));
8945 return WERR_ACCESS_DENIED;
8948 printer = lp_const_servicename(snum);
8950 /* delete the key and all subkeys */
8951 status = winreg_delete_printer_key(p->mem_ctx,
8955 if (W_ERROR_IS_OK(status)) {
8956 status = winreg_printer_update_changeid(p->mem_ctx,
8964 /****************************************************************
8965 _spoolss_EnumPrinterDataEx
8966 ****************************************************************/
8968 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8969 struct spoolss_EnumPrinterDataEx *r)
8972 struct spoolss_PrinterEnumValues *info = NULL;
8973 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8977 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8981 *r->out.info = NULL;
8984 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8985 OUR_HANDLE(r->in.handle)));
8990 * first check for a keyname of NULL or "". Win2k seems to send
8991 * this a lot and we should send back WERR_INVALID_PARAM
8992 * no need to spend time looking up the printer in this case.
8996 if (!strlen(r->in.key_name)) {
8997 result = WERR_INVALID_PARAM;
9001 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9005 /* now look for a match on the key name */
9006 result = winreg_enum_printer_dataex(p->mem_ctx,
9008 lp_const_servicename(snum),
9012 if (!W_ERROR_IS_OK(result)) {
9016 #if 0 /* FIXME - gd */
9017 /* housekeeping information in the reply */
9019 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9020 * the hand marshalled container size is a multiple
9021 * of 4 bytes for RPC alignment.
9025 needed += 4-(needed % 4);
9028 *r->out.count = count;
9029 *r->out.info = info;
9032 if (!W_ERROR_IS_OK(result)) {
9036 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9037 spoolss_EnumPrinterDataEx,
9040 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9041 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9043 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9046 /****************************************************************************
9047 ****************************************************************************/
9049 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9050 const char *servername,
9051 const char *environment,
9052 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9057 werr = compose_spoolss_server_path(mem_ctx,
9060 SPOOLSS_PRTPROCS_PATH,
9062 if (!W_ERROR_IS_OK(werr)) {
9066 DEBUG(4,("print processor directory: [%s]\n", path));
9068 r->directory_name = path;
9073 /****************************************************************
9074 _spoolss_GetPrintProcessorDirectory
9075 ****************************************************************/
9077 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9078 struct spoolss_GetPrintProcessorDirectory *r)
9082 /* that's an [in out] buffer */
9084 if (!r->in.buffer && (r->in.offered != 0)) {
9085 return WERR_INVALID_PARAM;
9088 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9093 /* r->in.level is ignored */
9095 /* We always should reply with a local print processor directory so that
9096 * users are not forced to have a [prnproc$] share on the Samba spoolss
9097 * server - Guenther */
9099 result = getprintprocessordirectory_level_1(p->mem_ctx,
9100 NULL, /* r->in.server */
9102 &r->out.info->info1);
9103 if (!W_ERROR_IS_OK(result)) {
9104 TALLOC_FREE(r->out.info);
9108 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9109 r->out.info, r->in.level);
9110 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9112 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9115 /*******************************************************************
9116 ********************************************************************/
9118 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9119 const char *dllname)
9121 enum ndr_err_code ndr_err;
9122 struct spoolss_MonitorUi ui;
9124 ui.dll_name = dllname;
9126 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9127 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9128 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9129 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9131 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9134 /*******************************************************************
9135 Streams the monitor UI DLL name in UNICODE
9136 *******************************************************************/
9138 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9139 NT_USER_TOKEN *token, DATA_BLOB *in,
9140 DATA_BLOB *out, uint32_t *needed)
9142 const char *dllname = "tcpmonui.dll";
9144 *needed = (strlen(dllname)+1) * 2;
9146 if (out->length < *needed) {
9147 return WERR_INSUFFICIENT_BUFFER;
9150 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9157 /*******************************************************************
9158 ********************************************************************/
9160 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9161 struct spoolss_PortData1 *port1,
9162 const DATA_BLOB *buf)
9164 enum ndr_err_code ndr_err;
9165 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9166 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9167 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9168 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9170 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9173 /*******************************************************************
9174 ********************************************************************/
9176 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9177 struct spoolss_PortData2 *port2,
9178 const DATA_BLOB *buf)
9180 enum ndr_err_code ndr_err;
9181 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9182 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9183 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9184 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9186 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9189 /*******************************************************************
9190 Create a new TCP/IP port
9191 *******************************************************************/
9193 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9194 NT_USER_TOKEN *token, DATA_BLOB *in,
9195 DATA_BLOB *out, uint32_t *needed)
9197 struct spoolss_PortData1 port1;
9198 struct spoolss_PortData2 port2;
9199 char *device_uri = NULL;
9202 const char *portname;
9203 const char *hostaddress;
9205 uint32_t port_number;
9208 /* peek for spoolss_PortData version */
9210 if (!in || (in->length < (128 + 4))) {
9211 return WERR_GENERAL_FAILURE;
9214 version = IVAL(in->data, 128);
9220 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9224 portname = port1.portname;
9225 hostaddress = port1.hostaddress;
9226 queue = port1.queue;
9227 protocol = port1.protocol;
9228 port_number = port1.port_number;
9234 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9238 portname = port2.portname;
9239 hostaddress = port2.hostaddress;
9240 queue = port2.queue;
9241 protocol = port2.protocol;
9242 port_number = port2.port_number;
9246 DEBUG(1,("xcvtcp_addport: "
9247 "unknown version of port_data: %d\n", version));
9248 return WERR_UNKNOWN_PORT;
9251 /* create the device URI and call the add_port_hook() */
9254 case PROTOCOL_RAWTCP_TYPE:
9255 device_uri = talloc_asprintf(mem_ctx,
9256 "socket://%s:%d/", hostaddress,
9260 case PROTOCOL_LPR_TYPE:
9261 device_uri = talloc_asprintf(mem_ctx,
9262 "lpr://%s/%s", hostaddress, queue );
9266 return WERR_UNKNOWN_PORT;
9273 return add_port_hook(mem_ctx, token, portname, device_uri);
9276 /*******************************************************************
9277 *******************************************************************/
9279 struct xcv_api_table xcvtcp_cmds[] = {
9280 { "MonitorUI", xcvtcp_monitorui },
9281 { "AddPort", xcvtcp_addport},
9285 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9286 NT_USER_TOKEN *token, const char *command,
9293 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9295 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9296 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9297 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9300 return WERR_BADFUNC;
9303 /*******************************************************************
9304 *******************************************************************/
9305 #if 0 /* don't support management using the "Local Port" monitor */
9307 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9308 NT_USER_TOKEN *token, DATA_BLOB *in,
9309 DATA_BLOB *out, uint32_t *needed)
9311 const char *dllname = "localui.dll";
9313 *needed = (strlen(dllname)+1) * 2;
9315 if (out->length < *needed) {
9316 return WERR_INSUFFICIENT_BUFFER;
9319 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9326 /*******************************************************************
9327 *******************************************************************/
9329 struct xcv_api_table xcvlocal_cmds[] = {
9330 { "MonitorUI", xcvlocal_monitorui },
9334 struct xcv_api_table xcvlocal_cmds[] = {
9341 /*******************************************************************
9342 *******************************************************************/
9344 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9345 NT_USER_TOKEN *token, const char *command,
9346 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9351 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9353 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9354 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9355 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9357 return WERR_BADFUNC;
9360 /****************************************************************
9362 ****************************************************************/
9364 WERROR _spoolss_XcvData(struct pipes_struct *p,
9365 struct spoolss_XcvData *r)
9367 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9368 DATA_BLOB out_data = data_blob_null;
9372 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9373 OUR_HANDLE(r->in.handle)));
9377 /* Has to be a handle to the TCP/IP port monitor */
9379 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9380 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9384 /* requires administrative access to the server */
9386 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9387 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9388 return WERR_ACCESS_DENIED;
9391 /* Allocate the outgoing buffer */
9393 if (r->in.out_data_size) {
9394 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9395 if (out_data.data == NULL) {
9400 switch ( Printer->printer_type ) {
9401 case SPLHND_PORTMON_TCP:
9402 werror = process_xcvtcp_command(p->mem_ctx,
9403 p->server_info->ptok,
9404 r->in.function_name,
9405 &r->in.in_data, &out_data,
9408 case SPLHND_PORTMON_LOCAL:
9409 werror = process_xcvlocal_command(p->mem_ctx,
9410 p->server_info->ptok,
9411 r->in.function_name,
9412 &r->in.in_data, &out_data,
9416 werror = WERR_INVALID_PRINT_MONITOR;
9419 if (!W_ERROR_IS_OK(werror)) {
9423 *r->out.status_code = 0;
9425 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9426 memcpy(r->out.out_data, out_data.data,
9427 MIN(r->in.out_data_size, out_data.length));
9433 /****************************************************************
9434 _spoolss_AddPrintProcessor
9435 ****************************************************************/
9437 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9438 struct spoolss_AddPrintProcessor *r)
9440 /* for now, just indicate success and ignore the add. We'll
9441 automatically set the winprint processor for printer
9442 entries later. Used to debug the LexMark Optra S 1855 PCL
9448 /****************************************************************
9450 ****************************************************************/
9452 WERROR _spoolss_AddPort(struct pipes_struct *p,
9453 struct spoolss_AddPort *r)
9455 /* do what w2k3 does */
9457 return WERR_NOT_SUPPORTED;
9460 /****************************************************************
9461 _spoolss_GetPrinterDriver
9462 ****************************************************************/
9464 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9465 struct spoolss_GetPrinterDriver *r)
9467 p->rng_fault_state = true;
9468 return WERR_NOT_SUPPORTED;
9471 /****************************************************************
9472 _spoolss_ReadPrinter
9473 ****************************************************************/
9475 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9476 struct spoolss_ReadPrinter *r)
9478 p->rng_fault_state = true;
9479 return WERR_NOT_SUPPORTED;
9482 /****************************************************************
9483 _spoolss_WaitForPrinterChange
9484 ****************************************************************/
9486 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9487 struct spoolss_WaitForPrinterChange *r)
9489 p->rng_fault_state = true;
9490 return WERR_NOT_SUPPORTED;
9493 /****************************************************************
9494 _spoolss_ConfigurePort
9495 ****************************************************************/
9497 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9498 struct spoolss_ConfigurePort *r)
9500 p->rng_fault_state = true;
9501 return WERR_NOT_SUPPORTED;
9504 /****************************************************************
9506 ****************************************************************/
9508 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9509 struct spoolss_DeletePort *r)
9511 p->rng_fault_state = true;
9512 return WERR_NOT_SUPPORTED;
9515 /****************************************************************
9516 _spoolss_CreatePrinterIC
9517 ****************************************************************/
9519 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9520 struct spoolss_CreatePrinterIC *r)
9522 p->rng_fault_state = true;
9523 return WERR_NOT_SUPPORTED;
9526 /****************************************************************
9527 _spoolss_PlayGDIScriptOnPrinterIC
9528 ****************************************************************/
9530 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9531 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9533 p->rng_fault_state = true;
9534 return WERR_NOT_SUPPORTED;
9537 /****************************************************************
9538 _spoolss_DeletePrinterIC
9539 ****************************************************************/
9541 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9542 struct spoolss_DeletePrinterIC *r)
9544 p->rng_fault_state = true;
9545 return WERR_NOT_SUPPORTED;
9548 /****************************************************************
9549 _spoolss_AddPrinterConnection
9550 ****************************************************************/
9552 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9553 struct spoolss_AddPrinterConnection *r)
9555 p->rng_fault_state = true;
9556 return WERR_NOT_SUPPORTED;
9559 /****************************************************************
9560 _spoolss_DeletePrinterConnection
9561 ****************************************************************/
9563 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9564 struct spoolss_DeletePrinterConnection *r)
9566 p->rng_fault_state = true;
9567 return WERR_NOT_SUPPORTED;
9570 /****************************************************************
9571 _spoolss_PrinterMessageBox
9572 ****************************************************************/
9574 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9575 struct spoolss_PrinterMessageBox *r)
9577 p->rng_fault_state = true;
9578 return WERR_NOT_SUPPORTED;
9581 /****************************************************************
9583 ****************************************************************/
9585 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9586 struct spoolss_AddMonitor *r)
9588 p->rng_fault_state = true;
9589 return WERR_NOT_SUPPORTED;
9592 /****************************************************************
9593 _spoolss_DeleteMonitor
9594 ****************************************************************/
9596 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9597 struct spoolss_DeleteMonitor *r)
9599 p->rng_fault_state = true;
9600 return WERR_NOT_SUPPORTED;
9603 /****************************************************************
9604 _spoolss_DeletePrintProcessor
9605 ****************************************************************/
9607 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9608 struct spoolss_DeletePrintProcessor *r)
9610 p->rng_fault_state = true;
9611 return WERR_NOT_SUPPORTED;
9614 /****************************************************************
9615 _spoolss_AddPrintProvidor
9616 ****************************************************************/
9618 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9619 struct spoolss_AddPrintProvidor *r)
9621 p->rng_fault_state = true;
9622 return WERR_NOT_SUPPORTED;
9625 /****************************************************************
9626 _spoolss_DeletePrintProvidor
9627 ****************************************************************/
9629 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9630 struct spoolss_DeletePrintProvidor *r)
9632 p->rng_fault_state = true;
9633 return WERR_NOT_SUPPORTED;
9636 /****************************************************************
9637 _spoolss_FindFirstPrinterChangeNotification
9638 ****************************************************************/
9640 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9641 struct spoolss_FindFirstPrinterChangeNotification *r)
9643 p->rng_fault_state = true;
9644 return WERR_NOT_SUPPORTED;
9647 /****************************************************************
9648 _spoolss_FindNextPrinterChangeNotification
9649 ****************************************************************/
9651 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9652 struct spoolss_FindNextPrinterChangeNotification *r)
9654 p->rng_fault_state = true;
9655 return WERR_NOT_SUPPORTED;
9658 /****************************************************************
9659 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9660 ****************************************************************/
9662 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9663 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9665 p->rng_fault_state = true;
9666 return WERR_NOT_SUPPORTED;
9669 /****************************************************************
9670 _spoolss_ReplyOpenPrinter
9671 ****************************************************************/
9673 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9674 struct spoolss_ReplyOpenPrinter *r)
9676 p->rng_fault_state = true;
9677 return WERR_NOT_SUPPORTED;
9680 /****************************************************************
9681 _spoolss_RouterReplyPrinter
9682 ****************************************************************/
9684 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9685 struct spoolss_RouterReplyPrinter *r)
9687 p->rng_fault_state = true;
9688 return WERR_NOT_SUPPORTED;
9691 /****************************************************************
9692 _spoolss_ReplyClosePrinter
9693 ****************************************************************/
9695 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9696 struct spoolss_ReplyClosePrinter *r)
9698 p->rng_fault_state = true;
9699 return WERR_NOT_SUPPORTED;
9702 /****************************************************************
9704 ****************************************************************/
9706 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9707 struct spoolss_AddPortEx *r)
9709 p->rng_fault_state = true;
9710 return WERR_NOT_SUPPORTED;
9713 /****************************************************************
9714 _spoolss_RouterFindFirstPrinterChangeNotification
9715 ****************************************************************/
9717 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9718 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9720 p->rng_fault_state = true;
9721 return WERR_NOT_SUPPORTED;
9724 /****************************************************************
9725 _spoolss_SpoolerInit
9726 ****************************************************************/
9728 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9729 struct spoolss_SpoolerInit *r)
9731 p->rng_fault_state = true;
9732 return WERR_NOT_SUPPORTED;
9735 /****************************************************************
9736 _spoolss_ResetPrinterEx
9737 ****************************************************************/
9739 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9740 struct spoolss_ResetPrinterEx *r)
9742 p->rng_fault_state = true;
9743 return WERR_NOT_SUPPORTED;
9746 /****************************************************************
9747 _spoolss_RouterReplyPrinterEx
9748 ****************************************************************/
9750 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9751 struct spoolss_RouterReplyPrinterEx *r)
9753 p->rng_fault_state = true;
9754 return WERR_NOT_SUPPORTED;
9757 /****************************************************************
9759 ****************************************************************/
9761 WERROR _spoolss_44(struct pipes_struct *p,
9762 struct spoolss_44 *r)
9764 p->rng_fault_state = true;
9765 return WERR_NOT_SUPPORTED;
9768 /****************************************************************
9770 ****************************************************************/
9772 WERROR _spoolss_47(struct pipes_struct *p,
9773 struct spoolss_47 *r)
9775 p->rng_fault_state = true;
9776 return WERR_NOT_SUPPORTED;
9779 /****************************************************************
9781 ****************************************************************/
9783 WERROR _spoolss_4a(struct pipes_struct *p,
9784 struct spoolss_4a *r)
9786 p->rng_fault_state = true;
9787 return WERR_NOT_SUPPORTED;
9790 /****************************************************************
9792 ****************************************************************/
9794 WERROR _spoolss_4b(struct pipes_struct *p,
9795 struct spoolss_4b *r)
9797 p->rng_fault_state = true;
9798 return WERR_NOT_SUPPORTED;
9801 /****************************************************************
9803 ****************************************************************/
9805 WERROR _spoolss_4c(struct pipes_struct *p,
9806 struct spoolss_4c *r)
9808 p->rng_fault_state = true;
9809 return WERR_NOT_SUPPORTED;
9812 /****************************************************************
9814 ****************************************************************/
9816 WERROR _spoolss_53(struct pipes_struct *p,
9817 struct spoolss_53 *r)
9819 p->rng_fault_state = true;
9820 return WERR_NOT_SUPPORTED;
9823 /****************************************************************
9825 ****************************************************************/
9827 WERROR _spoolss_55(struct pipes_struct *p,
9828 struct spoolss_55 *r)
9830 p->rng_fault_state = true;
9831 return WERR_NOT_SUPPORTED;
9834 /****************************************************************
9836 ****************************************************************/
9838 WERROR _spoolss_56(struct pipes_struct *p,
9839 struct spoolss_56 *r)
9841 p->rng_fault_state = true;
9842 return WERR_NOT_SUPPORTED;
9845 /****************************************************************
9847 ****************************************************************/
9849 WERROR _spoolss_57(struct pipes_struct *p,
9850 struct spoolss_57 *r)
9852 p->rng_fault_state = true;
9853 return WERR_NOT_SUPPORTED;
9856 /****************************************************************
9858 ****************************************************************/
9860 WERROR _spoolss_5a(struct pipes_struct *p,
9861 struct spoolss_5a *r)
9863 p->rng_fault_state = true;
9864 return WERR_NOT_SUPPORTED;
9867 /****************************************************************
9869 ****************************************************************/
9871 WERROR _spoolss_5b(struct pipes_struct *p,
9872 struct spoolss_5b *r)
9874 p->rng_fault_state = true;
9875 return WERR_NOT_SUPPORTED;
9878 /****************************************************************
9880 ****************************************************************/
9882 WERROR _spoolss_5c(struct pipes_struct *p,
9883 struct spoolss_5c *r)
9885 p->rng_fault_state = true;
9886 return WERR_NOT_SUPPORTED;
9889 /****************************************************************
9891 ****************************************************************/
9893 WERROR _spoolss_5d(struct pipes_struct *p,
9894 struct spoolss_5d *r)
9896 p->rng_fault_state = true;
9897 return WERR_NOT_SUPPORTED;
9900 /****************************************************************
9902 ****************************************************************/
9904 WERROR _spoolss_5e(struct pipes_struct *p,
9905 struct spoolss_5e *r)
9907 p->rng_fault_state = true;
9908 return WERR_NOT_SUPPORTED;
9911 /****************************************************************
9913 ****************************************************************/
9915 WERROR _spoolss_5f(struct pipes_struct *p,
9916 struct spoolss_5f *r)
9918 p->rng_fault_state = true;
9919 return WERR_NOT_SUPPORTED;
9922 /****************************************************************
9924 ****************************************************************/
9926 WERROR _spoolss_60(struct pipes_struct *p,
9927 struct spoolss_60 *r)
9929 p->rng_fault_state = true;
9930 return WERR_NOT_SUPPORTED;
9933 /****************************************************************
9935 ****************************************************************/
9937 WERROR _spoolss_61(struct pipes_struct *p,
9938 struct spoolss_61 *r)
9940 p->rng_fault_state = true;
9941 return WERR_NOT_SUPPORTED;
9944 /****************************************************************
9946 ****************************************************************/
9948 WERROR _spoolss_62(struct pipes_struct *p,
9949 struct spoolss_62 *r)
9951 p->rng_fault_state = true;
9952 return WERR_NOT_SUPPORTED;
9955 /****************************************************************
9957 ****************************************************************/
9959 WERROR _spoolss_63(struct pipes_struct *p,
9960 struct spoolss_63 *r)
9962 p->rng_fault_state = true;
9963 return WERR_NOT_SUPPORTED;
9966 /****************************************************************
9968 ****************************************************************/
9970 WERROR _spoolss_64(struct pipes_struct *p,
9971 struct spoolss_64 *r)
9973 p->rng_fault_state = true;
9974 return WERR_NOT_SUPPORTED;
9977 /****************************************************************
9979 ****************************************************************/
9981 WERROR _spoolss_65(struct pipes_struct *p,
9982 struct spoolss_65 *r)
9984 p->rng_fault_state = true;
9985 return WERR_NOT_SUPPORTED;
9988 /****************************************************************
9989 _spoolss_GetCorePrinterDrivers
9990 ****************************************************************/
9992 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9993 struct spoolss_GetCorePrinterDrivers *r)
9995 p->rng_fault_state = true;
9996 return WERR_NOT_SUPPORTED;
9999 /****************************************************************
10001 ****************************************************************/
10003 WERROR _spoolss_67(struct pipes_struct *p,
10004 struct spoolss_67 *r)
10006 p->rng_fault_state = true;
10007 return WERR_NOT_SUPPORTED;
10010 /****************************************************************
10011 _spoolss_GetPrinterDriverPackagePath
10012 ****************************************************************/
10014 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10015 struct spoolss_GetPrinterDriverPackagePath *r)
10017 p->rng_fault_state = true;
10018 return WERR_NOT_SUPPORTED;
10021 /****************************************************************
10023 ****************************************************************/
10025 WERROR _spoolss_69(struct pipes_struct *p,
10026 struct spoolss_69 *r)
10028 p->rng_fault_state = true;
10029 return WERR_NOT_SUPPORTED;
10032 /****************************************************************
10034 ****************************************************************/
10036 WERROR _spoolss_6a(struct pipes_struct *p,
10037 struct spoolss_6a *r)
10039 p->rng_fault_state = true;
10040 return WERR_NOT_SUPPORTED;
10043 /****************************************************************
10045 ****************************************************************/
10047 WERROR _spoolss_6b(struct pipes_struct *p,
10048 struct spoolss_6b *r)
10050 p->rng_fault_state = true;
10051 return WERR_NOT_SUPPORTED;
10054 /****************************************************************
10056 ****************************************************************/
10058 WERROR _spoolss_6c(struct pipes_struct *p,
10059 struct spoolss_6c *r)
10061 p->rng_fault_state = true;
10062 return WERR_NOT_SUPPORTED;
10065 /****************************************************************
10067 ****************************************************************/
10069 WERROR _spoolss_6d(struct pipes_struct *p,
10070 struct spoolss_6d *r)
10072 p->rng_fault_state = true;
10073 return WERR_NOT_SUPPORTED;