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 "srv_spoolss_util.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/cli_spoolss.h"
34 #include "rpc_client/init_spoolss.h"
35 #include "librpc/gen_ndr/messaging.h"
36 #include "librpc/gen_ndr/ndr_security.h"
38 #include "registry/reg_objects.h"
40 /* macros stolen from s4 spoolss server */
41 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
42 ((info)?ndr_size_##fn(info, level, 0):0)
44 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
45 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
47 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
48 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
50 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
53 extern userdom_struct current_user_info;
56 #define DBGC_CLASS DBGC_RPC_SRV
58 #ifndef MAX_OPEN_PRINTER_EXS
59 #define MAX_OPEN_PRINTER_EXS 50
62 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
64 static Printer_entry *printers_list;
66 typedef struct _counter_printer_0 {
67 struct _counter_printer_0 *next;
68 struct _counter_printer_0 *prev;
74 static counter_printer_0 *counter_list;
76 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
77 static uint32_t smb_connections = 0;
80 /* in printing/nt_printing.c */
82 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
84 /* API table for Xcv Monitor functions */
86 struct xcv_api_table {
88 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
91 /********************************************************************
92 * Canonicalize servername.
93 ********************************************************************/
95 static const char *canon_servername(const char *servername)
97 const char *pservername = servername;
98 while (*pservername == '\\') {
104 /* translate between internal status numbers and NT status numbers */
105 static int nt_printj_status(int v)
111 return JOB_STATUS_PAUSED;
113 return JOB_STATUS_SPOOLING;
115 return JOB_STATUS_PRINTING;
117 return JOB_STATUS_ERROR;
119 return JOB_STATUS_DELETING;
121 return JOB_STATUS_OFFLINE;
123 return JOB_STATUS_PAPEROUT;
125 return JOB_STATUS_PRINTED;
127 return JOB_STATUS_DELETED;
129 return JOB_STATUS_BLOCKED_DEVQ;
130 case LPQ_USER_INTERVENTION:
131 return JOB_STATUS_USER_INTERVENTION;
136 static int nt_printq_status(int v)
140 return PRINTER_STATUS_PAUSED;
149 /***************************************************************************
150 Disconnect from the client
151 ****************************************************************************/
153 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
159 * Tell the specific printing tdb we no longer want messages for this printer
160 * by deregistering our PID.
163 if (!print_notify_deregister_pid(snum))
164 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
166 /* weird if the test succeds !!! */
167 if (smb_connections==0) {
168 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
172 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
175 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
176 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
177 win_errstr(result)));
179 /* if it's the last connection, deconnect the IPC$ share */
180 if (smb_connections==1) {
182 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
183 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
185 messaging_deregister(smbd_messaging_context(),
186 MSG_PRINTER_NOTIFY2, NULL);
188 /* Tell the connections db we're no longer interested in
189 * printer notify messages. */
191 serverid_register_msg_flags(
192 messaging_server_id(smbd_messaging_context()),
193 false, FLAG_MSG_PRINT_NOTIFY);
199 /****************************************************************************
200 Functions to free a printer entry datastruct.
201 ****************************************************************************/
203 static int printer_entry_destructor(Printer_entry *Printer)
205 if (Printer->notify.client_connected == true) {
208 if ( Printer->printer_type == SPLHND_SERVER) {
210 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
211 } else if (Printer->printer_type == SPLHND_PRINTER) {
212 snum = print_queue_snum(Printer->sharename);
214 srv_spoolss_replycloseprinter(snum,
215 &Printer->notify.client_hnd);
219 Printer->notify.flags=0;
220 Printer->notify.options=0;
221 Printer->notify.localmachine[0]='\0';
222 Printer->notify.printerlocal=0;
223 TALLOC_FREE(Printer->notify.option);
224 Printer->notify.client_connected = false;
226 TALLOC_FREE(Printer->devmode);
227 free_a_printer( &Printer->printer_info, 2 );
229 /* Remove from the internal list. */
230 DLIST_REMOVE(printers_list, Printer);
234 /****************************************************************************
235 find printer index by handle
236 ****************************************************************************/
238 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
239 struct policy_handle *hnd)
241 Printer_entry *find_printer = NULL;
243 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
244 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
251 /****************************************************************************
252 Close printer index by handle.
253 ****************************************************************************/
255 static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
257 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
260 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
265 close_policy_hnd(p, hnd);
270 /****************************************************************************
271 Delete a printer given a handle.
272 ****************************************************************************/
274 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
276 char *cmd = lp_deleteprinter_cmd();
277 char *command = NULL;
279 SE_PRIV se_printop = SE_PRINT_OPERATOR;
280 bool is_print_op = false;
282 /* can't fail if we don't try */
287 command = talloc_asprintf(ctx,
294 is_print_op = user_has_privileges( token, &se_printop );
296 DEBUG(10,("Running [%s]\n", command));
298 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
303 if ( (ret = smbrun(command, NULL)) == 0 ) {
304 /* Tell everyone we updated smb.conf. */
305 message_send_all(smbd_messaging_context(),
306 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
312 /********** END SePrintOperatorPrivlege BLOCK **********/
314 DEBUGADD(10,("returned [%d]\n", ret));
316 TALLOC_FREE(command);
319 return WERR_BADFID; /* What to return here? */
321 /* go ahead and re-read the services immediately */
323 reload_services(false);
326 if ( lp_servicenumber( sharename ) > 0 )
327 return WERR_ACCESS_DENIED;
332 /****************************************************************************
333 Delete a printer given a handle.
334 ****************************************************************************/
336 static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
338 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
342 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
348 * It turns out that Windows allows delete printer on a handle
349 * opened by an admin user, then used on a pipe handle created
350 * by an anonymous user..... but they're working on security.... riiight !
354 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
355 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
356 return WERR_ACCESS_DENIED;
359 /* this does not need a become root since the access check has been
360 done on the handle already */
362 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
363 Printer->sharename, "");
364 if (!W_ERROR_IS_OK(result)) {
365 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
369 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
370 Printer->sharename );
373 /****************************************************************************
374 Return the snum of a printer corresponding to an handle.
375 ****************************************************************************/
377 static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
378 int *number, struct share_params **params)
380 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
383 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
388 switch (Printer->printer_type) {
390 DEBUG(4,("short name:%s\n", Printer->sharename));
391 *number = print_queue_snum(Printer->sharename);
392 return (*number != -1);
400 /****************************************************************************
401 Set printer handle type.
402 Check if it's \\server or \\server\printer
403 ****************************************************************************/
405 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
407 DEBUG(3,("Setting printer type=%s\n", handlename));
409 if ( strlen(handlename) < 3 ) {
410 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
414 /* it's a print server */
415 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
416 DEBUGADD(4,("Printer is a print server\n"));
417 Printer->printer_type = SPLHND_SERVER;
419 /* it's a printer (set_printer_hnd_name() will handle port monitors */
421 DEBUGADD(4,("Printer is a printer\n"));
422 Printer->printer_type = SPLHND_PRINTER;
428 /****************************************************************************
429 Set printer handle name.. Accept names like \\server, \\server\printer,
430 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
431 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
432 XcvDataPort() interface.
433 ****************************************************************************/
435 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
436 struct auth_serversupplied_info *server_info,
437 Printer_entry *Printer,
438 const char *handlename)
441 int n_services=lp_numservices();
443 const char *printername;
444 const char *servername;
447 struct spoolss_PrinterInfo2 *info2 = NULL;
450 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
451 (unsigned long)strlen(handlename)));
453 aprinter = CONST_DISCARD(char *, handlename);
454 if ( *handlename == '\\' ) {
455 servername = canon_servername(handlename);
456 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
460 if (!is_myname_or_ipaddr(servername)) {
464 fstrcpy(Printer->servername, servername);
467 if (Printer->printer_type == SPLHND_SERVER) {
471 if (Printer->printer_type != SPLHND_PRINTER) {
475 DEBUGADD(5, ("searching for [%s]\n", aprinter));
477 /* check for the Port Monitor Interface */
478 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
479 Printer->printer_type = SPLHND_PORTMON_TCP;
480 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
483 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
484 Printer->printer_type = SPLHND_PORTMON_LOCAL;
485 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
489 /* Search all sharenames first as this is easier than pulling
490 the printer_info_2 off of disk. Don't use find_service() since
491 that calls out to map_username() */
493 /* do another loop to look for printernames */
494 for (snum = 0; !found && snum < n_services; snum++) {
495 const char *printer = lp_const_servicename(snum);
497 /* no point going on if this is not a printer */
498 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
502 /* ignore [printers] share */
503 if (strequal(printer, "printers")) {
507 fstrcpy(sname, printer);
508 if (strequal(aprinter, printer)) {
513 /* no point looking up the printer object if
514 we aren't allowing printername != sharename */
515 if (lp_force_printername(snum)) {
519 result = winreg_get_printer(mem_ctx,
524 if ( !W_ERROR_IS_OK(result) ) {
525 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
526 sname, win_errstr(result)));
530 printername = strrchr(info2->printername, '\\');
531 if (printername == NULL) {
532 printername = info2->printername;
537 if (strequal(printername, aprinter)) {
542 DEBUGADD(10, ("printername: %s\n", printername));
548 DEBUGADD(4,("Printer not found\n"));
552 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
554 fstrcpy(Printer->sharename, sname);
559 /****************************************************************************
560 Find first available printer slot. creates a printer handle for you.
561 ****************************************************************************/
563 static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
564 const char *name, uint32_t access_granted)
566 Printer_entry *new_printer;
568 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
570 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
571 if (new_printer == NULL) {
574 talloc_set_destructor(new_printer, printer_entry_destructor);
576 if (!create_policy_hnd(p, hnd, new_printer)) {
577 TALLOC_FREE(new_printer);
581 /* Add to the internal list. */
582 DLIST_ADD(printers_list, new_printer);
584 new_printer->notify.option=NULL;
586 if (!set_printer_hnd_printertype(new_printer, name)) {
587 close_printer_handle(p, hnd);
591 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
592 close_printer_handle(p, hnd);
596 new_printer->access_granted = access_granted;
598 DEBUG(5, ("%d printer handles active\n",
599 (int)num_pipe_handles(p)));
604 /***************************************************************************
605 check to see if the client motify handle is monitoring the notification
606 given by (notify_type, notify_field).
607 **************************************************************************/
609 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
610 uint16_t notify_field)
615 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
616 uint16_t notify_field)
618 struct spoolss_NotifyOption *option = p->notify.option;
622 * Flags should always be zero when the change notify
623 * is registered by the client's spooler. A user Win32 app
624 * might use the flags though instead of the NOTIFY_OPTION_INFO
633 return is_monitoring_event_flags(
634 p->notify.flags, notify_type, notify_field);
636 for (i = 0; i < option->count; i++) {
638 /* Check match for notify_type */
640 if (option->types[i].type != notify_type)
643 /* Check match for field */
645 for (j = 0; j < option->types[i].count; j++) {
646 if (option->types[i].fields[j].field == notify_field) {
652 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
653 p->servername, p->sharename, notify_type, notify_field));
658 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
659 _data->data.integer[0] = _integer; \
660 _data->data.integer[1] = 0;
663 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
664 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
665 if (!_data->data.string.string) {\
666 _data->data.string.size = 0; \
668 _data->data.string.size = strlen_m_term(_p) * 2;
670 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
671 _data->data.devmode.devmode = _devmode;
673 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
674 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
675 if (!_data->data.sd.sd) { \
676 _data->data.sd.sd_size = 0; \
678 _data->data.sd.sd_size = \
679 ndr_size_security_descriptor(_data->data.sd.sd, 0);
681 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
686 struct spoolss_Time st;
690 if (!init_systemtime(&st, t)) {
694 p = talloc_array(mem_ctx, char, len);
700 * Systemtime must be linearized as a set of UINT16's.
701 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
704 SSVAL(p, 0, st.year);
705 SSVAL(p, 2, st.month);
706 SSVAL(p, 4, st.day_of_week);
708 SSVAL(p, 8, st.hour);
709 SSVAL(p, 10, st.minute);
710 SSVAL(p, 12, st.second);
711 SSVAL(p, 14, st.millisecond);
717 /* Convert a notification message to a struct spoolss_Notify */
719 static void notify_one_value(struct spoolss_notify_msg *msg,
720 struct spoolss_Notify *data,
723 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
726 static void notify_string(struct spoolss_notify_msg *msg,
727 struct spoolss_Notify *data,
730 /* The length of the message includes the trailing \0 */
732 data->data.string.size = msg->len * 2;
733 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
734 if (!data->data.string.string) {
735 data->data.string.size = 0;
740 static void notify_system_time(struct spoolss_notify_msg *msg,
741 struct spoolss_Notify *data,
744 data->data.string.string = NULL;
745 data->data.string.size = 0;
747 if (msg->len != sizeof(time_t)) {
748 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
753 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
754 &data->data.string.string,
755 &data->data.string.size);
758 struct notify2_message_table {
760 void (*fn)(struct spoolss_notify_msg *msg,
761 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
764 static struct notify2_message_table printer_notify_table[] = {
765 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
766 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
767 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
768 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
769 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
770 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
771 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
772 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
773 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
774 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
775 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
776 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
777 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
778 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
779 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
780 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
781 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
782 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
783 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
786 static struct notify2_message_table job_notify_table[] = {
787 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
788 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
789 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
790 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
791 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
792 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
793 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
794 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
795 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
796 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
797 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
798 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
799 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
800 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
801 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
802 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
803 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
804 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
805 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
806 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
807 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
808 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
809 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
810 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
814 /***********************************************************************
815 Allocate talloc context for container object
816 **********************************************************************/
818 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
823 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
828 /***********************************************************************
829 release all allocated memory and zero out structure
830 **********************************************************************/
832 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
838 talloc_destroy(ctr->ctx);
845 /***********************************************************************
846 **********************************************************************/
848 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
856 /***********************************************************************
857 **********************************************************************/
859 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
861 if ( !ctr || !ctr->msg_groups )
864 if ( idx >= ctr->num_groups )
867 return &ctr->msg_groups[idx];
871 /***********************************************************************
872 How many groups of change messages do we have ?
873 **********************************************************************/
875 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
880 return ctr->num_groups;
883 /***********************************************************************
884 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
885 **********************************************************************/
887 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
889 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
890 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
891 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
897 /* loop over all groups looking for a matching printer name */
899 for ( i=0; i<ctr->num_groups; i++ ) {
900 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
904 /* add a new group? */
906 if ( i == ctr->num_groups ) {
909 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
910 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
913 ctr->msg_groups = groups;
915 /* clear the new entry and set the printer name */
917 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
918 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
921 /* add the change messages; 'i' is the correct index now regardless */
923 msg_grp = &ctr->msg_groups[i];
927 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
928 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
931 msg_grp->msgs = msg_list;
933 new_slot = msg_grp->num_msgs-1;
934 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
936 /* need to allocate own copy of data */
939 msg_grp->msgs[new_slot].notify.data = (char *)
940 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
942 return ctr->num_groups;
945 static void construct_info_data(struct spoolss_Notify *info_data,
946 enum spoolss_NotifyType type,
947 uint16_t field, int id);
949 /***********************************************************************
950 Send a change notication message on all handles which have a call
952 **********************************************************************/
954 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
957 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
958 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
959 SPOOLSS_NOTIFY_MSG *messages;
960 int sending_msg_count;
963 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
967 messages = msg_group->msgs;
970 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
974 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
976 /* loop over all printers */
978 for (p = printers_list; p; p = p->next) {
979 struct spoolss_Notify *notifies;
984 /* Is there notification on this handle? */
986 if ( !p->notify.client_connected )
989 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
991 /* For this printer? Print servers always receive
994 if ( ( p->printer_type == SPLHND_PRINTER ) &&
995 ( !strequal(msg_group->printername, p->sharename) ) )
998 DEBUG(10,("Our printer\n"));
1000 /* allocate the max entries possible */
1002 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1007 /* build the array of change notifications */
1009 sending_msg_count = 0;
1011 for ( i=0; i<msg_group->num_msgs; i++ ) {
1012 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1014 /* Are we monitoring this event? */
1016 if (!is_monitoring_event(p, msg->type, msg->field))
1019 sending_msg_count++;
1022 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1023 msg->type, msg->field, p->sharename));
1026 * if the is a printer notification handle and not a job notification
1027 * type, then set the id to 0. Other wise just use what was specified
1030 * When registering change notification on a print server handle
1031 * we always need to send back the id (snum) matching the printer
1032 * for which the change took place. For change notify registered
1033 * on a printer handle, this does not matter and the id should be 0.
1038 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1044 /* Convert unix jobid to smb jobid */
1046 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1047 id = sysjob_to_jobid(msg->id);
1050 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1055 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1058 case PRINTER_NOTIFY_TYPE:
1059 if ( printer_notify_table[msg->field].fn )
1060 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1063 case JOB_NOTIFY_TYPE:
1064 if ( job_notify_table[msg->field].fn )
1065 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1069 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1076 if ( sending_msg_count ) {
1079 union spoolss_ReplyPrinterInfo info;
1080 struct spoolss_NotifyInfo info0;
1081 uint32_t reply_result;
1083 info0.version = 0x2;
1084 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1085 info0.count = count;
1086 info0.notifies = notifies;
1088 info.info0 = &info0;
1090 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1091 &p->notify.client_hnd,
1092 p->notify.change, /* color */
1095 0, /* reply_type, must be 0 */
1098 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1099 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1100 notify_cli_pipe->srv_name_slash,
1103 switch (reply_result) {
1106 case PRINTER_NOTIFY_INFO_DISCARDED:
1107 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1108 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1117 DEBUG(8,("send_notify2_changes: Exit...\n"));
1121 /***********************************************************************
1122 **********************************************************************/
1124 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1127 uint32_t tv_sec, tv_usec;
1130 /* Unpack message */
1132 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1135 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1137 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1140 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1141 &msg->notify.value[0], &msg->notify.value[1]);
1143 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1144 &msg->len, &msg->notify.data);
1146 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1147 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1149 tv->tv_sec = tv_sec;
1150 tv->tv_usec = tv_usec;
1153 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1154 msg->notify.value[1]));
1156 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1161 /********************************************************************
1162 Receive a notify2 message list
1163 ********************************************************************/
1165 static void receive_notify2_message_list(struct messaging_context *msg,
1168 struct server_id server_id,
1171 size_t msg_count, i;
1172 char *buf = (char *)data->data;
1175 SPOOLSS_NOTIFY_MSG notify;
1176 SPOOLSS_NOTIFY_MSG_CTR messages;
1179 if (data->length < 4) {
1180 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1184 msg_count = IVAL(buf, 0);
1187 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1189 if (msg_count == 0) {
1190 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1194 /* initialize the container */
1196 ZERO_STRUCT( messages );
1197 notify_msg_ctr_init( &messages );
1200 * build message groups for each printer identified
1201 * in a change_notify msg. Remember that a PCN message
1202 * includes the handle returned for the srv_spoolss_replyopenprinter()
1203 * call. Therefore messages are grouped according to printer handle.
1206 for ( i=0; i<msg_count; i++ ) {
1207 struct timeval msg_tv;
1209 if (msg_ptr + 4 - buf > data->length) {
1210 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1214 msg_len = IVAL(msg_ptr,0);
1217 if (msg_ptr + msg_len - buf > data->length) {
1218 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1222 /* unpack messages */
1224 ZERO_STRUCT( notify );
1225 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1228 /* add to correct list in container */
1230 notify_msg_ctr_addmsg( &messages, ¬ify );
1232 /* free memory that might have been allocated by notify2_unpack_msg() */
1234 if ( notify.len != 0 )
1235 SAFE_FREE( notify.notify.data );
1238 /* process each group of messages */
1240 num_groups = notify_msg_ctr_numgroups( &messages );
1241 for ( i=0; i<num_groups; i++ )
1242 send_notify2_changes( &messages, i );
1247 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1248 (uint32_t)msg_count ));
1250 notify_msg_ctr_destroy( &messages );
1255 /********************************************************************
1256 Send a message to ourself about new driver being installed
1257 so we can upgrade the information for each printer bound to this
1259 ********************************************************************/
1261 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1263 int len = strlen(drivername);
1268 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1271 messaging_send_buf(smbd_messaging_context(),
1272 messaging_server_id(smbd_messaging_context()),
1273 MSG_PRINTER_DRVUPGRADE,
1274 (uint8_t *)drivername, len+1);
1279 /**********************************************************************
1280 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1281 over all printers, upgrading ones as necessary
1282 **********************************************************************/
1284 void do_drv_upgrade_printer(struct messaging_context *msg,
1287 struct server_id server_id,
1290 TALLOC_CTX *tmp_ctx;
1291 struct auth_serversupplied_info *server_info = NULL;
1292 struct spoolss_PrinterInfo2 *pinfo2;
1295 const char *drivername;
1297 int n_services = lp_numservices();
1300 tmp_ctx = talloc_new(NULL);
1301 if (!tmp_ctx) return;
1303 status = make_server_info_system(tmp_ctx, &server_info);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 DEBUG(0, ("do_drv_upgrade_printer: "
1306 "Could not create system server_info\n"));
1310 len = MIN(data->length,sizeof(drivername)-1);
1311 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1313 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1317 DEBUG(10, ("do_drv_upgrade_printer: "
1318 "Got message for new driver [%s]\n", drivername));
1320 /* Iterate the printer list */
1322 for (snum = 0; snum < n_services; snum++) {
1323 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1327 result = winreg_get_printer(tmp_ctx, server_info, NULL,
1328 lp_const_servicename(snum),
1331 if (!W_ERROR_IS_OK(result)) {
1335 if (strcmp(drivername, pinfo2->drivername) != 0) {
1339 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1341 /* all we care about currently is the change_id */
1342 result = winreg_printer_update_changeid(tmp_ctx,
1344 pinfo2->printername);
1346 if (!W_ERROR_IS_OK(result)) {
1347 DEBUG(3, ("do_drv_upgrade_printer: "
1348 "Failed to update changeid [%s]\n",
1349 win_errstr(result)));
1355 talloc_free(tmp_ctx);
1358 /********************************************************************
1359 Update the cache for all printq's with a registered client
1361 ********************************************************************/
1363 void update_monitored_printq_cache( void )
1365 Printer_entry *printer = printers_list;
1368 /* loop through all printers and update the cache where
1369 client_connected == true */
1372 if ( (printer->printer_type == SPLHND_PRINTER)
1373 && printer->notify.client_connected )
1375 snum = print_queue_snum(printer->sharename);
1376 print_queue_status( snum, NULL, NULL );
1379 printer = printer->next;
1385 /****************************************************************
1386 _spoolss_OpenPrinter
1387 ****************************************************************/
1389 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1390 struct spoolss_OpenPrinter *r)
1392 struct spoolss_OpenPrinterEx e;
1395 ZERO_STRUCT(e.in.userlevel);
1397 e.in.printername = r->in.printername;
1398 e.in.datatype = r->in.datatype;
1399 e.in.devmode_ctr = r->in.devmode_ctr;
1400 e.in.access_mask = r->in.access_mask;
1403 e.out.handle = r->out.handle;
1405 werr = _spoolss_OpenPrinterEx(p, &e);
1407 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1408 /* OpenPrinterEx returns this for a bad
1409 * printer name. We must return WERR_INVALID_PRINTER_NAME
1412 werr = WERR_INVALID_PRINTER_NAME;
1418 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1419 struct spoolss_DeviceMode *orig,
1420 struct spoolss_DeviceMode **dest)
1422 struct spoolss_DeviceMode *dm;
1424 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1429 /* copy all values, then duplicate strings and structs */
1432 dm->devicename = talloc_strdup(dm, orig->devicename);
1433 if (!dm->devicename) {
1436 dm->formname = talloc_strdup(dm, orig->formname);
1437 if (!dm->formname) {
1440 if (orig->driverextra_data.data) {
1441 dm->driverextra_data.data =
1442 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1443 orig->driverextra_data.length);
1444 if (!dm->driverextra_data.data) {
1453 /****************************************************************
1454 _spoolss_OpenPrinterEx
1455 ****************************************************************/
1457 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1458 struct spoolss_OpenPrinterEx *r)
1461 Printer_entry *Printer=NULL;
1463 if (!r->in.printername) {
1464 return WERR_INVALID_PARAM;
1467 /* some sanity check because you can open a printer or a print server */
1468 /* aka: \\server\printer or \\server */
1470 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1472 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1473 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1474 " for printer %s\n", r->in.printername));
1475 ZERO_STRUCTP(r->out.handle);
1476 return WERR_INVALID_PARAM;
1479 Printer = find_printer_index_by_hnd(p, r->out.handle);
1481 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1482 "handle we created for printer %s\n", r->in.printername));
1483 close_printer_handle(p, r->out.handle);
1484 ZERO_STRUCTP(r->out.handle);
1485 return WERR_INVALID_PARAM;
1489 * First case: the user is opening the print server:
1491 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1492 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1494 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1495 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1496 * or if the user is listed in the smb.conf printer admin parameter.
1498 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1499 * client view printer folder, but does not show the MSAPW.
1501 * Note: this test needs code to check access rights here too. Jeremy
1502 * could you look at this?
1504 * Second case: the user is opening a printer:
1505 * NT doesn't let us connect to a printer if the connecting user
1506 * doesn't have print permission.
1508 * Third case: user is opening a Port Monitor
1509 * access checks same as opening a handle to the print server.
1512 switch (Printer->printer_type )
1515 case SPLHND_PORTMON_TCP:
1516 case SPLHND_PORTMON_LOCAL:
1517 /* Printserver handles use global struct... */
1521 /* Map standard access rights to object specific access rights */
1523 se_map_standard(&r->in.access_mask,
1524 &printserver_std_mapping);
1526 /* Deny any object specific bits that don't apply to print
1527 servers (i.e printer and job specific bits) */
1529 r->in.access_mask &= SEC_MASK_SPECIFIC;
1531 if (r->in.access_mask &
1532 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1533 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1534 close_printer_handle(p, r->out.handle);
1535 ZERO_STRUCTP(r->out.handle);
1536 return WERR_ACCESS_DENIED;
1539 /* Allow admin access */
1541 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1543 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1545 if (!lp_ms_add_printer_wizard()) {
1546 close_printer_handle(p, r->out.handle);
1547 ZERO_STRUCTP(r->out.handle);
1548 return WERR_ACCESS_DENIED;
1551 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1552 and not a printer admin, then fail */
1554 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1555 !user_has_privileges(p->server_info->ptok,
1557 !token_contains_name_in_list(
1558 uidtoname(p->server_info->utok.uid),
1559 p->server_info->info3->base.domain.string,
1561 p->server_info->ptok,
1562 lp_printer_admin(snum))) {
1563 close_printer_handle(p, r->out.handle);
1564 ZERO_STRUCTP(r->out.handle);
1565 return WERR_ACCESS_DENIED;
1568 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1572 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1575 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1576 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1578 /* We fall through to return WERR_OK */
1581 case SPLHND_PRINTER:
1582 /* NT doesn't let us connect to a printer if the connecting user
1583 doesn't have print permission. */
1585 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1586 close_printer_handle(p, r->out.handle);
1587 ZERO_STRUCTP(r->out.handle);
1591 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1592 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1595 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1597 /* map an empty access mask to the minimum access mask */
1598 if (r->in.access_mask == 0x0)
1599 r->in.access_mask = PRINTER_ACCESS_USE;
1602 * If we are not serving the printer driver for this printer,
1603 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1604 * will keep NT clients happy --jerry
1607 if (lp_use_client_driver(snum)
1608 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1610 r->in.access_mask = PRINTER_ACCESS_USE;
1613 /* check smb.conf parameters and the the sec_desc */
1615 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1616 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1617 ZERO_STRUCTP(r->out.handle);
1618 return WERR_ACCESS_DENIED;
1621 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1622 p->server_info->ptok, snum) ||
1623 !print_access_check(p->server_info, snum,
1624 r->in.access_mask)) {
1625 DEBUG(3, ("access DENIED for printer open\n"));
1626 close_printer_handle(p, r->out.handle);
1627 ZERO_STRUCTP(r->out.handle);
1628 return WERR_ACCESS_DENIED;
1631 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1632 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1633 close_printer_handle(p, r->out.handle);
1634 ZERO_STRUCTP(r->out.handle);
1635 return WERR_ACCESS_DENIED;
1638 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1639 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1641 r->in.access_mask = PRINTER_ACCESS_USE;
1643 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1644 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1646 winreg_create_printer(p->mem_ctx,
1648 Printer->servername,
1649 lp_const_servicename(snum));
1654 /* sanity check to prevent programmer error */
1655 ZERO_STRUCTP(r->out.handle);
1659 Printer->access_granted = r->in.access_mask;
1662 * If the client sent a devmode in the OpenPrinter() call, then
1663 * save it here in case we get a job submission on this handle
1666 if ((Printer->printer_type != SPLHND_SERVER) &&
1667 r->in.devmode_ctr.devmode) {
1668 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1672 #if 0 /* JERRY -- I'm doubtful this is really effective */
1673 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1674 optimization in Windows 2000 clients --jerry */
1676 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1677 && (RA_WIN2K == get_remote_arch()) )
1679 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1680 sys_usleep( 500000 );
1687 /****************************************************************
1688 _spoolss_ClosePrinter
1689 ****************************************************************/
1691 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1692 struct spoolss_ClosePrinter *r)
1694 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1696 if (Printer && Printer->document_started) {
1697 struct spoolss_EndDocPrinter e;
1699 e.in.handle = r->in.handle;
1701 _spoolss_EndDocPrinter(p, &e);
1704 if (!close_printer_handle(p, r->in.handle))
1707 /* clear the returned printer handle. Observed behavior
1708 from Win2k server. Don't think this really matters.
1709 Previous code just copied the value of the closed
1712 ZERO_STRUCTP(r->out.handle);
1717 /****************************************************************
1718 _spoolss_DeletePrinter
1719 ****************************************************************/
1721 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1722 struct spoolss_DeletePrinter *r)
1724 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1728 if (Printer && Printer->document_started) {
1729 struct spoolss_EndDocPrinter e;
1731 e.in.handle = r->in.handle;
1733 _spoolss_EndDocPrinter(p, &e);
1736 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1737 winreg_delete_printer_key(p->mem_ctx,
1739 lp_const_servicename(snum),
1743 result = delete_printer_handle(p, r->in.handle);
1748 /*******************************************************************
1749 * static function to lookup the version id corresponding to an
1750 * long architecture string
1751 ******************************************************************/
1753 static const struct print_architecture_table_node archi_table[]= {
1755 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1756 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1757 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1758 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1759 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1760 {"Windows IA64", SPL_ARCH_IA64, 3 },
1761 {"Windows x64", SPL_ARCH_X64, 3 },
1765 static int get_version_id(const char *arch)
1769 for (i=0; archi_table[i].long_archi != NULL; i++)
1771 if (strcmp(arch, archi_table[i].long_archi) == 0)
1772 return (archi_table[i].version);
1778 /****************************************************************
1779 _spoolss_DeletePrinterDriver
1780 ****************************************************************/
1782 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1783 struct spoolss_DeletePrinterDriver *r)
1786 struct spoolss_DriverInfo8 *info = NULL;
1787 struct spoolss_DriverInfo8 *info_win2k = NULL;
1790 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1792 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1793 and not a printer admin, then fail */
1795 if ( (p->server_info->utok.uid != sec_initial_uid())
1796 && !user_has_privileges(p->server_info->ptok, &se_printop )
1797 && !token_contains_name_in_list(
1798 uidtoname(p->server_info->utok.uid),
1799 p->server_info->info3->base.domain.string,
1801 p->server_info->ptok,
1802 lp_printer_admin(-1)) )
1804 return WERR_ACCESS_DENIED;
1807 /* check that we have a valid driver name first */
1809 if ((version = get_version_id(r->in.architecture)) == -1)
1810 return WERR_INVALID_ENVIRONMENT;
1812 status = winreg_get_driver(p->mem_ctx, p->server_info,
1813 r->in.architecture, r->in.driver,
1815 if (!W_ERROR_IS_OK(status)) {
1816 /* try for Win2k driver if "Windows NT x86" */
1818 if ( version == 2 ) {
1821 status = winreg_get_driver(p->mem_ctx, p->server_info,
1825 if (!W_ERROR_IS_OK(status)) {
1826 status = WERR_UNKNOWN_PRINTER_DRIVER;
1830 /* otherwise it was a failure */
1832 status = WERR_UNKNOWN_PRINTER_DRIVER;
1838 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1839 status = WERR_PRINTER_DRIVER_IN_USE;
1844 status = winreg_get_driver(p->mem_ctx, p->server_info,
1846 r->in.driver, 3, &info_win2k);
1847 if (W_ERROR_IS_OK(status)) {
1848 /* if we get to here, we now have 2 driver info structures to remove */
1849 /* remove the Win2k driver first*/
1851 status = winreg_del_driver(p->mem_ctx,
1854 talloc_free(info_win2k);
1856 /* this should not have failed---if it did, report to client */
1857 if (!W_ERROR_IS_OK(status)) {
1863 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1871 /****************************************************************
1872 _spoolss_DeletePrinterDriverEx
1873 ****************************************************************/
1875 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
1876 struct spoolss_DeletePrinterDriverEx *r)
1878 struct spoolss_DriverInfo8 *info = NULL;
1879 struct spoolss_DriverInfo8 *info_win2k = NULL;
1883 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1885 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1886 and not a printer admin, then fail */
1888 if ( (p->server_info->utok.uid != sec_initial_uid())
1889 && !user_has_privileges(p->server_info->ptok, &se_printop )
1890 && !token_contains_name_in_list(
1891 uidtoname(p->server_info->utok.uid),
1892 p->server_info->info3->base.domain.string,
1894 p->server_info->ptok, lp_printer_admin(-1)) )
1896 return WERR_ACCESS_DENIED;
1899 /* check that we have a valid driver name first */
1900 if ((version = get_version_id(r->in.architecture)) == -1) {
1901 /* this is what NT returns */
1902 return WERR_INVALID_ENVIRONMENT;
1905 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1906 version = r->in.version;
1908 status = winreg_get_driver(p->mem_ctx, p->server_info,
1909 r->in.architecture, r->in.driver,
1911 if (!W_ERROR_IS_OK(status)) {
1912 status = WERR_UNKNOWN_PRINTER_DRIVER;
1915 * if the client asked for a specific version,
1916 * or this is something other than Windows NT x86,
1920 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1923 /* try for Win2k driver if "Windows NT x86" */
1926 status = winreg_get_driver(info, p->server_info,
1930 if (!W_ERROR_IS_OK(status)) {
1931 status = WERR_UNKNOWN_PRINTER_DRIVER;
1936 if (printer_driver_in_use(info, p->server_info, info)) {
1937 status = WERR_PRINTER_DRIVER_IN_USE;
1942 * we have a couple of cases to consider.
1943 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1944 * then the delete should fail if **any** files overlap with
1946 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1947 * non-overlapping files
1948 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1949 * is set, the do not delete any files
1950 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1953 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1955 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1958 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1959 printer_driver_files_in_use(info, p->server_info, info)) {
1960 /* no idea of the correct error here */
1961 status = WERR_ACCESS_DENIED;
1966 /* also check for W32X86/3 if necessary; maybe we already have? */
1968 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1969 status = winreg_get_driver(info, p->server_info,
1971 r->in.driver, 3, &info_win2k);
1972 if (W_ERROR_IS_OK(status)) {
1975 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1976 printer_driver_files_in_use(info, p->server_info,
1978 /* no idea of the correct error here */
1979 talloc_free(info_win2k);
1980 status = WERR_ACCESS_DENIED;
1984 /* if we get to here, we now have 2 driver info structures to remove */
1985 /* remove the Win2k driver first*/
1987 status = winreg_del_driver(info, p->server_info,
1990 /* this should not have failed---if it did, report to client */
1992 if (!W_ERROR_IS_OK(status)) {
1997 * now delete any associated files if delete_files is
1998 * true. Even if this part failes, we return succes
1999 * because the driver doesn not exist any more
2002 delete_driver_files(p->server_info,
2008 status = winreg_del_driver(info, p->server_info, info, version);
2009 if (!W_ERROR_IS_OK(status)) {
2014 * now delete any associated files if delete_files is
2015 * true. Even if this part failes, we return succes
2016 * because the driver doesn not exist any more
2019 delete_driver_files(p->server_info, info);
2028 /****************************************************************************
2029 Internal routine for storing printerdata
2030 ***************************************************************************/
2032 WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2033 const char *key, const char *value,
2034 uint32_t type, uint8_t *data, int real_len)
2036 /* the registry objects enforce uniqueness based on value name */
2038 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2041 /********************************************************************
2042 GetPrinterData on a printer server Handle.
2043 ********************************************************************/
2045 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2047 enum winreg_Type *type,
2048 union spoolss_PrinterData *data)
2050 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2052 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2058 if (!StrCaseCmp(value, "BeepEnabled")) {
2064 if (!StrCaseCmp(value, "EventLog")) {
2066 /* formally was 0x1b */
2071 if (!StrCaseCmp(value, "NetPopup")) {
2077 if (!StrCaseCmp(value, "MajorVersion")) {
2080 /* Windows NT 4.0 seems to not allow uploading of drivers
2081 to a server that reports 0x3 as the MajorVersion.
2082 need to investigate more how Win2k gets around this .
2085 if (RA_WINNT == get_remote_arch()) {
2094 if (!StrCaseCmp(value, "MinorVersion")) {
2101 * uint32_t size = 0x114
2102 * uint32_t major = 5
2103 * uint32_t minor = [0|1]
2104 * uint32_t build = [2195|2600]
2105 * extra unicode string = e.g. "Service Pack 3"
2107 if (!StrCaseCmp(value, "OSVersion")) {
2109 enum ndr_err_code ndr_err;
2110 struct spoolss_OSVersion os;
2112 os.major = 5; /* Windows 2000 == 5.0 */
2114 os.build = 2195; /* build */
2115 os.extra_string = ""; /* leave extra string empty */
2117 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2118 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2119 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2120 return WERR_GENERAL_FAILURE;
2124 data->binary = blob;
2130 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2133 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2134 W_ERROR_HAVE_NO_MEMORY(data->string);
2139 if (!StrCaseCmp(value, "Architecture")) {
2141 data->string = talloc_strdup(mem_ctx,
2142 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2143 W_ERROR_HAVE_NO_MEMORY(data->string);
2148 if (!StrCaseCmp(value, "DsPresent")) {
2151 /* only show the publish check box if we are a
2152 member of a AD domain */
2154 if (lp_security() == SEC_ADS) {
2162 if (!StrCaseCmp(value, "DNSMachineName")) {
2163 const char *hostname = get_mydnsfullname();
2166 return WERR_BADFILE;
2170 data->string = talloc_strdup(mem_ctx, hostname);
2171 W_ERROR_HAVE_NO_MEMORY(data->string);
2178 return WERR_INVALID_PARAM;
2181 /****************************************************************
2182 _spoolss_GetPrinterData
2183 ****************************************************************/
2185 WERROR _spoolss_GetPrinterData(pipes_struct *p,
2186 struct spoolss_GetPrinterData *r)
2188 struct spoolss_GetPrinterDataEx r2;
2190 r2.in.handle = r->in.handle;
2191 r2.in.key_name = "PrinterDriverData";
2192 r2.in.value_name = r->in.value_name;
2193 r2.in.offered = r->in.offered;
2194 r2.out.type = r->out.type;
2195 r2.out.data = r->out.data;
2196 r2.out.needed = r->out.needed;
2198 return _spoolss_GetPrinterDataEx(p, &r2);
2201 /*********************************************************
2202 Connect to the client machine.
2203 **********************************************************/
2205 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2206 struct sockaddr_storage *client_ss, const char *remote_machine)
2209 struct cli_state *the_cli;
2210 struct sockaddr_storage rm_addr;
2211 char addr[INET6_ADDRSTRLEN];
2213 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2214 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2216 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2217 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2220 print_sockaddr(addr, sizeof(addr), &rm_addr);
2222 rm_addr = *client_ss;
2223 print_sockaddr(addr, sizeof(addr), &rm_addr);
2224 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2228 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2229 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2234 /* setup the connection */
2235 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2236 &rm_addr, 0, "IPC$", "IPC",
2240 0, lp_client_signing(), NULL );
2242 if ( !NT_STATUS_IS_OK( ret ) ) {
2243 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2248 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2249 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2250 cli_shutdown(the_cli);
2255 * Ok - we have an anonymous connection to the IPC$ share.
2256 * Now start the NT Domain stuff :-).
2259 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2260 if (!NT_STATUS_IS_OK(ret)) {
2261 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2262 remote_machine, nt_errstr(ret)));
2263 cli_shutdown(the_cli);
2270 /***************************************************************************
2271 Connect to the client.
2272 ****************************************************************************/
2274 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2275 uint32_t localprinter, uint32_t type,
2276 struct policy_handle *handle,
2277 struct sockaddr_storage *client_ss)
2283 * If it's the first connection, contact the client
2284 * and connect to the IPC$ share anonymously
2286 if (smb_connections==0) {
2287 fstring unix_printer;
2289 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2291 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2294 messaging_register(smbd_messaging_context(), NULL,
2295 MSG_PRINTER_NOTIFY2,
2296 receive_notify2_message_list);
2297 /* Tell the connections db we're now interested in printer
2298 * notify messages. */
2299 serverid_register_msg_flags(
2300 messaging_server_id(smbd_messaging_context()),
2301 true, FLAG_MSG_PRINT_NOTIFY);
2305 * Tell the specific printing tdb we want messages for this printer
2306 * by registering our PID.
2309 if (!print_notify_register_pid(snum))
2310 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2314 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2322 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2323 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2324 win_errstr(result)));
2326 return (W_ERROR_IS_OK(result));
2329 /****************************************************************
2330 ****************************************************************/
2332 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2333 const struct spoolss_NotifyOption *r)
2335 struct spoolss_NotifyOption *option;
2342 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2349 if (!option->count) {
2353 option->types = talloc_zero_array(option,
2354 struct spoolss_NotifyOptionType, option->count);
2355 if (!option->types) {
2356 talloc_free(option);
2360 for (i=0; i < option->count; i++) {
2361 option->types[i] = r->types[i];
2363 if (option->types[i].count) {
2364 option->types[i].fields = talloc_zero_array(option,
2365 union spoolss_Field, option->types[i].count);
2366 if (!option->types[i].fields) {
2367 talloc_free(option);
2370 for (k=0; k<option->types[i].count; k++) {
2371 option->types[i].fields[k] =
2372 r->types[i].fields[k];
2380 /****************************************************************
2381 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2383 * before replying OK: status=0 a rpc call is made to the workstation
2384 * asking ReplyOpenPrinter
2386 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2387 * called from api_spoolss_rffpcnex
2388 ****************************************************************/
2390 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2391 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2394 struct spoolss_NotifyOption *option = r->in.notify_options;
2395 struct sockaddr_storage client_ss;
2397 /* store the notify value in the printer struct */
2399 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2402 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2403 "Invalid handle (%s:%u:%u).\n",
2404 OUR_HANDLE(r->in.handle)));
2408 Printer->notify.flags = r->in.flags;
2409 Printer->notify.options = r->in.options;
2410 Printer->notify.printerlocal = r->in.printer_local;
2412 TALLOC_FREE(Printer->notify.option);
2413 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2415 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2417 /* Connect to the client machine and send a ReplyOpenPrinter */
2419 if ( Printer->printer_type == SPLHND_SERVER)
2421 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2422 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2425 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2426 "client_address is %s\n", p->client_address));
2428 if (!interpret_string_addr(&client_ss, p->client_address,
2430 return WERR_SERVER_UNAVAILABLE;
2433 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2434 Printer->notify.printerlocal, 1,
2435 &Printer->notify.client_hnd, &client_ss))
2436 return WERR_SERVER_UNAVAILABLE;
2438 Printer->notify.client_connected = true;
2443 /*******************************************************************
2444 * fill a notify_info_data with the servername
2445 ********************************************************************/
2447 static void spoolss_notify_server_name(int snum,
2448 struct spoolss_Notify *data,
2449 print_queue_struct *queue,
2450 struct spoolss_PrinterInfo2 *pinfo2,
2451 TALLOC_CTX *mem_ctx)
2453 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2456 /*******************************************************************
2457 * fill a notify_info_data with the printername (not including the servername).
2458 ********************************************************************/
2460 static void spoolss_notify_printer_name(int snum,
2461 struct spoolss_Notify *data,
2462 print_queue_struct *queue,
2463 struct spoolss_PrinterInfo2 *pinfo2,
2464 TALLOC_CTX *mem_ctx)
2466 /* the notify name should not contain the \\server\ part */
2467 const char *p = strrchr(pinfo2->printername, '\\');
2470 p = pinfo2->printername;
2475 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2478 /*******************************************************************
2479 * fill a notify_info_data with the servicename
2480 ********************************************************************/
2482 static void spoolss_notify_share_name(int snum,
2483 struct spoolss_Notify *data,
2484 print_queue_struct *queue,
2485 struct spoolss_PrinterInfo2 *pinfo2,
2486 TALLOC_CTX *mem_ctx)
2488 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2491 /*******************************************************************
2492 * fill a notify_info_data with the port name
2493 ********************************************************************/
2495 static void spoolss_notify_port_name(int snum,
2496 struct spoolss_Notify *data,
2497 print_queue_struct *queue,
2498 struct spoolss_PrinterInfo2 *pinfo2,
2499 TALLOC_CTX *mem_ctx)
2501 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2504 /*******************************************************************
2505 * fill a notify_info_data with the printername
2506 * but it doesn't exist, have to see what to do
2507 ********************************************************************/
2509 static void spoolss_notify_driver_name(int snum,
2510 struct spoolss_Notify *data,
2511 print_queue_struct *queue,
2512 struct spoolss_PrinterInfo2 *pinfo2,
2513 TALLOC_CTX *mem_ctx)
2515 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2518 /*******************************************************************
2519 * fill a notify_info_data with the comment
2520 ********************************************************************/
2522 static void spoolss_notify_comment(int snum,
2523 struct spoolss_Notify *data,
2524 print_queue_struct *queue,
2525 struct spoolss_PrinterInfo2 *pinfo2,
2526 TALLOC_CTX *mem_ctx)
2530 if (*pinfo2->comment == '\0') {
2531 p = lp_comment(snum);
2533 p = pinfo2->comment;
2536 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2539 /*******************************************************************
2540 * fill a notify_info_data with the comment
2541 * location = "Room 1, floor 2, building 3"
2542 ********************************************************************/
2544 static void spoolss_notify_location(int snum,
2545 struct spoolss_Notify *data,
2546 print_queue_struct *queue,
2547 struct spoolss_PrinterInfo2 *pinfo2,
2548 TALLOC_CTX *mem_ctx)
2550 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2553 /*******************************************************************
2554 * fill a notify_info_data with the device mode
2555 * jfm:xxxx don't to it for know but that's a real problem !!!
2556 ********************************************************************/
2558 static void spoolss_notify_devmode(int snum,
2559 struct spoolss_Notify *data,
2560 print_queue_struct *queue,
2561 struct spoolss_PrinterInfo2 *pinfo2,
2562 TALLOC_CTX *mem_ctx)
2564 /* for a dummy implementation we have to zero the fields */
2565 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2568 /*******************************************************************
2569 * fill a notify_info_data with the separator file name
2570 ********************************************************************/
2572 static void spoolss_notify_sepfile(int snum,
2573 struct spoolss_Notify *data,
2574 print_queue_struct *queue,
2575 struct spoolss_PrinterInfo2 *pinfo2,
2576 TALLOC_CTX *mem_ctx)
2578 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2581 /*******************************************************************
2582 * fill a notify_info_data with the print processor
2583 * jfm:xxxx return always winprint to indicate we don't do anything to it
2584 ********************************************************************/
2586 static void spoolss_notify_print_processor(int snum,
2587 struct spoolss_Notify *data,
2588 print_queue_struct *queue,
2589 struct spoolss_PrinterInfo2 *pinfo2,
2590 TALLOC_CTX *mem_ctx)
2592 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2595 /*******************************************************************
2596 * fill a notify_info_data with the print processor options
2597 * jfm:xxxx send an empty string
2598 ********************************************************************/
2600 static void spoolss_notify_parameters(int snum,
2601 struct spoolss_Notify *data,
2602 print_queue_struct *queue,
2603 struct spoolss_PrinterInfo2 *pinfo2,
2604 TALLOC_CTX *mem_ctx)
2606 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2609 /*******************************************************************
2610 * fill a notify_info_data with the data type
2611 * jfm:xxxx always send RAW as data type
2612 ********************************************************************/
2614 static void spoolss_notify_datatype(int snum,
2615 struct spoolss_Notify *data,
2616 print_queue_struct *queue,
2617 struct spoolss_PrinterInfo2 *pinfo2,
2618 TALLOC_CTX *mem_ctx)
2620 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2623 /*******************************************************************
2624 * fill a notify_info_data with the security descriptor
2625 * jfm:xxxx send an null pointer to say no security desc
2626 * have to implement security before !
2627 ********************************************************************/
2629 static void spoolss_notify_security_desc(int snum,
2630 struct spoolss_Notify *data,
2631 print_queue_struct *queue,
2632 struct spoolss_PrinterInfo2 *pinfo2,
2633 TALLOC_CTX *mem_ctx)
2635 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2638 /*******************************************************************
2639 * fill a notify_info_data with the attributes
2640 * jfm:xxxx a samba printer is always shared
2641 ********************************************************************/
2643 static void spoolss_notify_attributes(int snum,
2644 struct spoolss_Notify *data,
2645 print_queue_struct *queue,
2646 struct spoolss_PrinterInfo2 *pinfo2,
2647 TALLOC_CTX *mem_ctx)
2649 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2652 /*******************************************************************
2653 * fill a notify_info_data with the priority
2654 ********************************************************************/
2656 static void spoolss_notify_priority(int snum,
2657 struct spoolss_Notify *data,
2658 print_queue_struct *queue,
2659 struct spoolss_PrinterInfo2 *pinfo2,
2660 TALLOC_CTX *mem_ctx)
2662 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2665 /*******************************************************************
2666 * fill a notify_info_data with the default priority
2667 ********************************************************************/
2669 static void spoolss_notify_default_priority(int snum,
2670 struct spoolss_Notify *data,
2671 print_queue_struct *queue,
2672 struct spoolss_PrinterInfo2 *pinfo2,
2673 TALLOC_CTX *mem_ctx)
2675 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2678 /*******************************************************************
2679 * fill a notify_info_data with the start time
2680 ********************************************************************/
2682 static void spoolss_notify_start_time(int snum,
2683 struct spoolss_Notify *data,
2684 print_queue_struct *queue,
2685 struct spoolss_PrinterInfo2 *pinfo2,
2686 TALLOC_CTX *mem_ctx)
2688 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2691 /*******************************************************************
2692 * fill a notify_info_data with the until time
2693 ********************************************************************/
2695 static void spoolss_notify_until_time(int snum,
2696 struct spoolss_Notify *data,
2697 print_queue_struct *queue,
2698 struct spoolss_PrinterInfo2 *pinfo2,
2699 TALLOC_CTX *mem_ctx)
2701 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2704 /*******************************************************************
2705 * fill a notify_info_data with the status
2706 ********************************************************************/
2708 static void spoolss_notify_status(int snum,
2709 struct spoolss_Notify *data,
2710 print_queue_struct *queue,
2711 struct spoolss_PrinterInfo2 *pinfo2,
2712 TALLOC_CTX *mem_ctx)
2714 print_status_struct status;
2716 print_queue_length(snum, &status);
2717 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2720 /*******************************************************************
2721 * fill a notify_info_data with the number of jobs queued
2722 ********************************************************************/
2724 static void spoolss_notify_cjobs(int snum,
2725 struct spoolss_Notify *data,
2726 print_queue_struct *queue,
2727 struct spoolss_PrinterInfo2 *pinfo2,
2728 TALLOC_CTX *mem_ctx)
2730 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2733 /*******************************************************************
2734 * fill a notify_info_data with the average ppm
2735 ********************************************************************/
2737 static void spoolss_notify_average_ppm(int snum,
2738 struct spoolss_Notify *data,
2739 print_queue_struct *queue,
2740 struct spoolss_PrinterInfo2 *pinfo2,
2741 TALLOC_CTX *mem_ctx)
2743 /* always respond 8 pages per minutes */
2744 /* a little hard ! */
2745 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2748 /*******************************************************************
2749 * fill a notify_info_data with username
2750 ********************************************************************/
2752 static void spoolss_notify_username(int snum,
2753 struct spoolss_Notify *data,
2754 print_queue_struct *queue,
2755 struct spoolss_PrinterInfo2 *pinfo2,
2756 TALLOC_CTX *mem_ctx)
2758 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2761 /*******************************************************************
2762 * fill a notify_info_data with job status
2763 ********************************************************************/
2765 static void spoolss_notify_job_status(int snum,
2766 struct spoolss_Notify *data,
2767 print_queue_struct *queue,
2768 struct spoolss_PrinterInfo2 *pinfo2,
2769 TALLOC_CTX *mem_ctx)
2771 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2774 /*******************************************************************
2775 * fill a notify_info_data with job name
2776 ********************************************************************/
2778 static void spoolss_notify_job_name(int snum,
2779 struct spoolss_Notify *data,
2780 print_queue_struct *queue,
2781 struct spoolss_PrinterInfo2 *pinfo2,
2782 TALLOC_CTX *mem_ctx)
2784 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2787 /*******************************************************************
2788 * fill a notify_info_data with job status
2789 ********************************************************************/
2791 static void spoolss_notify_job_status_string(int snum,
2792 struct spoolss_Notify *data,
2793 print_queue_struct *queue,
2794 struct spoolss_PrinterInfo2 *pinfo2,
2795 TALLOC_CTX *mem_ctx)
2798 * Now we're returning job status codes we just return a "" here. JRA.
2803 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2806 switch (queue->status) {
2811 p = ""; /* NT provides the paused string */
2820 #endif /* NO LONGER NEEDED. */
2822 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2825 /*******************************************************************
2826 * fill a notify_info_data with job time
2827 ********************************************************************/
2829 static void spoolss_notify_job_time(int snum,
2830 struct spoolss_Notify *data,
2831 print_queue_struct *queue,
2832 struct spoolss_PrinterInfo2 *pinfo2,
2833 TALLOC_CTX *mem_ctx)
2835 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2838 /*******************************************************************
2839 * fill a notify_info_data with job size
2840 ********************************************************************/
2842 static void spoolss_notify_job_size(int snum,
2843 struct spoolss_Notify *data,
2844 print_queue_struct *queue,
2845 struct spoolss_PrinterInfo2 *pinfo2,
2846 TALLOC_CTX *mem_ctx)
2848 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2851 /*******************************************************************
2852 * fill a notify_info_data with page info
2853 ********************************************************************/
2854 static void spoolss_notify_total_pages(int snum,
2855 struct spoolss_Notify *data,
2856 print_queue_struct *queue,
2857 struct spoolss_PrinterInfo2 *pinfo2,
2858 TALLOC_CTX *mem_ctx)
2860 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2863 /*******************************************************************
2864 * fill a notify_info_data with pages printed info.
2865 ********************************************************************/
2866 static void spoolss_notify_pages_printed(int snum,
2867 struct spoolss_Notify *data,
2868 print_queue_struct *queue,
2869 struct spoolss_PrinterInfo2 *pinfo2,
2870 TALLOC_CTX *mem_ctx)
2872 /* Add code when back-end tracks this */
2873 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2876 /*******************************************************************
2877 Fill a notify_info_data with job position.
2878 ********************************************************************/
2880 static void spoolss_notify_job_position(int snum,
2881 struct spoolss_Notify *data,
2882 print_queue_struct *queue,
2883 struct spoolss_PrinterInfo2 *pinfo2,
2884 TALLOC_CTX *mem_ctx)
2886 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2889 /*******************************************************************
2890 Fill a notify_info_data with submitted time.
2891 ********************************************************************/
2893 static void spoolss_notify_submitted_time(int snum,
2894 struct spoolss_Notify *data,
2895 print_queue_struct *queue,
2896 struct spoolss_PrinterInfo2 *pinfo2,
2897 TALLOC_CTX *mem_ctx)
2899 data->data.string.string = NULL;
2900 data->data.string.size = 0;
2902 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2903 &data->data.string.string,
2904 &data->data.string.size);
2908 struct s_notify_info_data_table
2910 enum spoolss_NotifyType type;
2913 enum spoolss_NotifyTable variable_type;
2914 void (*fn) (int snum, struct spoolss_Notify *data,
2915 print_queue_struct *queue,
2916 struct spoolss_PrinterInfo2 *pinfo2,
2917 TALLOC_CTX *mem_ctx);
2920 /* A table describing the various print notification constants and
2921 whether the notification data is a pointer to a variable sized
2922 buffer, a one value uint32_t or a two value uint32_t. */
2924 static const struct s_notify_info_data_table notify_info_data_table[] =
2926 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2927 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2928 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2929 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2930 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2931 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2932 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2933 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2934 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2935 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2936 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2937 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2938 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2939 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2940 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2941 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2942 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2943 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2950 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2951 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2952 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2953 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2954 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2955 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2956 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2957 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2958 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2959 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2960 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2961 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2962 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2963 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2964 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2965 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2966 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2967 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2968 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2969 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2970 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2971 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2972 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2973 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2974 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2977 /*******************************************************************
2978 Return the variable_type of info_data structure.
2979 ********************************************************************/
2981 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
2986 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
2987 if ( (notify_info_data_table[i].type == type) &&
2988 (notify_info_data_table[i].field == field) ) {
2989 return notify_info_data_table[i].variable_type;
2993 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
2998 /****************************************************************************
2999 ****************************************************************************/
3001 static bool search_notify(enum spoolss_NotifyType type,
3007 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3008 if (notify_info_data_table[i].type == type &&
3009 notify_info_data_table[i].field == field &&
3010 notify_info_data_table[i].fn != NULL) {
3019 /****************************************************************************
3020 ****************************************************************************/
3022 static void construct_info_data(struct spoolss_Notify *info_data,
3023 enum spoolss_NotifyType type,
3024 uint16_t field, int id)
3026 info_data->type = type;
3027 info_data->field.field = field;
3028 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3029 info_data->job_id = id;
3032 /*******************************************************************
3034 * fill a notify_info struct with info asked
3036 ********************************************************************/
3038 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3039 struct spoolss_NotifyInfo *info,
3040 struct spoolss_PrinterInfo2 *pinfo2,
3042 const struct spoolss_NotifyOptionType *option_type,
3044 TALLOC_CTX *mem_ctx)
3047 enum spoolss_NotifyType type;
3050 struct spoolss_Notify *current_data;
3051 print_queue_struct *queue=NULL;
3053 type = option_type->type;
3055 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3056 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3057 option_type->count, lp_servicename(snum)));
3059 for(field_num=0; field_num < option_type->count; field_num++) {
3060 field = option_type->fields[field_num].field;
3062 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3064 if (!search_notify(type, field, &j) )
3067 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3068 struct spoolss_Notify,
3070 if (info->notifies == NULL) {
3071 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3075 current_data = &info->notifies[info->count];
3077 construct_info_data(current_data, type, field, id);
3079 DEBUG(10, ("construct_notify_printer_info: "
3080 "calling [%s] snum=%d printername=[%s])\n",
3081 notify_info_data_table[j].name, snum,
3082 pinfo2->printername));
3084 notify_info_data_table[j].fn(snum, current_data, queue,
3093 /*******************************************************************
3095 * fill a notify_info struct with info asked
3097 ********************************************************************/
3099 static bool construct_notify_jobs_info(print_queue_struct *queue,
3100 struct spoolss_NotifyInfo *info,
3101 struct spoolss_PrinterInfo2 *pinfo2,
3103 const struct spoolss_NotifyOptionType *option_type,
3105 TALLOC_CTX *mem_ctx)
3108 enum spoolss_NotifyType type;
3110 struct spoolss_Notify *current_data;
3112 DEBUG(4,("construct_notify_jobs_info\n"));
3114 type = option_type->type;
3116 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3117 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3118 option_type->count));
3120 for(field_num=0; field_num<option_type->count; field_num++) {
3121 field = option_type->fields[field_num].field;
3123 if (!search_notify(type, field, &j) )
3126 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3127 struct spoolss_Notify,
3129 if (info->notifies == NULL) {
3130 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3134 current_data=&(info->notifies[info->count]);
3136 construct_info_data(current_data, type, field, id);
3137 notify_info_data_table[j].fn(snum, current_data, queue,
3146 * JFM: The enumeration is not that simple, it's even non obvious.
3148 * let's take an example: I want to monitor the PRINTER SERVER for
3149 * the printer's name and the number of jobs currently queued.
3150 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3151 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3153 * I have 3 printers on the back of my server.
3155 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3158 * 1 printer 1 name 1
3159 * 2 printer 1 cjob 1
3160 * 3 printer 2 name 2
3161 * 4 printer 2 cjob 2
3162 * 5 printer 3 name 3
3163 * 6 printer 3 name 3
3165 * that's the print server case, the printer case is even worse.
3168 /*******************************************************************
3170 * enumerate all printers on the printserver
3171 * fill a notify_info struct with info asked
3173 ********************************************************************/
3175 static WERROR printserver_notify_info(pipes_struct *p,
3176 struct policy_handle *hnd,
3177 struct spoolss_NotifyInfo *info,
3178 TALLOC_CTX *mem_ctx)
3181 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3182 int n_services=lp_numservices();
3184 struct spoolss_NotifyOption *option;
3185 struct spoolss_NotifyOptionType option_type;
3186 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3189 DEBUG(4,("printserver_notify_info\n"));
3194 option = Printer->notify.option;
3197 info->notifies = NULL;
3200 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3201 sending a ffpcn() request first */
3206 for (i=0; i<option->count; i++) {
3207 option_type = option->types[i];
3209 if (option_type.type != PRINTER_NOTIFY_TYPE)
3212 for (snum = 0; snum < n_services; snum++) {
3213 if (!lp_browseable(snum) ||
3214 !lp_snum_ok(snum) ||
3215 !lp_print_ok(snum)) {
3216 continue; /* skip */
3219 /* FIXME: should we use a SYSTEM server_info here? */
3220 result = winreg_get_printer(mem_ctx, p->server_info,
3221 Printer->servername,
3222 lp_servicename(snum),
3224 if (!W_ERROR_IS_OK(result)) {
3225 DEBUG(4, ("printserver_notify_info: "
3226 "Failed to get printer [%s]\n",
3227 lp_servicename(snum)));
3232 construct_notify_printer_info(Printer, info,
3237 TALLOC_FREE(pinfo2);
3243 * Debugging information, don't delete.
3246 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3247 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3248 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3250 for (i=0; i<info->count; i++) {
3251 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3252 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3253 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3260 /*******************************************************************
3262 * fill a notify_info struct with info asked
3264 ********************************************************************/
3266 static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3267 struct spoolss_NotifyInfo *info,
3268 TALLOC_CTX *mem_ctx)
3271 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3274 struct spoolss_NotifyOption *option;
3275 struct spoolss_NotifyOptionType option_type;
3277 print_queue_struct *queue=NULL;
3278 print_status_struct status;
3279 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3282 DEBUG(4,("printer_notify_info\n"));
3287 option = Printer->notify.option;
3291 info->notifies = NULL;
3294 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3295 sending a ffpcn() request first */
3300 get_printer_snum(p, hnd, &snum, NULL);
3302 /* FIXME: should we use a SYSTEM server_info here ? */
3303 result = winreg_get_printer(mem_ctx, p->server_info,
3304 Printer->servername,
3305 lp_servicename(snum), &pinfo2);
3306 if (!W_ERROR_IS_OK(result)) {
3310 for (i=0; i<option->count; i++) {
3311 option_type = option->types[i];
3313 switch (option_type.type) {
3314 case PRINTER_NOTIFY_TYPE:
3315 if (construct_notify_printer_info(Printer, info,
3323 case JOB_NOTIFY_TYPE:
3325 count = print_queue_status(snum, &queue, &status);
3327 for (j=0; j<count; j++) {
3328 construct_notify_jobs_info(&queue[j], info,
3341 * Debugging information, don't delete.
3344 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3345 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3346 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3348 for (i=0; i<info->count; i++) {
3349 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3350 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3351 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3355 talloc_free(pinfo2);
3359 /****************************************************************
3360 _spoolss_RouterRefreshPrinterChangeNotify
3361 ****************************************************************/
3363 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3364 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3366 struct spoolss_NotifyInfo *info;
3368 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3369 WERROR result = WERR_BADFID;
3371 /* we always have a spoolss_NotifyInfo struct */
3372 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3374 result = WERR_NOMEM;
3378 *r->out.info = info;
3381 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3382 "Invalid handle (%s:%u:%u).\n",
3383 OUR_HANDLE(r->in.handle)));
3387 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3390 * We are now using the change value, and
3391 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3392 * I don't have a global notification system, I'm sending back all the
3393 * informations even when _NOTHING_ has changed.
3396 /* We need to keep track of the change value to send back in
3397 RRPCN replies otherwise our updates are ignored. */
3399 Printer->notify.fnpcn = true;
3401 if (Printer->notify.client_connected) {
3402 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3403 "Saving change value in request [%x]\n",
3405 Printer->notify.change = r->in.change_low;
3408 /* just ignore the spoolss_NotifyOption */
3410 switch (Printer->printer_type) {
3412 result = printserver_notify_info(p, r->in.handle,
3416 case SPLHND_PRINTER:
3417 result = printer_notify_info(p, r->in.handle,
3422 Printer->notify.fnpcn = false;
3428 /********************************************************************
3429 * construct_printer_info_0
3430 * fill a printer_info_0 struct
3431 ********************************************************************/
3433 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3434 struct auth_serversupplied_info *server_info,
3435 struct spoolss_PrinterInfo2 *info2,
3436 struct spoolss_PrinterInfo0 *r,
3440 counter_printer_0 *session_counter;
3441 struct timeval setuptime;
3442 print_status_struct status;
3444 r->printername = talloc_strdup(mem_ctx, info2->printername);
3445 W_ERROR_HAVE_NO_MEMORY(r->printername);
3447 r->servername = talloc_strdup(mem_ctx, info2->servername);
3448 W_ERROR_HAVE_NO_MEMORY(r->servername);
3450 count = print_queue_length(snum, &status);
3452 /* check if we already have a counter for this printer */
3453 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3454 if (session_counter->snum == snum)
3458 /* it's the first time, add it to the list */
3459 if (session_counter == NULL) {
3460 session_counter = SMB_MALLOC_P(counter_printer_0);
3461 W_ERROR_HAVE_NO_MEMORY(session_counter);
3462 ZERO_STRUCTP(session_counter);
3463 session_counter->snum = snum;
3464 session_counter->counter = 0;
3465 DLIST_ADD(counter_list, session_counter);
3469 session_counter->counter++;
3475 get_startup_time(&setuptime);
3476 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3479 * the global_counter should be stored in a TDB as it's common to all the clients
3480 * and should be zeroed on samba startup
3482 r->global_counter = session_counter->counter;
3484 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3485 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3486 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3487 r->free_build = SPOOLSS_RELEASE_BUILD;
3489 r->max_spooling = 0;
3490 r->session_counter = session_counter->counter;
3491 r->num_error_out_of_paper = 0x0;
3492 r->num_error_not_ready = 0x0; /* number of print failure */
3494 r->number_of_processors = 0x1;
3495 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3496 r->high_part_total_bytes = 0x0;
3497 winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3498 r->last_error = WERR_OK;
3499 r->status = nt_printq_status(status.status);
3500 r->enumerate_network_printers = 0x0;
3501 r->c_setprinter = 0x0;
3502 r->processor_architecture = 0x0;
3503 r->processor_level = 0x6; /* 6 ???*/
3512 /********************************************************************
3513 * construct_printer_info1
3514 * fill a spoolss_PrinterInfo1 struct
3515 ********************************************************************/
3517 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3518 const struct spoolss_PrinterInfo2 *info2,
3520 struct spoolss_PrinterInfo1 *r,
3525 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3529 W_ERROR_HAVE_NO_MEMORY(r->description);
3531 if (info2->comment == NULL || info2->comment[0] == '\0') {
3532 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3534 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3536 W_ERROR_HAVE_NO_MEMORY(r->comment);
3538 r->name = talloc_strdup(mem_ctx, info2->printername);
3539 W_ERROR_HAVE_NO_MEMORY(r->name);
3544 /********************************************************************
3545 * construct_printer_info2
3546 * fill a spoolss_PrinterInfo2 struct
3547 ********************************************************************/
3549 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3550 const struct spoolss_PrinterInfo2 *info2,
3551 struct spoolss_PrinterInfo2 *r,
3555 print_status_struct status;
3557 count = print_queue_length(snum, &status);
3559 r->servername = talloc_strdup(mem_ctx, info2->servername);
3560 W_ERROR_HAVE_NO_MEMORY(r->servername);
3561 r->printername = talloc_strdup(mem_ctx, info2->printername);
3562 W_ERROR_HAVE_NO_MEMORY(r->printername);
3563 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3564 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3565 r->portname = talloc_strdup(mem_ctx, info2->portname);
3566 W_ERROR_HAVE_NO_MEMORY(r->portname);
3567 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3568 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3570 if (info2->comment[0] == '\0') {
3571 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3573 r->comment = talloc_strdup(mem_ctx, info2->comment);
3575 W_ERROR_HAVE_NO_MEMORY(r->comment);
3577 r->location = talloc_strdup(mem_ctx, info2->location);
3578 W_ERROR_HAVE_NO_MEMORY(r->location);
3579 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3580 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3581 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3582 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3583 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3584 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3585 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3586 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3588 r->attributes = info2->attributes;
3590 r->priority = info2->priority;
3591 r->defaultpriority = info2->defaultpriority;
3592 r->starttime = info2->starttime;
3593 r->untiltime = info2->untiltime;
3594 r->status = nt_printq_status(status.status);
3596 r->averageppm = info2->averageppm;
3598 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3600 DEBUG(8,("Returning NULL Devicemode!\n"));
3605 if (info2->secdesc != NULL) {
3606 /* don't use talloc_steal() here unless you do a deep steal of all
3607 the SEC_DESC members */
3609 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3615 /********************************************************************
3616 * construct_printer_info3
3617 * fill a spoolss_PrinterInfo3 struct
3618 ********************************************************************/
3620 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3621 const struct spoolss_PrinterInfo2 *info2,
3622 struct spoolss_PrinterInfo3 *r,
3625 /* These are the components of the SD we are returning. */
3627 if (info2->secdesc != NULL) {
3628 /* don't use talloc_steal() here unless you do a deep steal of all
3629 the SEC_DESC members */
3631 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3632 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3638 /********************************************************************
3639 * construct_printer_info4
3640 * fill a spoolss_PrinterInfo4 struct
3641 ********************************************************************/
3643 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3644 const struct spoolss_PrinterInfo2 *info2,
3645 struct spoolss_PrinterInfo4 *r,
3648 r->printername = talloc_strdup(mem_ctx, info2->printername);
3649 W_ERROR_HAVE_NO_MEMORY(r->printername);
3650 r->servername = talloc_strdup(mem_ctx, info2->servername);
3651 W_ERROR_HAVE_NO_MEMORY(r->servername);
3653 r->attributes = info2->attributes;
3658 /********************************************************************
3659 * construct_printer_info5
3660 * fill a spoolss_PrinterInfo5 struct
3661 ********************************************************************/
3663 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3664 const struct spoolss_PrinterInfo2 *info2,
3665 struct spoolss_PrinterInfo5 *r,
3668 r->printername = talloc_strdup(mem_ctx, info2->printername);
3669 W_ERROR_HAVE_NO_MEMORY(r->printername);
3670 r->portname = talloc_strdup(mem_ctx, info2->portname);
3671 W_ERROR_HAVE_NO_MEMORY(r->portname);
3673 r->attributes = info2->attributes;
3675 /* these two are not used by NT+ according to MSDN */
3676 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3677 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3682 /********************************************************************
3683 * construct_printer_info_6
3684 * fill a spoolss_PrinterInfo6 struct
3685 ********************************************************************/
3687 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3688 const struct spoolss_PrinterInfo2 *info2,
3689 struct spoolss_PrinterInfo6 *r,
3693 print_status_struct status;
3695 count = print_queue_length(snum, &status);
3697 r->status = nt_printq_status(status.status);
3702 /********************************************************************
3703 * construct_printer_info7
3704 * fill a spoolss_PrinterInfo7 struct
3705 ********************************************************************/
3707 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3708 Printer_entry *print_hnd,
3709 struct spoolss_PrinterInfo7 *r,
3712 struct auth_serversupplied_info *server_info;
3716 status = make_server_info_system(mem_ctx, &server_info);
3717 if (!NT_STATUS_IS_OK(status)) {
3718 DEBUG(0, ("construct_printer_info7: "
3719 "Could not create system server_info\n"));
3723 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3724 lp_servicename(snum), &guid, NULL)) {
3725 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3726 r->action = DSPRINT_PUBLISH;
3728 r->guid = talloc_strdup(mem_ctx, "");
3729 r->action = DSPRINT_UNPUBLISH;
3731 W_ERROR_HAVE_NO_MEMORY(r->guid);
3733 TALLOC_FREE(server_info);
3737 /********************************************************************
3738 * construct_printer_info8
3739 * fill a spoolss_PrinterInfo8 struct
3740 ********************************************************************/
3742 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3743 const struct spoolss_PrinterInfo2 *info2,
3744 struct spoolss_DeviceModeInfo *r,
3747 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3749 DEBUG(8,("Returning NULL Devicemode!\n"));
3756 /********************************************************************
3757 ********************************************************************/
3759 static bool snum_is_shared_printer(int snum)
3761 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3764 /********************************************************************
3765 Spoolss_enumprinters.
3766 ********************************************************************/
3768 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3769 struct auth_serversupplied_info *server_info,
3772 union spoolss_PrinterInfo **info_p,
3776 int n_services = lp_numservices();
3777 union spoolss_PrinterInfo *info = NULL;
3779 WERROR result = WERR_OK;
3784 for (snum = 0; snum < n_services; snum++) {
3786 const char *printer;
3787 struct spoolss_PrinterInfo2 *info2;
3789 if (!snum_is_shared_printer(snum)) {
3793 printer = lp_const_servicename(snum);
3795 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3798 result = winreg_create_printer(mem_ctx,
3802 if (!W_ERROR_IS_OK(result)) {
3806 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3807 union spoolss_PrinterInfo,
3810 result = WERR_NOMEM;
3814 result = winreg_get_printer(mem_ctx, server_info,
3815 NULL, printer, &info2);
3816 if (!W_ERROR_IS_OK(result)) {
3822 result = construct_printer_info0(info, server_info, info2,
3823 &info[count].info0, snum);
3826 result = construct_printer_info1(info, info2, flags,
3827 &info[count].info1, snum);
3830 result = construct_printer_info2(info, info2,
3831 &info[count].info2, snum);
3834 result = construct_printer_info4(info, info2,
3835 &info[count].info4, snum);
3838 result = construct_printer_info5(info, info2,
3839 &info[count].info5, snum);
3843 result = WERR_UNKNOWN_LEVEL;
3847 if (!W_ERROR_IS_OK(result)) {
3858 if (!W_ERROR_IS_OK(result)) {
3868 /********************************************************************
3869 * handle enumeration of printers at level 0
3870 ********************************************************************/
3872 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3873 struct auth_serversupplied_info *server_info,
3875 const char *servername,
3876 union spoolss_PrinterInfo **info,
3879 DEBUG(4,("enum_all_printers_info_0\n"));
3881 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3885 /********************************************************************
3886 ********************************************************************/
3888 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3889 struct auth_serversupplied_info *server_info,
3891 union spoolss_PrinterInfo **info,
3894 DEBUG(4,("enum_all_printers_info_1\n"));
3896 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3899 /********************************************************************
3900 enum_all_printers_info_1_local.
3901 *********************************************************************/
3903 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3904 struct auth_serversupplied_info *server_info,
3905 union spoolss_PrinterInfo **info,
3908 DEBUG(4,("enum_all_printers_info_1_local\n"));
3910 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3913 /********************************************************************
3914 enum_all_printers_info_1_name.
3915 *********************************************************************/
3917 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3918 struct auth_serversupplied_info *server_info,
3920 union spoolss_PrinterInfo **info,
3923 const char *s = name;
3925 DEBUG(4,("enum_all_printers_info_1_name\n"));
3927 if ((name[0] == '\\') && (name[1] == '\\')) {
3931 if (!is_myname_or_ipaddr(s)) {
3932 return WERR_INVALID_NAME;
3935 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3938 /********************************************************************
3939 enum_all_printers_info_1_network.
3940 *********************************************************************/
3942 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3943 struct auth_serversupplied_info *server_info,
3945 union spoolss_PrinterInfo **info,
3948 const char *s = name;
3950 DEBUG(4,("enum_all_printers_info_1_network\n"));
3952 /* If we respond to a enum_printers level 1 on our name with flags
3953 set to PRINTER_ENUM_REMOTE with a list of printers then these
3954 printers incorrectly appear in the APW browse list.
3955 Specifically the printers for the server appear at the workgroup
3956 level where all the other servers in the domain are
3957 listed. Windows responds to this call with a
3958 WERR_CAN_NOT_COMPLETE so we should do the same. */
3960 if (name[0] == '\\' && name[1] == '\\') {
3964 if (is_myname_or_ipaddr(s)) {
3965 return WERR_CAN_NOT_COMPLETE;
3968 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3971 /********************************************************************
3972 * api_spoolss_enumprinters
3974 * called from api_spoolss_enumprinters (see this to understand)
3975 ********************************************************************/
3977 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3978 struct auth_serversupplied_info *server_info,
3979 union spoolss_PrinterInfo **info,
3982 DEBUG(4,("enum_all_printers_info_2\n"));
3984 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
3987 /********************************************************************
3988 * handle enumeration of printers at level 1
3989 ********************************************************************/
3991 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
3992 struct auth_serversupplied_info *server_info,
3995 union spoolss_PrinterInfo **info,
3998 /* Not all the flags are equals */
4000 if (flags & PRINTER_ENUM_LOCAL) {
4001 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4004 if (flags & PRINTER_ENUM_NAME) {
4005 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4008 if (flags & PRINTER_ENUM_NETWORK) {
4009 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4012 return WERR_OK; /* NT4sp5 does that */
4015 /********************************************************************
4016 * handle enumeration of printers at level 2
4017 ********************************************************************/
4019 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4020 struct auth_serversupplied_info *server_info,
4022 const char *servername,
4023 union spoolss_PrinterInfo **info,
4026 if (flags & PRINTER_ENUM_LOCAL) {
4027 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4030 if (flags & PRINTER_ENUM_NAME) {
4031 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4032 return WERR_INVALID_NAME;
4035 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4038 if (flags & PRINTER_ENUM_REMOTE) {
4039 return WERR_UNKNOWN_LEVEL;
4045 /********************************************************************
4046 * handle enumeration of printers at level 4
4047 ********************************************************************/
4049 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4050 struct auth_serversupplied_info *server_info,
4052 const char *servername,
4053 union spoolss_PrinterInfo **info,
4056 DEBUG(4,("enum_all_printers_info_4\n"));
4058 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4062 /********************************************************************
4063 * handle enumeration of printers at level 5
4064 ********************************************************************/
4066 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4067 struct auth_serversupplied_info *server_info,
4069 const char *servername,
4070 union spoolss_PrinterInfo **info,
4073 DEBUG(4,("enum_all_printers_info_5\n"));
4075 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4078 /****************************************************************
4079 _spoolss_EnumPrinters
4080 ****************************************************************/
4082 WERROR _spoolss_EnumPrinters(pipes_struct *p,
4083 struct spoolss_EnumPrinters *r)
4085 const char *name = NULL;
4088 /* that's an [in out] buffer */
4090 if (!r->in.buffer && (r->in.offered != 0)) {
4091 return WERR_INVALID_PARAM;
4094 DEBUG(4,("_spoolss_EnumPrinters\n"));
4098 *r->out.info = NULL;
4102 * flags==PRINTER_ENUM_NAME
4103 * if name=="" then enumerates all printers
4104 * if name!="" then enumerate the printer
4105 * flags==PRINTER_ENUM_REMOTE
4106 * name is NULL, enumerate printers
4107 * Level 2: name!="" enumerates printers, name can't be NULL
4108 * Level 3: doesn't exist
4109 * Level 4: does a local registry lookup
4110 * Level 5: same as Level 2
4114 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4115 W_ERROR_HAVE_NO_MEMORY(name);
4118 switch (r->in.level) {
4120 result = enumprinters_level0(p->mem_ctx, p->server_info,
4122 r->out.info, r->out.count);
4125 result = enumprinters_level1(p->mem_ctx, p->server_info,
4127 r->out.info, r->out.count);
4130 result = enumprinters_level2(p->mem_ctx, p->server_info,
4132 r->out.info, r->out.count);
4135 result = enumprinters_level4(p->mem_ctx, p->server_info,
4137 r->out.info, r->out.count);
4140 result = enumprinters_level5(p->mem_ctx, p->server_info,
4142 r->out.info, r->out.count);
4145 return WERR_UNKNOWN_LEVEL;
4148 if (!W_ERROR_IS_OK(result)) {
4152 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4153 spoolss_EnumPrinters,
4154 *r->out.info, r->in.level,
4156 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4157 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4159 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4162 /****************************************************************
4164 ****************************************************************/
4166 WERROR _spoolss_GetPrinter(pipes_struct *p,
4167 struct spoolss_GetPrinter *r)
4169 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4170 struct spoolss_PrinterInfo2 *info2 = NULL;
4171 WERROR result = WERR_OK;
4172 const char *servername = NULL;
4175 /* that's an [in out] buffer */
4177 if (!r->in.buffer && (r->in.offered != 0)) {
4178 return WERR_INVALID_PARAM;
4183 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4187 if (Printer != NULL || Printer->servername != NULL) {
4188 servername = Printer->servername;
4191 result = winreg_get_printer(p->mem_ctx,
4194 lp_const_servicename(snum),
4196 if (!W_ERROR_IS_OK(result)) {
4200 switch (r->in.level) {
4202 result = construct_printer_info0(p->mem_ctx, p->server_info,
4204 &r->out.info->info0, snum);
4207 result = construct_printer_info1(p->mem_ctx, info2,
4209 &r->out.info->info1, snum);
4212 result = construct_printer_info2(p->mem_ctx, info2,
4213 &r->out.info->info2, snum);
4216 result = construct_printer_info3(p->mem_ctx, info2,
4217 &r->out.info->info3, snum);
4220 result = construct_printer_info4(p->mem_ctx, info2,
4221 &r->out.info->info4, snum);
4224 result = construct_printer_info5(p->mem_ctx, info2,
4225 &r->out.info->info5, snum);
4228 result = construct_printer_info6(p->mem_ctx, info2,
4229 &r->out.info->info6, snum);
4232 result = construct_printer_info7(p->mem_ctx, Printer,
4233 &r->out.info->info7, snum);
4236 result = construct_printer_info8(p->mem_ctx, info2,
4237 &r->out.info->info8, snum);
4240 result = WERR_UNKNOWN_LEVEL;
4244 if (!W_ERROR_IS_OK(result)) {
4245 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4246 r->in.level, win_errstr(result)));
4247 TALLOC_FREE(r->out.info);
4251 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4252 r->out.info, r->in.level);
4253 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4255 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4258 /********************************************************************
4259 ********************************************************************/
4261 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4263 if (in && strlen(in)) { \
4264 out = talloc_strdup(mem_ctx, in); \
4265 W_ERROR_HAVE_NO_MEMORY(out); \
4271 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4273 if (in && strlen(in)) { \
4274 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4276 out = talloc_strdup(mem_ctx, ""); \
4278 W_ERROR_HAVE_NO_MEMORY(out); \
4281 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4282 const char **string_array,
4283 const char ***presult,
4284 const char *cservername,
4288 int i, num_strings = 0;
4289 const char **array = NULL;
4291 if (string_array == NULL) {
4292 return WERR_INVALID_PARAMETER;;
4295 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4296 const char *str = NULL;
4298 if (cservername == NULL || arch == NULL) {
4299 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4301 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4304 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4311 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4312 &array, &num_strings);
4322 /********************************************************************
4323 * fill a spoolss_DriverInfo1 struct
4324 ********************************************************************/
4326 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4327 struct spoolss_DriverInfo1 *r,
4328 const struct spoolss_DriverInfo8 *driver,
4329 const char *servername)
4331 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4332 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4337 /********************************************************************
4338 * fill a spoolss_DriverInfo2 struct
4339 ********************************************************************/
4341 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4342 struct spoolss_DriverInfo2 *r,
4343 const struct spoolss_DriverInfo8 *driver,
4344 const char *servername)
4347 const char *cservername = canon_servername(servername);
4349 r->version = driver->version;
4351 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4352 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4353 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4354 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4356 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4357 driver->architecture,
4359 driver->driver_path,
4362 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4363 driver->architecture,
4368 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4369 driver->architecture,
4371 driver->config_file,
4377 /********************************************************************
4378 * fill a spoolss_DriverInfo3 struct
4379 ********************************************************************/
4381 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4382 struct spoolss_DriverInfo3 *r,
4383 const struct spoolss_DriverInfo8 *driver,
4384 const char *servername)
4386 const char *cservername = canon_servername(servername);
4388 r->version = driver->version;
4390 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4391 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4392 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4393 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4395 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4396 driver->architecture,
4398 driver->driver_path,
4401 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4402 driver->architecture,
4407 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4408 driver->architecture,
4410 driver->config_file,
4413 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4414 driver->architecture,
4419 FILL_DRIVER_STRING(mem_ctx,
4420 driver->monitor_name,
4423 FILL_DRIVER_STRING(mem_ctx,
4424 driver->default_datatype,
4425 r->default_datatype);
4427 return string_array_from_driver_info(mem_ctx,
4428 driver->dependent_files,
4429 &r->dependent_files,
4431 driver->architecture,
4435 /********************************************************************
4436 * fill a spoolss_DriverInfo4 struct
4437 ********************************************************************/
4439 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4440 struct spoolss_DriverInfo4 *r,
4441 const struct spoolss_DriverInfo8 *driver,
4442 const char *servername)
4444 const char *cservername = canon_servername(servername);
4447 r->version = driver->version;
4449 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4450 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4451 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4452 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4454 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4455 driver->architecture,
4457 driver->driver_path,
4460 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4461 driver->architecture,
4466 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4467 driver->architecture,
4469 driver->config_file,
4472 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4473 driver->architecture,
4478 result = string_array_from_driver_info(mem_ctx,
4479 driver->dependent_files,
4480 &r->dependent_files,
4482 driver->architecture,
4484 if (!W_ERROR_IS_OK(result)) {
4488 FILL_DRIVER_STRING(mem_ctx,
4489 driver->monitor_name,
4492 FILL_DRIVER_STRING(mem_ctx,
4493 driver->default_datatype,
4494 r->default_datatype);
4497 result = string_array_from_driver_info(mem_ctx,
4498 driver->previous_names,
4505 /********************************************************************
4506 * fill a spoolss_DriverInfo5 struct
4507 ********************************************************************/
4509 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4510 struct spoolss_DriverInfo5 *r,
4511 const struct spoolss_DriverInfo8 *driver,
4512 const char *servername)
4514 const char *cservername = canon_servername(servername);
4516 r->version = driver->version;
4518 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4519 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4520 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4521 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4523 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4524 driver->architecture,
4526 driver->driver_path,
4529 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4530 driver->architecture,
4535 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4536 driver->architecture,
4538 driver->config_file,
4541 r->driver_attributes = 0;
4542 r->config_version = 0;
4543 r->driver_version = 0;
4547 /********************************************************************
4548 * fill a spoolss_DriverInfo6 struct
4549 ********************************************************************/
4551 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4552 struct spoolss_DriverInfo6 *r,
4553 const struct spoolss_DriverInfo8 *driver,
4554 const char *servername)
4556 const char *cservername = canon_servername(servername);
4559 r->version = driver->version;
4561 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4562 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4563 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4564 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4566 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4567 driver->architecture,
4569 driver->driver_path,
4572 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4573 driver->architecture,
4578 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4579 driver->architecture,
4581 driver->config_file,
4584 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4585 driver->architecture,
4590 FILL_DRIVER_STRING(mem_ctx,
4591 driver->monitor_name,
4594 FILL_DRIVER_STRING(mem_ctx,
4595 driver->default_datatype,
4596 r->default_datatype);
4598 result = string_array_from_driver_info(mem_ctx,
4599 driver->dependent_files,
4600 &r->dependent_files,
4602 driver->architecture,
4604 if (!W_ERROR_IS_OK(result)) {
4608 result = string_array_from_driver_info(mem_ctx,
4609 driver->previous_names,
4612 if (!W_ERROR_IS_OK(result)) {
4616 r->driver_date = driver->driver_date;
4617 r->driver_version = driver->driver_version;
4619 FILL_DRIVER_STRING(mem_ctx,
4620 driver->manufacturer_name,
4621 r->manufacturer_name);
4622 FILL_DRIVER_STRING(mem_ctx,
4623 driver->manufacturer_url,
4624 r->manufacturer_url);
4625 FILL_DRIVER_STRING(mem_ctx,
4626 driver->hardware_id,
4628 FILL_DRIVER_STRING(mem_ctx,
4635 /********************************************************************
4636 * fill a spoolss_DriverInfo8 struct
4637 ********************************************************************/
4639 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4640 struct spoolss_DriverInfo8 *r,
4641 const struct spoolss_DriverInfo8 *driver,
4642 const char *servername)
4644 const char *cservername = canon_servername(servername);
4647 r->version = driver->version;
4649 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4650 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4651 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4652 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4654 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4655 driver->architecture,
4657 driver->driver_path,
4660 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4661 driver->architecture,
4666 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4667 driver->architecture,
4669 driver->config_file,
4672 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4673 driver->architecture,
4678 FILL_DRIVER_STRING(mem_ctx,
4679 driver->monitor_name,
4682 FILL_DRIVER_STRING(mem_ctx,
4683 driver->default_datatype,
4684 r->default_datatype);
4686 result = string_array_from_driver_info(mem_ctx,
4687 driver->dependent_files,
4688 &r->dependent_files,
4690 driver->architecture,
4692 if (!W_ERROR_IS_OK(result)) {
4696 result = string_array_from_driver_info(mem_ctx,
4697 driver->previous_names,
4700 if (!W_ERROR_IS_OK(result)) {
4704 r->driver_date = driver->driver_date;
4705 r->driver_version = driver->driver_version;
4707 FILL_DRIVER_STRING(mem_ctx,
4708 driver->manufacturer_name,
4709 r->manufacturer_name);
4710 FILL_DRIVER_STRING(mem_ctx,
4711 driver->manufacturer_url,
4712 r->manufacturer_url);
4713 FILL_DRIVER_STRING(mem_ctx,
4714 driver->hardware_id,
4716 FILL_DRIVER_STRING(mem_ctx,
4720 FILL_DRIVER_STRING(mem_ctx,
4721 driver->print_processor,
4722 r->print_processor);
4723 FILL_DRIVER_STRING(mem_ctx,
4724 driver->vendor_setup,
4727 result = string_array_from_driver_info(mem_ctx,
4728 driver->color_profiles,
4731 if (!W_ERROR_IS_OK(result)) {
4735 FILL_DRIVER_STRING(mem_ctx,
4739 r->printer_driver_attributes = driver->printer_driver_attributes;
4741 result = string_array_from_driver_info(mem_ctx,
4742 driver->core_driver_dependencies,
4743 &r->core_driver_dependencies,
4745 if (!W_ERROR_IS_OK(result)) {
4749 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4750 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4755 #if 0 /* disabled until marshalling issues are resolved - gd */
4756 /********************************************************************
4757 ********************************************************************/
4759 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4760 struct spoolss_DriverFileInfo *r,
4761 const char *cservername,
4762 const char *file_name,
4763 enum spoolss_DriverFileType file_type,
4764 uint32_t file_version)
4766 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4767 cservername, file_name);
4768 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4769 r->file_type = file_type;
4770 r->file_version = file_version;
4775 /********************************************************************
4776 ********************************************************************/
4778 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4779 const struct spoolss_DriverInfo8 *driver,
4780 const char *cservername,
4781 struct spoolss_DriverFileInfo **info_p,
4784 struct spoolss_DriverFileInfo *info = NULL;
4792 if (strlen(driver->driver_path)) {
4793 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4794 struct spoolss_DriverFileInfo,
4796 W_ERROR_HAVE_NO_MEMORY(info);
4797 result = fill_spoolss_DriverFileInfo(info,
4800 driver->driver_path,
4801 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4803 W_ERROR_NOT_OK_RETURN(result);
4807 if (strlen(driver->config_file)) {
4808 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4809 struct spoolss_DriverFileInfo,
4811 W_ERROR_HAVE_NO_MEMORY(info);
4812 result = fill_spoolss_DriverFileInfo(info,
4815 driver->config_file,
4816 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4818 W_ERROR_NOT_OK_RETURN(result);
4822 if (strlen(driver->data_file)) {
4823 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4824 struct spoolss_DriverFileInfo,
4826 W_ERROR_HAVE_NO_MEMORY(info);
4827 result = fill_spoolss_DriverFileInfo(info,
4831 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4833 W_ERROR_NOT_OK_RETURN(result);
4837 if (strlen(driver->help_file)) {
4838 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4839 struct spoolss_DriverFileInfo,
4841 W_ERROR_HAVE_NO_MEMORY(info);
4842 result = fill_spoolss_DriverFileInfo(info,
4846 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4848 W_ERROR_NOT_OK_RETURN(result);
4852 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4853 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4854 struct spoolss_DriverFileInfo,
4856 W_ERROR_HAVE_NO_MEMORY(info);
4857 result = fill_spoolss_DriverFileInfo(info,
4860 driver->dependent_files[i],
4861 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4863 W_ERROR_NOT_OK_RETURN(result);
4873 /********************************************************************
4874 * fill a spoolss_DriverInfo101 struct
4875 ********************************************************************/
4877 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4878 struct spoolss_DriverInfo101 *r,
4879 const struct spoolss_DriverInfo8 *driver,
4880 const char *servername)
4882 const char *cservername = canon_servername(servername);
4885 r->version = driver->version;
4887 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4888 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4889 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4890 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4892 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4896 if (!W_ERROR_IS_OK(result)) {
4900 FILL_DRIVER_STRING(mem_ctx,
4901 driver->monitor_name,
4904 FILL_DRIVER_STRING(mem_ctx,
4905 driver->default_datatype,
4906 r->default_datatype);
4908 result = string_array_from_driver_info(mem_ctx,
4909 driver->previous_names,
4912 if (!W_ERROR_IS_OK(result)) {
4916 r->driver_date = driver->driver_date;
4917 r->driver_version = driver->driver_version;
4919 FILL_DRIVER_STRING(mem_ctx,
4920 driver->manufacturer_name,
4921 r->manufacturer_name);
4922 FILL_DRIVER_STRING(mem_ctx,
4923 driver->manufacturer_url,
4924 r->manufacturer_url);
4925 FILL_DRIVER_STRING(mem_ctx,
4926 driver->hardware_id,
4928 FILL_DRIVER_STRING(mem_ctx,
4935 /********************************************************************
4936 ********************************************************************/
4938 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4939 struct auth_serversupplied_info *server_info,
4941 union spoolss_DriverInfo *r,
4943 const char *servername,
4944 const char *architecture,
4947 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4948 struct spoolss_DriverInfo8 *driver;
4951 result = winreg_get_printer(mem_ctx,
4954 lp_const_servicename(snum),
4957 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4958 win_errstr(result)));
4960 if (!W_ERROR_IS_OK(result)) {
4961 return WERR_INVALID_PRINTER_NAME;
4964 result = winreg_get_driver(mem_ctx, server_info, architecture,
4965 pinfo2->drivername, version, &driver);
4967 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4968 win_errstr(result)));
4970 if (!W_ERROR_IS_OK(result)) {
4972 * Is this a W2k client ?
4976 talloc_free(pinfo2);
4977 return WERR_UNKNOWN_PRINTER_DRIVER;
4980 /* Yes - try again with a WinNT driver. */
4982 result = winreg_get_driver(mem_ctx, server_info, architecture,
4985 DEBUG(8,("construct_printer_driver_level: status: %s\n",
4986 win_errstr(result)));
4987 if (!W_ERROR_IS_OK(result)) {
4988 talloc_free(pinfo2);
4989 return WERR_UNKNOWN_PRINTER_DRIVER;
4995 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
4998 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5001 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5004 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5007 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5010 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5013 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5015 #if 0 /* disabled until marshalling issues are resolved - gd */
5017 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5021 result = WERR_UNKNOWN_LEVEL;
5025 talloc_free(pinfo2);
5026 talloc_free(driver);
5031 /****************************************************************
5032 _spoolss_GetPrinterDriver2
5033 ****************************************************************/
5035 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5036 struct spoolss_GetPrinterDriver2 *r)
5038 Printer_entry *printer;
5043 /* that's an [in out] buffer */
5045 if (!r->in.buffer && (r->in.offered != 0)) {
5046 return WERR_INVALID_PARAM;
5049 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5051 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5052 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5053 return WERR_INVALID_PRINTER_NAME;
5057 *r->out.server_major_version = 0;
5058 *r->out.server_minor_version = 0;
5060 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5064 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5065 r->in.level, r->out.info,
5066 snum, printer->servername,
5068 r->in.client_major_version);
5069 if (!W_ERROR_IS_OK(result)) {
5070 TALLOC_FREE(r->out.info);
5074 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5075 r->out.info, r->in.level);
5076 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5078 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5082 /****************************************************************
5083 _spoolss_StartPagePrinter
5084 ****************************************************************/
5086 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5087 struct spoolss_StartPagePrinter *r)
5089 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5092 DEBUG(3,("_spoolss_StartPagePrinter: "
5093 "Error in startpageprinter printer handle\n"));
5097 Printer->page_started = true;
5101 /****************************************************************
5102 _spoolss_EndPagePrinter
5103 ****************************************************************/
5105 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5106 struct spoolss_EndPagePrinter *r)
5110 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5113 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5114 OUR_HANDLE(r->in.handle)));
5118 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5121 Printer->page_started = false;
5122 print_job_endpage(snum, Printer->jobid);
5127 /****************************************************************
5128 _spoolss_StartDocPrinter
5129 ****************************************************************/
5131 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5132 struct spoolss_StartDocPrinter *r)
5134 struct spoolss_DocumentInfo1 *info_1;
5136 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5139 DEBUG(2,("_spoolss_StartDocPrinter: "
5140 "Invalid handle (%s:%u:%u)\n",
5141 OUR_HANDLE(r->in.handle)));
5145 if (r->in.level != 1) {
5146 return WERR_UNKNOWN_LEVEL;
5149 info_1 = r->in.info.info1;
5152 * a nice thing with NT is it doesn't listen to what you tell it.
5153 * when asked to send _only_ RAW datas, it tries to send datas
5156 * So I add checks like in NT Server ...
5159 if (info_1->datatype) {
5160 if (strcmp(info_1->datatype, "RAW") != 0) {
5162 return WERR_INVALID_DATATYPE;
5166 /* get the share number of the printer */
5167 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5171 Printer->jobid = print_job_start(p->server_info, snum,
5172 info_1->document_name,
5175 /* An error occured in print_job_start() so return an appropriate
5178 if (Printer->jobid == -1) {
5179 return map_werror_from_unix(errno);
5182 Printer->document_started = true;
5183 *r->out.job_id = Printer->jobid;
5188 /****************************************************************
5189 _spoolss_EndDocPrinter
5190 ****************************************************************/
5192 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5193 struct spoolss_EndDocPrinter *r)
5195 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5199 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5200 OUR_HANDLE(r->in.handle)));
5204 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5208 Printer->document_started = false;
5209 print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5210 /* error codes unhandled so far ... */
5215 /****************************************************************
5216 _spoolss_WritePrinter
5217 ****************************************************************/
5219 WERROR _spoolss_WritePrinter(pipes_struct *p,
5220 struct spoolss_WritePrinter *r)
5222 ssize_t buffer_written;
5224 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5227 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5228 OUR_HANDLE(r->in.handle)));
5229 *r->out.num_written = r->in._data_size;
5233 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5236 buffer_written = print_job_write(snum, Printer->jobid,
5237 (const char *)r->in.data.data,
5239 (size_t)r->in._data_size);
5240 if (buffer_written == (ssize_t)-1) {
5241 *r->out.num_written = 0;
5242 if (errno == ENOSPC)
5243 return WERR_NO_SPOOL_SPACE;
5245 return WERR_ACCESS_DENIED;
5248 *r->out.num_written = r->in._data_size;
5253 /********************************************************************
5254 * api_spoolss_getprinter
5255 * called from the spoolss dispatcher
5257 ********************************************************************/
5259 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5263 WERROR errcode = WERR_BADFUNC;
5264 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5267 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5268 OUR_HANDLE(handle)));
5272 if (!get_printer_snum(p, handle, &snum, NULL))
5276 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5277 errcode = print_queue_pause(p->server_info, snum);
5279 case SPOOLSS_PRINTER_CONTROL_RESUME:
5280 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5281 errcode = print_queue_resume(p->server_info, snum);
5283 case SPOOLSS_PRINTER_CONTROL_PURGE:
5284 errcode = print_queue_purge(p->server_info, snum);
5287 return WERR_UNKNOWN_LEVEL;
5294 /****************************************************************
5295 _spoolss_AbortPrinter
5296 * From MSDN: "Deletes printer's spool file if printer is configured
5298 ****************************************************************/
5300 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5301 struct spoolss_AbortPrinter *r)
5303 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5305 WERROR errcode = WERR_OK;
5308 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5309 OUR_HANDLE(r->in.handle)));
5313 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5316 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5321 /********************************************************************
5322 * called by spoolss_api_setprinter
5323 * when updating a printer description
5324 ********************************************************************/
5326 static WERROR update_printer_sec(struct policy_handle *handle,
5327 pipes_struct *p, struct sec_desc_buf *secdesc_ctr)
5329 struct spoolss_security_descriptor *new_secdesc = NULL;
5330 struct spoolss_security_descriptor *old_secdesc = NULL;
5331 const char *printer;
5335 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5337 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5338 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5339 OUR_HANDLE(handle)));
5341 result = WERR_BADFID;
5345 if (secdesc_ctr == NULL) {
5346 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5347 result = WERR_INVALID_PARAM;
5350 printer = lp_const_servicename(snum);
5352 /* Check the user has permissions to change the security
5353 descriptor. By experimentation with two NT machines, the user
5354 requires Full Access to the printer to change security
5357 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5358 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5359 result = WERR_ACCESS_DENIED;
5363 /* NT seems to like setting the security descriptor even though
5364 nothing may have actually changed. */
5365 result = winreg_get_printer_secdesc(p->mem_ctx,
5369 if (!W_ERROR_IS_OK(result)) {
5370 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5371 result = WERR_BADFID;
5375 if (DEBUGLEVEL >= 10) {
5376 struct security_acl *the_acl;
5379 the_acl = secdesc_ctr->sd->dacl;
5380 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5381 printer, the_acl->num_aces));
5383 for (i = 0; i < the_acl->num_aces; i++) {
5384 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5385 &the_acl->aces[i].trustee),
5386 the_acl->aces[i].access_mask));
5389 the_acl = secdesc_ctr->sd->dacl;
5392 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5393 printer, the_acl->num_aces));
5395 for (i = 0; i < the_acl->num_aces; i++) {
5396 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5397 &the_acl->aces[i].trustee),
5398 the_acl->aces[i].access_mask));
5401 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5405 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5406 if (new_secdesc == NULL) {
5407 result = WERR_NOMEM;
5411 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5416 result = winreg_set_printer_secdesc(p->mem_ctx,
5425 /********************************************************************
5426 Canonicalize printer info from a client
5428 ATTN: It does not matter what we set the servername to hear
5429 since we do the necessary work in get_a_printer() to set it to
5430 the correct value based on what the client sent in the
5431 _spoolss_open_printer_ex().
5432 ********************************************************************/
5434 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5435 struct spoolss_SetPrinterInfo2 *info2,
5438 fstring printername;
5441 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5442 "portname=%s drivername=%s comment=%s location=%s\n",
5443 info2->servername, info2->printername, info2->sharename,
5444 info2->portname, info2->drivername, info2->comment,
5447 /* we force some elements to "correct" values */
5448 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5449 if (info2->servername == NULL) {
5452 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5453 if (info2->sharename == NULL) {
5457 /* check to see if we allow printername != sharename */
5458 if (lp_force_printername(snum)) {
5459 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5460 global_myname(), info2->sharename);
5462 /* make sure printername is in \\server\printername format */
5463 fstrcpy(printername, info2->printername);
5465 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5466 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5470 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5471 global_myname(), p);
5473 if (info2->printername == NULL) {
5477 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5478 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5483 /****************************************************************************
5484 ****************************************************************************/
5486 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5488 char *cmd = lp_addport_cmd();
5489 char *command = NULL;
5491 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5492 bool is_print_op = false;
5495 return WERR_ACCESS_DENIED;
5498 command = talloc_asprintf(ctx,
5499 "%s \"%s\" \"%s\"", cmd, portname, uri );
5505 is_print_op = user_has_privileges( token, &se_printop );
5507 DEBUG(10,("Running [%s]\n", command));
5509 /********* BEGIN SePrintOperatorPrivilege **********/
5514 ret = smbrun(command, NULL);
5519 /********* END SePrintOperatorPrivilege **********/
5521 DEBUGADD(10,("returned [%d]\n", ret));
5523 TALLOC_FREE(command);
5526 return WERR_ACCESS_DENIED;
5532 /****************************************************************************
5533 ****************************************************************************/
5535 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5536 struct spoolss_SetPrinterInfo2 *info2)
5538 char *cmd = lp_addprinter_cmd();
5540 char *command = NULL;
5544 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5545 bool is_print_op = false;
5546 char *remote_machine = talloc_strdup(ctx, "%m");
5548 if (!remote_machine) {
5551 remote_machine = talloc_sub_basic(ctx,
5552 current_user_info.smb_name,
5553 current_user_info.domain,
5555 if (!remote_machine) {
5559 command = talloc_asprintf(ctx,
5560 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5561 cmd, info2->printername, info2->sharename,
5562 info2->portname, info2->drivername,
5563 info2->location, info2->comment, remote_machine);
5569 is_print_op = user_has_privileges( token, &se_printop );
5571 DEBUG(10,("Running [%s]\n", command));
5573 /********* BEGIN SePrintOperatorPrivilege **********/
5578 if ( (ret = smbrun(command, &fd)) == 0 ) {
5579 /* Tell everyone we updated smb.conf. */
5580 message_send_all(smbd_messaging_context(),
5581 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5587 /********* END SePrintOperatorPrivilege **********/
5589 DEBUGADD(10,("returned [%d]\n", ret));
5591 TALLOC_FREE(command);
5592 TALLOC_FREE(remote_machine);
5600 /* reload our services immediately */
5602 reload_services(false);
5606 /* Get lines and convert them back to dos-codepage */
5607 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5608 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5611 /* Set the portname to what the script says the portname should be. */
5612 /* but don't require anything to be return from the script exit a good error code */
5615 /* Set the portname to what the script says the portname should be. */
5616 info2->portname = talloc_strdup(ctx, qlines[0]);
5617 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5620 TALLOC_FREE(qlines);
5625 /********************************************************************
5626 * Called by spoolss_api_setprinter
5627 * when updating a printer description.
5628 ********************************************************************/
5630 static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5631 struct spoolss_SetPrinterInfoCtr *info_ctr,
5632 struct spoolss_DeviceMode *devmode)
5634 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5635 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5636 struct spoolss_PrinterInfo2 *old_printer;
5637 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5638 const char *servername = NULL;
5639 const char *uncname;
5641 WERROR result = WERR_OK;
5643 TALLOC_CTX *tmp_ctx;
5645 DEBUG(8,("update_printer\n"));
5647 tmp_ctx = talloc_new(p->mem_ctx);
5648 if (tmp_ctx == NULL) {
5653 result = WERR_BADFID;
5657 if (!get_printer_snum(p, handle, &snum, NULL)) {
5658 result = WERR_BADFID;
5662 if (Printer != NULL || Printer->servername != NULL) {
5663 servername = Printer->servername;
5666 result = winreg_get_printer(tmp_ctx,
5669 lp_const_servicename(snum),
5671 if (!W_ERROR_IS_OK(result)) {
5672 result = WERR_BADFID;
5676 /* Do sanity check on the requested changes for Samba */
5677 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5678 result = WERR_INVALID_PARAM;
5682 /* FIXME!!! If the driver has changed we really should verify that
5683 it is installed before doing much else --jerry */
5685 /* Check calling user has permission to update printer description */
5686 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5687 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5688 result = WERR_ACCESS_DENIED;
5692 /* Call addprinter hook */
5693 /* Check changes to see if this is really needed */
5695 if (*lp_addprinter_cmd() &&
5696 (!strequal(printer->drivername, old_printer->drivername) ||
5697 !strequal(printer->comment, old_printer->comment) ||
5698 !strequal(printer->portname, old_printer->portname) ||
5699 !strequal(printer->location, old_printer->location)) )
5701 /* add_printer_hook() will call reload_services() */
5702 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5704 result = WERR_ACCESS_DENIED;
5710 * When a *new* driver is bound to a printer, the drivername is used to
5711 * lookup previously saved driver initialization info, which is then
5712 * bound to the printer, simulating what happens in the Windows arch.
5714 if (!strequal(printer->drivername, old_printer->drivername)) {
5715 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5716 printer->drivername));
5718 notify_printer_driver(snum, printer->drivername);
5722 * flag which changes actually occured. This is a small subset of
5723 * all the possible changes. We also have to update things in the
5726 if (!strequal(printer->comment, old_printer->comment)) {
5727 push_reg_sz(tmp_ctx, &buffer, printer->comment);
5728 winreg_set_printer_dataex(p->mem_ctx,
5731 SPOOL_DSSPOOLER_KEY,
5737 notify_printer_comment(snum, printer->comment);
5740 if (!strequal(printer->sharename, old_printer->sharename)) {
5741 push_reg_sz(tmp_ctx, &buffer, printer->sharename);
5742 winreg_set_printer_dataex(tmp_ctx,
5745 SPOOL_DSSPOOLER_KEY,
5751 notify_printer_sharename(snum, printer->sharename);
5754 if (!strequal(printer->printername, old_printer->printername)) {
5757 if ( (pname = strchr_m( printer->printername+2, '\\' )) != NULL )
5760 pname = printer->printername;
5762 push_reg_sz(tmp_ctx, &buffer, pname);
5763 winreg_set_printer_dataex(tmp_ctx,
5766 SPOOL_DSSPOOLER_KEY,
5772 notify_printer_printername( snum, pname );
5775 if (!strequal(printer->portname, old_printer->portname)) {
5776 push_reg_sz(tmp_ctx, &buffer, printer->portname);
5777 winreg_set_printer_dataex(tmp_ctx,
5780 SPOOL_DSSPOOLER_KEY,
5786 notify_printer_port(snum, printer->portname);
5789 if (!strequal(printer->location, old_printer->location)) {
5790 push_reg_sz(tmp_ctx, &buffer, printer->location);
5791 winreg_set_printer_dataex(tmp_ctx,
5794 SPOOL_DSSPOOLER_KEY,
5800 notify_printer_location(snum, printer->location);
5803 /* here we need to update some more DsSpooler keys */
5804 /* uNCName, serverName, shortServerName */
5806 push_reg_sz(tmp_ctx, &buffer, global_myname());
5807 winreg_set_printer_dataex(tmp_ctx,
5810 SPOOL_DSSPOOLER_KEY,
5815 winreg_set_printer_dataex(tmp_ctx,
5818 SPOOL_DSSPOOLER_KEY,
5824 uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
5825 global_myname(), printer->sharename);
5826 push_reg_sz(tmp_ctx, &buffer, uncname);
5827 winreg_set_printer_dataex(tmp_ctx,
5830 SPOOL_DSSPOOLER_KEY,
5836 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
5838 if (devmode == NULL) {
5839 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
5841 result = winreg_update_printer(tmp_ctx,
5850 talloc_free(tmp_ctx);
5855 /****************************************************************************
5856 ****************************************************************************/
5857 static WERROR publish_or_unpublish_printer(pipes_struct *p,
5858 struct policy_handle *handle,
5859 struct spoolss_SetPrinterInfo7 *info7)
5862 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5865 Printer_entry *Printer;
5867 if ( lp_security() != SEC_ADS ) {
5868 return WERR_UNKNOWN_LEVEL;
5871 Printer = find_printer_index_by_hnd(p, handle);
5873 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5878 if (!get_printer_snum(p, handle, &snum, NULL))
5881 result = winreg_get_printer(p->mem_ctx, p->server_info,
5882 Printer->servername,
5883 lp_servicename(snum), &pinfo2);
5884 if (!W_ERROR_IS_OK(result)) {
5888 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
5890 TALLOC_FREE(pinfo2);
5893 return WERR_UNKNOWN_LEVEL;
5897 /********************************************************************
5898 ********************************************************************/
5900 static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
5901 struct spoolss_DeviceMode *devmode)
5904 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5905 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
5907 DEBUG(8,("update_printer_devmode\n"));
5913 if (!get_printer_snum(p, handle, &snum, NULL)) {
5917 /* Check calling user has permission to update printer description */
5918 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5919 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5920 return WERR_ACCESS_DENIED;
5923 return winreg_update_printer(p->mem_ctx,
5925 lp_const_servicename(snum),
5933 /****************************************************************
5935 ****************************************************************/
5937 WERROR _spoolss_SetPrinter(pipes_struct *p,
5938 struct spoolss_SetPrinter *r)
5942 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5945 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5946 OUR_HANDLE(r->in.handle)));
5950 /* check the level */
5951 switch (r->in.info_ctr->level) {
5953 return control_printer(r->in.handle, r->in.command, p);
5955 result = update_printer(p, r->in.handle,
5957 r->in.devmode_ctr->devmode);
5958 if (!W_ERROR_IS_OK(result))
5960 if (r->in.secdesc_ctr->sd)
5961 result = update_printer_sec(r->in.handle, p,
5965 return update_printer_sec(r->in.handle, p,
5968 return publish_or_unpublish_printer(p, r->in.handle,
5969 r->in.info_ctr->info.info7);
5971 return update_printer_devmode(p, r->in.handle,
5972 r->in.devmode_ctr->devmode);
5974 return WERR_UNKNOWN_LEVEL;
5978 /****************************************************************
5979 _spoolss_FindClosePrinterNotify
5980 ****************************************************************/
5982 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
5983 struct spoolss_FindClosePrinterNotify *r)
5985 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5988 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
5989 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
5993 if (Printer->notify.client_connected == true) {
5996 if ( Printer->printer_type == SPLHND_SERVER)
5998 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
5999 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6002 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6005 Printer->notify.flags=0;
6006 Printer->notify.options=0;
6007 Printer->notify.localmachine[0]='\0';
6008 Printer->notify.printerlocal=0;
6009 TALLOC_FREE(Printer->notify.option);
6010 Printer->notify.client_connected = false;
6015 /****************************************************************
6017 ****************************************************************/
6019 WERROR _spoolss_AddJob(pipes_struct *p,
6020 struct spoolss_AddJob *r)
6022 if (!r->in.buffer && (r->in.offered != 0)) {
6023 return WERR_INVALID_PARAM;
6026 /* this is what a NT server returns for AddJob. AddJob must fail on
6027 * non-local printers */
6029 if (r->in.level != 1) {
6030 return WERR_UNKNOWN_LEVEL;
6033 return WERR_INVALID_PARAM;
6036 /****************************************************************************
6038 ****************************************************************************/
6040 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6041 struct spoolss_JobInfo1 *r,
6042 const print_queue_struct *queue,
6043 int position, int snum,
6044 struct spoolss_PrinterInfo2 *pinfo2)
6048 t = gmtime(&queue->time);
6050 r->job_id = queue->job;
6052 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6053 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6054 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6055 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6056 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6057 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6058 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6059 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6060 r->data_type = talloc_strdup(mem_ctx, "RAW");
6061 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6062 r->text_status = talloc_strdup(mem_ctx, "");
6063 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6065 r->status = nt_printj_status(queue->status);
6066 r->priority = queue->priority;
6067 r->position = position;
6068 r->total_pages = queue->page_count;
6069 r->pages_printed = 0; /* ??? */
6071 init_systemtime(&r->submitted, t);
6076 /****************************************************************************
6078 ****************************************************************************/
6080 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6081 struct spoolss_JobInfo2 *r,
6082 const print_queue_struct *queue,
6083 int position, int snum,
6084 struct spoolss_PrinterInfo2 *pinfo2,
6085 struct spoolss_DeviceMode *devmode)
6089 t = gmtime(&queue->time);
6091 r->job_id = queue->job;
6093 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6094 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6095 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6096 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6097 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6098 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6099 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6100 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6101 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6102 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6103 r->data_type = talloc_strdup(mem_ctx, "RAW");
6104 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6105 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6106 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6107 r->parameters = talloc_strdup(mem_ctx, "");
6108 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6109 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6110 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6112 r->devmode = devmode;
6114 r->text_status = talloc_strdup(mem_ctx, "");
6115 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6119 r->status = nt_printj_status(queue->status);
6120 r->priority = queue->priority;
6121 r->position = position;
6124 r->total_pages = queue->page_count;
6125 r->size = queue->size;
6126 init_systemtime(&r->submitted, t);
6128 r->pages_printed = 0; /* ??? */
6133 /****************************************************************************
6135 ****************************************************************************/
6137 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6138 struct spoolss_JobInfo3 *r,
6139 const print_queue_struct *queue,
6140 const print_queue_struct *next_queue,
6141 int position, int snum,
6142 struct spoolss_PrinterInfo2 *pinfo2)
6144 r->job_id = queue->job;
6147 r->next_job_id = next_queue->job;
6154 /****************************************************************************
6155 Enumjobs at level 1.
6156 ****************************************************************************/
6158 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6159 const print_queue_struct *queue,
6160 uint32_t num_queues, int snum,
6161 struct spoolss_PrinterInfo2 *pinfo2,
6162 union spoolss_JobInfo **info_p,
6165 union spoolss_JobInfo *info;
6167 WERROR result = WERR_OK;
6169 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6170 W_ERROR_HAVE_NO_MEMORY(info);
6172 *count = num_queues;
6174 for (i=0; i<*count; i++) {
6175 result = fill_job_info1(info,
6181 if (!W_ERROR_IS_OK(result)) {
6187 if (!W_ERROR_IS_OK(result)) {
6198 /****************************************************************************
6199 Enumjobs at level 2.
6200 ****************************************************************************/
6202 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6203 const print_queue_struct *queue,
6204 uint32_t num_queues, int snum,
6205 struct spoolss_PrinterInfo2 *pinfo2,
6206 union spoolss_JobInfo **info_p,
6209 union spoolss_JobInfo *info;
6211 WERROR result = WERR_OK;
6213 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6214 W_ERROR_HAVE_NO_MEMORY(info);
6216 *count = num_queues;
6218 for (i=0; i<*count; i++) {
6219 struct spoolss_DeviceMode *devmode;
6221 result = spoolss_create_default_devmode(info,
6222 pinfo2->printername,
6224 if (!W_ERROR_IS_OK(result)) {
6225 DEBUG(3, ("Can't proceed w/o a devmode!"));
6229 result = fill_job_info2(info,
6236 if (!W_ERROR_IS_OK(result)) {
6242 if (!W_ERROR_IS_OK(result)) {
6253 /****************************************************************************
6254 Enumjobs at level 3.
6255 ****************************************************************************/
6257 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6258 const print_queue_struct *queue,
6259 uint32_t num_queues, int snum,
6260 struct spoolss_PrinterInfo2 *pinfo2,
6261 union spoolss_JobInfo **info_p,
6264 union spoolss_JobInfo *info;
6266 WERROR result = WERR_OK;
6268 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6269 W_ERROR_HAVE_NO_MEMORY(info);
6271 *count = num_queues;
6273 for (i=0; i<*count; i++) {
6274 const print_queue_struct *next_queue = NULL;
6277 next_queue = &queue[i+1];
6280 result = fill_job_info3(info,
6287 if (!W_ERROR_IS_OK(result)) {
6293 if (!W_ERROR_IS_OK(result)) {
6304 /****************************************************************
6306 ****************************************************************/
6308 WERROR _spoolss_EnumJobs(pipes_struct *p,
6309 struct spoolss_EnumJobs *r)
6312 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6314 print_status_struct prt_status;
6315 print_queue_struct *queue = NULL;
6318 /* that's an [in out] buffer */
6320 if (!r->in.buffer && (r->in.offered != 0)) {
6321 return WERR_INVALID_PARAM;
6324 DEBUG(4,("_spoolss_EnumJobs\n"));
6328 *r->out.info = NULL;
6330 /* lookup the printer snum and tdb entry */
6332 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6336 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6337 lp_servicename(snum), &pinfo2);
6338 if (!W_ERROR_IS_OK(result)) {
6342 count = print_queue_status(snum, &queue, &prt_status);
6343 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6344 count, prt_status.status, prt_status.message));
6348 TALLOC_FREE(pinfo2);
6352 switch (r->in.level) {
6354 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6355 pinfo2, r->out.info, r->out.count);
6358 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6359 pinfo2, r->out.info, r->out.count);
6362 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6363 pinfo2, r->out.info, r->out.count);
6366 result = WERR_UNKNOWN_LEVEL;
6371 TALLOC_FREE(pinfo2);
6373 if (!W_ERROR_IS_OK(result)) {
6377 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6379 *r->out.info, r->in.level,
6381 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6382 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6384 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6387 /****************************************************************
6388 _spoolss_ScheduleJob
6389 ****************************************************************/
6391 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6392 struct spoolss_ScheduleJob *r)
6397 /****************************************************************
6398 ****************************************************************/
6400 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6401 const char *printer_name,
6403 struct spoolss_SetJobInfo1 *r)
6407 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6411 if (strequal(old_doc_name, r->document_name)) {
6415 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6422 /****************************************************************
6424 ****************************************************************/
6426 WERROR _spoolss_SetJob(pipes_struct *p,
6427 struct spoolss_SetJob *r)
6430 WERROR errcode = WERR_BADFUNC;
6432 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6436 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6437 return WERR_INVALID_PRINTER_NAME;
6440 switch (r->in.command) {
6441 case SPOOLSS_JOB_CONTROL_CANCEL:
6442 case SPOOLSS_JOB_CONTROL_DELETE:
6443 if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6447 case SPOOLSS_JOB_CONTROL_PAUSE:
6448 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6452 case SPOOLSS_JOB_CONTROL_RESTART:
6453 case SPOOLSS_JOB_CONTROL_RESUME:
6454 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6462 return WERR_UNKNOWN_LEVEL;
6465 if (!W_ERROR_IS_OK(errcode)) {
6469 if (r->in.ctr == NULL) {
6473 switch (r->in.ctr->level) {
6475 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6477 r->in.ctr->info.info1);
6483 return WERR_UNKNOWN_LEVEL;
6489 /****************************************************************************
6490 Enumerates all printer drivers by level and architecture.
6491 ****************************************************************************/
6493 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6494 struct auth_serversupplied_info *server_info,
6495 const char *servername,
6496 const char *architecture,
6498 union spoolss_DriverInfo **info_p,
6503 struct spoolss_DriverInfo8 *driver;
6504 union spoolss_DriverInfo *info = NULL;
6506 WERROR result = WERR_OK;
6507 uint32_t num_drivers;
6508 const char **drivers;
6513 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6514 result = winreg_get_driver_list(mem_ctx, server_info,
6515 architecture, version,
6516 &num_drivers, &drivers);
6517 if (!W_ERROR_IS_OK(result)) {
6520 DEBUG(4, ("we have:[%d] drivers in environment"
6521 " [%s] and version [%d]\n",
6522 num_drivers, architecture, version));
6524 if (num_drivers != 0) {
6525 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6526 union spoolss_DriverInfo,
6527 count + num_drivers);
6529 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6530 "failed to enlarge driver info buffer!\n"));
6531 result = WERR_NOMEM;
6536 for (i = 0; i < num_drivers; i++) {
6537 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6539 result = winreg_get_driver(mem_ctx, server_info,
6540 architecture, drivers[i],
6542 if (!W_ERROR_IS_OK(result)) {
6548 result = fill_printer_driver_info1(info, &info[count+i].info1,
6549 driver, servername);
6552 result = fill_printer_driver_info2(info, &info[count+i].info2,
6553 driver, servername);
6556 result = fill_printer_driver_info3(info, &info[count+i].info3,
6557 driver, servername);
6560 result = fill_printer_driver_info4(info, &info[count+i].info4,
6561 driver, servername);
6564 result = fill_printer_driver_info5(info, &info[count+i].info5,
6565 driver, servername);
6568 result = fill_printer_driver_info6(info, &info[count+i].info6,
6569 driver, servername);
6572 result = fill_printer_driver_info8(info, &info[count+i].info8,
6573 driver, servername);
6576 result = WERR_UNKNOWN_LEVEL;
6580 TALLOC_FREE(driver);
6582 if (!W_ERROR_IS_OK(result)) {
6587 count += num_drivers;
6588 TALLOC_FREE(drivers);
6592 TALLOC_FREE(drivers);
6594 if (!W_ERROR_IS_OK(result)) {
6605 /****************************************************************************
6606 Enumerates all printer drivers by level.
6607 ****************************************************************************/
6609 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6610 struct auth_serversupplied_info *server_info,
6611 const char *servername,
6612 const char *architecture,
6614 union spoolss_DriverInfo **info_p,
6618 WERROR result = WERR_OK;
6620 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6622 for (a=0; archi_table[a].long_archi != NULL; a++) {
6624 union spoolss_DriverInfo *info = NULL;
6627 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6630 archi_table[a].long_archi,
6634 if (!W_ERROR_IS_OK(result)) {
6638 for (i=0; i < count; i++) {
6639 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6640 info[i], info_p, count_p);
6647 return enumprinterdrivers_level_by_architecture(mem_ctx,
6656 /****************************************************************
6657 _spoolss_EnumPrinterDrivers
6658 ****************************************************************/
6660 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6661 struct spoolss_EnumPrinterDrivers *r)
6663 const char *cservername;
6666 /* that's an [in out] buffer */
6668 if (!r->in.buffer && (r->in.offered != 0)) {
6669 return WERR_INVALID_PARAM;
6672 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6676 *r->out.info = NULL;
6678 cservername = canon_servername(r->in.server);
6680 if (!is_myname_or_ipaddr(cservername)) {
6681 return WERR_UNKNOWN_PRINTER_DRIVER;
6684 result = enumprinterdrivers_level(p->mem_ctx,
6691 if (!W_ERROR_IS_OK(result)) {
6695 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6696 spoolss_EnumPrinterDrivers,
6697 *r->out.info, r->in.level,
6699 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6700 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6702 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6705 /****************************************************************
6707 ****************************************************************/
6709 WERROR _spoolss_EnumForms(pipes_struct *p,
6710 struct spoolss_EnumForms *r)
6716 *r->out.info = NULL;
6718 /* that's an [in out] buffer */
6720 if (!r->in.buffer && (r->in.offered != 0) ) {
6721 return WERR_INVALID_PARAM;
6724 DEBUG(4,("_spoolss_EnumForms\n"));
6725 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6726 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6728 switch (r->in.level) {
6730 result = winreg_printer_enumforms1(p->mem_ctx,
6736 result = WERR_UNKNOWN_LEVEL;
6740 if (!W_ERROR_IS_OK(result)) {
6744 if (*r->out.count == 0) {
6745 return WERR_NO_MORE_ITEMS;
6748 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6750 *r->out.info, r->in.level,
6752 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6753 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6755 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6758 /****************************************************************
6760 ****************************************************************/
6762 WERROR _spoolss_GetForm(pipes_struct *p,
6763 struct spoolss_GetForm *r)
6767 /* that's an [in out] buffer */
6769 if (!r->in.buffer && (r->in.offered != 0)) {
6770 return WERR_INVALID_PARAM;
6773 DEBUG(4,("_spoolss_GetForm\n"));
6774 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6775 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6777 switch (r->in.level) {
6779 result = winreg_printer_getform1(p->mem_ctx,
6782 &r->out.info->info1);
6785 result = WERR_UNKNOWN_LEVEL;
6789 if (!W_ERROR_IS_OK(result)) {
6790 TALLOC_FREE(r->out.info);
6794 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6795 r->out.info, r->in.level);
6796 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6798 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6801 /****************************************************************************
6802 ****************************************************************************/
6804 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6805 struct spoolss_PortInfo1 *r,
6808 r->port_name = talloc_strdup(mem_ctx, name);
6809 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6814 /****************************************************************************
6815 TODO: This probably needs distinguish between TCP/IP and Local ports
6817 ****************************************************************************/
6819 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6820 struct spoolss_PortInfo2 *r,
6823 r->port_name = talloc_strdup(mem_ctx, name);
6824 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6826 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6827 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6829 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6830 W_ERROR_HAVE_NO_MEMORY(r->description);
6832 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6839 /****************************************************************************
6840 wrapper around the enumer ports command
6841 ****************************************************************************/
6843 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6845 char *cmd = lp_enumports_cmd();
6846 char **qlines = NULL;
6847 char *command = NULL;
6855 /* if no hook then just fill in the default port */
6858 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
6861 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
6862 TALLOC_FREE(qlines);
6869 /* we have a valid enumport command */
6871 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
6876 DEBUG(10,("Running [%s]\n", command));
6877 ret = smbrun(command, &fd);
6878 DEBUG(10,("Returned [%d]\n", ret));
6879 TALLOC_FREE(command);
6884 return WERR_ACCESS_DENIED;
6888 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6889 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6899 /****************************************************************************
6901 ****************************************************************************/
6903 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
6904 union spoolss_PortInfo **info_p,
6907 union spoolss_PortInfo *info = NULL;
6909 WERROR result = WERR_OK;
6910 char **qlines = NULL;
6913 result = enumports_hook(talloc_tos(), &numlines, &qlines );
6914 if (!W_ERROR_IS_OK(result)) {
6919 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
6921 DEBUG(10,("Returning WERR_NOMEM\n"));
6922 result = WERR_NOMEM;
6926 for (i=0; i<numlines; i++) {
6927 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
6928 result = fill_port_1(info, &info[i].info1, qlines[i]);
6929 if (!W_ERROR_IS_OK(result)) {
6934 TALLOC_FREE(qlines);
6937 if (!W_ERROR_IS_OK(result)) {
6939 TALLOC_FREE(qlines);
6951 /****************************************************************************
6953 ****************************************************************************/
6955 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
6956 union spoolss_PortInfo **info_p,
6959 union spoolss_PortInfo *info = NULL;
6961 WERROR result = WERR_OK;
6962 char **qlines = NULL;
6965 result = enumports_hook(talloc_tos(), &numlines, &qlines );
6966 if (!W_ERROR_IS_OK(result)) {
6971 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
6973 DEBUG(10,("Returning WERR_NOMEM\n"));
6974 result = WERR_NOMEM;
6978 for (i=0; i<numlines; i++) {
6979 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
6980 result = fill_port_2(info, &info[i].info2, qlines[i]);
6981 if (!W_ERROR_IS_OK(result)) {
6986 TALLOC_FREE(qlines);
6989 if (!W_ERROR_IS_OK(result)) {
6991 TALLOC_FREE(qlines);
7003 /****************************************************************
7005 ****************************************************************/
7007 WERROR _spoolss_EnumPorts(pipes_struct *p,
7008 struct spoolss_EnumPorts *r)
7012 /* that's an [in out] buffer */
7014 if (!r->in.buffer && (r->in.offered != 0)) {
7015 return WERR_INVALID_PARAM;
7018 DEBUG(4,("_spoolss_EnumPorts\n"));
7022 *r->out.info = NULL;
7024 switch (r->in.level) {
7026 result = enumports_level_1(p->mem_ctx, r->out.info,
7030 result = enumports_level_2(p->mem_ctx, r->out.info,
7034 return WERR_UNKNOWN_LEVEL;
7037 if (!W_ERROR_IS_OK(result)) {
7041 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7043 *r->out.info, r->in.level,
7045 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7046 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7048 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7051 /****************************************************************************
7052 ****************************************************************************/
7054 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7056 struct spoolss_SetPrinterInfoCtr *info_ctr,
7057 struct spoolss_DeviceMode *devmode,
7058 struct security_descriptor *secdesc,
7059 struct spoolss_UserLevelCtr *user_ctr,
7060 struct policy_handle *handle)
7062 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7063 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7065 WERROR err = WERR_OK;
7067 /* samba does not have a concept of local, non-shared printers yet, so
7068 * make sure we always setup sharename - gd */
7069 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7070 (info2->printername != NULL && info2->printername[0] != '\0')) {
7071 DEBUG(5, ("spoolss_addprinterex_level_2: "
7072 "no sharename has been set, setting printername %s as sharename\n",
7073 info2->printername));
7074 info2->sharename = info2->printername;
7077 /* check to see if the printer already exists */
7078 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7079 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7081 return WERR_PRINTER_ALREADY_EXISTS;
7084 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7085 if ((snum = print_queue_snum(info2->printername)) != -1) {
7086 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7087 info2->printername));
7088 return WERR_PRINTER_ALREADY_EXISTS;
7092 /* validate printer info struct */
7093 if (!info2->printername || strlen(info2->printername) == 0) {
7094 return WERR_INVALID_PRINTER_NAME;
7096 if (!info2->portname || strlen(info2->portname) == 0) {
7097 return WERR_UNKNOWN_PORT;
7099 if (!info2->drivername || strlen(info2->drivername) == 0) {
7100 return WERR_UNKNOWN_PRINTER_DRIVER;
7102 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7103 return WERR_UNKNOWN_PRINTPROCESSOR;
7106 /* FIXME!!! smbd should check to see if the driver is installed before
7107 trying to add a printer like this --jerry */
7109 if (*lp_addprinter_cmd() ) {
7110 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7112 return WERR_ACCESS_DENIED;
7115 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7116 "smb.conf parameter \"addprinter command\" is defined. This"
7117 "parameter must exist for this call to succeed\n",
7118 info2->sharename ));
7121 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7122 return WERR_ACCESS_DENIED;
7125 /* you must be a printer admin to add a new printer */
7126 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7127 return WERR_ACCESS_DENIED;
7131 * Do sanity check on the requested changes for Samba.
7134 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7135 return WERR_INVALID_PARAM;
7138 if (devmode == NULL) {
7139 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7142 err = winreg_update_printer(p->mem_ctx,
7149 if (!W_ERROR_IS_OK(err)) {
7153 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7154 /* Handle open failed - remove addition. */
7155 ZERO_STRUCTP(handle);
7156 return WERR_ACCESS_DENIED;
7162 /****************************************************************
7163 _spoolss_AddPrinterEx
7164 ****************************************************************/
7166 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7167 struct spoolss_AddPrinterEx *r)
7169 switch (r->in.info_ctr->level) {
7171 /* we don't handle yet */
7172 /* but I know what to do ... */
7173 return WERR_UNKNOWN_LEVEL;
7175 return spoolss_addprinterex_level_2(p, r->in.server,
7177 r->in.devmode_ctr->devmode,
7178 r->in.secdesc_ctr->sd,
7179 r->in.userlevel_ctr,
7182 return WERR_UNKNOWN_LEVEL;
7186 /****************************************************************
7188 ****************************************************************/
7190 WERROR _spoolss_AddPrinter(pipes_struct *p,
7191 struct spoolss_AddPrinter *r)
7193 struct spoolss_AddPrinterEx a;
7194 struct spoolss_UserLevelCtr userlevel_ctr;
7196 ZERO_STRUCT(userlevel_ctr);
7198 userlevel_ctr.level = 1;
7200 a.in.server = r->in.server;
7201 a.in.info_ctr = r->in.info_ctr;
7202 a.in.devmode_ctr = r->in.devmode_ctr;
7203 a.in.secdesc_ctr = r->in.secdesc_ctr;
7204 a.in.userlevel_ctr = &userlevel_ctr;
7205 a.out.handle = r->out.handle;
7207 return _spoolss_AddPrinterEx(p, &a);
7210 /****************************************************************
7211 _spoolss_AddPrinterDriverEx
7212 ****************************************************************/
7214 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7215 struct spoolss_AddPrinterDriverEx *r)
7217 WERROR err = WERR_OK;
7218 const char *driver_name = NULL;
7223 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7224 fn = "_spoolss_AddPrinterDriver";
7226 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7227 fn = "_spoolss_AddPrinterDriverEx";
7230 return WERR_INVALID_PARAM;
7234 * we only support the semantics of AddPrinterDriver()
7235 * i.e. only copy files that are newer than existing ones
7238 if (r->in.flags == 0) {
7239 return WERR_INVALID_PARAM;
7242 if (r->in.flags != APD_COPY_NEW_FILES) {
7243 return WERR_ACCESS_DENIED;
7247 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7248 /* Clever hack from Martin Zielinski <mz@seh.de>
7249 * to allow downgrade from level 8 (Vista).
7251 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7252 r->in.info_ctr->level));
7253 return WERR_UNKNOWN_LEVEL;
7256 DEBUG(5,("Cleaning driver's information\n"));
7257 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7258 if (!W_ERROR_IS_OK(err))
7261 DEBUG(5,("Moving driver to final destination\n"));
7262 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7267 err = winreg_add_driver(p->mem_ctx, p->server_info,
7268 r->in.info_ctr, &driver_name, &version);
7269 if (!W_ERROR_IS_OK(err)) {
7274 * I think this is where he DrvUpgradePrinter() hook would be
7275 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7276 * server. Right now, we just need to send ourselves a message
7277 * to update each printer bound to this driver. --jerry
7280 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7281 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7289 /****************************************************************
7290 _spoolss_AddPrinterDriver
7291 ****************************************************************/
7293 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7294 struct spoolss_AddPrinterDriver *r)
7296 struct spoolss_AddPrinterDriverEx a;
7298 switch (r->in.info_ctr->level) {
7305 return WERR_UNKNOWN_LEVEL;
7308 a.in.servername = r->in.servername;
7309 a.in.info_ctr = r->in.info_ctr;
7310 a.in.flags = APD_COPY_NEW_FILES;
7312 return _spoolss_AddPrinterDriverEx(p, &a);
7315 /****************************************************************************
7316 ****************************************************************************/
7318 struct _spoolss_paths {
7324 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7326 static const struct _spoolss_paths spoolss_paths[]= {
7327 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7328 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7331 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7332 const char *servername,
7333 const char *environment,
7337 const char *pservername = NULL;
7338 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7339 const char *short_archi;
7343 /* environment may be empty */
7344 if (environment && strlen(environment)) {
7345 long_archi = environment;
7348 /* servername may be empty */
7349 if (servername && strlen(servername)) {
7350 pservername = canon_servername(servername);
7352 if (!is_myname_or_ipaddr(pservername)) {
7353 return WERR_INVALID_PARAM;
7357 if (!(short_archi = get_short_archi(long_archi))) {
7358 return WERR_INVALID_ENVIRONMENT;
7361 switch (component) {
7362 case SPOOLSS_PRTPROCS_PATH:
7363 case SPOOLSS_DRIVER_PATH:
7365 *path = talloc_asprintf(mem_ctx,
7368 spoolss_paths[component].share,
7371 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7372 SPOOLSS_DEFAULT_SERVER_PATH,
7373 spoolss_paths[component].dir,
7378 return WERR_INVALID_PARAM;
7388 /****************************************************************************
7389 ****************************************************************************/
7391 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7392 const char *servername,
7393 const char *environment,
7394 struct spoolss_DriverDirectoryInfo1 *r)
7399 werr = compose_spoolss_server_path(mem_ctx,
7402 SPOOLSS_DRIVER_PATH,
7404 if (!W_ERROR_IS_OK(werr)) {
7408 DEBUG(4,("printer driver directory: [%s]\n", path));
7410 r->directory_name = path;
7415 /****************************************************************
7416 _spoolss_GetPrinterDriverDirectory
7417 ****************************************************************/
7419 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7420 struct spoolss_GetPrinterDriverDirectory *r)
7424 /* that's an [in out] buffer */
7426 if (!r->in.buffer && (r->in.offered != 0)) {
7427 return WERR_INVALID_PARAM;
7430 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7435 /* r->in.level is ignored */
7437 werror = getprinterdriverdir_level_1(p->mem_ctx,
7440 &r->out.info->info1);
7441 if (!W_ERROR_IS_OK(werror)) {
7442 TALLOC_FREE(r->out.info);
7446 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7447 r->out.info, r->in.level);
7448 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7450 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7453 /****************************************************************
7454 _spoolss_EnumPrinterData
7455 ****************************************************************/
7457 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7458 struct spoolss_EnumPrinterData *r)
7461 struct spoolss_EnumPrinterDataEx r2;
7463 struct spoolss_PrinterEnumValues *info, *val = NULL;
7466 r2.in.handle = r->in.handle;
7467 r2.in.key_name = "PrinterDriverData";
7469 r2.out.count = &count;
7470 r2.out.info = &info;
7471 r2.out.needed = &needed;
7473 result = _spoolss_EnumPrinterDataEx(p, &r2);
7474 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7475 r2.in.offered = needed;
7476 result = _spoolss_EnumPrinterDataEx(p, &r2);
7478 if (!W_ERROR_IS_OK(result)) {
7483 * The NT machine wants to know the biggest size of value and data
7485 * cf: MSDN EnumPrinterData remark section
7488 if (!r->in.value_offered && !r->in.data_offered) {
7489 uint32_t biggest_valuesize = 0;
7490 uint32_t biggest_datasize = 0;
7493 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7495 for (i=0; i<count; i++) {
7497 name_length = strlen(info[i].value_name);
7498 if (strlen(info[i].value_name) > biggest_valuesize) {
7499 biggest_valuesize = name_length;
7502 if (info[i].data_length > biggest_datasize) {
7503 biggest_datasize = info[i].data_length;
7506 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7510 /* the value is an UNICODE string but real_value_size is the length
7511 in bytes including the trailing 0 */
7513 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7514 *r->out.data_needed = biggest_datasize;
7516 DEBUG(6,("final values: [%d], [%d]\n",
7517 *r->out.value_needed, *r->out.data_needed));
7522 if (r->in.enum_index < count) {
7523 val = &info[r->in.enum_index];
7527 /* out_value should default to "" or else NT4 has
7528 problems unmarshalling the response */
7530 if (r->in.value_offered) {
7531 *r->out.value_needed = 1;
7532 r->out.value_name = talloc_strdup(r, "");
7533 if (!r->out.value_name) {
7537 r->out.value_name = NULL;
7538 *r->out.value_needed = 0;
7541 /* the data is counted in bytes */
7543 *r->out.data_needed = r->in.data_offered;
7545 result = WERR_NO_MORE_ITEMS;
7549 * - counted in bytes in the request
7550 * - counted in UNICODE chars in the max reply
7551 * - counted in bytes in the real size
7553 * take a pause *before* coding not *during* coding
7557 if (r->in.value_offered) {
7558 r->out.value_name = talloc_strdup(r, val->value_name);
7559 if (!r->out.value_name) {
7562 *r->out.value_needed = val->value_name_len;
7564 r->out.value_name = NULL;
7565 *r->out.value_needed = 0;
7570 *r->out.type = val->type;
7572 /* data - counted in bytes */
7575 * See the section "Dynamically Typed Query Parameters"
7579 if (r->out.data && val->data && val->data->data &&
7580 val->data_length && r->in.data_offered) {
7581 memcpy(r->out.data, val->data->data,
7582 MIN(val->data_length,r->in.data_offered));
7585 *r->out.data_needed = val->data_length;
7593 /****************************************************************
7594 _spoolss_SetPrinterData
7595 ****************************************************************/
7597 WERROR _spoolss_SetPrinterData(pipes_struct *p,
7598 struct spoolss_SetPrinterData *r)
7600 struct spoolss_SetPrinterDataEx r2;
7602 r2.in.handle = r->in.handle;
7603 r2.in.key_name = "PrinterDriverData";
7604 r2.in.value_name = r->in.value_name;
7605 r2.in.type = r->in.type;
7606 r2.in.data = r->in.data;
7607 r2.in.offered = r->in.offered;
7609 return _spoolss_SetPrinterDataEx(p, &r2);
7612 /****************************************************************
7613 _spoolss_ResetPrinter
7614 ****************************************************************/
7616 WERROR _spoolss_ResetPrinter(pipes_struct *p,
7617 struct spoolss_ResetPrinter *r)
7619 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7622 DEBUG(5,("_spoolss_ResetPrinter\n"));
7625 * All we do is to check to see if the handle and queue is valid.
7626 * This call really doesn't mean anything to us because we only
7627 * support RAW printing. --jerry
7631 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7632 OUR_HANDLE(r->in.handle)));
7636 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7640 /* blindly return success */
7644 /****************************************************************
7645 _spoolss_DeletePrinterData
7646 ****************************************************************/
7648 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7649 struct spoolss_DeletePrinterData *r)
7651 struct spoolss_DeletePrinterDataEx r2;
7653 r2.in.handle = r->in.handle;
7654 r2.in.key_name = "PrinterDriverData";
7655 r2.in.value_name = r->in.value_name;
7657 return _spoolss_DeletePrinterDataEx(p, &r2);
7660 /****************************************************************
7662 ****************************************************************/
7664 WERROR _spoolss_AddForm(pipes_struct *p,
7665 struct spoolss_AddForm *r)
7667 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7669 WERROR status = WERR_OK;
7670 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7672 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7674 DEBUG(5,("_spoolss_AddForm\n"));
7677 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7678 OUR_HANDLE(r->in.handle)));
7682 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7683 and not a printer admin, then fail */
7685 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7686 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7687 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7688 p->server_info->info3->base.domain.string,
7690 p->server_info->ptok,
7691 lp_printer_admin(snum))) {
7692 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7693 return WERR_ACCESS_DENIED;
7696 switch (form->flags) {
7697 case SPOOLSS_FORM_USER:
7698 case SPOOLSS_FORM_BUILTIN:
7699 case SPOOLSS_FORM_PRINTER:
7702 return WERR_INVALID_PARAM;
7705 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7706 if (!W_ERROR_IS_OK(status)) {
7711 * ChangeID must always be set if this is a printer
7713 if (Printer->printer_type == SPLHND_PRINTER) {
7714 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7718 status = winreg_printer_update_changeid(p->mem_ctx,
7720 lp_const_servicename(snum));
7721 if (!W_ERROR_IS_OK(status)) {
7729 /****************************************************************
7731 ****************************************************************/
7733 WERROR _spoolss_DeleteForm(pipes_struct *p,
7734 struct spoolss_DeleteForm *r)
7736 const char *form_name = r->in.form_name;
7737 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7739 WERROR status = WERR_OK;
7740 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7742 DEBUG(5,("_spoolss_DeleteForm\n"));
7745 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7746 OUR_HANDLE(r->in.handle)));
7750 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7751 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7752 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7753 p->server_info->info3->base.domain.string,
7755 p->server_info->ptok,
7756 lp_printer_admin(snum))) {
7757 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7758 return WERR_ACCESS_DENIED;
7761 status = winreg_printer_deleteform1(p->mem_ctx,
7764 if (!W_ERROR_IS_OK(status)) {
7769 * ChangeID must always be set if this is a printer
7771 if (Printer->printer_type == SPLHND_PRINTER) {
7772 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7776 status = winreg_printer_update_changeid(p->mem_ctx,
7778 lp_const_servicename(snum));
7779 if (!W_ERROR_IS_OK(status)) {
7787 /****************************************************************
7789 ****************************************************************/
7791 WERROR _spoolss_SetForm(pipes_struct *p,
7792 struct spoolss_SetForm *r)
7794 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7795 const char *form_name = r->in.form_name;
7797 WERROR status = WERR_OK;
7798 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7800 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7802 DEBUG(5,("_spoolss_SetForm\n"));
7805 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7806 OUR_HANDLE(r->in.handle)));
7810 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7811 and not a printer admin, then fail */
7813 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7814 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7815 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7816 p->server_info->info3->base.domain.string,
7818 p->server_info->ptok,
7819 lp_printer_admin(snum))) {
7820 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7821 return WERR_ACCESS_DENIED;
7824 status = winreg_printer_setform1(p->mem_ctx,
7828 if (!W_ERROR_IS_OK(status)) {
7833 * ChangeID must always be set if this is a printer
7835 if (Printer->printer_type == SPLHND_PRINTER) {
7836 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7840 status = winreg_printer_update_changeid(p->mem_ctx,
7842 lp_const_servicename(snum));
7843 if (!W_ERROR_IS_OK(status)) {
7851 /****************************************************************************
7852 fill_print_processor1
7853 ****************************************************************************/
7855 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
7856 struct spoolss_PrintProcessorInfo1 *r,
7857 const char *print_processor_name)
7859 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
7860 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
7865 /****************************************************************************
7866 enumprintprocessors level 1.
7867 ****************************************************************************/
7869 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
7870 union spoolss_PrintProcessorInfo **info_p,
7873 union spoolss_PrintProcessorInfo *info;
7876 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
7877 W_ERROR_HAVE_NO_MEMORY(info);
7881 result = fill_print_processor1(info, &info[0].info1, "winprint");
7882 if (!W_ERROR_IS_OK(result)) {
7887 if (!W_ERROR_IS_OK(result)) {
7898 /****************************************************************
7899 _spoolss_EnumPrintProcessors
7900 ****************************************************************/
7902 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
7903 struct spoolss_EnumPrintProcessors *r)
7907 /* that's an [in out] buffer */
7909 if (!r->in.buffer && (r->in.offered != 0)) {
7910 return WERR_INVALID_PARAM;
7913 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
7916 * Enumerate the print processors ...
7918 * Just reply with "winprint", to keep NT happy
7919 * and I can use my nice printer checker.
7924 *r->out.info = NULL;
7926 switch (r->in.level) {
7928 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
7932 return WERR_UNKNOWN_LEVEL;
7935 if (!W_ERROR_IS_OK(result)) {
7939 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7940 spoolss_EnumPrintProcessors,
7941 *r->out.info, r->in.level,
7943 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7944 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7946 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7949 /****************************************************************************
7950 fill_printprocdatatype1
7951 ****************************************************************************/
7953 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
7954 struct spoolss_PrintProcDataTypesInfo1 *r,
7955 const char *name_array)
7957 r->name_array = talloc_strdup(mem_ctx, name_array);
7958 W_ERROR_HAVE_NO_MEMORY(r->name_array);
7963 /****************************************************************************
7964 enumprintprocdatatypes level 1.
7965 ****************************************************************************/
7967 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
7968 union spoolss_PrintProcDataTypesInfo **info_p,
7972 union spoolss_PrintProcDataTypesInfo *info;
7974 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
7975 W_ERROR_HAVE_NO_MEMORY(info);
7979 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
7980 if (!W_ERROR_IS_OK(result)) {
7985 if (!W_ERROR_IS_OK(result)) {
7996 /****************************************************************
7997 _spoolss_EnumPrintProcDataTypes
7998 ****************************************************************/
8000 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8001 struct spoolss_EnumPrintProcDataTypes *r)
8005 /* that's an [in out] buffer */
8007 if (!r->in.buffer && (r->in.offered != 0)) {
8008 return WERR_INVALID_PARAM;
8011 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8015 *r->out.info = NULL;
8017 switch (r->in.level) {
8019 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8023 return WERR_UNKNOWN_LEVEL;
8026 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8027 spoolss_EnumPrintProcDataTypes,
8028 *r->out.info, r->in.level,
8030 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8031 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8033 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8036 /****************************************************************************
8038 ****************************************************************************/
8040 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8041 struct spoolss_MonitorInfo1 *r,
8042 const char *monitor_name)
8044 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8045 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8050 /****************************************************************************
8052 ****************************************************************************/
8054 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8055 struct spoolss_MonitorInfo2 *r,
8056 const char *monitor_name,
8057 const char *environment,
8058 const char *dll_name)
8060 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8061 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8062 r->environment = talloc_strdup(mem_ctx, environment);
8063 W_ERROR_HAVE_NO_MEMORY(r->environment);
8064 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8065 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8070 /****************************************************************************
8071 enumprintmonitors level 1.
8072 ****************************************************************************/
8074 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8075 union spoolss_MonitorInfo **info_p,
8078 union spoolss_MonitorInfo *info;
8079 WERROR result = WERR_OK;
8081 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8082 W_ERROR_HAVE_NO_MEMORY(info);
8086 result = fill_monitor_1(info, &info[0].info1,
8088 if (!W_ERROR_IS_OK(result)) {
8092 result = fill_monitor_1(info, &info[1].info1,
8094 if (!W_ERROR_IS_OK(result)) {
8099 if (!W_ERROR_IS_OK(result)) {
8110 /****************************************************************************
8111 enumprintmonitors level 2.
8112 ****************************************************************************/
8114 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8115 union spoolss_MonitorInfo **info_p,
8118 union spoolss_MonitorInfo *info;
8119 WERROR result = WERR_OK;
8121 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8122 W_ERROR_HAVE_NO_MEMORY(info);
8126 result = fill_monitor_2(info, &info[0].info2,
8128 "Windows NT X86", /* FIXME */
8130 if (!W_ERROR_IS_OK(result)) {
8134 result = fill_monitor_2(info, &info[1].info2,
8136 "Windows NT X86", /* FIXME */
8138 if (!W_ERROR_IS_OK(result)) {
8143 if (!W_ERROR_IS_OK(result)) {
8154 /****************************************************************
8155 _spoolss_EnumMonitors
8156 ****************************************************************/
8158 WERROR _spoolss_EnumMonitors(pipes_struct *p,
8159 struct spoolss_EnumMonitors *r)
8163 /* that's an [in out] buffer */
8165 if (!r->in.buffer && (r->in.offered != 0)) {
8166 return WERR_INVALID_PARAM;
8169 DEBUG(5,("_spoolss_EnumMonitors\n"));
8172 * Enumerate the print monitors ...
8174 * Just reply with "Local Port", to keep NT happy
8175 * and I can use my nice printer checker.
8180 *r->out.info = NULL;
8182 switch (r->in.level) {
8184 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8188 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8192 return WERR_UNKNOWN_LEVEL;
8195 if (!W_ERROR_IS_OK(result)) {
8199 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8200 spoolss_EnumMonitors,
8201 *r->out.info, r->in.level,
8203 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8204 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8206 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8209 /****************************************************************************
8210 ****************************************************************************/
8212 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8213 const print_queue_struct *queue,
8214 int count, int snum,
8215 struct spoolss_PrinterInfo2 *pinfo2,
8217 struct spoolss_JobInfo1 *r)
8222 for (i=0; i<count; i++) {
8223 if (queue[i].job == (int)jobid) {
8229 if (found == false) {
8230 /* NT treats not found as bad param... yet another bad choice */
8231 return WERR_INVALID_PARAM;
8234 return fill_job_info1(mem_ctx,
8242 /****************************************************************************
8243 ****************************************************************************/
8245 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8246 const print_queue_struct *queue,
8247 int count, int snum,
8248 struct spoolss_PrinterInfo2 *pinfo2,
8250 struct spoolss_JobInfo2 *r)
8254 struct spoolss_DeviceMode *devmode;
8257 for (i=0; i<count; i++) {
8258 if (queue[i].job == (int)jobid) {
8264 if (found == false) {
8265 /* NT treats not found as bad param... yet another bad
8267 return WERR_INVALID_PARAM;
8271 * if the print job does not have a DEVMODE associated with it,
8272 * just use the one for the printer. A NULL devicemode is not
8273 * a failure condition
8276 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8278 result = spoolss_create_default_devmode(mem_ctx,
8279 pinfo2->printername,
8281 if (!W_ERROR_IS_OK(result)) {
8282 DEBUG(3, ("Can't proceed w/o a devmode!"));
8287 return fill_job_info2(mem_ctx,
8296 /****************************************************************
8298 ****************************************************************/
8300 WERROR _spoolss_GetJob(pipes_struct *p,
8301 struct spoolss_GetJob *r)
8303 WERROR result = WERR_OK;
8304 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8307 print_queue_struct *queue = NULL;
8308 print_status_struct prt_status;
8310 /* that's an [in out] buffer */
8312 if (!r->in.buffer && (r->in.offered != 0)) {
8313 return WERR_INVALID_PARAM;
8316 DEBUG(5,("_spoolss_GetJob\n"));
8320 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8324 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8325 lp_servicename(snum), &pinfo2);
8326 if (!W_ERROR_IS_OK(result)) {
8330 count = print_queue_status(snum, &queue, &prt_status);
8332 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8333 count, prt_status.status, prt_status.message));
8335 switch (r->in.level) {
8337 result = getjob_level_1(p->mem_ctx,
8338 queue, count, snum, pinfo2,
8339 r->in.job_id, &r->out.info->info1);
8342 result = getjob_level_2(p->mem_ctx,
8343 queue, count, snum, pinfo2,
8344 r->in.job_id, &r->out.info->info2);
8347 result = WERR_UNKNOWN_LEVEL;
8352 TALLOC_FREE(pinfo2);
8354 if (!W_ERROR_IS_OK(result)) {
8355 TALLOC_FREE(r->out.info);
8359 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8361 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8363 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8366 /****************************************************************
8367 _spoolss_GetPrinterDataEx
8368 ****************************************************************/
8370 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8371 struct spoolss_GetPrinterDataEx *r)
8374 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8375 const char *printer;
8377 WERROR result = WERR_OK;
8379 enum winreg_Type val_type;
8384 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8386 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8387 r->in.key_name, r->in.value_name));
8389 /* in case of problem, return some default values */
8392 *r->out.type = REG_NONE;
8395 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8396 OUR_HANDLE(r->in.handle)));
8397 result = WERR_BADFID;
8401 /* Is the handle to a printer or to the server? */
8403 if (Printer->printer_type == SPLHND_SERVER) {
8405 union spoolss_PrinterData data;
8407 result = getprinterdata_printer_server(p->mem_ctx,
8411 if (!W_ERROR_IS_OK(result)) {
8415 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8416 *r->out.type, &data);
8417 if (!W_ERROR_IS_OK(result)) {
8421 *r->out.needed = blob.length;
8423 if (r->in.offered >= *r->out.needed) {
8424 memcpy(r->out.data, blob.data, blob.length);
8427 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8430 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8433 printer = lp_const_servicename(snum);
8435 /* check to see if the keyname is valid */
8436 if (!strlen(r->in.key_name)) {
8437 return WERR_INVALID_PARAM;
8440 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8441 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8442 strequal(r->in.value_name, "ChangeId")) {
8443 *r->out.type = REG_DWORD;
8445 if (r->in.offered >= *r->out.needed) {
8446 uint32_t changeid = 0;
8448 result = winreg_printer_get_changeid(p->mem_ctx,
8452 if (!W_ERROR_IS_OK(result)) {
8456 SIVAL(r->out.data, 0, changeid);
8462 result = winreg_get_printer_dataex(p->mem_ctx,
8470 if (!W_ERROR_IS_OK(result)) {
8474 *r->out.needed = val_size;
8475 *r->out.type = val_type;
8477 if (r->in.offered >= *r->out.needed) {
8478 memcpy(r->out.data, val_data, val_size);
8482 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8483 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8485 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8488 /****************************************************************
8489 _spoolss_SetPrinterDataEx
8490 ****************************************************************/
8492 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8493 struct spoolss_SetPrinterDataEx *r)
8495 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8497 WERROR result = WERR_OK;
8498 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8501 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8503 /* From MSDN documentation of SetPrinterDataEx: pass request to
8504 SetPrinterData if key is "PrinterDriverData" */
8507 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8508 OUR_HANDLE(r->in.handle)));
8512 if (Printer->printer_type == SPLHND_SERVER) {
8513 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8514 "Not implemented for server handles yet\n"));
8515 return WERR_INVALID_PARAM;
8518 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8523 * Access check : NT returns "access denied" if you make a
8524 * SetPrinterData call without the necessary privildge.
8525 * we were originally returning OK if nothing changed
8526 * which made Win2k issue **a lot** of SetPrinterData
8527 * when connecting to a printer --jerry
8530 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8531 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8532 "change denied by handle access permissions\n"));
8533 return WERR_ACCESS_DENIED;
8536 result = winreg_get_printer(Printer, p->server_info,
8537 Printer->servername,
8538 lp_servicename(snum),
8540 if (!W_ERROR_IS_OK(result)) {
8544 /* check for OID in valuename */
8546 oid_string = strchr(r->in.value_name, ',');
8552 /* save the registry data */
8554 result = winreg_set_printer_dataex(p->mem_ctx,
8563 if (W_ERROR_IS_OK(result)) {
8564 /* save the OID if one was specified */
8566 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8567 r->in.key_name, SPOOL_OID_KEY);
8569 result = WERR_NOMEM;
8574 * I'm not checking the status here on purpose. Don't know
8575 * if this is right, but I'm returning the status from the
8576 * previous set_printer_dataex() call. I have no idea if
8577 * this is right. --jerry
8579 winreg_set_printer_dataex(p->mem_ctx,
8585 (uint8_t *) oid_string,
8586 strlen(oid_string) + 1);
8589 result = winreg_printer_update_changeid(p->mem_ctx,
8591 lp_const_servicename(snum));
8596 talloc_free(pinfo2);
8600 /****************************************************************
8601 _spoolss_DeletePrinterDataEx
8602 ****************************************************************/
8604 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8605 struct spoolss_DeletePrinterDataEx *r)
8607 const char *printer;
8609 WERROR status = WERR_OK;
8610 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8612 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8615 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8616 "Invalid handle (%s:%u:%u).\n",
8617 OUR_HANDLE(r->in.handle)));
8621 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8622 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8623 "printer properties change denied by handle\n"));
8624 return WERR_ACCESS_DENIED;
8627 if (!r->in.value_name || !r->in.key_name) {
8631 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8634 printer = lp_const_servicename(snum);
8636 status = winreg_delete_printer_dataex(p->mem_ctx,
8641 if (W_ERROR_IS_OK(status)) {
8642 status = winreg_printer_update_changeid(p->mem_ctx,
8650 /****************************************************************
8651 _spoolss_EnumPrinterKey
8652 ****************************************************************/
8654 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
8655 struct spoolss_EnumPrinterKey *r)
8658 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8660 WERROR result = WERR_BADFILE;
8661 const char **array = NULL;
8664 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8667 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8668 OUR_HANDLE(r->in.handle)));
8672 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8676 result = winreg_enum_printer_key(p->mem_ctx,
8678 lp_const_servicename(snum),
8682 if (!W_ERROR_IS_OK(result)) {
8686 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8687 result = WERR_NOMEM;
8691 *r->out._ndr_size = r->in.offered / 2;
8692 *r->out.needed = blob.length;
8694 if (r->in.offered < *r->out.needed) {
8695 result = WERR_MORE_DATA;
8698 r->out.key_buffer->string_array = array;
8702 if (!W_ERROR_IS_OK(result)) {
8704 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8712 /****************************************************************
8713 _spoolss_DeletePrinterKey
8714 ****************************************************************/
8716 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
8717 struct spoolss_DeletePrinterKey *r)
8719 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8722 const char *printer;
8724 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8727 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8728 OUR_HANDLE(r->in.handle)));
8732 /* if keyname == NULL, return error */
8733 if ( !r->in.key_name )
8734 return WERR_INVALID_PARAM;
8736 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8740 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8741 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8742 "printer properties change denied by handle\n"));
8743 return WERR_ACCESS_DENIED;
8746 printer = lp_const_servicename(snum);
8748 /* delete the key and all subkeys */
8749 status = winreg_delete_printer_key(p->mem_ctx,
8753 if (W_ERROR_IS_OK(status)) {
8754 status = winreg_printer_update_changeid(p->mem_ctx,
8762 /****************************************************************
8763 _spoolss_EnumPrinterDataEx
8764 ****************************************************************/
8766 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
8767 struct spoolss_EnumPrinterDataEx *r)
8770 struct spoolss_PrinterEnumValues *info = NULL;
8771 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8775 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8779 *r->out.info = NULL;
8782 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8783 OUR_HANDLE(r->in.handle)));
8788 * first check for a keyname of NULL or "". Win2k seems to send
8789 * this a lot and we should send back WERR_INVALID_PARAM
8790 * no need to spend time looking up the printer in this case.
8794 if (!strlen(r->in.key_name)) {
8795 result = WERR_INVALID_PARAM;
8799 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8803 /* now look for a match on the key name */
8804 result = winreg_enum_printer_dataex(p->mem_ctx,
8806 lp_const_servicename(snum),
8810 if (!W_ERROR_IS_OK(result)) {
8814 #if 0 /* FIXME - gd */
8815 /* housekeeping information in the reply */
8817 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8818 * the hand marshalled container size is a multiple
8819 * of 4 bytes for RPC alignment.
8823 needed += 4-(needed % 4);
8826 *r->out.count = count;
8827 *r->out.info = info;
8830 if (!W_ERROR_IS_OK(result)) {
8834 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
8835 spoolss_EnumPrinterDataEx,
8838 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8839 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
8841 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8844 /****************************************************************************
8845 ****************************************************************************/
8847 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
8848 const char *servername,
8849 const char *environment,
8850 struct spoolss_PrintProcessorDirectoryInfo1 *r)
8855 werr = compose_spoolss_server_path(mem_ctx,
8858 SPOOLSS_PRTPROCS_PATH,
8860 if (!W_ERROR_IS_OK(werr)) {
8864 DEBUG(4,("print processor directory: [%s]\n", path));
8866 r->directory_name = path;
8871 /****************************************************************
8872 _spoolss_GetPrintProcessorDirectory
8873 ****************************************************************/
8875 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
8876 struct spoolss_GetPrintProcessorDirectory *r)
8880 /* that's an [in out] buffer */
8882 if (!r->in.buffer && (r->in.offered != 0)) {
8883 return WERR_INVALID_PARAM;
8886 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
8891 /* r->in.level is ignored */
8893 /* We always should reply with a local print processor directory so that
8894 * users are not forced to have a [prnproc$] share on the Samba spoolss
8895 * server - Guenther */
8897 result = getprintprocessordirectory_level_1(p->mem_ctx,
8898 NULL, /* r->in.server */
8900 &r->out.info->info1);
8901 if (!W_ERROR_IS_OK(result)) {
8902 TALLOC_FREE(r->out.info);
8906 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
8907 r->out.info, r->in.level);
8908 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8910 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8913 /*******************************************************************
8914 ********************************************************************/
8916 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
8917 const char *dllname)
8919 enum ndr_err_code ndr_err;
8920 struct spoolss_MonitorUi ui;
8922 ui.dll_name = dllname;
8924 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
8925 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
8926 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
8927 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
8929 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
8932 /*******************************************************************
8933 Streams the monitor UI DLL name in UNICODE
8934 *******************************************************************/
8936 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
8937 NT_USER_TOKEN *token, DATA_BLOB *in,
8938 DATA_BLOB *out, uint32_t *needed)
8940 const char *dllname = "tcpmonui.dll";
8942 *needed = (strlen(dllname)+1) * 2;
8944 if (out->length < *needed) {
8945 return WERR_INSUFFICIENT_BUFFER;
8948 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
8955 /*******************************************************************
8956 ********************************************************************/
8958 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
8959 struct spoolss_PortData1 *port1,
8960 const DATA_BLOB *buf)
8962 enum ndr_err_code ndr_err;
8963 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
8964 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
8965 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
8966 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
8968 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
8971 /*******************************************************************
8972 ********************************************************************/
8974 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
8975 struct spoolss_PortData2 *port2,
8976 const DATA_BLOB *buf)
8978 enum ndr_err_code ndr_err;
8979 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
8980 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
8981 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
8982 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
8984 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
8987 /*******************************************************************
8988 Create a new TCP/IP port
8989 *******************************************************************/
8991 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
8992 NT_USER_TOKEN *token, DATA_BLOB *in,
8993 DATA_BLOB *out, uint32_t *needed)
8995 struct spoolss_PortData1 port1;
8996 struct spoolss_PortData2 port2;
8997 char *device_uri = NULL;
9000 const char *portname;
9001 const char *hostaddress;
9003 uint32_t port_number;
9006 /* peek for spoolss_PortData version */
9008 if (!in || (in->length < (128 + 4))) {
9009 return WERR_GENERAL_FAILURE;
9012 version = IVAL(in->data, 128);
9018 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9022 portname = port1.portname;
9023 hostaddress = port1.hostaddress;
9024 queue = port1.queue;
9025 protocol = port1.protocol;
9026 port_number = port1.port_number;
9032 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9036 portname = port2.portname;
9037 hostaddress = port2.hostaddress;
9038 queue = port2.queue;
9039 protocol = port2.protocol;
9040 port_number = port2.port_number;
9044 DEBUG(1,("xcvtcp_addport: "
9045 "unknown version of port_data: %d\n", version));
9046 return WERR_UNKNOWN_PORT;
9049 /* create the device URI and call the add_port_hook() */
9052 case PROTOCOL_RAWTCP_TYPE:
9053 device_uri = talloc_asprintf(mem_ctx,
9054 "socket://%s:%d/", hostaddress,
9058 case PROTOCOL_LPR_TYPE:
9059 device_uri = talloc_asprintf(mem_ctx,
9060 "lpr://%s/%s", hostaddress, queue );
9064 return WERR_UNKNOWN_PORT;
9071 return add_port_hook(mem_ctx, token, portname, device_uri);
9074 /*******************************************************************
9075 *******************************************************************/
9077 struct xcv_api_table xcvtcp_cmds[] = {
9078 { "MonitorUI", xcvtcp_monitorui },
9079 { "AddPort", xcvtcp_addport},
9083 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9084 NT_USER_TOKEN *token, const char *command,
9091 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9093 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9094 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9095 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9098 return WERR_BADFUNC;
9101 /*******************************************************************
9102 *******************************************************************/
9103 #if 0 /* don't support management using the "Local Port" monitor */
9105 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9106 NT_USER_TOKEN *token, DATA_BLOB *in,
9107 DATA_BLOB *out, uint32_t *needed)
9109 const char *dllname = "localui.dll";
9111 *needed = (strlen(dllname)+1) * 2;
9113 if (out->length < *needed) {
9114 return WERR_INSUFFICIENT_BUFFER;
9117 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9124 /*******************************************************************
9125 *******************************************************************/
9127 struct xcv_api_table xcvlocal_cmds[] = {
9128 { "MonitorUI", xcvlocal_monitorui },
9132 struct xcv_api_table xcvlocal_cmds[] = {
9139 /*******************************************************************
9140 *******************************************************************/
9142 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9143 NT_USER_TOKEN *token, const char *command,
9144 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9149 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9151 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9152 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9153 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9155 return WERR_BADFUNC;
9158 /****************************************************************
9160 ****************************************************************/
9162 WERROR _spoolss_XcvData(pipes_struct *p,
9163 struct spoolss_XcvData *r)
9165 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9166 DATA_BLOB out_data = data_blob_null;
9170 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9171 OUR_HANDLE(r->in.handle)));
9175 /* Has to be a handle to the TCP/IP port monitor */
9177 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9178 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9182 /* requires administrative access to the server */
9184 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9185 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9186 return WERR_ACCESS_DENIED;
9189 /* Allocate the outgoing buffer */
9191 if (r->in.out_data_size) {
9192 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9193 if (out_data.data == NULL) {
9198 switch ( Printer->printer_type ) {
9199 case SPLHND_PORTMON_TCP:
9200 werror = process_xcvtcp_command(p->mem_ctx,
9201 p->server_info->ptok,
9202 r->in.function_name,
9203 &r->in.in_data, &out_data,
9206 case SPLHND_PORTMON_LOCAL:
9207 werror = process_xcvlocal_command(p->mem_ctx,
9208 p->server_info->ptok,
9209 r->in.function_name,
9210 &r->in.in_data, &out_data,
9214 werror = WERR_INVALID_PRINT_MONITOR;
9217 if (!W_ERROR_IS_OK(werror)) {
9221 *r->out.status_code = 0;
9223 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9224 memcpy(r->out.out_data, out_data.data,
9225 MIN(r->in.out_data_size, out_data.length));
9231 /****************************************************************
9232 _spoolss_AddPrintProcessor
9233 ****************************************************************/
9235 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9236 struct spoolss_AddPrintProcessor *r)
9238 /* for now, just indicate success and ignore the add. We'll
9239 automatically set the winprint processor for printer
9240 entries later. Used to debug the LexMark Optra S 1855 PCL
9246 /****************************************************************
9248 ****************************************************************/
9250 WERROR _spoolss_AddPort(pipes_struct *p,
9251 struct spoolss_AddPort *r)
9253 /* do what w2k3 does */
9255 return WERR_NOT_SUPPORTED;
9258 /****************************************************************
9259 _spoolss_GetPrinterDriver
9260 ****************************************************************/
9262 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9263 struct spoolss_GetPrinterDriver *r)
9265 p->rng_fault_state = true;
9266 return WERR_NOT_SUPPORTED;
9269 /****************************************************************
9270 _spoolss_ReadPrinter
9271 ****************************************************************/
9273 WERROR _spoolss_ReadPrinter(pipes_struct *p,
9274 struct spoolss_ReadPrinter *r)
9276 p->rng_fault_state = true;
9277 return WERR_NOT_SUPPORTED;
9280 /****************************************************************
9281 _spoolss_WaitForPrinterChange
9282 ****************************************************************/
9284 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9285 struct spoolss_WaitForPrinterChange *r)
9287 p->rng_fault_state = true;
9288 return WERR_NOT_SUPPORTED;
9291 /****************************************************************
9292 _spoolss_ConfigurePort
9293 ****************************************************************/
9295 WERROR _spoolss_ConfigurePort(pipes_struct *p,
9296 struct spoolss_ConfigurePort *r)
9298 p->rng_fault_state = true;
9299 return WERR_NOT_SUPPORTED;
9302 /****************************************************************
9304 ****************************************************************/
9306 WERROR _spoolss_DeletePort(pipes_struct *p,
9307 struct spoolss_DeletePort *r)
9309 p->rng_fault_state = true;
9310 return WERR_NOT_SUPPORTED;
9313 /****************************************************************
9314 _spoolss_CreatePrinterIC
9315 ****************************************************************/
9317 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9318 struct spoolss_CreatePrinterIC *r)
9320 p->rng_fault_state = true;
9321 return WERR_NOT_SUPPORTED;
9324 /****************************************************************
9325 _spoolss_PlayGDIScriptOnPrinterIC
9326 ****************************************************************/
9328 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9329 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9331 p->rng_fault_state = true;
9332 return WERR_NOT_SUPPORTED;
9335 /****************************************************************
9336 _spoolss_DeletePrinterIC
9337 ****************************************************************/
9339 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9340 struct spoolss_DeletePrinterIC *r)
9342 p->rng_fault_state = true;
9343 return WERR_NOT_SUPPORTED;
9346 /****************************************************************
9347 _spoolss_AddPrinterConnection
9348 ****************************************************************/
9350 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9351 struct spoolss_AddPrinterConnection *r)
9353 p->rng_fault_state = true;
9354 return WERR_NOT_SUPPORTED;
9357 /****************************************************************
9358 _spoolss_DeletePrinterConnection
9359 ****************************************************************/
9361 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9362 struct spoolss_DeletePrinterConnection *r)
9364 p->rng_fault_state = true;
9365 return WERR_NOT_SUPPORTED;
9368 /****************************************************************
9369 _spoolss_PrinterMessageBox
9370 ****************************************************************/
9372 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9373 struct spoolss_PrinterMessageBox *r)
9375 p->rng_fault_state = true;
9376 return WERR_NOT_SUPPORTED;
9379 /****************************************************************
9381 ****************************************************************/
9383 WERROR _spoolss_AddMonitor(pipes_struct *p,
9384 struct spoolss_AddMonitor *r)
9386 p->rng_fault_state = true;
9387 return WERR_NOT_SUPPORTED;
9390 /****************************************************************
9391 _spoolss_DeleteMonitor
9392 ****************************************************************/
9394 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9395 struct spoolss_DeleteMonitor *r)
9397 p->rng_fault_state = true;
9398 return WERR_NOT_SUPPORTED;
9401 /****************************************************************
9402 _spoolss_DeletePrintProcessor
9403 ****************************************************************/
9405 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9406 struct spoolss_DeletePrintProcessor *r)
9408 p->rng_fault_state = true;
9409 return WERR_NOT_SUPPORTED;
9412 /****************************************************************
9413 _spoolss_AddPrintProvidor
9414 ****************************************************************/
9416 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9417 struct spoolss_AddPrintProvidor *r)
9419 p->rng_fault_state = true;
9420 return WERR_NOT_SUPPORTED;
9423 /****************************************************************
9424 _spoolss_DeletePrintProvidor
9425 ****************************************************************/
9427 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9428 struct spoolss_DeletePrintProvidor *r)
9430 p->rng_fault_state = true;
9431 return WERR_NOT_SUPPORTED;
9434 /****************************************************************
9435 _spoolss_FindFirstPrinterChangeNotification
9436 ****************************************************************/
9438 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9439 struct spoolss_FindFirstPrinterChangeNotification *r)
9441 p->rng_fault_state = true;
9442 return WERR_NOT_SUPPORTED;
9445 /****************************************************************
9446 _spoolss_FindNextPrinterChangeNotification
9447 ****************************************************************/
9449 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9450 struct spoolss_FindNextPrinterChangeNotification *r)
9452 p->rng_fault_state = true;
9453 return WERR_NOT_SUPPORTED;
9456 /****************************************************************
9457 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9458 ****************************************************************/
9460 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9461 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9463 p->rng_fault_state = true;
9464 return WERR_NOT_SUPPORTED;
9467 /****************************************************************
9468 _spoolss_ReplyOpenPrinter
9469 ****************************************************************/
9471 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9472 struct spoolss_ReplyOpenPrinter *r)
9474 p->rng_fault_state = true;
9475 return WERR_NOT_SUPPORTED;
9478 /****************************************************************
9479 _spoolss_RouterReplyPrinter
9480 ****************************************************************/
9482 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9483 struct spoolss_RouterReplyPrinter *r)
9485 p->rng_fault_state = true;
9486 return WERR_NOT_SUPPORTED;
9489 /****************************************************************
9490 _spoolss_ReplyClosePrinter
9491 ****************************************************************/
9493 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9494 struct spoolss_ReplyClosePrinter *r)
9496 p->rng_fault_state = true;
9497 return WERR_NOT_SUPPORTED;
9500 /****************************************************************
9502 ****************************************************************/
9504 WERROR _spoolss_AddPortEx(pipes_struct *p,
9505 struct spoolss_AddPortEx *r)
9507 p->rng_fault_state = true;
9508 return WERR_NOT_SUPPORTED;
9511 /****************************************************************
9512 _spoolss_RouterFindFirstPrinterChangeNotification
9513 ****************************************************************/
9515 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9516 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9518 p->rng_fault_state = true;
9519 return WERR_NOT_SUPPORTED;
9522 /****************************************************************
9523 _spoolss_SpoolerInit
9524 ****************************************************************/
9526 WERROR _spoolss_SpoolerInit(pipes_struct *p,
9527 struct spoolss_SpoolerInit *r)
9529 p->rng_fault_state = true;
9530 return WERR_NOT_SUPPORTED;
9533 /****************************************************************
9534 _spoolss_ResetPrinterEx
9535 ****************************************************************/
9537 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
9538 struct spoolss_ResetPrinterEx *r)
9540 p->rng_fault_state = true;
9541 return WERR_NOT_SUPPORTED;
9544 /****************************************************************
9545 _spoolss_RouterReplyPrinterEx
9546 ****************************************************************/
9548 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
9549 struct spoolss_RouterReplyPrinterEx *r)
9551 p->rng_fault_state = true;
9552 return WERR_NOT_SUPPORTED;
9555 /****************************************************************
9557 ****************************************************************/
9559 WERROR _spoolss_44(pipes_struct *p,
9560 struct spoolss_44 *r)
9562 p->rng_fault_state = true;
9563 return WERR_NOT_SUPPORTED;
9566 /****************************************************************
9568 ****************************************************************/
9570 WERROR _spoolss_47(pipes_struct *p,
9571 struct spoolss_47 *r)
9573 p->rng_fault_state = true;
9574 return WERR_NOT_SUPPORTED;
9577 /****************************************************************
9579 ****************************************************************/
9581 WERROR _spoolss_4a(pipes_struct *p,
9582 struct spoolss_4a *r)
9584 p->rng_fault_state = true;
9585 return WERR_NOT_SUPPORTED;
9588 /****************************************************************
9590 ****************************************************************/
9592 WERROR _spoolss_4b(pipes_struct *p,
9593 struct spoolss_4b *r)
9595 p->rng_fault_state = true;
9596 return WERR_NOT_SUPPORTED;
9599 /****************************************************************
9601 ****************************************************************/
9603 WERROR _spoolss_4c(pipes_struct *p,
9604 struct spoolss_4c *r)
9606 p->rng_fault_state = true;
9607 return WERR_NOT_SUPPORTED;
9610 /****************************************************************
9612 ****************************************************************/
9614 WERROR _spoolss_53(pipes_struct *p,
9615 struct spoolss_53 *r)
9617 p->rng_fault_state = true;
9618 return WERR_NOT_SUPPORTED;
9621 /****************************************************************
9623 ****************************************************************/
9625 WERROR _spoolss_55(pipes_struct *p,
9626 struct spoolss_55 *r)
9628 p->rng_fault_state = true;
9629 return WERR_NOT_SUPPORTED;
9632 /****************************************************************
9634 ****************************************************************/
9636 WERROR _spoolss_56(pipes_struct *p,
9637 struct spoolss_56 *r)
9639 p->rng_fault_state = true;
9640 return WERR_NOT_SUPPORTED;
9643 /****************************************************************
9645 ****************************************************************/
9647 WERROR _spoolss_57(pipes_struct *p,
9648 struct spoolss_57 *r)
9650 p->rng_fault_state = true;
9651 return WERR_NOT_SUPPORTED;
9654 /****************************************************************
9656 ****************************************************************/
9658 WERROR _spoolss_5a(pipes_struct *p,
9659 struct spoolss_5a *r)
9661 p->rng_fault_state = true;
9662 return WERR_NOT_SUPPORTED;
9665 /****************************************************************
9667 ****************************************************************/
9669 WERROR _spoolss_5b(pipes_struct *p,
9670 struct spoolss_5b *r)
9672 p->rng_fault_state = true;
9673 return WERR_NOT_SUPPORTED;
9676 /****************************************************************
9678 ****************************************************************/
9680 WERROR _spoolss_5c(pipes_struct *p,
9681 struct spoolss_5c *r)
9683 p->rng_fault_state = true;
9684 return WERR_NOT_SUPPORTED;
9687 /****************************************************************
9689 ****************************************************************/
9691 WERROR _spoolss_5d(pipes_struct *p,
9692 struct spoolss_5d *r)
9694 p->rng_fault_state = true;
9695 return WERR_NOT_SUPPORTED;
9698 /****************************************************************
9700 ****************************************************************/
9702 WERROR _spoolss_5e(pipes_struct *p,
9703 struct spoolss_5e *r)
9705 p->rng_fault_state = true;
9706 return WERR_NOT_SUPPORTED;
9709 /****************************************************************
9711 ****************************************************************/
9713 WERROR _spoolss_5f(pipes_struct *p,
9714 struct spoolss_5f *r)
9716 p->rng_fault_state = true;
9717 return WERR_NOT_SUPPORTED;
9720 /****************************************************************
9722 ****************************************************************/
9724 WERROR _spoolss_60(pipes_struct *p,
9725 struct spoolss_60 *r)
9727 p->rng_fault_state = true;
9728 return WERR_NOT_SUPPORTED;
9731 /****************************************************************
9733 ****************************************************************/
9735 WERROR _spoolss_61(pipes_struct *p,
9736 struct spoolss_61 *r)
9738 p->rng_fault_state = true;
9739 return WERR_NOT_SUPPORTED;
9742 /****************************************************************
9744 ****************************************************************/
9746 WERROR _spoolss_62(pipes_struct *p,
9747 struct spoolss_62 *r)
9749 p->rng_fault_state = true;
9750 return WERR_NOT_SUPPORTED;
9753 /****************************************************************
9755 ****************************************************************/
9757 WERROR _spoolss_63(pipes_struct *p,
9758 struct spoolss_63 *r)
9760 p->rng_fault_state = true;
9761 return WERR_NOT_SUPPORTED;
9764 /****************************************************************
9766 ****************************************************************/
9768 WERROR _spoolss_64(pipes_struct *p,
9769 struct spoolss_64 *r)
9771 p->rng_fault_state = true;
9772 return WERR_NOT_SUPPORTED;
9775 /****************************************************************
9777 ****************************************************************/
9779 WERROR _spoolss_65(pipes_struct *p,
9780 struct spoolss_65 *r)
9782 p->rng_fault_state = true;
9783 return WERR_NOT_SUPPORTED;
9786 /****************************************************************
9787 _spoolss_GetCorePrinterDrivers
9788 ****************************************************************/
9790 WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
9791 struct spoolss_GetCorePrinterDrivers *r)
9793 p->rng_fault_state = true;
9794 return WERR_NOT_SUPPORTED;
9797 /****************************************************************
9799 ****************************************************************/
9801 WERROR _spoolss_67(pipes_struct *p,
9802 struct spoolss_67 *r)
9804 p->rng_fault_state = true;
9805 return WERR_NOT_SUPPORTED;
9808 /****************************************************************
9809 _spoolss_GetPrinterDriverPackagePath
9810 ****************************************************************/
9812 WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
9813 struct spoolss_GetPrinterDriverPackagePath *r)
9815 p->rng_fault_state = true;
9816 return WERR_NOT_SUPPORTED;
9819 /****************************************************************
9821 ****************************************************************/
9823 WERROR _spoolss_69(pipes_struct *p,
9824 struct spoolss_69 *r)
9826 p->rng_fault_state = true;
9827 return WERR_NOT_SUPPORTED;
9830 /****************************************************************
9832 ****************************************************************/
9834 WERROR _spoolss_6a(pipes_struct *p,
9835 struct spoolss_6a *r)
9837 p->rng_fault_state = true;
9838 return WERR_NOT_SUPPORTED;
9841 /****************************************************************
9843 ****************************************************************/
9845 WERROR _spoolss_6b(pipes_struct *p,
9846 struct spoolss_6b *r)
9848 p->rng_fault_state = true;
9849 return WERR_NOT_SUPPORTED;
9852 /****************************************************************
9854 ****************************************************************/
9856 WERROR _spoolss_6c(pipes_struct *p,
9857 struct spoolss_6c *r)
9859 p->rng_fault_state = true;
9860 return WERR_NOT_SUPPORTED;
9863 /****************************************************************
9865 ****************************************************************/
9867 WERROR _spoolss_6d(pipes_struct *p,
9868 struct spoolss_6d *r)
9870 p->rng_fault_state = true;
9871 return WERR_NOT_SUPPORTED;