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,
5674 SPOOL_DSSPOOLER_KEY,
5675 SPOOL_REG_DRIVERNAME,
5680 if (!force_update) {
5681 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5682 printer->drivername));
5684 notify_printer_driver(snum, printer->drivername);
5688 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5689 push_reg_sz(mem_ctx, &buffer, printer->comment);
5690 winreg_set_printer_dataex(mem_ctx,
5693 SPOOL_DSSPOOLER_KEY,
5694 SPOOL_REG_DESCRIPTION,
5699 if (!force_update) {
5700 notify_printer_comment(snum, printer->comment);
5704 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5705 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5706 winreg_set_printer_dataex(mem_ctx,
5709 SPOOL_DSSPOOLER_KEY,
5710 SPOOL_REG_PRINTSHARENAME,
5715 if (!force_update) {
5716 notify_printer_sharename(snum, printer->sharename);
5720 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5723 p = strrchr(printer->printername, '\\' );
5727 p = printer->printername;
5730 push_reg_sz(mem_ctx, &buffer, p);
5731 winreg_set_printer_dataex(mem_ctx,
5734 SPOOL_DSSPOOLER_KEY,
5735 SPOOL_REG_PRINTERNAME,
5740 if (!force_update) {
5741 notify_printer_printername(snum, p);
5745 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5746 push_reg_sz(mem_ctx, &buffer, printer->portname);
5747 winreg_set_printer_dataex(mem_ctx,
5750 SPOOL_DSSPOOLER_KEY,
5756 if (!force_update) {
5757 notify_printer_port(snum, printer->portname);
5761 if (force_update || !strequal(printer->location, old_printer->location)) {
5762 push_reg_sz(mem_ctx, &buffer, printer->location);
5763 winreg_set_printer_dataex(mem_ctx,
5766 SPOOL_DSSPOOLER_KEY,
5772 if (!force_update) {
5773 notify_printer_location(snum, printer->location);
5777 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5778 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5779 winreg_set_printer_dataex(mem_ctx,
5782 SPOOL_DSSPOOLER_KEY,
5783 SPOOL_REG_PRINTSEPARATORFILE,
5788 if (!force_update) {
5789 notify_printer_location(snum, printer->location);
5793 if (force_update || printer->starttime != old_printer->starttime) {
5794 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5795 SIVAL(buffer.data, 0, printer->starttime);
5796 winreg_set_printer_dataex(mem_ctx,
5799 SPOOL_DSSPOOLER_KEY,
5800 SPOOL_REG_PRINTSTARTTIME,
5806 if (force_update || printer->untiltime != old_printer->untiltime) {
5807 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5808 SIVAL(buffer.data, 0, printer->untiltime);
5809 winreg_set_printer_dataex(mem_ctx,
5812 SPOOL_DSSPOOLER_KEY,
5813 SPOOL_REG_PRINTENDTIME,
5819 if (force_update || printer->priority != old_printer->priority) {
5820 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5821 SIVAL(buffer.data, 0, printer->priority);
5822 winreg_set_printer_dataex(mem_ctx,
5825 SPOOL_DSSPOOLER_KEY,
5832 if (force_update || printer->attributes != old_printer->attributes) {
5833 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5834 SIVAL(buffer.data, 0, (printer->attributes &
5835 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5836 winreg_set_printer_dataex(mem_ctx,
5839 SPOOL_DSSPOOLER_KEY,
5840 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5845 switch (printer->attributes & 0x3) {
5847 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5850 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5853 spooling = SPOOL_REGVAL_PRINTDIRECT;
5856 spooling = "unknown";
5858 push_reg_sz(mem_ctx, &buffer, spooling);
5859 winreg_set_printer_dataex(mem_ctx,
5862 SPOOL_DSSPOOLER_KEY,
5863 SPOOL_REG_PRINTSPOOLING,
5869 push_reg_sz(mem_ctx, &buffer, global_myname());
5870 winreg_set_printer_dataex(mem_ctx,
5873 SPOOL_DSSPOOLER_KEY,
5874 SPOOL_REG_SHORTSERVERNAME,
5879 dnsdomname = get_mydnsfullname();
5880 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5881 longname = talloc_strdup(mem_ctx, dnsdomname);
5883 longname = talloc_strdup(mem_ctx, global_myname());
5885 if (longname == NULL) {
5886 result = WERR_NOMEM;
5890 push_reg_sz(mem_ctx, &buffer, longname);
5891 winreg_set_printer_dataex(mem_ctx,
5894 SPOOL_DSSPOOLER_KEY,
5895 SPOOL_REG_SERVERNAME,
5900 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5901 global_myname(), printer->sharename);
5902 push_reg_sz(mem_ctx, &buffer, uncname);
5903 winreg_set_printer_dataex(mem_ctx,
5906 SPOOL_DSSPOOLER_KEY,
5916 /********************************************************************
5917 * Called by spoolss_api_setprinter
5918 * when updating a printer description.
5919 ********************************************************************/
5921 static WERROR update_printer(struct pipes_struct *p,
5922 struct policy_handle *handle,
5923 struct spoolss_SetPrinterInfoCtr *info_ctr,
5924 struct spoolss_DeviceMode *devmode)
5926 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5927 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5928 struct spoolss_PrinterInfo2 *old_printer;
5929 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5930 const char *servername = NULL;
5932 WERROR result = WERR_OK;
5933 TALLOC_CTX *tmp_ctx;
5935 DEBUG(8,("update_printer\n"));
5937 tmp_ctx = talloc_new(p->mem_ctx);
5938 if (tmp_ctx == NULL) {
5943 result = WERR_BADFID;
5947 if (!get_printer_snum(p, handle, &snum, NULL)) {
5948 result = WERR_BADFID;
5952 if (Printer != NULL || Printer->servername != NULL) {
5953 servername = Printer->servername;
5956 result = winreg_get_printer(tmp_ctx,
5960 lp_const_servicename(snum),
5962 if (!W_ERROR_IS_OK(result)) {
5963 result = WERR_BADFID;
5967 /* Do sanity check on the requested changes for Samba */
5968 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5969 result = WERR_INVALID_PARAM;
5973 /* FIXME!!! If the driver has changed we really should verify that
5974 it is installed before doing much else --jerry */
5976 /* Check calling user has permission to update printer description */
5977 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5978 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5979 result = WERR_ACCESS_DENIED;
5983 /* Call addprinter hook */
5984 /* Check changes to see if this is really needed */
5986 if (*lp_addprinter_cmd() &&
5987 (!strequal(printer->drivername, old_printer->drivername) ||
5988 !strequal(printer->comment, old_printer->comment) ||
5989 !strequal(printer->portname, old_printer->portname) ||
5990 !strequal(printer->location, old_printer->location)) )
5992 /* add_printer_hook() will call reload_services() */
5993 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5994 printer, p->client_address,
5996 result = WERR_ACCESS_DENIED;
6001 update_dsspooler(tmp_ctx,
6007 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6009 if (devmode == NULL) {
6010 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6012 result = winreg_update_printer(tmp_ctx,
6022 talloc_free(tmp_ctx);
6027 /****************************************************************************
6028 ****************************************************************************/
6029 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6030 struct policy_handle *handle,
6031 struct spoolss_SetPrinterInfo7 *info7)
6034 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6037 Printer_entry *Printer;
6039 if ( lp_security() != SEC_ADS ) {
6040 return WERR_UNKNOWN_LEVEL;
6043 Printer = find_printer_index_by_hnd(p, handle);
6045 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6050 if (!get_printer_snum(p, handle, &snum, NULL))
6053 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6054 Printer->servername,
6055 lp_servicename(snum), &pinfo2);
6056 if (!W_ERROR_IS_OK(result)) {
6060 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6062 TALLOC_FREE(pinfo2);
6065 return WERR_UNKNOWN_LEVEL;
6069 /********************************************************************
6070 ********************************************************************/
6072 static WERROR update_printer_devmode(struct pipes_struct *p,
6073 struct policy_handle *handle,
6074 struct spoolss_DeviceMode *devmode)
6077 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6078 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6080 DEBUG(8,("update_printer_devmode\n"));
6086 if (!get_printer_snum(p, handle, &snum, NULL)) {
6090 /* Check calling user has permission to update printer description */
6091 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6092 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6093 return WERR_ACCESS_DENIED;
6096 return winreg_update_printer(p->mem_ctx,
6099 lp_const_servicename(snum),
6107 /****************************************************************
6109 ****************************************************************/
6111 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6112 struct spoolss_SetPrinter *r)
6116 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6119 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6120 OUR_HANDLE(r->in.handle)));
6124 /* check the level */
6125 switch (r->in.info_ctr->level) {
6127 return control_printer(r->in.handle, r->in.command, p);
6129 result = update_printer(p, r->in.handle,
6131 r->in.devmode_ctr->devmode);
6132 if (!W_ERROR_IS_OK(result))
6134 if (r->in.secdesc_ctr->sd)
6135 result = update_printer_sec(r->in.handle, p,
6139 return update_printer_sec(r->in.handle, p,
6142 return publish_or_unpublish_printer(p, r->in.handle,
6143 r->in.info_ctr->info.info7);
6145 return update_printer_devmode(p, r->in.handle,
6146 r->in.devmode_ctr->devmode);
6148 return WERR_UNKNOWN_LEVEL;
6152 /****************************************************************
6153 _spoolss_FindClosePrinterNotify
6154 ****************************************************************/
6156 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6157 struct spoolss_FindClosePrinterNotify *r)
6159 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6162 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6163 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6167 if (Printer->notify.client_connected == true) {
6170 if ( Printer->printer_type == SPLHND_SERVER)
6172 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6173 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6176 srv_spoolss_replycloseprinter(
6177 snum, &Printer->notify.client_hnd, p->msg_ctx);
6180 Printer->notify.flags=0;
6181 Printer->notify.options=0;
6182 Printer->notify.localmachine[0]='\0';
6183 Printer->notify.printerlocal=0;
6184 TALLOC_FREE(Printer->notify.option);
6185 Printer->notify.client_connected = false;
6190 /****************************************************************
6192 ****************************************************************/
6194 WERROR _spoolss_AddJob(struct pipes_struct *p,
6195 struct spoolss_AddJob *r)
6197 if (!r->in.buffer && (r->in.offered != 0)) {
6198 return WERR_INVALID_PARAM;
6201 /* this is what a NT server returns for AddJob. AddJob must fail on
6202 * non-local printers */
6204 if (r->in.level != 1) {
6205 return WERR_UNKNOWN_LEVEL;
6208 return WERR_INVALID_PARAM;
6211 /****************************************************************************
6213 ****************************************************************************/
6215 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6216 struct spoolss_JobInfo1 *r,
6217 const print_queue_struct *queue,
6218 int position, int snum,
6219 struct spoolss_PrinterInfo2 *pinfo2)
6223 t = gmtime(&queue->time);
6225 r->job_id = queue->job;
6227 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6228 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6229 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6230 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6231 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6232 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6233 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6234 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6235 r->data_type = talloc_strdup(mem_ctx, "RAW");
6236 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6237 r->text_status = talloc_strdup(mem_ctx, "");
6238 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6240 r->status = nt_printj_status(queue->status);
6241 r->priority = queue->priority;
6242 r->position = position;
6243 r->total_pages = queue->page_count;
6244 r->pages_printed = 0; /* ??? */
6246 init_systemtime(&r->submitted, t);
6251 /****************************************************************************
6253 ****************************************************************************/
6255 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6256 struct spoolss_JobInfo2 *r,
6257 const print_queue_struct *queue,
6258 int position, int snum,
6259 struct spoolss_PrinterInfo2 *pinfo2,
6260 struct spoolss_DeviceMode *devmode)
6264 t = gmtime(&queue->time);
6266 r->job_id = queue->job;
6268 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6269 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6270 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6271 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6272 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6273 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6274 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6275 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6276 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6277 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6278 r->data_type = talloc_strdup(mem_ctx, "RAW");
6279 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6280 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6281 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6282 r->parameters = talloc_strdup(mem_ctx, "");
6283 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6284 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6285 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6287 r->devmode = devmode;
6289 r->text_status = talloc_strdup(mem_ctx, "");
6290 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6294 r->status = nt_printj_status(queue->status);
6295 r->priority = queue->priority;
6296 r->position = position;
6299 r->total_pages = queue->page_count;
6300 r->size = queue->size;
6301 init_systemtime(&r->submitted, t);
6303 r->pages_printed = 0; /* ??? */
6308 /****************************************************************************
6310 ****************************************************************************/
6312 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6313 struct spoolss_JobInfo3 *r,
6314 const print_queue_struct *queue,
6315 const print_queue_struct *next_queue,
6316 int position, int snum,
6317 struct spoolss_PrinterInfo2 *pinfo2)
6319 r->job_id = queue->job;
6322 r->next_job_id = next_queue->job;
6329 /****************************************************************************
6330 Enumjobs at level 1.
6331 ****************************************************************************/
6333 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6334 const print_queue_struct *queue,
6335 uint32_t num_queues, int snum,
6336 struct spoolss_PrinterInfo2 *pinfo2,
6337 union spoolss_JobInfo **info_p,
6340 union spoolss_JobInfo *info;
6342 WERROR result = WERR_OK;
6344 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6345 W_ERROR_HAVE_NO_MEMORY(info);
6347 *count = num_queues;
6349 for (i=0; i<*count; i++) {
6350 result = fill_job_info1(info,
6356 if (!W_ERROR_IS_OK(result)) {
6362 if (!W_ERROR_IS_OK(result)) {
6373 /****************************************************************************
6374 Enumjobs at level 2.
6375 ****************************************************************************/
6377 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6378 const print_queue_struct *queue,
6379 uint32_t num_queues, int snum,
6380 struct spoolss_PrinterInfo2 *pinfo2,
6381 union spoolss_JobInfo **info_p,
6384 union spoolss_JobInfo *info;
6386 WERROR result = WERR_OK;
6388 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6389 W_ERROR_HAVE_NO_MEMORY(info);
6391 *count = num_queues;
6393 for (i=0; i<*count; i++) {
6394 struct spoolss_DeviceMode *devmode;
6396 result = spoolss_create_default_devmode(info,
6397 pinfo2->printername,
6399 if (!W_ERROR_IS_OK(result)) {
6400 DEBUG(3, ("Can't proceed w/o a devmode!"));
6404 result = fill_job_info2(info,
6411 if (!W_ERROR_IS_OK(result)) {
6417 if (!W_ERROR_IS_OK(result)) {
6428 /****************************************************************************
6429 Enumjobs at level 3.
6430 ****************************************************************************/
6432 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6433 const print_queue_struct *queue,
6434 uint32_t num_queues, int snum,
6435 struct spoolss_PrinterInfo2 *pinfo2,
6436 union spoolss_JobInfo **info_p,
6439 union spoolss_JobInfo *info;
6441 WERROR result = WERR_OK;
6443 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6444 W_ERROR_HAVE_NO_MEMORY(info);
6446 *count = num_queues;
6448 for (i=0; i<*count; i++) {
6449 const print_queue_struct *next_queue = NULL;
6452 next_queue = &queue[i+1];
6455 result = fill_job_info3(info,
6462 if (!W_ERROR_IS_OK(result)) {
6468 if (!W_ERROR_IS_OK(result)) {
6479 /****************************************************************
6481 ****************************************************************/
6483 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6484 struct spoolss_EnumJobs *r)
6487 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6489 print_status_struct prt_status;
6490 print_queue_struct *queue = NULL;
6493 /* that's an [in out] buffer */
6495 if (!r->in.buffer && (r->in.offered != 0)) {
6496 return WERR_INVALID_PARAM;
6499 DEBUG(4,("_spoolss_EnumJobs\n"));
6503 *r->out.info = NULL;
6505 /* lookup the printer snum and tdb entry */
6507 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6511 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6512 NULL, lp_servicename(snum), &pinfo2);
6513 if (!W_ERROR_IS_OK(result)) {
6517 count = print_queue_status(snum, &queue, &prt_status);
6518 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6519 count, prt_status.status, prt_status.message));
6523 TALLOC_FREE(pinfo2);
6527 switch (r->in.level) {
6529 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6530 pinfo2, r->out.info, r->out.count);
6533 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6534 pinfo2, r->out.info, r->out.count);
6537 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6538 pinfo2, r->out.info, r->out.count);
6541 result = WERR_UNKNOWN_LEVEL;
6546 TALLOC_FREE(pinfo2);
6548 if (!W_ERROR_IS_OK(result)) {
6552 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6554 *r->out.info, r->in.level,
6556 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6557 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6559 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6562 /****************************************************************
6563 _spoolss_ScheduleJob
6564 ****************************************************************/
6566 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6567 struct spoolss_ScheduleJob *r)
6572 /****************************************************************
6573 ****************************************************************/
6575 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6576 const char *printer_name,
6578 struct spoolss_SetJobInfo1 *r)
6582 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6586 if (strequal(old_doc_name, r->document_name)) {
6590 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6597 /****************************************************************
6599 ****************************************************************/
6601 WERROR _spoolss_SetJob(struct pipes_struct *p,
6602 struct spoolss_SetJob *r)
6605 WERROR errcode = WERR_BADFUNC;
6607 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6611 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6612 return WERR_INVALID_PRINTER_NAME;
6615 switch (r->in.command) {
6616 case SPOOLSS_JOB_CONTROL_CANCEL:
6617 case SPOOLSS_JOB_CONTROL_DELETE:
6618 errcode = print_job_delete(p->server_info,
6619 snum, r->in.job_id);
6620 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6624 case SPOOLSS_JOB_CONTROL_PAUSE:
6625 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6629 case SPOOLSS_JOB_CONTROL_RESTART:
6630 case SPOOLSS_JOB_CONTROL_RESUME:
6631 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6639 return WERR_UNKNOWN_LEVEL;
6642 if (!W_ERROR_IS_OK(errcode)) {
6646 if (r->in.ctr == NULL) {
6650 switch (r->in.ctr->level) {
6652 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6654 r->in.ctr->info.info1);
6660 return WERR_UNKNOWN_LEVEL;
6666 /****************************************************************************
6667 Enumerates all printer drivers by level and architecture.
6668 ****************************************************************************/
6670 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6671 struct auth_serversupplied_info *server_info,
6672 const char *servername,
6673 const char *architecture,
6675 union spoolss_DriverInfo **info_p,
6680 struct spoolss_DriverInfo8 *driver;
6681 union spoolss_DriverInfo *info = NULL;
6683 WERROR result = WERR_OK;
6684 uint32_t num_drivers;
6685 const char **drivers;
6690 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6691 result = winreg_get_driver_list(mem_ctx, server_info,
6692 architecture, version,
6693 &num_drivers, &drivers);
6694 if (!W_ERROR_IS_OK(result)) {
6697 DEBUG(4, ("we have:[%d] drivers in environment"
6698 " [%s] and version [%d]\n",
6699 num_drivers, architecture, version));
6701 if (num_drivers != 0) {
6702 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6703 union spoolss_DriverInfo,
6704 count + num_drivers);
6706 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6707 "failed to enlarge driver info buffer!\n"));
6708 result = WERR_NOMEM;
6713 for (i = 0; i < num_drivers; i++) {
6714 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6716 result = winreg_get_driver(mem_ctx, server_info,
6717 architecture, drivers[i],
6719 if (!W_ERROR_IS_OK(result)) {
6725 result = fill_printer_driver_info1(info, &info[count+i].info1,
6726 driver, servername);
6729 result = fill_printer_driver_info2(info, &info[count+i].info2,
6730 driver, servername);
6733 result = fill_printer_driver_info3(info, &info[count+i].info3,
6734 driver, servername);
6737 result = fill_printer_driver_info4(info, &info[count+i].info4,
6738 driver, servername);
6741 result = fill_printer_driver_info5(info, &info[count+i].info5,
6742 driver, servername);
6745 result = fill_printer_driver_info6(info, &info[count+i].info6,
6746 driver, servername);
6749 result = fill_printer_driver_info8(info, &info[count+i].info8,
6750 driver, servername);
6753 result = WERR_UNKNOWN_LEVEL;
6757 TALLOC_FREE(driver);
6759 if (!W_ERROR_IS_OK(result)) {
6764 count += num_drivers;
6765 TALLOC_FREE(drivers);
6769 TALLOC_FREE(drivers);
6771 if (!W_ERROR_IS_OK(result)) {
6782 /****************************************************************************
6783 Enumerates all printer drivers by level.
6784 ****************************************************************************/
6786 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6787 struct auth_serversupplied_info *server_info,
6788 const char *servername,
6789 const char *architecture,
6791 union spoolss_DriverInfo **info_p,
6795 WERROR result = WERR_OK;
6797 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6799 for (a=0; archi_table[a].long_archi != NULL; a++) {
6801 union spoolss_DriverInfo *info = NULL;
6804 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6807 archi_table[a].long_archi,
6811 if (!W_ERROR_IS_OK(result)) {
6815 for (i=0; i < count; i++) {
6816 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6817 info[i], info_p, count_p);
6824 return enumprinterdrivers_level_by_architecture(mem_ctx,
6833 /****************************************************************
6834 _spoolss_EnumPrinterDrivers
6835 ****************************************************************/
6837 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6838 struct spoolss_EnumPrinterDrivers *r)
6840 const char *cservername;
6843 /* that's an [in out] buffer */
6845 if (!r->in.buffer && (r->in.offered != 0)) {
6846 return WERR_INVALID_PARAM;
6849 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6853 *r->out.info = NULL;
6855 cservername = canon_servername(r->in.server);
6857 if (!is_myname_or_ipaddr(cservername)) {
6858 return WERR_UNKNOWN_PRINTER_DRIVER;
6861 result = enumprinterdrivers_level(p->mem_ctx,
6868 if (!W_ERROR_IS_OK(result)) {
6872 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6873 spoolss_EnumPrinterDrivers,
6874 *r->out.info, r->in.level,
6876 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6877 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6879 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6882 /****************************************************************
6884 ****************************************************************/
6886 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6887 struct spoolss_EnumForms *r)
6893 *r->out.info = NULL;
6895 /* that's an [in out] buffer */
6897 if (!r->in.buffer && (r->in.offered != 0) ) {
6898 return WERR_INVALID_PARAM;
6901 DEBUG(4,("_spoolss_EnumForms\n"));
6902 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6903 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6905 switch (r->in.level) {
6907 result = winreg_printer_enumforms1(p->mem_ctx,
6913 result = WERR_UNKNOWN_LEVEL;
6917 if (!W_ERROR_IS_OK(result)) {
6921 if (*r->out.count == 0) {
6922 return WERR_NO_MORE_ITEMS;
6925 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6927 *r->out.info, r->in.level,
6929 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6930 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6932 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6935 /****************************************************************
6937 ****************************************************************/
6939 WERROR _spoolss_GetForm(struct pipes_struct *p,
6940 struct spoolss_GetForm *r)
6944 /* that's an [in out] buffer */
6946 if (!r->in.buffer && (r->in.offered != 0)) {
6947 return WERR_INVALID_PARAM;
6950 DEBUG(4,("_spoolss_GetForm\n"));
6951 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6952 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6954 switch (r->in.level) {
6956 result = winreg_printer_getform1(p->mem_ctx,
6959 &r->out.info->info1);
6962 result = WERR_UNKNOWN_LEVEL;
6966 if (!W_ERROR_IS_OK(result)) {
6967 TALLOC_FREE(r->out.info);
6971 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6972 r->out.info, r->in.level);
6973 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6975 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6978 /****************************************************************************
6979 ****************************************************************************/
6981 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6982 struct spoolss_PortInfo1 *r,
6985 r->port_name = talloc_strdup(mem_ctx, name);
6986 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6991 /****************************************************************************
6992 TODO: This probably needs distinguish between TCP/IP and Local ports
6994 ****************************************************************************/
6996 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6997 struct spoolss_PortInfo2 *r,
7000 r->port_name = talloc_strdup(mem_ctx, name);
7001 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7003 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7004 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7006 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7007 W_ERROR_HAVE_NO_MEMORY(r->description);
7009 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7016 /****************************************************************************
7017 wrapper around the enumer ports command
7018 ****************************************************************************/
7020 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7022 char *cmd = lp_enumports_cmd();
7023 char **qlines = NULL;
7024 char *command = NULL;
7032 /* if no hook then just fill in the default port */
7035 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7038 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7039 TALLOC_FREE(qlines);
7046 /* we have a valid enumport command */
7048 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7053 DEBUG(10,("Running [%s]\n", command));
7054 ret = smbrun(command, &fd);
7055 DEBUG(10,("Returned [%d]\n", ret));
7056 TALLOC_FREE(command);
7061 return WERR_ACCESS_DENIED;
7065 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7066 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7076 /****************************************************************************
7078 ****************************************************************************/
7080 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7081 union spoolss_PortInfo **info_p,
7084 union spoolss_PortInfo *info = NULL;
7086 WERROR result = WERR_OK;
7087 char **qlines = NULL;
7090 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7091 if (!W_ERROR_IS_OK(result)) {
7096 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7098 DEBUG(10,("Returning WERR_NOMEM\n"));
7099 result = WERR_NOMEM;
7103 for (i=0; i<numlines; i++) {
7104 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7105 result = fill_port_1(info, &info[i].info1, qlines[i]);
7106 if (!W_ERROR_IS_OK(result)) {
7111 TALLOC_FREE(qlines);
7114 if (!W_ERROR_IS_OK(result)) {
7116 TALLOC_FREE(qlines);
7128 /****************************************************************************
7130 ****************************************************************************/
7132 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7133 union spoolss_PortInfo **info_p,
7136 union spoolss_PortInfo *info = NULL;
7138 WERROR result = WERR_OK;
7139 char **qlines = NULL;
7142 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7143 if (!W_ERROR_IS_OK(result)) {
7148 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7150 DEBUG(10,("Returning WERR_NOMEM\n"));
7151 result = WERR_NOMEM;
7155 for (i=0; i<numlines; i++) {
7156 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7157 result = fill_port_2(info, &info[i].info2, qlines[i]);
7158 if (!W_ERROR_IS_OK(result)) {
7163 TALLOC_FREE(qlines);
7166 if (!W_ERROR_IS_OK(result)) {
7168 TALLOC_FREE(qlines);
7180 /****************************************************************
7182 ****************************************************************/
7184 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7185 struct spoolss_EnumPorts *r)
7189 /* that's an [in out] buffer */
7191 if (!r->in.buffer && (r->in.offered != 0)) {
7192 return WERR_INVALID_PARAM;
7195 DEBUG(4,("_spoolss_EnumPorts\n"));
7199 *r->out.info = NULL;
7201 switch (r->in.level) {
7203 result = enumports_level_1(p->mem_ctx, r->out.info,
7207 result = enumports_level_2(p->mem_ctx, r->out.info,
7211 return WERR_UNKNOWN_LEVEL;
7214 if (!W_ERROR_IS_OK(result)) {
7218 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7220 *r->out.info, r->in.level,
7222 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7223 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7225 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7228 /****************************************************************************
7229 ****************************************************************************/
7231 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7233 struct spoolss_SetPrinterInfoCtr *info_ctr,
7234 struct spoolss_DeviceMode *devmode,
7235 struct security_descriptor *secdesc,
7236 struct spoolss_UserLevelCtr *user_ctr,
7237 struct policy_handle *handle)
7239 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7240 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7242 WERROR err = WERR_OK;
7244 /* samba does not have a concept of local, non-shared printers yet, so
7245 * make sure we always setup sharename - gd */
7246 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7247 (info2->printername != NULL && info2->printername[0] != '\0')) {
7248 DEBUG(5, ("spoolss_addprinterex_level_2: "
7249 "no sharename has been set, setting printername %s as sharename\n",
7250 info2->printername));
7251 info2->sharename = info2->printername;
7254 /* check to see if the printer already exists */
7255 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7256 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7258 return WERR_PRINTER_ALREADY_EXISTS;
7261 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7262 if ((snum = print_queue_snum(info2->printername)) != -1) {
7263 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7264 info2->printername));
7265 return WERR_PRINTER_ALREADY_EXISTS;
7269 /* validate printer info struct */
7270 if (!info2->printername || strlen(info2->printername) == 0) {
7271 return WERR_INVALID_PRINTER_NAME;
7273 if (!info2->portname || strlen(info2->portname) == 0) {
7274 return WERR_UNKNOWN_PORT;
7276 if (!info2->drivername || strlen(info2->drivername) == 0) {
7277 return WERR_UNKNOWN_PRINTER_DRIVER;
7279 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7280 return WERR_UNKNOWN_PRINTPROCESSOR;
7283 /* FIXME!!! smbd should check to see if the driver is installed before
7284 trying to add a printer like this --jerry */
7286 if (*lp_addprinter_cmd() ) {
7287 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7288 info2, p->client_address,
7290 return WERR_ACCESS_DENIED;
7293 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7294 "smb.conf parameter \"addprinter command\" is defined. This"
7295 "parameter must exist for this call to succeed\n",
7296 info2->sharename ));
7299 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7300 return WERR_ACCESS_DENIED;
7303 /* you must be a printer admin to add a new printer */
7304 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7305 return WERR_ACCESS_DENIED;
7309 * Do sanity check on the requested changes for Samba.
7312 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7313 return WERR_INVALID_PARAM;
7316 if (devmode == NULL) {
7317 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7320 update_dsspooler(p->mem_ctx,
7326 err = winreg_update_printer(p->mem_ctx,
7334 if (!W_ERROR_IS_OK(err)) {
7338 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7339 /* Handle open failed - remove addition. */
7340 ZERO_STRUCTP(handle);
7341 return WERR_ACCESS_DENIED;
7347 /****************************************************************
7348 _spoolss_AddPrinterEx
7349 ****************************************************************/
7351 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7352 struct spoolss_AddPrinterEx *r)
7354 switch (r->in.info_ctr->level) {
7356 /* we don't handle yet */
7357 /* but I know what to do ... */
7358 return WERR_UNKNOWN_LEVEL;
7360 return spoolss_addprinterex_level_2(p, r->in.server,
7362 r->in.devmode_ctr->devmode,
7363 r->in.secdesc_ctr->sd,
7364 r->in.userlevel_ctr,
7367 return WERR_UNKNOWN_LEVEL;
7371 /****************************************************************
7373 ****************************************************************/
7375 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7376 struct spoolss_AddPrinter *r)
7378 struct spoolss_AddPrinterEx a;
7379 struct spoolss_UserLevelCtr userlevel_ctr;
7381 ZERO_STRUCT(userlevel_ctr);
7383 userlevel_ctr.level = 1;
7385 a.in.server = r->in.server;
7386 a.in.info_ctr = r->in.info_ctr;
7387 a.in.devmode_ctr = r->in.devmode_ctr;
7388 a.in.secdesc_ctr = r->in.secdesc_ctr;
7389 a.in.userlevel_ctr = &userlevel_ctr;
7390 a.out.handle = r->out.handle;
7392 return _spoolss_AddPrinterEx(p, &a);
7395 /****************************************************************
7396 _spoolss_AddPrinterDriverEx
7397 ****************************************************************/
7399 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7400 struct spoolss_AddPrinterDriverEx *r)
7402 WERROR err = WERR_OK;
7403 const char *driver_name = NULL;
7408 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7409 fn = "_spoolss_AddPrinterDriver";
7411 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7412 fn = "_spoolss_AddPrinterDriverEx";
7415 return WERR_INVALID_PARAM;
7419 * we only support the semantics of AddPrinterDriver()
7420 * i.e. only copy files that are newer than existing ones
7423 if (r->in.flags == 0) {
7424 return WERR_INVALID_PARAM;
7427 if (r->in.flags != APD_COPY_NEW_FILES) {
7428 return WERR_ACCESS_DENIED;
7432 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7433 /* Clever hack from Martin Zielinski <mz@seh.de>
7434 * to allow downgrade from level 8 (Vista).
7436 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7437 r->in.info_ctr->level));
7438 return WERR_UNKNOWN_LEVEL;
7441 DEBUG(5,("Cleaning driver's information\n"));
7442 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7443 if (!W_ERROR_IS_OK(err))
7446 DEBUG(5,("Moving driver to final destination\n"));
7447 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7452 err = winreg_add_driver(p->mem_ctx, p->server_info,
7453 r->in.info_ctr, &driver_name, &version);
7454 if (!W_ERROR_IS_OK(err)) {
7459 * I think this is where he DrvUpgradePrinter() hook would be
7460 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7461 * server. Right now, we just need to send ourselves a message
7462 * to update each printer bound to this driver. --jerry
7465 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7466 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7474 /****************************************************************
7475 _spoolss_AddPrinterDriver
7476 ****************************************************************/
7478 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7479 struct spoolss_AddPrinterDriver *r)
7481 struct spoolss_AddPrinterDriverEx a;
7483 switch (r->in.info_ctr->level) {
7490 return WERR_UNKNOWN_LEVEL;
7493 a.in.servername = r->in.servername;
7494 a.in.info_ctr = r->in.info_ctr;
7495 a.in.flags = APD_COPY_NEW_FILES;
7497 return _spoolss_AddPrinterDriverEx(p, &a);
7500 /****************************************************************************
7501 ****************************************************************************/
7503 struct _spoolss_paths {
7509 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7511 static const struct _spoolss_paths spoolss_paths[]= {
7512 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7513 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7516 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7517 const char *servername,
7518 const char *environment,
7522 const char *pservername = NULL;
7523 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7524 const char *short_archi;
7528 /* environment may be empty */
7529 if (environment && strlen(environment)) {
7530 long_archi = environment;
7533 /* servername may be empty */
7534 if (servername && strlen(servername)) {
7535 pservername = canon_servername(servername);
7537 if (!is_myname_or_ipaddr(pservername)) {
7538 return WERR_INVALID_PARAM;
7542 if (!(short_archi = get_short_archi(long_archi))) {
7543 return WERR_INVALID_ENVIRONMENT;
7546 switch (component) {
7547 case SPOOLSS_PRTPROCS_PATH:
7548 case SPOOLSS_DRIVER_PATH:
7550 *path = talloc_asprintf(mem_ctx,
7553 spoolss_paths[component].share,
7556 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7557 SPOOLSS_DEFAULT_SERVER_PATH,
7558 spoolss_paths[component].dir,
7563 return WERR_INVALID_PARAM;
7573 /****************************************************************************
7574 ****************************************************************************/
7576 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7577 const char *servername,
7578 const char *environment,
7579 struct spoolss_DriverDirectoryInfo1 *r)
7584 werr = compose_spoolss_server_path(mem_ctx,
7587 SPOOLSS_DRIVER_PATH,
7589 if (!W_ERROR_IS_OK(werr)) {
7593 DEBUG(4,("printer driver directory: [%s]\n", path));
7595 r->directory_name = path;
7600 /****************************************************************
7601 _spoolss_GetPrinterDriverDirectory
7602 ****************************************************************/
7604 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7605 struct spoolss_GetPrinterDriverDirectory *r)
7609 /* that's an [in out] buffer */
7611 if (!r->in.buffer && (r->in.offered != 0)) {
7612 return WERR_INVALID_PARAM;
7615 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7620 /* r->in.level is ignored */
7622 werror = getprinterdriverdir_level_1(p->mem_ctx,
7625 &r->out.info->info1);
7626 if (!W_ERROR_IS_OK(werror)) {
7627 TALLOC_FREE(r->out.info);
7631 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7632 r->out.info, r->in.level);
7633 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7635 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7638 /****************************************************************
7639 _spoolss_EnumPrinterData
7640 ****************************************************************/
7642 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7643 struct spoolss_EnumPrinterData *r)
7646 struct spoolss_EnumPrinterDataEx r2;
7648 struct spoolss_PrinterEnumValues *info, *val = NULL;
7651 r2.in.handle = r->in.handle;
7652 r2.in.key_name = "PrinterDriverData";
7654 r2.out.count = &count;
7655 r2.out.info = &info;
7656 r2.out.needed = &needed;
7658 result = _spoolss_EnumPrinterDataEx(p, &r2);
7659 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7660 r2.in.offered = needed;
7661 result = _spoolss_EnumPrinterDataEx(p, &r2);
7663 if (!W_ERROR_IS_OK(result)) {
7668 * The NT machine wants to know the biggest size of value and data
7670 * cf: MSDN EnumPrinterData remark section
7673 if (!r->in.value_offered && !r->in.data_offered) {
7674 uint32_t biggest_valuesize = 0;
7675 uint32_t biggest_datasize = 0;
7678 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7680 for (i=0; i<count; i++) {
7682 name_length = strlen(info[i].value_name);
7683 if (strlen(info[i].value_name) > biggest_valuesize) {
7684 biggest_valuesize = name_length;
7687 if (info[i].data_length > biggest_datasize) {
7688 biggest_datasize = info[i].data_length;
7691 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7695 /* the value is an UNICODE string but real_value_size is the length
7696 in bytes including the trailing 0 */
7698 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7699 *r->out.data_needed = biggest_datasize;
7701 DEBUG(6,("final values: [%d], [%d]\n",
7702 *r->out.value_needed, *r->out.data_needed));
7707 if (r->in.enum_index < count) {
7708 val = &info[r->in.enum_index];
7712 /* out_value should default to "" or else NT4 has
7713 problems unmarshalling the response */
7715 if (r->in.value_offered) {
7716 *r->out.value_needed = 1;
7717 r->out.value_name = talloc_strdup(r, "");
7718 if (!r->out.value_name) {
7722 r->out.value_name = NULL;
7723 *r->out.value_needed = 0;
7726 /* the data is counted in bytes */
7728 *r->out.data_needed = r->in.data_offered;
7730 result = WERR_NO_MORE_ITEMS;
7734 * - counted in bytes in the request
7735 * - counted in UNICODE chars in the max reply
7736 * - counted in bytes in the real size
7738 * take a pause *before* coding not *during* coding
7742 if (r->in.value_offered) {
7743 r->out.value_name = talloc_strdup(r, val->value_name);
7744 if (!r->out.value_name) {
7747 *r->out.value_needed = val->value_name_len;
7749 r->out.value_name = NULL;
7750 *r->out.value_needed = 0;
7755 *r->out.type = val->type;
7757 /* data - counted in bytes */
7760 * See the section "Dynamically Typed Query Parameters"
7764 if (r->out.data && val->data && val->data->data &&
7765 val->data_length && r->in.data_offered) {
7766 memcpy(r->out.data, val->data->data,
7767 MIN(val->data_length,r->in.data_offered));
7770 *r->out.data_needed = val->data_length;
7778 /****************************************************************
7779 _spoolss_SetPrinterData
7780 ****************************************************************/
7782 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7783 struct spoolss_SetPrinterData *r)
7785 struct spoolss_SetPrinterDataEx r2;
7787 r2.in.handle = r->in.handle;
7788 r2.in.key_name = "PrinterDriverData";
7789 r2.in.value_name = r->in.value_name;
7790 r2.in.type = r->in.type;
7791 r2.in.data = r->in.data;
7792 r2.in.offered = r->in.offered;
7794 return _spoolss_SetPrinterDataEx(p, &r2);
7797 /****************************************************************
7798 _spoolss_ResetPrinter
7799 ****************************************************************/
7801 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7802 struct spoolss_ResetPrinter *r)
7804 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7807 DEBUG(5,("_spoolss_ResetPrinter\n"));
7810 * All we do is to check to see if the handle and queue is valid.
7811 * This call really doesn't mean anything to us because we only
7812 * support RAW printing. --jerry
7816 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7817 OUR_HANDLE(r->in.handle)));
7821 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7825 /* blindly return success */
7829 /****************************************************************
7830 _spoolss_DeletePrinterData
7831 ****************************************************************/
7833 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7834 struct spoolss_DeletePrinterData *r)
7836 struct spoolss_DeletePrinterDataEx r2;
7838 r2.in.handle = r->in.handle;
7839 r2.in.key_name = "PrinterDriverData";
7840 r2.in.value_name = r->in.value_name;
7842 return _spoolss_DeletePrinterDataEx(p, &r2);
7845 /****************************************************************
7847 ****************************************************************/
7849 WERROR _spoolss_AddForm(struct pipes_struct *p,
7850 struct spoolss_AddForm *r)
7852 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7854 WERROR status = WERR_OK;
7855 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7857 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7859 DEBUG(5,("_spoolss_AddForm\n"));
7862 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7863 OUR_HANDLE(r->in.handle)));
7867 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7868 and not a printer admin, then fail */
7870 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7871 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7872 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7873 p->server_info->info3->base.domain.string,
7875 p->server_info->ptok,
7876 lp_printer_admin(snum))) {
7877 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7878 return WERR_ACCESS_DENIED;
7881 switch (form->flags) {
7882 case SPOOLSS_FORM_USER:
7883 case SPOOLSS_FORM_BUILTIN:
7884 case SPOOLSS_FORM_PRINTER:
7887 return WERR_INVALID_PARAM;
7890 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7891 if (!W_ERROR_IS_OK(status)) {
7896 * ChangeID must always be set if this is a printer
7898 if (Printer->printer_type == SPLHND_PRINTER) {
7899 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7903 status = winreg_printer_update_changeid(p->mem_ctx,
7905 lp_const_servicename(snum));
7906 if (!W_ERROR_IS_OK(status)) {
7914 /****************************************************************
7916 ****************************************************************/
7918 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7919 struct spoolss_DeleteForm *r)
7921 const char *form_name = r->in.form_name;
7922 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7924 WERROR status = WERR_OK;
7925 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7927 DEBUG(5,("_spoolss_DeleteForm\n"));
7930 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7931 OUR_HANDLE(r->in.handle)));
7935 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7936 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7937 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7938 p->server_info->info3->base.domain.string,
7940 p->server_info->ptok,
7941 lp_printer_admin(snum))) {
7942 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7943 return WERR_ACCESS_DENIED;
7946 status = winreg_printer_deleteform1(p->mem_ctx,
7949 if (!W_ERROR_IS_OK(status)) {
7954 * ChangeID must always be set if this is a printer
7956 if (Printer->printer_type == SPLHND_PRINTER) {
7957 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7961 status = winreg_printer_update_changeid(p->mem_ctx,
7963 lp_const_servicename(snum));
7964 if (!W_ERROR_IS_OK(status)) {
7972 /****************************************************************
7974 ****************************************************************/
7976 WERROR _spoolss_SetForm(struct pipes_struct *p,
7977 struct spoolss_SetForm *r)
7979 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7980 const char *form_name = r->in.form_name;
7982 WERROR status = WERR_OK;
7983 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7985 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7987 DEBUG(5,("_spoolss_SetForm\n"));
7990 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7991 OUR_HANDLE(r->in.handle)));
7995 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7996 and not a printer admin, then fail */
7998 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7999 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8000 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8001 p->server_info->info3->base.domain.string,
8003 p->server_info->ptok,
8004 lp_printer_admin(snum))) {
8005 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8006 return WERR_ACCESS_DENIED;
8009 status = winreg_printer_setform1(p->mem_ctx,
8013 if (!W_ERROR_IS_OK(status)) {
8018 * ChangeID must always be set if this is a printer
8020 if (Printer->printer_type == SPLHND_PRINTER) {
8021 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8025 status = winreg_printer_update_changeid(p->mem_ctx,
8027 lp_const_servicename(snum));
8028 if (!W_ERROR_IS_OK(status)) {
8036 /****************************************************************************
8037 fill_print_processor1
8038 ****************************************************************************/
8040 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8041 struct spoolss_PrintProcessorInfo1 *r,
8042 const char *print_processor_name)
8044 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8045 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8050 /****************************************************************************
8051 enumprintprocessors level 1.
8052 ****************************************************************************/
8054 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8055 union spoolss_PrintProcessorInfo **info_p,
8058 union spoolss_PrintProcessorInfo *info;
8061 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8062 W_ERROR_HAVE_NO_MEMORY(info);
8066 result = fill_print_processor1(info, &info[0].info1, "winprint");
8067 if (!W_ERROR_IS_OK(result)) {
8072 if (!W_ERROR_IS_OK(result)) {
8083 /****************************************************************
8084 _spoolss_EnumPrintProcessors
8085 ****************************************************************/
8087 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8088 struct spoolss_EnumPrintProcessors *r)
8092 /* that's an [in out] buffer */
8094 if (!r->in.buffer && (r->in.offered != 0)) {
8095 return WERR_INVALID_PARAM;
8098 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8101 * Enumerate the print processors ...
8103 * Just reply with "winprint", to keep NT happy
8104 * and I can use my nice printer checker.
8109 *r->out.info = NULL;
8111 switch (r->in.level) {
8113 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8117 return WERR_UNKNOWN_LEVEL;
8120 if (!W_ERROR_IS_OK(result)) {
8124 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8125 spoolss_EnumPrintProcessors,
8126 *r->out.info, r->in.level,
8128 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8129 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8131 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8134 /****************************************************************************
8135 fill_printprocdatatype1
8136 ****************************************************************************/
8138 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8139 struct spoolss_PrintProcDataTypesInfo1 *r,
8140 const char *name_array)
8142 r->name_array = talloc_strdup(mem_ctx, name_array);
8143 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8148 /****************************************************************************
8149 enumprintprocdatatypes level 1.
8150 ****************************************************************************/
8152 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8153 union spoolss_PrintProcDataTypesInfo **info_p,
8157 union spoolss_PrintProcDataTypesInfo *info;
8159 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8160 W_ERROR_HAVE_NO_MEMORY(info);
8164 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8165 if (!W_ERROR_IS_OK(result)) {
8170 if (!W_ERROR_IS_OK(result)) {
8181 /****************************************************************
8182 _spoolss_EnumPrintProcDataTypes
8183 ****************************************************************/
8185 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8186 struct spoolss_EnumPrintProcDataTypes *r)
8190 /* that's an [in out] buffer */
8192 if (!r->in.buffer && (r->in.offered != 0)) {
8193 return WERR_INVALID_PARAM;
8196 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8200 *r->out.info = NULL;
8202 switch (r->in.level) {
8204 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8208 return WERR_UNKNOWN_LEVEL;
8211 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8212 spoolss_EnumPrintProcDataTypes,
8213 *r->out.info, r->in.level,
8215 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8216 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8218 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8221 /****************************************************************************
8223 ****************************************************************************/
8225 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8226 struct spoolss_MonitorInfo1 *r,
8227 const char *monitor_name)
8229 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8230 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8235 /****************************************************************************
8237 ****************************************************************************/
8239 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8240 struct spoolss_MonitorInfo2 *r,
8241 const char *monitor_name,
8242 const char *environment,
8243 const char *dll_name)
8245 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8246 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8247 r->environment = talloc_strdup(mem_ctx, environment);
8248 W_ERROR_HAVE_NO_MEMORY(r->environment);
8249 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8250 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8255 /****************************************************************************
8256 enumprintmonitors level 1.
8257 ****************************************************************************/
8259 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8260 union spoolss_MonitorInfo **info_p,
8263 union spoolss_MonitorInfo *info;
8264 WERROR result = WERR_OK;
8266 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8267 W_ERROR_HAVE_NO_MEMORY(info);
8271 result = fill_monitor_1(info, &info[0].info1,
8273 if (!W_ERROR_IS_OK(result)) {
8277 result = fill_monitor_1(info, &info[1].info1,
8279 if (!W_ERROR_IS_OK(result)) {
8284 if (!W_ERROR_IS_OK(result)) {
8295 /****************************************************************************
8296 enumprintmonitors level 2.
8297 ****************************************************************************/
8299 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8300 union spoolss_MonitorInfo **info_p,
8303 union spoolss_MonitorInfo *info;
8304 WERROR result = WERR_OK;
8306 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8307 W_ERROR_HAVE_NO_MEMORY(info);
8311 result = fill_monitor_2(info, &info[0].info2,
8313 "Windows NT X86", /* FIXME */
8315 if (!W_ERROR_IS_OK(result)) {
8319 result = fill_monitor_2(info, &info[1].info2,
8321 "Windows NT X86", /* FIXME */
8323 if (!W_ERROR_IS_OK(result)) {
8328 if (!W_ERROR_IS_OK(result)) {
8339 /****************************************************************
8340 _spoolss_EnumMonitors
8341 ****************************************************************/
8343 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8344 struct spoolss_EnumMonitors *r)
8348 /* that's an [in out] buffer */
8350 if (!r->in.buffer && (r->in.offered != 0)) {
8351 return WERR_INVALID_PARAM;
8354 DEBUG(5,("_spoolss_EnumMonitors\n"));
8357 * Enumerate the print monitors ...
8359 * Just reply with "Local Port", to keep NT happy
8360 * and I can use my nice printer checker.
8365 *r->out.info = NULL;
8367 switch (r->in.level) {
8369 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8373 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8377 return WERR_UNKNOWN_LEVEL;
8380 if (!W_ERROR_IS_OK(result)) {
8384 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8385 spoolss_EnumMonitors,
8386 *r->out.info, r->in.level,
8388 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8389 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8391 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8394 /****************************************************************************
8395 ****************************************************************************/
8397 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8398 const print_queue_struct *queue,
8399 int count, int snum,
8400 struct spoolss_PrinterInfo2 *pinfo2,
8402 struct spoolss_JobInfo1 *r)
8407 for (i=0; i<count; i++) {
8408 if (queue[i].job == (int)jobid) {
8414 if (found == false) {
8415 /* NT treats not found as bad param... yet another bad choice */
8416 return WERR_INVALID_PARAM;
8419 return fill_job_info1(mem_ctx,
8427 /****************************************************************************
8428 ****************************************************************************/
8430 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8431 const print_queue_struct *queue,
8432 int count, int snum,
8433 struct spoolss_PrinterInfo2 *pinfo2,
8435 struct spoolss_JobInfo2 *r)
8439 struct spoolss_DeviceMode *devmode;
8442 for (i=0; i<count; i++) {
8443 if (queue[i].job == (int)jobid) {
8449 if (found == false) {
8450 /* NT treats not found as bad param... yet another bad
8452 return WERR_INVALID_PARAM;
8456 * if the print job does not have a DEVMODE associated with it,
8457 * just use the one for the printer. A NULL devicemode is not
8458 * a failure condition
8461 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8463 result = spoolss_create_default_devmode(mem_ctx,
8464 pinfo2->printername,
8466 if (!W_ERROR_IS_OK(result)) {
8467 DEBUG(3, ("Can't proceed w/o a devmode!"));
8472 return fill_job_info2(mem_ctx,
8481 /****************************************************************
8483 ****************************************************************/
8485 WERROR _spoolss_GetJob(struct pipes_struct *p,
8486 struct spoolss_GetJob *r)
8488 WERROR result = WERR_OK;
8489 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8492 print_queue_struct *queue = NULL;
8493 print_status_struct prt_status;
8495 /* that's an [in out] buffer */
8497 if (!r->in.buffer && (r->in.offered != 0)) {
8498 return WERR_INVALID_PARAM;
8501 DEBUG(5,("_spoolss_GetJob\n"));
8505 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8509 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
8510 NULL, lp_servicename(snum), &pinfo2);
8511 if (!W_ERROR_IS_OK(result)) {
8515 count = print_queue_status(snum, &queue, &prt_status);
8517 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8518 count, prt_status.status, prt_status.message));
8520 switch (r->in.level) {
8522 result = getjob_level_1(p->mem_ctx,
8523 queue, count, snum, pinfo2,
8524 r->in.job_id, &r->out.info->info1);
8527 result = getjob_level_2(p->mem_ctx,
8528 queue, count, snum, pinfo2,
8529 r->in.job_id, &r->out.info->info2);
8532 result = WERR_UNKNOWN_LEVEL;
8537 TALLOC_FREE(pinfo2);
8539 if (!W_ERROR_IS_OK(result)) {
8540 TALLOC_FREE(r->out.info);
8544 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8546 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8548 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8551 /****************************************************************
8552 _spoolss_GetPrinterDataEx
8553 ****************************************************************/
8555 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8556 struct spoolss_GetPrinterDataEx *r)
8559 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8560 const char *printer;
8562 WERROR result = WERR_OK;
8564 enum winreg_Type val_type;
8569 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8571 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8572 r->in.key_name, r->in.value_name));
8574 /* in case of problem, return some default values */
8577 *r->out.type = REG_NONE;
8580 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8581 OUR_HANDLE(r->in.handle)));
8582 result = WERR_BADFID;
8586 /* Is the handle to a printer or to the server? */
8588 if (Printer->printer_type == SPLHND_SERVER) {
8590 union spoolss_PrinterData data;
8592 result = getprinterdata_printer_server(p->mem_ctx,
8596 if (!W_ERROR_IS_OK(result)) {
8600 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8601 *r->out.type, &data);
8602 if (!W_ERROR_IS_OK(result)) {
8606 *r->out.needed = blob.length;
8608 if (r->in.offered >= *r->out.needed) {
8609 memcpy(r->out.data, blob.data, blob.length);
8612 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8615 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8618 printer = lp_const_servicename(snum);
8620 /* check to see if the keyname is valid */
8621 if (!strlen(r->in.key_name)) {
8622 return WERR_INVALID_PARAM;
8625 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8626 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8627 strequal(r->in.value_name, "ChangeId")) {
8628 *r->out.type = REG_DWORD;
8630 if (r->in.offered >= *r->out.needed) {
8631 uint32_t changeid = 0;
8633 result = winreg_printer_get_changeid(p->mem_ctx,
8637 if (!W_ERROR_IS_OK(result)) {
8641 SIVAL(r->out.data, 0, changeid);
8647 result = winreg_get_printer_dataex(p->mem_ctx,
8655 if (!W_ERROR_IS_OK(result)) {
8659 *r->out.needed = val_size;
8660 *r->out.type = val_type;
8662 if (r->in.offered >= *r->out.needed) {
8663 memcpy(r->out.data, val_data, val_size);
8667 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8668 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8670 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8673 /****************************************************************
8674 _spoolss_SetPrinterDataEx
8675 ****************************************************************/
8677 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8678 struct spoolss_SetPrinterDataEx *r)
8680 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8682 WERROR result = WERR_OK;
8683 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8686 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8688 /* From MSDN documentation of SetPrinterDataEx: pass request to
8689 SetPrinterData if key is "PrinterDriverData" */
8692 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8693 OUR_HANDLE(r->in.handle)));
8697 if (Printer->printer_type == SPLHND_SERVER) {
8698 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8699 "Not implemented for server handles yet\n"));
8700 return WERR_INVALID_PARAM;
8703 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8708 * Access check : NT returns "access denied" if you make a
8709 * SetPrinterData call without the necessary privildge.
8710 * we were originally returning OK if nothing changed
8711 * which made Win2k issue **a lot** of SetPrinterData
8712 * when connecting to a printer --jerry
8715 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8716 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8717 "change denied by handle access permissions\n"));
8718 return WERR_ACCESS_DENIED;
8721 result = winreg_get_printer(Printer, p->server_info, p->msg_ctx,
8722 Printer->servername,
8723 lp_servicename(snum),
8725 if (!W_ERROR_IS_OK(result)) {
8729 /* check for OID in valuename */
8731 oid_string = strchr(r->in.value_name, ',');
8737 /* save the registry data */
8739 result = winreg_set_printer_dataex(p->mem_ctx,
8748 if (W_ERROR_IS_OK(result)) {
8749 /* save the OID if one was specified */
8751 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8752 r->in.key_name, SPOOL_OID_KEY);
8754 result = WERR_NOMEM;
8759 * I'm not checking the status here on purpose. Don't know
8760 * if this is right, but I'm returning the status from the
8761 * previous set_printer_dataex() call. I have no idea if
8762 * this is right. --jerry
8764 winreg_set_printer_dataex(p->mem_ctx,
8770 (uint8_t *) oid_string,
8771 strlen(oid_string) + 1);
8774 result = winreg_printer_update_changeid(p->mem_ctx,
8776 lp_const_servicename(snum));
8781 talloc_free(pinfo2);
8785 /****************************************************************
8786 _spoolss_DeletePrinterDataEx
8787 ****************************************************************/
8789 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8790 struct spoolss_DeletePrinterDataEx *r)
8792 const char *printer;
8794 WERROR status = WERR_OK;
8795 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8797 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8800 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8801 "Invalid handle (%s:%u:%u).\n",
8802 OUR_HANDLE(r->in.handle)));
8806 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8807 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8808 "printer properties change denied by handle\n"));
8809 return WERR_ACCESS_DENIED;
8812 if (!r->in.value_name || !r->in.key_name) {
8816 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8819 printer = lp_const_servicename(snum);
8821 status = winreg_delete_printer_dataex(p->mem_ctx,
8826 if (W_ERROR_IS_OK(status)) {
8827 status = winreg_printer_update_changeid(p->mem_ctx,
8835 /****************************************************************
8836 _spoolss_EnumPrinterKey
8837 ****************************************************************/
8839 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8840 struct spoolss_EnumPrinterKey *r)
8843 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8845 WERROR result = WERR_BADFILE;
8846 const char **array = NULL;
8849 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8852 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8853 OUR_HANDLE(r->in.handle)));
8857 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8861 result = winreg_enum_printer_key(p->mem_ctx,
8863 lp_const_servicename(snum),
8867 if (!W_ERROR_IS_OK(result)) {
8871 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8872 result = WERR_NOMEM;
8876 *r->out._ndr_size = r->in.offered / 2;
8877 *r->out.needed = blob.length;
8879 if (r->in.offered < *r->out.needed) {
8880 result = WERR_MORE_DATA;
8883 r->out.key_buffer->string_array = array;
8887 if (!W_ERROR_IS_OK(result)) {
8889 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8897 /****************************************************************
8898 _spoolss_DeletePrinterKey
8899 ****************************************************************/
8901 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8902 struct spoolss_DeletePrinterKey *r)
8904 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8907 const char *printer;
8909 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8912 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8913 OUR_HANDLE(r->in.handle)));
8917 /* if keyname == NULL, return error */
8918 if ( !r->in.key_name )
8919 return WERR_INVALID_PARAM;
8921 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8925 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8926 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8927 "printer properties change denied by handle\n"));
8928 return WERR_ACCESS_DENIED;
8931 printer = lp_const_servicename(snum);
8933 /* delete the key and all subkeys */
8934 status = winreg_delete_printer_key(p->mem_ctx,
8938 if (W_ERROR_IS_OK(status)) {
8939 status = winreg_printer_update_changeid(p->mem_ctx,
8947 /****************************************************************
8948 _spoolss_EnumPrinterDataEx
8949 ****************************************************************/
8951 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8952 struct spoolss_EnumPrinterDataEx *r)
8955 struct spoolss_PrinterEnumValues *info = NULL;
8956 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8960 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8964 *r->out.info = NULL;
8967 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8968 OUR_HANDLE(r->in.handle)));
8973 * first check for a keyname of NULL or "". Win2k seems to send
8974 * this a lot and we should send back WERR_INVALID_PARAM
8975 * no need to spend time looking up the printer in this case.
8979 if (!strlen(r->in.key_name)) {
8980 result = WERR_INVALID_PARAM;
8984 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8988 /* now look for a match on the key name */
8989 result = winreg_enum_printer_dataex(p->mem_ctx,
8991 lp_const_servicename(snum),
8995 if (!W_ERROR_IS_OK(result)) {
8999 #if 0 /* FIXME - gd */
9000 /* housekeeping information in the reply */
9002 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9003 * the hand marshalled container size is a multiple
9004 * of 4 bytes for RPC alignment.
9008 needed += 4-(needed % 4);
9011 *r->out.count = count;
9012 *r->out.info = info;
9015 if (!W_ERROR_IS_OK(result)) {
9019 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9020 spoolss_EnumPrinterDataEx,
9023 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9024 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9026 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9029 /****************************************************************************
9030 ****************************************************************************/
9032 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9033 const char *servername,
9034 const char *environment,
9035 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9040 werr = compose_spoolss_server_path(mem_ctx,
9043 SPOOLSS_PRTPROCS_PATH,
9045 if (!W_ERROR_IS_OK(werr)) {
9049 DEBUG(4,("print processor directory: [%s]\n", path));
9051 r->directory_name = path;
9056 /****************************************************************
9057 _spoolss_GetPrintProcessorDirectory
9058 ****************************************************************/
9060 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9061 struct spoolss_GetPrintProcessorDirectory *r)
9065 /* that's an [in out] buffer */
9067 if (!r->in.buffer && (r->in.offered != 0)) {
9068 return WERR_INVALID_PARAM;
9071 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9076 /* r->in.level is ignored */
9078 /* We always should reply with a local print processor directory so that
9079 * users are not forced to have a [prnproc$] share on the Samba spoolss
9080 * server - Guenther */
9082 result = getprintprocessordirectory_level_1(p->mem_ctx,
9083 NULL, /* r->in.server */
9085 &r->out.info->info1);
9086 if (!W_ERROR_IS_OK(result)) {
9087 TALLOC_FREE(r->out.info);
9091 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9092 r->out.info, r->in.level);
9093 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9095 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9098 /*******************************************************************
9099 ********************************************************************/
9101 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9102 const char *dllname)
9104 enum ndr_err_code ndr_err;
9105 struct spoolss_MonitorUi ui;
9107 ui.dll_name = dllname;
9109 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9110 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9111 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9112 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9114 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9117 /*******************************************************************
9118 Streams the monitor UI DLL name in UNICODE
9119 *******************************************************************/
9121 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9122 NT_USER_TOKEN *token, DATA_BLOB *in,
9123 DATA_BLOB *out, uint32_t *needed)
9125 const char *dllname = "tcpmonui.dll";
9127 *needed = (strlen(dllname)+1) * 2;
9129 if (out->length < *needed) {
9130 return WERR_INSUFFICIENT_BUFFER;
9133 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9140 /*******************************************************************
9141 ********************************************************************/
9143 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9144 struct spoolss_PortData1 *port1,
9145 const DATA_BLOB *buf)
9147 enum ndr_err_code ndr_err;
9148 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9149 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9150 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9151 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9153 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9156 /*******************************************************************
9157 ********************************************************************/
9159 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9160 struct spoolss_PortData2 *port2,
9161 const DATA_BLOB *buf)
9163 enum ndr_err_code ndr_err;
9164 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9165 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9166 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9167 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9169 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9172 /*******************************************************************
9173 Create a new TCP/IP port
9174 *******************************************************************/
9176 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9177 NT_USER_TOKEN *token, DATA_BLOB *in,
9178 DATA_BLOB *out, uint32_t *needed)
9180 struct spoolss_PortData1 port1;
9181 struct spoolss_PortData2 port2;
9182 char *device_uri = NULL;
9185 const char *portname;
9186 const char *hostaddress;
9188 uint32_t port_number;
9191 /* peek for spoolss_PortData version */
9193 if (!in || (in->length < (128 + 4))) {
9194 return WERR_GENERAL_FAILURE;
9197 version = IVAL(in->data, 128);
9203 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9207 portname = port1.portname;
9208 hostaddress = port1.hostaddress;
9209 queue = port1.queue;
9210 protocol = port1.protocol;
9211 port_number = port1.port_number;
9217 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9221 portname = port2.portname;
9222 hostaddress = port2.hostaddress;
9223 queue = port2.queue;
9224 protocol = port2.protocol;
9225 port_number = port2.port_number;
9229 DEBUG(1,("xcvtcp_addport: "
9230 "unknown version of port_data: %d\n", version));
9231 return WERR_UNKNOWN_PORT;
9234 /* create the device URI and call the add_port_hook() */
9237 case PROTOCOL_RAWTCP_TYPE:
9238 device_uri = talloc_asprintf(mem_ctx,
9239 "socket://%s:%d/", hostaddress,
9243 case PROTOCOL_LPR_TYPE:
9244 device_uri = talloc_asprintf(mem_ctx,
9245 "lpr://%s/%s", hostaddress, queue );
9249 return WERR_UNKNOWN_PORT;
9256 return add_port_hook(mem_ctx, token, portname, device_uri);
9259 /*******************************************************************
9260 *******************************************************************/
9262 struct xcv_api_table xcvtcp_cmds[] = {
9263 { "MonitorUI", xcvtcp_monitorui },
9264 { "AddPort", xcvtcp_addport},
9268 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9269 NT_USER_TOKEN *token, const char *command,
9276 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9278 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9279 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9280 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9283 return WERR_BADFUNC;
9286 /*******************************************************************
9287 *******************************************************************/
9288 #if 0 /* don't support management using the "Local Port" monitor */
9290 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9291 NT_USER_TOKEN *token, DATA_BLOB *in,
9292 DATA_BLOB *out, uint32_t *needed)
9294 const char *dllname = "localui.dll";
9296 *needed = (strlen(dllname)+1) * 2;
9298 if (out->length < *needed) {
9299 return WERR_INSUFFICIENT_BUFFER;
9302 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9309 /*******************************************************************
9310 *******************************************************************/
9312 struct xcv_api_table xcvlocal_cmds[] = {
9313 { "MonitorUI", xcvlocal_monitorui },
9317 struct xcv_api_table xcvlocal_cmds[] = {
9324 /*******************************************************************
9325 *******************************************************************/
9327 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9328 NT_USER_TOKEN *token, const char *command,
9329 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9334 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9336 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9337 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9338 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9340 return WERR_BADFUNC;
9343 /****************************************************************
9345 ****************************************************************/
9347 WERROR _spoolss_XcvData(struct pipes_struct *p,
9348 struct spoolss_XcvData *r)
9350 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9351 DATA_BLOB out_data = data_blob_null;
9355 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9356 OUR_HANDLE(r->in.handle)));
9360 /* Has to be a handle to the TCP/IP port monitor */
9362 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9363 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9367 /* requires administrative access to the server */
9369 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9370 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9371 return WERR_ACCESS_DENIED;
9374 /* Allocate the outgoing buffer */
9376 if (r->in.out_data_size) {
9377 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9378 if (out_data.data == NULL) {
9383 switch ( Printer->printer_type ) {
9384 case SPLHND_PORTMON_TCP:
9385 werror = process_xcvtcp_command(p->mem_ctx,
9386 p->server_info->ptok,
9387 r->in.function_name,
9388 &r->in.in_data, &out_data,
9391 case SPLHND_PORTMON_LOCAL:
9392 werror = process_xcvlocal_command(p->mem_ctx,
9393 p->server_info->ptok,
9394 r->in.function_name,
9395 &r->in.in_data, &out_data,
9399 werror = WERR_INVALID_PRINT_MONITOR;
9402 if (!W_ERROR_IS_OK(werror)) {
9406 *r->out.status_code = 0;
9408 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9409 memcpy(r->out.out_data, out_data.data,
9410 MIN(r->in.out_data_size, out_data.length));
9416 /****************************************************************
9417 _spoolss_AddPrintProcessor
9418 ****************************************************************/
9420 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9421 struct spoolss_AddPrintProcessor *r)
9423 /* for now, just indicate success and ignore the add. We'll
9424 automatically set the winprint processor for printer
9425 entries later. Used to debug the LexMark Optra S 1855 PCL
9431 /****************************************************************
9433 ****************************************************************/
9435 WERROR _spoolss_AddPort(struct pipes_struct *p,
9436 struct spoolss_AddPort *r)
9438 /* do what w2k3 does */
9440 return WERR_NOT_SUPPORTED;
9443 /****************************************************************
9444 _spoolss_GetPrinterDriver
9445 ****************************************************************/
9447 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9448 struct spoolss_GetPrinterDriver *r)
9450 p->rng_fault_state = true;
9451 return WERR_NOT_SUPPORTED;
9454 /****************************************************************
9455 _spoolss_ReadPrinter
9456 ****************************************************************/
9458 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9459 struct spoolss_ReadPrinter *r)
9461 p->rng_fault_state = true;
9462 return WERR_NOT_SUPPORTED;
9465 /****************************************************************
9466 _spoolss_WaitForPrinterChange
9467 ****************************************************************/
9469 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9470 struct spoolss_WaitForPrinterChange *r)
9472 p->rng_fault_state = true;
9473 return WERR_NOT_SUPPORTED;
9476 /****************************************************************
9477 _spoolss_ConfigurePort
9478 ****************************************************************/
9480 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9481 struct spoolss_ConfigurePort *r)
9483 p->rng_fault_state = true;
9484 return WERR_NOT_SUPPORTED;
9487 /****************************************************************
9489 ****************************************************************/
9491 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9492 struct spoolss_DeletePort *r)
9494 p->rng_fault_state = true;
9495 return WERR_NOT_SUPPORTED;
9498 /****************************************************************
9499 _spoolss_CreatePrinterIC
9500 ****************************************************************/
9502 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9503 struct spoolss_CreatePrinterIC *r)
9505 p->rng_fault_state = true;
9506 return WERR_NOT_SUPPORTED;
9509 /****************************************************************
9510 _spoolss_PlayGDIScriptOnPrinterIC
9511 ****************************************************************/
9513 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9514 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9516 p->rng_fault_state = true;
9517 return WERR_NOT_SUPPORTED;
9520 /****************************************************************
9521 _spoolss_DeletePrinterIC
9522 ****************************************************************/
9524 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9525 struct spoolss_DeletePrinterIC *r)
9527 p->rng_fault_state = true;
9528 return WERR_NOT_SUPPORTED;
9531 /****************************************************************
9532 _spoolss_AddPrinterConnection
9533 ****************************************************************/
9535 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9536 struct spoolss_AddPrinterConnection *r)
9538 p->rng_fault_state = true;
9539 return WERR_NOT_SUPPORTED;
9542 /****************************************************************
9543 _spoolss_DeletePrinterConnection
9544 ****************************************************************/
9546 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9547 struct spoolss_DeletePrinterConnection *r)
9549 p->rng_fault_state = true;
9550 return WERR_NOT_SUPPORTED;
9553 /****************************************************************
9554 _spoolss_PrinterMessageBox
9555 ****************************************************************/
9557 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9558 struct spoolss_PrinterMessageBox *r)
9560 p->rng_fault_state = true;
9561 return WERR_NOT_SUPPORTED;
9564 /****************************************************************
9566 ****************************************************************/
9568 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9569 struct spoolss_AddMonitor *r)
9571 p->rng_fault_state = true;
9572 return WERR_NOT_SUPPORTED;
9575 /****************************************************************
9576 _spoolss_DeleteMonitor
9577 ****************************************************************/
9579 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9580 struct spoolss_DeleteMonitor *r)
9582 p->rng_fault_state = true;
9583 return WERR_NOT_SUPPORTED;
9586 /****************************************************************
9587 _spoolss_DeletePrintProcessor
9588 ****************************************************************/
9590 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9591 struct spoolss_DeletePrintProcessor *r)
9593 p->rng_fault_state = true;
9594 return WERR_NOT_SUPPORTED;
9597 /****************************************************************
9598 _spoolss_AddPrintProvidor
9599 ****************************************************************/
9601 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9602 struct spoolss_AddPrintProvidor *r)
9604 p->rng_fault_state = true;
9605 return WERR_NOT_SUPPORTED;
9608 /****************************************************************
9609 _spoolss_DeletePrintProvidor
9610 ****************************************************************/
9612 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9613 struct spoolss_DeletePrintProvidor *r)
9615 p->rng_fault_state = true;
9616 return WERR_NOT_SUPPORTED;
9619 /****************************************************************
9620 _spoolss_FindFirstPrinterChangeNotification
9621 ****************************************************************/
9623 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9624 struct spoolss_FindFirstPrinterChangeNotification *r)
9626 p->rng_fault_state = true;
9627 return WERR_NOT_SUPPORTED;
9630 /****************************************************************
9631 _spoolss_FindNextPrinterChangeNotification
9632 ****************************************************************/
9634 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9635 struct spoolss_FindNextPrinterChangeNotification *r)
9637 p->rng_fault_state = true;
9638 return WERR_NOT_SUPPORTED;
9641 /****************************************************************
9642 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9643 ****************************************************************/
9645 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9646 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9648 p->rng_fault_state = true;
9649 return WERR_NOT_SUPPORTED;
9652 /****************************************************************
9653 _spoolss_ReplyOpenPrinter
9654 ****************************************************************/
9656 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9657 struct spoolss_ReplyOpenPrinter *r)
9659 p->rng_fault_state = true;
9660 return WERR_NOT_SUPPORTED;
9663 /****************************************************************
9664 _spoolss_RouterReplyPrinter
9665 ****************************************************************/
9667 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9668 struct spoolss_RouterReplyPrinter *r)
9670 p->rng_fault_state = true;
9671 return WERR_NOT_SUPPORTED;
9674 /****************************************************************
9675 _spoolss_ReplyClosePrinter
9676 ****************************************************************/
9678 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9679 struct spoolss_ReplyClosePrinter *r)
9681 p->rng_fault_state = true;
9682 return WERR_NOT_SUPPORTED;
9685 /****************************************************************
9687 ****************************************************************/
9689 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9690 struct spoolss_AddPortEx *r)
9692 p->rng_fault_state = true;
9693 return WERR_NOT_SUPPORTED;
9696 /****************************************************************
9697 _spoolss_RouterFindFirstPrinterChangeNotification
9698 ****************************************************************/
9700 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9701 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9703 p->rng_fault_state = true;
9704 return WERR_NOT_SUPPORTED;
9707 /****************************************************************
9708 _spoolss_SpoolerInit
9709 ****************************************************************/
9711 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9712 struct spoolss_SpoolerInit *r)
9714 p->rng_fault_state = true;
9715 return WERR_NOT_SUPPORTED;
9718 /****************************************************************
9719 _spoolss_ResetPrinterEx
9720 ****************************************************************/
9722 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9723 struct spoolss_ResetPrinterEx *r)
9725 p->rng_fault_state = true;
9726 return WERR_NOT_SUPPORTED;
9729 /****************************************************************
9730 _spoolss_RouterReplyPrinterEx
9731 ****************************************************************/
9733 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9734 struct spoolss_RouterReplyPrinterEx *r)
9736 p->rng_fault_state = true;
9737 return WERR_NOT_SUPPORTED;
9740 /****************************************************************
9742 ****************************************************************/
9744 WERROR _spoolss_44(struct pipes_struct *p,
9745 struct spoolss_44 *r)
9747 p->rng_fault_state = true;
9748 return WERR_NOT_SUPPORTED;
9751 /****************************************************************
9753 ****************************************************************/
9755 WERROR _spoolss_47(struct pipes_struct *p,
9756 struct spoolss_47 *r)
9758 p->rng_fault_state = true;
9759 return WERR_NOT_SUPPORTED;
9762 /****************************************************************
9764 ****************************************************************/
9766 WERROR _spoolss_4a(struct pipes_struct *p,
9767 struct spoolss_4a *r)
9769 p->rng_fault_state = true;
9770 return WERR_NOT_SUPPORTED;
9773 /****************************************************************
9775 ****************************************************************/
9777 WERROR _spoolss_4b(struct pipes_struct *p,
9778 struct spoolss_4b *r)
9780 p->rng_fault_state = true;
9781 return WERR_NOT_SUPPORTED;
9784 /****************************************************************
9786 ****************************************************************/
9788 WERROR _spoolss_4c(struct pipes_struct *p,
9789 struct spoolss_4c *r)
9791 p->rng_fault_state = true;
9792 return WERR_NOT_SUPPORTED;
9795 /****************************************************************
9797 ****************************************************************/
9799 WERROR _spoolss_53(struct pipes_struct *p,
9800 struct spoolss_53 *r)
9802 p->rng_fault_state = true;
9803 return WERR_NOT_SUPPORTED;
9806 /****************************************************************
9808 ****************************************************************/
9810 WERROR _spoolss_55(struct pipes_struct *p,
9811 struct spoolss_55 *r)
9813 p->rng_fault_state = true;
9814 return WERR_NOT_SUPPORTED;
9817 /****************************************************************
9819 ****************************************************************/
9821 WERROR _spoolss_56(struct pipes_struct *p,
9822 struct spoolss_56 *r)
9824 p->rng_fault_state = true;
9825 return WERR_NOT_SUPPORTED;
9828 /****************************************************************
9830 ****************************************************************/
9832 WERROR _spoolss_57(struct pipes_struct *p,
9833 struct spoolss_57 *r)
9835 p->rng_fault_state = true;
9836 return WERR_NOT_SUPPORTED;
9839 /****************************************************************
9841 ****************************************************************/
9843 WERROR _spoolss_5a(struct pipes_struct *p,
9844 struct spoolss_5a *r)
9846 p->rng_fault_state = true;
9847 return WERR_NOT_SUPPORTED;
9850 /****************************************************************
9852 ****************************************************************/
9854 WERROR _spoolss_5b(struct pipes_struct *p,
9855 struct spoolss_5b *r)
9857 p->rng_fault_state = true;
9858 return WERR_NOT_SUPPORTED;
9861 /****************************************************************
9863 ****************************************************************/
9865 WERROR _spoolss_5c(struct pipes_struct *p,
9866 struct spoolss_5c *r)
9868 p->rng_fault_state = true;
9869 return WERR_NOT_SUPPORTED;
9872 /****************************************************************
9874 ****************************************************************/
9876 WERROR _spoolss_5d(struct pipes_struct *p,
9877 struct spoolss_5d *r)
9879 p->rng_fault_state = true;
9880 return WERR_NOT_SUPPORTED;
9883 /****************************************************************
9885 ****************************************************************/
9887 WERROR _spoolss_5e(struct pipes_struct *p,
9888 struct spoolss_5e *r)
9890 p->rng_fault_state = true;
9891 return WERR_NOT_SUPPORTED;
9894 /****************************************************************
9896 ****************************************************************/
9898 WERROR _spoolss_5f(struct pipes_struct *p,
9899 struct spoolss_5f *r)
9901 p->rng_fault_state = true;
9902 return WERR_NOT_SUPPORTED;
9905 /****************************************************************
9907 ****************************************************************/
9909 WERROR _spoolss_60(struct pipes_struct *p,
9910 struct spoolss_60 *r)
9912 p->rng_fault_state = true;
9913 return WERR_NOT_SUPPORTED;
9916 /****************************************************************
9918 ****************************************************************/
9920 WERROR _spoolss_61(struct pipes_struct *p,
9921 struct spoolss_61 *r)
9923 p->rng_fault_state = true;
9924 return WERR_NOT_SUPPORTED;
9927 /****************************************************************
9929 ****************************************************************/
9931 WERROR _spoolss_62(struct pipes_struct *p,
9932 struct spoolss_62 *r)
9934 p->rng_fault_state = true;
9935 return WERR_NOT_SUPPORTED;
9938 /****************************************************************
9940 ****************************************************************/
9942 WERROR _spoolss_63(struct pipes_struct *p,
9943 struct spoolss_63 *r)
9945 p->rng_fault_state = true;
9946 return WERR_NOT_SUPPORTED;
9949 /****************************************************************
9951 ****************************************************************/
9953 WERROR _spoolss_64(struct pipes_struct *p,
9954 struct spoolss_64 *r)
9956 p->rng_fault_state = true;
9957 return WERR_NOT_SUPPORTED;
9960 /****************************************************************
9962 ****************************************************************/
9964 WERROR _spoolss_65(struct pipes_struct *p,
9965 struct spoolss_65 *r)
9967 p->rng_fault_state = true;
9968 return WERR_NOT_SUPPORTED;
9971 /****************************************************************
9972 _spoolss_GetCorePrinterDrivers
9973 ****************************************************************/
9975 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9976 struct spoolss_GetCorePrinterDrivers *r)
9978 p->rng_fault_state = true;
9979 return WERR_NOT_SUPPORTED;
9982 /****************************************************************
9984 ****************************************************************/
9986 WERROR _spoolss_67(struct pipes_struct *p,
9987 struct spoolss_67 *r)
9989 p->rng_fault_state = true;
9990 return WERR_NOT_SUPPORTED;
9993 /****************************************************************
9994 _spoolss_GetPrinterDriverPackagePath
9995 ****************************************************************/
9997 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
9998 struct spoolss_GetPrinterDriverPackagePath *r)
10000 p->rng_fault_state = true;
10001 return WERR_NOT_SUPPORTED;
10004 /****************************************************************
10006 ****************************************************************/
10008 WERROR _spoolss_69(struct pipes_struct *p,
10009 struct spoolss_69 *r)
10011 p->rng_fault_state = true;
10012 return WERR_NOT_SUPPORTED;
10015 /****************************************************************
10017 ****************************************************************/
10019 WERROR _spoolss_6a(struct pipes_struct *p,
10020 struct spoolss_6a *r)
10022 p->rng_fault_state = true;
10023 return WERR_NOT_SUPPORTED;
10026 /****************************************************************
10028 ****************************************************************/
10030 WERROR _spoolss_6b(struct pipes_struct *p,
10031 struct spoolss_6b *r)
10033 p->rng_fault_state = true;
10034 return WERR_NOT_SUPPORTED;
10037 /****************************************************************
10039 ****************************************************************/
10041 WERROR _spoolss_6c(struct pipes_struct *p,
10042 struct spoolss_6c *r)
10044 p->rng_fault_state = true;
10045 return WERR_NOT_SUPPORTED;
10048 /****************************************************************
10050 ****************************************************************/
10052 WERROR _spoolss_6d(struct pipes_struct *p,
10053 struct spoolss_6d *r)
10055 p->rng_fault_state = true;
10056 return WERR_NOT_SUPPORTED;