2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009-2010.
11 * Copyright (C) Andreas Schneider 2010.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
39 #include "registry/reg_objects.h"
40 #include "include/printing.h"
42 #include "../librpc/gen_ndr/netlogon.h"
44 /* macros stolen from s4 spoolss server */
45 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
46 ((info)?ndr_size_##fn(info, level, 0):0)
48 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
49 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
51 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
52 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
54 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
57 #define DBGC_CLASS DBGC_RPC_SRV
59 static Printer_entry *printers_list;
61 typedef struct _counter_printer_0 {
62 struct _counter_printer_0 *next;
63 struct _counter_printer_0 *prev;
69 static counter_printer_0 *counter_list;
71 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
72 static uint32_t smb_connections = 0;
75 /* Map generic permissions to printer object specific permissions */
77 const struct standard_mapping printer_std_mapping = {
84 /* Map generic permissions to print server object specific permissions */
86 const struct standard_mapping printserver_std_mapping = {
93 /* API table for Xcv Monitor functions */
95 struct xcv_api_table {
97 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
100 /********************************************************************
101 * Canonicalize servername.
102 ********************************************************************/
104 static const char *canon_servername(const char *servername)
106 const char *pservername = servername;
107 while (*pservername == '\\') {
113 /* translate between internal status numbers and NT status numbers */
114 static int nt_printj_status(int v)
120 return JOB_STATUS_PAUSED;
122 return JOB_STATUS_SPOOLING;
124 return JOB_STATUS_PRINTING;
126 return JOB_STATUS_ERROR;
128 return JOB_STATUS_DELETING;
130 return JOB_STATUS_OFFLINE;
132 return JOB_STATUS_PAPEROUT;
134 return JOB_STATUS_PRINTED;
136 return JOB_STATUS_DELETED;
138 return JOB_STATUS_BLOCKED_DEVQ;
139 case LPQ_USER_INTERVENTION:
140 return JOB_STATUS_USER_INTERVENTION;
145 static int nt_printq_status(int v)
149 return PRINTER_STATUS_PAUSED;
158 /***************************************************************************
159 Disconnect from the client
160 ****************************************************************************/
162 static void srv_spoolss_replycloseprinter(
163 int snum, struct policy_handle *handle,
164 struct messaging_context *msg_ctx)
170 * Tell the specific printing tdb we no longer want messages for this printer
171 * by deregistering our PID.
174 if (!print_notify_deregister_pid(snum))
175 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
177 /* weird if the test succeeds !!! */
178 if (smb_connections==0) {
179 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
183 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
186 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
187 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
188 win_errstr(result)));
190 /* if it's the last connection, deconnect the IPC$ share */
191 if (smb_connections==1) {
193 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
195 * The above call shuts down the pipe also.
197 notify_cli_pipe = NULL;
199 if (msg_ctx != NULL) {
200 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
204 * Tell the serverid.tdb we're no longer
205 * interested in printer notify messages.
208 serverid_register_msg_flags(
209 messaging_server_id(msg_ctx),
210 false, FLAG_MSG_PRINT_NOTIFY);
217 /****************************************************************************
218 Functions to free a printer entry datastruct.
219 ****************************************************************************/
221 static int printer_entry_destructor(Printer_entry *Printer)
223 if (Printer->notify.client_connected == true) {
226 if ( Printer->printer_type == SPLHND_SERVER) {
228 srv_spoolss_replycloseprinter(
229 snum, &Printer->notify.client_hnd,
230 Printer->notify.msg_ctx);
231 } else if (Printer->printer_type == SPLHND_PRINTER) {
232 snum = print_queue_snum(Printer->sharename);
234 srv_spoolss_replycloseprinter(
235 snum, &Printer->notify.client_hnd,
236 Printer->notify.msg_ctx);
240 Printer->notify.flags=0;
241 Printer->notify.options=0;
242 Printer->notify.localmachine[0]='\0';
243 Printer->notify.printerlocal=0;
244 TALLOC_FREE(Printer->notify.option);
245 Printer->notify.client_connected = false;
247 TALLOC_FREE(Printer->devmode);
249 /* Remove from the internal list. */
250 DLIST_REMOVE(printers_list, Printer);
254 /****************************************************************************
255 find printer index by handle
256 ****************************************************************************/
258 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
259 struct policy_handle *hnd)
261 Printer_entry *find_printer = NULL;
263 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
264 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
271 /****************************************************************************
272 Close printer index by handle.
273 ****************************************************************************/
275 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
277 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
280 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
285 close_policy_hnd(p, hnd);
290 /****************************************************************************
291 Delete a printer given a handle.
292 ****************************************************************************/
294 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
295 const char *sharename,
296 struct messaging_context *msg_ctx)
298 char *cmd = lp_deleteprinter_cmd();
299 char *command = NULL;
301 SE_PRIV se_printop = SE_PRINT_OPERATOR;
302 bool is_print_op = false;
304 /* can't fail if we don't try */
309 command = talloc_asprintf(ctx,
316 is_print_op = user_has_privileges( token, &se_printop );
318 DEBUG(10,("Running [%s]\n", command));
320 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
325 if ( (ret = smbrun(command, NULL)) == 0 ) {
326 /* Tell everyone we updated smb.conf. */
327 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
333 /********** END SePrintOperatorPrivlege BLOCK **********/
335 DEBUGADD(10,("returned [%d]\n", ret));
337 TALLOC_FREE(command);
340 return WERR_BADFID; /* What to return here? */
342 /* go ahead and re-read the services immediately */
344 reload_services(false);
347 if ( lp_servicenumber( sharename ) > 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
363 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
369 * It turns out that Windows allows delete printer on a handle
370 * opened by an admin user, then used on a pipe handle created
371 * by an anonymous user..... but they're working on security.... riiight !
375 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
376 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
377 return WERR_ACCESS_DENIED;
380 /* this does not need a become root since the access check has been
381 done on the handle already */
383 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
384 p->msg_ctx, Printer->sharename, "");
385 if (!W_ERROR_IS_OK(result)) {
386 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
390 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
391 Printer->sharename, p->msg_ctx);
394 /****************************************************************************
395 Return the snum of a printer corresponding to an handle.
396 ****************************************************************************/
398 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
399 int *number, struct share_params **params)
401 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
404 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
409 switch (Printer->printer_type) {
411 DEBUG(4,("short name:%s\n", Printer->sharename));
412 *number = print_queue_snum(Printer->sharename);
413 return (*number != -1);
421 /****************************************************************************
422 Set printer handle type.
423 Check if it's \\server or \\server\printer
424 ****************************************************************************/
426 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
428 DEBUG(3,("Setting printer type=%s\n", handlename));
430 if ( strlen(handlename) < 3 ) {
431 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
435 /* it's a print server */
436 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
437 DEBUGADD(4,("Printer is a print server\n"));
438 Printer->printer_type = SPLHND_SERVER;
440 /* it's a printer (set_printer_hnd_name() will handle port monitors */
442 DEBUGADD(4,("Printer is a printer\n"));
443 Printer->printer_type = SPLHND_PRINTER;
449 /****************************************************************************
450 Set printer handle name.. Accept names like \\server, \\server\printer,
451 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
452 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
453 XcvDataPort() interface.
454 ****************************************************************************/
456 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
457 struct auth_serversupplied_info *server_info,
458 Printer_entry *Printer,
459 const char *handlename)
462 int n_services=lp_numservices();
464 const char *printername;
465 const char *servername = NULL;
468 struct spoolss_PrinterInfo2 *info2 = NULL;
471 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
472 (unsigned long)strlen(handlename)));
474 aprinter = CONST_DISCARD(char *, handlename);
475 if ( *handlename == '\\' ) {
476 servername = canon_servername(handlename);
477 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
481 if (!is_myname_or_ipaddr(servername)) {
485 fstrcpy(Printer->servername, servername);
488 if (Printer->printer_type == SPLHND_SERVER) {
492 if (Printer->printer_type != SPLHND_PRINTER) {
496 DEBUGADD(5, ("searching for [%s]\n", aprinter));
498 /* check for the Port Monitor Interface */
499 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
500 Printer->printer_type = SPLHND_PORTMON_TCP;
501 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
504 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
505 Printer->printer_type = SPLHND_PORTMON_LOCAL;
506 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
510 /* Search all sharenames first as this is easier than pulling
511 the printer_info_2 off of disk. Don't use find_service() since
512 that calls out to map_username() */
514 /* do another loop to look for printernames */
515 for (snum = 0; !found && snum < n_services; snum++) {
516 const char *printer = lp_const_servicename(snum);
518 /* no point going on if this is not a printer */
519 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
523 /* ignore [printers] share */
524 if (strequal(printer, "printers")) {
528 fstrcpy(sname, printer);
529 if (strequal(aprinter, printer)) {
534 /* no point looking up the printer object if
535 we aren't allowing printername != sharename */
536 if (lp_force_printername(snum)) {
540 result = winreg_get_printer(mem_ctx,
542 smbd_messaging_context(),
546 if ( !W_ERROR_IS_OK(result) ) {
547 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
548 sname, win_errstr(result)));
552 printername = strrchr(info2->printername, '\\');
553 if (printername == NULL) {
554 printername = info2->printername;
559 if (strequal(printername, aprinter)) {
564 DEBUGADD(10, ("printername: %s\n", printername));
570 DEBUGADD(4,("Printer not found\n"));
574 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
576 fstrcpy(Printer->sharename, sname);
581 /****************************************************************************
582 Find first available printer slot. creates a printer handle for you.
583 ****************************************************************************/
585 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
586 const char *name, uint32_t access_granted)
588 Printer_entry *new_printer;
590 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
592 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
593 if (new_printer == NULL) {
596 talloc_set_destructor(new_printer, printer_entry_destructor);
598 if (!create_policy_hnd(p, hnd, new_printer)) {
599 TALLOC_FREE(new_printer);
603 /* Add to the internal list. */
604 DLIST_ADD(printers_list, new_printer);
606 new_printer->notify.option=NULL;
608 if (!set_printer_hnd_printertype(new_printer, name)) {
609 close_printer_handle(p, hnd);
613 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
614 close_printer_handle(p, hnd);
618 new_printer->access_granted = access_granted;
620 DEBUG(5, ("%d printer handles active\n",
621 (int)num_pipe_handles(p)));
626 /***************************************************************************
627 check to see if the client motify handle is monitoring the notification
628 given by (notify_type, notify_field).
629 **************************************************************************/
631 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
632 uint16_t notify_field)
637 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
638 uint16_t notify_field)
640 struct spoolss_NotifyOption *option = p->notify.option;
644 * Flags should always be zero when the change notify
645 * is registered by the client's spooler. A user Win32 app
646 * might use the flags though instead of the NOTIFY_OPTION_INFO
655 return is_monitoring_event_flags(
656 p->notify.flags, notify_type, notify_field);
658 for (i = 0; i < option->count; i++) {
660 /* Check match for notify_type */
662 if (option->types[i].type != notify_type)
665 /* Check match for field */
667 for (j = 0; j < option->types[i].count; j++) {
668 if (option->types[i].fields[j].field == notify_field) {
674 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
675 p->servername, p->sharename, notify_type, notify_field));
680 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
681 _data->data.integer[0] = _integer; \
682 _data->data.integer[1] = 0;
685 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
686 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
687 if (!_data->data.string.string) {\
688 _data->data.string.size = 0; \
690 _data->data.string.size = strlen_m_term(_p) * 2;
692 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
693 _data->data.devmode.devmode = _devmode;
695 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
696 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
697 if (!_data->data.sd.sd) { \
698 _data->data.sd.sd_size = 0; \
700 _data->data.sd.sd_size = \
701 ndr_size_security_descriptor(_data->data.sd.sd, 0);
703 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
708 struct spoolss_Time st;
712 if (!init_systemtime(&st, t)) {
716 p = talloc_array(mem_ctx, char, len);
722 * Systemtime must be linearized as a set of UINT16's.
723 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
726 SSVAL(p, 0, st.year);
727 SSVAL(p, 2, st.month);
728 SSVAL(p, 4, st.day_of_week);
730 SSVAL(p, 8, st.hour);
731 SSVAL(p, 10, st.minute);
732 SSVAL(p, 12, st.second);
733 SSVAL(p, 14, st.millisecond);
739 /* Convert a notification message to a struct spoolss_Notify */
741 static void notify_one_value(struct spoolss_notify_msg *msg,
742 struct spoolss_Notify *data,
745 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
748 static void notify_string(struct spoolss_notify_msg *msg,
749 struct spoolss_Notify *data,
752 /* The length of the message includes the trailing \0 */
754 data->data.string.size = msg->len * 2;
755 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
756 if (!data->data.string.string) {
757 data->data.string.size = 0;
762 static void notify_system_time(struct spoolss_notify_msg *msg,
763 struct spoolss_Notify *data,
766 data->data.string.string = NULL;
767 data->data.string.size = 0;
769 if (msg->len != sizeof(time_t)) {
770 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
775 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
776 &data->data.string.string,
777 &data->data.string.size);
780 struct notify2_message_table {
782 void (*fn)(struct spoolss_notify_msg *msg,
783 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
786 static struct notify2_message_table printer_notify_table[] = {
787 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
788 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
789 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
790 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
791 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
792 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
793 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
794 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
795 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
796 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
797 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
798 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
799 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
800 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
801 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
802 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
803 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
804 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
805 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
808 static struct notify2_message_table job_notify_table[] = {
809 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
810 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
811 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
812 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
813 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
814 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
815 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
816 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
817 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
818 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
819 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
820 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
821 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
822 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
823 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
824 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
825 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
826 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
827 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
828 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
829 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
830 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
831 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
832 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
836 /***********************************************************************
837 Allocate talloc context for container object
838 **********************************************************************/
840 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
845 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
850 /***********************************************************************
851 release all allocated memory and zero out structure
852 **********************************************************************/
854 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
860 talloc_destroy(ctr->ctx);
867 /***********************************************************************
868 **********************************************************************/
870 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
878 /***********************************************************************
879 **********************************************************************/
881 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
883 if ( !ctr || !ctr->msg_groups )
886 if ( idx >= ctr->num_groups )
889 return &ctr->msg_groups[idx];
893 /***********************************************************************
894 How many groups of change messages do we have ?
895 **********************************************************************/
897 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
902 return ctr->num_groups;
905 /***********************************************************************
906 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
907 **********************************************************************/
909 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
911 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
912 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
913 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
919 /* loop over all groups looking for a matching printer name */
921 for ( i=0; i<ctr->num_groups; i++ ) {
922 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
926 /* add a new group? */
928 if ( i == ctr->num_groups ) {
931 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
932 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
935 ctr->msg_groups = groups;
937 /* clear the new entry and set the printer name */
939 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
940 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
943 /* add the change messages; 'i' is the correct index now regardless */
945 msg_grp = &ctr->msg_groups[i];
949 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
950 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
953 msg_grp->msgs = msg_list;
955 new_slot = msg_grp->num_msgs-1;
956 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
958 /* need to allocate own copy of data */
961 msg_grp->msgs[new_slot].notify.data = (char *)
962 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
964 return ctr->num_groups;
967 static void construct_info_data(struct spoolss_Notify *info_data,
968 enum spoolss_NotifyType type,
969 uint16_t field, int id);
971 /***********************************************************************
972 Send a change notication message on all handles which have a call
974 **********************************************************************/
976 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
979 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
980 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
981 SPOOLSS_NOTIFY_MSG *messages;
982 int sending_msg_count;
985 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
989 messages = msg_group->msgs;
992 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
996 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
998 /* loop over all printers */
1000 for (p = printers_list; p; p = p->next) {
1001 struct spoolss_Notify *notifies;
1006 /* Is there notification on this handle? */
1008 if ( !p->notify.client_connected )
1011 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1013 /* For this printer? Print servers always receive
1016 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1017 ( !strequal(msg_group->printername, p->sharename) ) )
1020 DEBUG(10,("Our printer\n"));
1022 /* allocate the max entries possible */
1024 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1029 /* build the array of change notifications */
1031 sending_msg_count = 0;
1033 for ( i=0; i<msg_group->num_msgs; i++ ) {
1034 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1036 /* Are we monitoring this event? */
1038 if (!is_monitoring_event(p, msg->type, msg->field))
1041 sending_msg_count++;
1044 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1045 msg->type, msg->field, p->sharename));
1048 * if the is a printer notification handle and not a job notification
1049 * type, then set the id to 0. Other wise just use what was specified
1052 * When registering change notification on a print server handle
1053 * we always need to send back the id (snum) matching the printer
1054 * for which the change took place. For change notify registered
1055 * on a printer handle, this does not matter and the id should be 0.
1060 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1066 /* Convert unix jobid to smb jobid */
1068 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1069 id = sysjob_to_jobid(msg->id);
1072 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1077 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1080 case PRINTER_NOTIFY_TYPE:
1081 if ( printer_notify_table[msg->field].fn )
1082 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1085 case JOB_NOTIFY_TYPE:
1086 if ( job_notify_table[msg->field].fn )
1087 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1091 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1098 if ( sending_msg_count ) {
1101 union spoolss_ReplyPrinterInfo info;
1102 struct spoolss_NotifyInfo info0;
1103 uint32_t reply_result;
1105 info0.version = 0x2;
1106 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1107 info0.count = count;
1108 info0.notifies = notifies;
1110 info.info0 = &info0;
1112 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1113 &p->notify.client_hnd,
1114 p->notify.change, /* color */
1117 0, /* reply_type, must be 0 */
1120 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1121 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1122 notify_cli_pipe->srv_name_slash,
1125 switch (reply_result) {
1128 case PRINTER_NOTIFY_INFO_DISCARDED:
1129 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1130 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1139 DEBUG(8,("send_notify2_changes: Exit...\n"));
1143 /***********************************************************************
1144 **********************************************************************/
1146 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1149 uint32_t tv_sec, tv_usec;
1152 /* Unpack message */
1154 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1157 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1159 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1162 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1163 &msg->notify.value[0], &msg->notify.value[1]);
1165 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1166 &msg->len, &msg->notify.data);
1168 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1169 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1171 tv->tv_sec = tv_sec;
1172 tv->tv_usec = tv_usec;
1175 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1176 msg->notify.value[1]));
1178 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1183 /********************************************************************
1184 Receive a notify2 message list
1185 ********************************************************************/
1187 static void receive_notify2_message_list(struct messaging_context *msg,
1190 struct server_id server_id,
1193 size_t msg_count, i;
1194 char *buf = (char *)data->data;
1197 SPOOLSS_NOTIFY_MSG notify;
1198 SPOOLSS_NOTIFY_MSG_CTR messages;
1201 if (data->length < 4) {
1202 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1206 msg_count = IVAL(buf, 0);
1209 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1211 if (msg_count == 0) {
1212 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1216 /* initialize the container */
1218 ZERO_STRUCT( messages );
1219 notify_msg_ctr_init( &messages );
1222 * build message groups for each printer identified
1223 * in a change_notify msg. Remember that a PCN message
1224 * includes the handle returned for the srv_spoolss_replyopenprinter()
1225 * call. Therefore messages are grouped according to printer handle.
1228 for ( i=0; i<msg_count; i++ ) {
1229 struct timeval msg_tv;
1231 if (msg_ptr + 4 - buf > data->length) {
1232 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1236 msg_len = IVAL(msg_ptr,0);
1239 if (msg_ptr + msg_len - buf > data->length) {
1240 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1244 /* unpack messages */
1246 ZERO_STRUCT( notify );
1247 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1250 /* add to correct list in container */
1252 notify_msg_ctr_addmsg( &messages, ¬ify );
1254 /* free memory that might have been allocated by notify2_unpack_msg() */
1256 if ( notify.len != 0 )
1257 SAFE_FREE( notify.notify.data );
1260 /* process each group of messages */
1262 num_groups = notify_msg_ctr_numgroups( &messages );
1263 for ( i=0; i<num_groups; i++ )
1264 send_notify2_changes( &messages, i );
1269 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1270 (uint32_t)msg_count ));
1272 notify_msg_ctr_destroy( &messages );
1277 /********************************************************************
1278 Send a message to ourself about new driver being installed
1279 so we can upgrade the information for each printer bound to this
1281 ********************************************************************/
1283 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1284 struct messaging_context *msg_ctx)
1286 int len = strlen(drivername);
1291 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1294 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1295 MSG_PRINTER_DRVUPGRADE,
1296 (uint8_t *)drivername, len+1);
1301 /**********************************************************************
1302 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1303 over all printers, upgrading ones as necessary
1304 **********************************************************************/
1306 void do_drv_upgrade_printer(struct messaging_context *msg,
1309 struct server_id server_id,
1312 TALLOC_CTX *tmp_ctx;
1313 struct auth_serversupplied_info *server_info = NULL;
1314 struct spoolss_PrinterInfo2 *pinfo2;
1317 const char *drivername;
1319 int n_services = lp_numservices();
1322 tmp_ctx = talloc_new(NULL);
1323 if (!tmp_ctx) return;
1325 status = make_server_info_system(tmp_ctx, &server_info);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 DEBUG(0, ("do_drv_upgrade_printer: "
1328 "Could not create system server_info\n"));
1332 len = MIN(data->length,sizeof(drivername)-1);
1333 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1335 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1339 DEBUG(10, ("do_drv_upgrade_printer: "
1340 "Got message for new driver [%s]\n", drivername));
1342 /* Iterate the printer list */
1344 for (snum = 0; snum < n_services; snum++) {
1345 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1349 result = winreg_get_printer(tmp_ctx, server_info, msg,
1351 lp_const_servicename(snum),
1354 if (!W_ERROR_IS_OK(result)) {
1358 if (!pinfo2->drivername) {
1362 if (strcmp(drivername, pinfo2->drivername) != 0) {
1366 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1368 /* all we care about currently is the change_id */
1369 result = winreg_printer_update_changeid(tmp_ctx,
1372 pinfo2->printername);
1374 if (!W_ERROR_IS_OK(result)) {
1375 DEBUG(3, ("do_drv_upgrade_printer: "
1376 "Failed to update changeid [%s]\n",
1377 win_errstr(result)));
1383 talloc_free(tmp_ctx);
1386 /********************************************************************
1387 Update the cache for all printq's with a registered client
1389 ********************************************************************/
1391 void update_monitored_printq_cache( void )
1393 Printer_entry *printer = printers_list;
1396 /* loop through all printers and update the cache where
1397 client_connected == true */
1400 if ( (printer->printer_type == SPLHND_PRINTER)
1401 && printer->notify.client_connected )
1403 snum = print_queue_snum(printer->sharename);
1404 print_queue_status( snum, NULL, NULL );
1407 printer = printer->next;
1413 /****************************************************************
1414 _spoolss_OpenPrinter
1415 ****************************************************************/
1417 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1418 struct spoolss_OpenPrinter *r)
1420 struct spoolss_OpenPrinterEx e;
1423 ZERO_STRUCT(e.in.userlevel);
1425 e.in.printername = r->in.printername;
1426 e.in.datatype = r->in.datatype;
1427 e.in.devmode_ctr = r->in.devmode_ctr;
1428 e.in.access_mask = r->in.access_mask;
1431 e.out.handle = r->out.handle;
1433 werr = _spoolss_OpenPrinterEx(p, &e);
1435 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1436 /* OpenPrinterEx returns this for a bad
1437 * printer name. We must return WERR_INVALID_PRINTER_NAME
1440 werr = WERR_INVALID_PRINTER_NAME;
1446 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1447 struct spoolss_DeviceMode *orig,
1448 struct spoolss_DeviceMode **dest)
1450 struct spoolss_DeviceMode *dm;
1452 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1457 /* copy all values, then duplicate strings and structs */
1460 dm->devicename = talloc_strdup(dm, orig->devicename);
1461 if (!dm->devicename) {
1464 dm->formname = talloc_strdup(dm, orig->formname);
1465 if (!dm->formname) {
1468 if (orig->driverextra_data.data) {
1469 dm->driverextra_data.data =
1470 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1471 orig->driverextra_data.length);
1472 if (!dm->driverextra_data.data) {
1481 /****************************************************************
1482 _spoolss_OpenPrinterEx
1483 ****************************************************************/
1485 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1486 struct spoolss_OpenPrinterEx *r)
1489 Printer_entry *Printer=NULL;
1491 if (!r->in.printername) {
1492 return WERR_INVALID_PARAM;
1495 /* some sanity check because you can open a printer or a print server */
1496 /* aka: \\server\printer or \\server */
1498 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1500 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1501 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1502 " for printer %s\n", r->in.printername));
1503 ZERO_STRUCTP(r->out.handle);
1504 return WERR_INVALID_PARAM;
1507 Printer = find_printer_index_by_hnd(p, r->out.handle);
1509 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1510 "handle we created for printer %s\n", r->in.printername));
1511 close_printer_handle(p, r->out.handle);
1512 ZERO_STRUCTP(r->out.handle);
1513 return WERR_INVALID_PARAM;
1517 * First case: the user is opening the print server:
1519 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1520 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1522 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1523 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1524 * or if the user is listed in the smb.conf printer admin parameter.
1526 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1527 * client view printer folder, but does not show the MSAPW.
1529 * Note: this test needs code to check access rights here too. Jeremy
1530 * could you look at this?
1532 * Second case: the user is opening a printer:
1533 * NT doesn't let us connect to a printer if the connecting user
1534 * doesn't have print permission.
1536 * Third case: user is opening a Port Monitor
1537 * access checks same as opening a handle to the print server.
1540 switch (Printer->printer_type )
1543 case SPLHND_PORTMON_TCP:
1544 case SPLHND_PORTMON_LOCAL:
1545 /* Printserver handles use global struct... */
1549 /* Map standard access rights to object specific access rights */
1551 se_map_standard(&r->in.access_mask,
1552 &printserver_std_mapping);
1554 /* Deny any object specific bits that don't apply to print
1555 servers (i.e printer and job specific bits) */
1557 r->in.access_mask &= SEC_MASK_SPECIFIC;
1559 if (r->in.access_mask &
1560 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1561 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1562 close_printer_handle(p, r->out.handle);
1563 ZERO_STRUCTP(r->out.handle);
1564 return WERR_ACCESS_DENIED;
1567 /* Allow admin access */
1569 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1571 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1573 if (!lp_ms_add_printer_wizard()) {
1574 close_printer_handle(p, r->out.handle);
1575 ZERO_STRUCTP(r->out.handle);
1576 return WERR_ACCESS_DENIED;
1579 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1580 and not a printer admin, then fail */
1582 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1583 !user_has_privileges(p->server_info->ptok,
1585 !token_contains_name_in_list(
1586 uidtoname(p->server_info->utok.uid),
1587 p->server_info->info3->base.domain.string,
1589 p->server_info->ptok,
1590 lp_printer_admin(snum))) {
1591 close_printer_handle(p, r->out.handle);
1592 ZERO_STRUCTP(r->out.handle);
1593 return WERR_ACCESS_DENIED;
1596 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1600 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1603 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1604 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1606 /* We fall through to return WERR_OK */
1609 case SPLHND_PRINTER:
1610 /* NT doesn't let us connect to a printer if the connecting user
1611 doesn't have print permission. */
1613 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1614 close_printer_handle(p, r->out.handle);
1615 ZERO_STRUCTP(r->out.handle);
1619 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1620 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1623 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1625 /* map an empty access mask to the minimum access mask */
1626 if (r->in.access_mask == 0x0)
1627 r->in.access_mask = PRINTER_ACCESS_USE;
1630 * If we are not serving the printer driver for this printer,
1631 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1632 * will keep NT clients happy --jerry
1635 if (lp_use_client_driver(snum)
1636 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1638 r->in.access_mask = PRINTER_ACCESS_USE;
1641 /* check smb.conf parameters and the the sec_desc */
1643 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1644 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1645 ZERO_STRUCTP(r->out.handle);
1646 return WERR_ACCESS_DENIED;
1649 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1650 p->server_info->ptok, snum) ||
1651 !print_access_check(p->server_info, snum,
1652 r->in.access_mask)) {
1653 DEBUG(3, ("access DENIED for printer open\n"));
1654 close_printer_handle(p, r->out.handle);
1655 ZERO_STRUCTP(r->out.handle);
1656 return WERR_ACCESS_DENIED;
1659 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1660 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1661 close_printer_handle(p, r->out.handle);
1662 ZERO_STRUCTP(r->out.handle);
1663 return WERR_ACCESS_DENIED;
1666 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1667 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1669 r->in.access_mask = PRINTER_ACCESS_USE;
1671 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1672 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1674 winreg_create_printer(p->mem_ctx,
1677 Printer->servername,
1678 lp_const_servicename(snum));
1683 /* sanity check to prevent programmer error */
1684 ZERO_STRUCTP(r->out.handle);
1688 Printer->access_granted = r->in.access_mask;
1691 * If the client sent a devmode in the OpenPrinter() call, then
1692 * save it here in case we get a job submission on this handle
1695 if ((Printer->printer_type != SPLHND_SERVER) &&
1696 r->in.devmode_ctr.devmode) {
1697 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1701 #if 0 /* JERRY -- I'm doubtful this is really effective */
1702 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1703 optimization in Windows 2000 clients --jerry */
1705 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1706 && (RA_WIN2K == get_remote_arch()) )
1708 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1709 sys_usleep( 500000 );
1716 /****************************************************************
1717 _spoolss_ClosePrinter
1718 ****************************************************************/
1720 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1721 struct spoolss_ClosePrinter *r)
1723 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1725 if (Printer && Printer->document_started) {
1726 struct spoolss_EndDocPrinter e;
1728 e.in.handle = r->in.handle;
1730 _spoolss_EndDocPrinter(p, &e);
1733 if (!close_printer_handle(p, r->in.handle))
1736 /* clear the returned printer handle. Observed behavior
1737 from Win2k server. Don't think this really matters.
1738 Previous code just copied the value of the closed
1741 ZERO_STRUCTP(r->out.handle);
1746 /****************************************************************
1747 _spoolss_DeletePrinter
1748 ****************************************************************/
1750 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1751 struct spoolss_DeletePrinter *r)
1753 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1757 if (Printer && Printer->document_started) {
1758 struct spoolss_EndDocPrinter e;
1760 e.in.handle = r->in.handle;
1762 _spoolss_EndDocPrinter(p, &e);
1765 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1766 winreg_delete_printer_key(p->mem_ctx,
1769 lp_const_servicename(snum),
1773 result = delete_printer_handle(p, r->in.handle);
1778 /*******************************************************************
1779 * static function to lookup the version id corresponding to an
1780 * long architecture string
1781 ******************************************************************/
1783 static const struct print_architecture_table_node archi_table[]= {
1785 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1786 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1787 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1788 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1789 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1790 {"Windows IA64", SPL_ARCH_IA64, 3 },
1791 {"Windows x64", SPL_ARCH_X64, 3 },
1795 static int get_version_id(const char *arch)
1799 for (i=0; archi_table[i].long_archi != NULL; i++)
1801 if (strcmp(arch, archi_table[i].long_archi) == 0)
1802 return (archi_table[i].version);
1808 /****************************************************************
1809 _spoolss_DeletePrinterDriver
1810 ****************************************************************/
1812 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1813 struct spoolss_DeletePrinterDriver *r)
1816 struct spoolss_DriverInfo8 *info = NULL;
1817 struct spoolss_DriverInfo8 *info_win2k = NULL;
1820 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1822 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1823 and not a printer admin, then fail */
1825 if ( (p->server_info->utok.uid != sec_initial_uid())
1826 && !user_has_privileges(p->server_info->ptok, &se_printop )
1827 && !token_contains_name_in_list(
1828 uidtoname(p->server_info->utok.uid),
1829 p->server_info->info3->base.domain.string,
1831 p->server_info->ptok,
1832 lp_printer_admin(-1)) )
1834 return WERR_ACCESS_DENIED;
1837 /* check that we have a valid driver name first */
1839 if ((version = get_version_id(r->in.architecture)) == -1)
1840 return WERR_INVALID_ENVIRONMENT;
1842 status = winreg_get_driver(p->mem_ctx, p->server_info,
1843 r->in.architecture, r->in.driver,
1845 if (!W_ERROR_IS_OK(status)) {
1846 /* try for Win2k driver if "Windows NT x86" */
1848 if ( version == 2 ) {
1851 status = winreg_get_driver(p->mem_ctx, p->server_info,
1855 if (!W_ERROR_IS_OK(status)) {
1856 status = WERR_UNKNOWN_PRINTER_DRIVER;
1860 /* otherwise it was a failure */
1862 status = WERR_UNKNOWN_PRINTER_DRIVER;
1868 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1869 status = WERR_PRINTER_DRIVER_IN_USE;
1874 status = winreg_get_driver(p->mem_ctx, p->server_info,
1876 r->in.driver, 3, &info_win2k);
1877 if (W_ERROR_IS_OK(status)) {
1878 /* if we get to here, we now have 2 driver info structures to remove */
1879 /* remove the Win2k driver first*/
1881 status = winreg_del_driver(p->mem_ctx,
1884 talloc_free(info_win2k);
1886 /* this should not have failed---if it did, report to client */
1887 if (!W_ERROR_IS_OK(status)) {
1893 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1901 /****************************************************************
1902 _spoolss_DeletePrinterDriverEx
1903 ****************************************************************/
1905 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1906 struct spoolss_DeletePrinterDriverEx *r)
1908 struct spoolss_DriverInfo8 *info = NULL;
1909 struct spoolss_DriverInfo8 *info_win2k = NULL;
1913 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1915 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1916 and not a printer admin, then fail */
1918 if ( (p->server_info->utok.uid != sec_initial_uid())
1919 && !user_has_privileges(p->server_info->ptok, &se_printop )
1920 && !token_contains_name_in_list(
1921 uidtoname(p->server_info->utok.uid),
1922 p->server_info->info3->base.domain.string,
1924 p->server_info->ptok, lp_printer_admin(-1)) )
1926 return WERR_ACCESS_DENIED;
1929 /* check that we have a valid driver name first */
1930 if ((version = get_version_id(r->in.architecture)) == -1) {
1931 /* this is what NT returns */
1932 return WERR_INVALID_ENVIRONMENT;
1935 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1936 version = r->in.version;
1938 status = winreg_get_driver(p->mem_ctx, p->server_info,
1939 r->in.architecture, r->in.driver,
1941 if (!W_ERROR_IS_OK(status)) {
1942 status = WERR_UNKNOWN_PRINTER_DRIVER;
1945 * if the client asked for a specific version,
1946 * or this is something other than Windows NT x86,
1950 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1953 /* try for Win2k driver if "Windows NT x86" */
1956 status = winreg_get_driver(info, p->server_info,
1960 if (!W_ERROR_IS_OK(status)) {
1961 status = WERR_UNKNOWN_PRINTER_DRIVER;
1966 if (printer_driver_in_use(info, p->server_info, info)) {
1967 status = WERR_PRINTER_DRIVER_IN_USE;
1972 * we have a couple of cases to consider.
1973 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1974 * then the delete should fail if **any** files overlap with
1976 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1977 * non-overlapping files
1978 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1979 * is set, the do not delete any files
1980 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1983 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1985 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1988 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1989 printer_driver_files_in_use(info, p->server_info, info)) {
1990 /* no idea of the correct error here */
1991 status = WERR_ACCESS_DENIED;
1996 /* also check for W32X86/3 if necessary; maybe we already have? */
1998 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1999 status = winreg_get_driver(info, p->server_info,
2001 r->in.driver, 3, &info_win2k);
2002 if (W_ERROR_IS_OK(status)) {
2005 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2006 printer_driver_files_in_use(info, p->server_info,
2008 /* no idea of the correct error here */
2009 talloc_free(info_win2k);
2010 status = WERR_ACCESS_DENIED;
2014 /* if we get to here, we now have 2 driver info structures to remove */
2015 /* remove the Win2k driver first*/
2017 status = winreg_del_driver(info, p->server_info,
2020 /* this should not have failed---if it did, report to client */
2022 if (!W_ERROR_IS_OK(status)) {
2027 * now delete any associated files if delete_files is
2028 * true. Even if this part failes, we return succes
2029 * because the driver doesn not exist any more
2032 delete_driver_files(p->server_info,
2038 status = winreg_del_driver(info, p->server_info, info, version);
2039 if (!W_ERROR_IS_OK(status)) {
2044 * now delete any associated files if delete_files is
2045 * true. Even if this part failes, we return succes
2046 * because the driver doesn not exist any more
2049 delete_driver_files(p->server_info, info);
2058 /********************************************************************
2059 GetPrinterData on a printer server Handle.
2060 ********************************************************************/
2062 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2064 enum winreg_Type *type,
2065 union spoolss_PrinterData *data)
2067 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2069 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2075 if (!StrCaseCmp(value, "BeepEnabled")) {
2081 if (!StrCaseCmp(value, "EventLog")) {
2083 /* formally was 0x1b */
2088 if (!StrCaseCmp(value, "NetPopup")) {
2094 if (!StrCaseCmp(value, "MajorVersion")) {
2097 /* Windows NT 4.0 seems to not allow uploading of drivers
2098 to a server that reports 0x3 as the MajorVersion.
2099 need to investigate more how Win2k gets around this .
2102 if (RA_WINNT == get_remote_arch()) {
2111 if (!StrCaseCmp(value, "MinorVersion")) {
2118 * uint32_t size = 0x114
2119 * uint32_t major = 5
2120 * uint32_t minor = [0|1]
2121 * uint32_t build = [2195|2600]
2122 * extra unicode string = e.g. "Service Pack 3"
2124 if (!StrCaseCmp(value, "OSVersion")) {
2126 enum ndr_err_code ndr_err;
2127 struct spoolss_OSVersion os;
2129 os.major = 5; /* Windows 2000 == 5.0 */
2131 os.build = 2195; /* build */
2132 os.extra_string = ""; /* leave extra string empty */
2134 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2135 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2136 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2137 return WERR_GENERAL_FAILURE;
2141 data->binary = blob;
2147 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2150 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2151 W_ERROR_HAVE_NO_MEMORY(data->string);
2156 if (!StrCaseCmp(value, "Architecture")) {
2158 data->string = talloc_strdup(mem_ctx,
2159 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2160 W_ERROR_HAVE_NO_MEMORY(data->string);
2165 if (!StrCaseCmp(value, "DsPresent")) {
2168 /* only show the publish check box if we are a
2169 member of a AD domain */
2171 if (lp_security() == SEC_ADS) {
2179 if (!StrCaseCmp(value, "DNSMachineName")) {
2180 const char *hostname = get_mydnsfullname();
2183 return WERR_BADFILE;
2187 data->string = talloc_strdup(mem_ctx, hostname);
2188 W_ERROR_HAVE_NO_MEMORY(data->string);
2195 return WERR_INVALID_PARAM;
2198 /****************************************************************
2199 _spoolss_GetPrinterData
2200 ****************************************************************/
2202 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2203 struct spoolss_GetPrinterData *r)
2205 struct spoolss_GetPrinterDataEx r2;
2207 r2.in.handle = r->in.handle;
2208 r2.in.key_name = "PrinterDriverData";
2209 r2.in.value_name = r->in.value_name;
2210 r2.in.offered = r->in.offered;
2211 r2.out.type = r->out.type;
2212 r2.out.data = r->out.data;
2213 r2.out.needed = r->out.needed;
2215 return _spoolss_GetPrinterDataEx(p, &r2);
2218 /*********************************************************
2219 Connect to the client machine.
2220 **********************************************************/
2222 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2223 struct sockaddr_storage *client_ss, const char *remote_machine)
2226 struct cli_state *the_cli;
2227 struct sockaddr_storage rm_addr;
2228 char addr[INET6_ADDRSTRLEN];
2230 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2231 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2233 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2234 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2237 print_sockaddr(addr, sizeof(addr), &rm_addr);
2239 rm_addr = *client_ss;
2240 print_sockaddr(addr, sizeof(addr), &rm_addr);
2241 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2245 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2246 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2251 /* setup the connection */
2252 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2253 &rm_addr, 0, "IPC$", "IPC",
2257 0, lp_client_signing(), NULL );
2259 if ( !NT_STATUS_IS_OK( ret ) ) {
2260 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2265 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2266 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2267 cli_shutdown(the_cli);
2272 * Ok - we have an anonymous connection to the IPC$ share.
2273 * Now start the NT Domain stuff :-).
2276 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2277 if (!NT_STATUS_IS_OK(ret)) {
2278 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2279 remote_machine, nt_errstr(ret)));
2280 cli_shutdown(the_cli);
2287 /***************************************************************************
2288 Connect to the client.
2289 ****************************************************************************/
2291 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2292 uint32_t localprinter, uint32_t type,
2293 struct policy_handle *handle,
2294 struct sockaddr_storage *client_ss,
2295 struct messaging_context *msg_ctx)
2301 * If it's the first connection, contact the client
2302 * and connect to the IPC$ share anonymously
2304 if (smb_connections==0) {
2305 fstring unix_printer;
2307 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2309 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2312 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2313 receive_notify2_message_list);
2314 /* Tell the connections db we're now interested in printer
2315 * notify messages. */
2316 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2317 true, FLAG_MSG_PRINT_NOTIFY);
2321 * Tell the specific printing tdb we want messages for this printer
2322 * by registering our PID.
2325 if (!print_notify_register_pid(snum))
2326 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2330 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2338 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2339 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2340 win_errstr(result)));
2342 return (W_ERROR_IS_OK(result));
2345 /****************************************************************
2346 ****************************************************************/
2348 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2349 const struct spoolss_NotifyOption *r)
2351 struct spoolss_NotifyOption *option;
2358 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2365 if (!option->count) {
2369 option->types = talloc_zero_array(option,
2370 struct spoolss_NotifyOptionType, option->count);
2371 if (!option->types) {
2372 talloc_free(option);
2376 for (i=0; i < option->count; i++) {
2377 option->types[i] = r->types[i];
2379 if (option->types[i].count) {
2380 option->types[i].fields = talloc_zero_array(option,
2381 union spoolss_Field, option->types[i].count);
2382 if (!option->types[i].fields) {
2383 talloc_free(option);
2386 for (k=0; k<option->types[i].count; k++) {
2387 option->types[i].fields[k] =
2388 r->types[i].fields[k];
2396 /****************************************************************
2397 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2399 * before replying OK: status=0 a rpc call is made to the workstation
2400 * asking ReplyOpenPrinter
2402 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2403 * called from api_spoolss_rffpcnex
2404 ****************************************************************/
2406 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2407 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2410 struct spoolss_NotifyOption *option = r->in.notify_options;
2411 struct sockaddr_storage client_ss;
2413 /* store the notify value in the printer struct */
2415 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2418 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2419 "Invalid handle (%s:%u:%u).\n",
2420 OUR_HANDLE(r->in.handle)));
2424 Printer->notify.flags = r->in.flags;
2425 Printer->notify.options = r->in.options;
2426 Printer->notify.printerlocal = r->in.printer_local;
2427 Printer->notify.msg_ctx = p->msg_ctx;
2429 TALLOC_FREE(Printer->notify.option);
2430 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2432 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2434 /* Connect to the client machine and send a ReplyOpenPrinter */
2436 if ( Printer->printer_type == SPLHND_SERVER)
2438 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2439 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2442 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2443 "client_address is %s\n", p->client_address));
2445 if (!interpret_string_addr(&client_ss, p->client_address,
2447 return WERR_SERVER_UNAVAILABLE;
2450 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2451 Printer->notify.printerlocal, 1,
2452 &Printer->notify.client_hnd,
2453 &client_ss, p->msg_ctx))
2454 return WERR_SERVER_UNAVAILABLE;
2456 Printer->notify.client_connected = true;
2461 /*******************************************************************
2462 * fill a notify_info_data with the servername
2463 ********************************************************************/
2465 static void spoolss_notify_server_name(int snum,
2466 struct spoolss_Notify *data,
2467 print_queue_struct *queue,
2468 struct spoolss_PrinterInfo2 *pinfo2,
2469 TALLOC_CTX *mem_ctx)
2471 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2474 /*******************************************************************
2475 * fill a notify_info_data with the printername (not including the servername).
2476 ********************************************************************/
2478 static void spoolss_notify_printer_name(int snum,
2479 struct spoolss_Notify *data,
2480 print_queue_struct *queue,
2481 struct spoolss_PrinterInfo2 *pinfo2,
2482 TALLOC_CTX *mem_ctx)
2484 /* the notify name should not contain the \\server\ part */
2485 const char *p = strrchr(pinfo2->printername, '\\');
2488 p = pinfo2->printername;
2493 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2496 /*******************************************************************
2497 * fill a notify_info_data with the servicename
2498 ********************************************************************/
2500 static void spoolss_notify_share_name(int snum,
2501 struct spoolss_Notify *data,
2502 print_queue_struct *queue,
2503 struct spoolss_PrinterInfo2 *pinfo2,
2504 TALLOC_CTX *mem_ctx)
2506 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2509 /*******************************************************************
2510 * fill a notify_info_data with the port name
2511 ********************************************************************/
2513 static void spoolss_notify_port_name(int snum,
2514 struct spoolss_Notify *data,
2515 print_queue_struct *queue,
2516 struct spoolss_PrinterInfo2 *pinfo2,
2517 TALLOC_CTX *mem_ctx)
2519 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2522 /*******************************************************************
2523 * fill a notify_info_data with the printername
2524 * but it doesn't exist, have to see what to do
2525 ********************************************************************/
2527 static void spoolss_notify_driver_name(int snum,
2528 struct spoolss_Notify *data,
2529 print_queue_struct *queue,
2530 struct spoolss_PrinterInfo2 *pinfo2,
2531 TALLOC_CTX *mem_ctx)
2533 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2536 /*******************************************************************
2537 * fill a notify_info_data with the comment
2538 ********************************************************************/
2540 static void spoolss_notify_comment(int snum,
2541 struct spoolss_Notify *data,
2542 print_queue_struct *queue,
2543 struct spoolss_PrinterInfo2 *pinfo2,
2544 TALLOC_CTX *mem_ctx)
2548 if (*pinfo2->comment == '\0') {
2549 p = lp_comment(snum);
2551 p = pinfo2->comment;
2554 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2557 /*******************************************************************
2558 * fill a notify_info_data with the comment
2559 * location = "Room 1, floor 2, building 3"
2560 ********************************************************************/
2562 static void spoolss_notify_location(int snum,
2563 struct spoolss_Notify *data,
2564 print_queue_struct *queue,
2565 struct spoolss_PrinterInfo2 *pinfo2,
2566 TALLOC_CTX *mem_ctx)
2568 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2571 /*******************************************************************
2572 * fill a notify_info_data with the device mode
2573 * jfm:xxxx don't to it for know but that's a real problem !!!
2574 ********************************************************************/
2576 static void spoolss_notify_devmode(int snum,
2577 struct spoolss_Notify *data,
2578 print_queue_struct *queue,
2579 struct spoolss_PrinterInfo2 *pinfo2,
2580 TALLOC_CTX *mem_ctx)
2582 /* for a dummy implementation we have to zero the fields */
2583 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2586 /*******************************************************************
2587 * fill a notify_info_data with the separator file name
2588 ********************************************************************/
2590 static void spoolss_notify_sepfile(int snum,
2591 struct spoolss_Notify *data,
2592 print_queue_struct *queue,
2593 struct spoolss_PrinterInfo2 *pinfo2,
2594 TALLOC_CTX *mem_ctx)
2596 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2599 /*******************************************************************
2600 * fill a notify_info_data with the print processor
2601 * jfm:xxxx return always winprint to indicate we don't do anything to it
2602 ********************************************************************/
2604 static void spoolss_notify_print_processor(int snum,
2605 struct spoolss_Notify *data,
2606 print_queue_struct *queue,
2607 struct spoolss_PrinterInfo2 *pinfo2,
2608 TALLOC_CTX *mem_ctx)
2610 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2613 /*******************************************************************
2614 * fill a notify_info_data with the print processor options
2615 * jfm:xxxx send an empty string
2616 ********************************************************************/
2618 static void spoolss_notify_parameters(int snum,
2619 struct spoolss_Notify *data,
2620 print_queue_struct *queue,
2621 struct spoolss_PrinterInfo2 *pinfo2,
2622 TALLOC_CTX *mem_ctx)
2624 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2627 /*******************************************************************
2628 * fill a notify_info_data with the data type
2629 * jfm:xxxx always send RAW as data type
2630 ********************************************************************/
2632 static void spoolss_notify_datatype(int snum,
2633 struct spoolss_Notify *data,
2634 print_queue_struct *queue,
2635 struct spoolss_PrinterInfo2 *pinfo2,
2636 TALLOC_CTX *mem_ctx)
2638 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2641 /*******************************************************************
2642 * fill a notify_info_data with the security descriptor
2643 * jfm:xxxx send an null pointer to say no security desc
2644 * have to implement security before !
2645 ********************************************************************/
2647 static void spoolss_notify_security_desc(int snum,
2648 struct spoolss_Notify *data,
2649 print_queue_struct *queue,
2650 struct spoolss_PrinterInfo2 *pinfo2,
2651 TALLOC_CTX *mem_ctx)
2653 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2656 /*******************************************************************
2657 * fill a notify_info_data with the attributes
2658 * jfm:xxxx a samba printer is always shared
2659 ********************************************************************/
2661 static void spoolss_notify_attributes(int snum,
2662 struct spoolss_Notify *data,
2663 print_queue_struct *queue,
2664 struct spoolss_PrinterInfo2 *pinfo2,
2665 TALLOC_CTX *mem_ctx)
2667 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2670 /*******************************************************************
2671 * fill a notify_info_data with the priority
2672 ********************************************************************/
2674 static void spoolss_notify_priority(int snum,
2675 struct spoolss_Notify *data,
2676 print_queue_struct *queue,
2677 struct spoolss_PrinterInfo2 *pinfo2,
2678 TALLOC_CTX *mem_ctx)
2680 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2683 /*******************************************************************
2684 * fill a notify_info_data with the default priority
2685 ********************************************************************/
2687 static void spoolss_notify_default_priority(int snum,
2688 struct spoolss_Notify *data,
2689 print_queue_struct *queue,
2690 struct spoolss_PrinterInfo2 *pinfo2,
2691 TALLOC_CTX *mem_ctx)
2693 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2696 /*******************************************************************
2697 * fill a notify_info_data with the start time
2698 ********************************************************************/
2700 static void spoolss_notify_start_time(int snum,
2701 struct spoolss_Notify *data,
2702 print_queue_struct *queue,
2703 struct spoolss_PrinterInfo2 *pinfo2,
2704 TALLOC_CTX *mem_ctx)
2706 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2709 /*******************************************************************
2710 * fill a notify_info_data with the until time
2711 ********************************************************************/
2713 static void spoolss_notify_until_time(int snum,
2714 struct spoolss_Notify *data,
2715 print_queue_struct *queue,
2716 struct spoolss_PrinterInfo2 *pinfo2,
2717 TALLOC_CTX *mem_ctx)
2719 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2722 /*******************************************************************
2723 * fill a notify_info_data with the status
2724 ********************************************************************/
2726 static void spoolss_notify_status(int snum,
2727 struct spoolss_Notify *data,
2728 print_queue_struct *queue,
2729 struct spoolss_PrinterInfo2 *pinfo2,
2730 TALLOC_CTX *mem_ctx)
2732 print_status_struct status;
2734 print_queue_length(snum, &status);
2735 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2738 /*******************************************************************
2739 * fill a notify_info_data with the number of jobs queued
2740 ********************************************************************/
2742 static void spoolss_notify_cjobs(int snum,
2743 struct spoolss_Notify *data,
2744 print_queue_struct *queue,
2745 struct spoolss_PrinterInfo2 *pinfo2,
2746 TALLOC_CTX *mem_ctx)
2748 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2751 /*******************************************************************
2752 * fill a notify_info_data with the average ppm
2753 ********************************************************************/
2755 static void spoolss_notify_average_ppm(int snum,
2756 struct spoolss_Notify *data,
2757 print_queue_struct *queue,
2758 struct spoolss_PrinterInfo2 *pinfo2,
2759 TALLOC_CTX *mem_ctx)
2761 /* always respond 8 pages per minutes */
2762 /* a little hard ! */
2763 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2766 /*******************************************************************
2767 * fill a notify_info_data with username
2768 ********************************************************************/
2770 static void spoolss_notify_username(int snum,
2771 struct spoolss_Notify *data,
2772 print_queue_struct *queue,
2773 struct spoolss_PrinterInfo2 *pinfo2,
2774 TALLOC_CTX *mem_ctx)
2776 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2779 /*******************************************************************
2780 * fill a notify_info_data with job status
2781 ********************************************************************/
2783 static void spoolss_notify_job_status(int snum,
2784 struct spoolss_Notify *data,
2785 print_queue_struct *queue,
2786 struct spoolss_PrinterInfo2 *pinfo2,
2787 TALLOC_CTX *mem_ctx)
2789 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2792 /*******************************************************************
2793 * fill a notify_info_data with job name
2794 ********************************************************************/
2796 static void spoolss_notify_job_name(int snum,
2797 struct spoolss_Notify *data,
2798 print_queue_struct *queue,
2799 struct spoolss_PrinterInfo2 *pinfo2,
2800 TALLOC_CTX *mem_ctx)
2802 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2805 /*******************************************************************
2806 * fill a notify_info_data with job status
2807 ********************************************************************/
2809 static void spoolss_notify_job_status_string(int snum,
2810 struct spoolss_Notify *data,
2811 print_queue_struct *queue,
2812 struct spoolss_PrinterInfo2 *pinfo2,
2813 TALLOC_CTX *mem_ctx)
2816 * Now we're returning job status codes we just return a "" here. JRA.
2821 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2824 switch (queue->status) {
2829 p = ""; /* NT provides the paused string */
2838 #endif /* NO LONGER NEEDED. */
2840 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2843 /*******************************************************************
2844 * fill a notify_info_data with job time
2845 ********************************************************************/
2847 static void spoolss_notify_job_time(int snum,
2848 struct spoolss_Notify *data,
2849 print_queue_struct *queue,
2850 struct spoolss_PrinterInfo2 *pinfo2,
2851 TALLOC_CTX *mem_ctx)
2853 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2856 /*******************************************************************
2857 * fill a notify_info_data with job size
2858 ********************************************************************/
2860 static void spoolss_notify_job_size(int snum,
2861 struct spoolss_Notify *data,
2862 print_queue_struct *queue,
2863 struct spoolss_PrinterInfo2 *pinfo2,
2864 TALLOC_CTX *mem_ctx)
2866 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2869 /*******************************************************************
2870 * fill a notify_info_data with page info
2871 ********************************************************************/
2872 static void spoolss_notify_total_pages(int snum,
2873 struct spoolss_Notify *data,
2874 print_queue_struct *queue,
2875 struct spoolss_PrinterInfo2 *pinfo2,
2876 TALLOC_CTX *mem_ctx)
2878 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2881 /*******************************************************************
2882 * fill a notify_info_data with pages printed info.
2883 ********************************************************************/
2884 static void spoolss_notify_pages_printed(int snum,
2885 struct spoolss_Notify *data,
2886 print_queue_struct *queue,
2887 struct spoolss_PrinterInfo2 *pinfo2,
2888 TALLOC_CTX *mem_ctx)
2890 /* Add code when back-end tracks this */
2891 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2894 /*******************************************************************
2895 Fill a notify_info_data with job position.
2896 ********************************************************************/
2898 static void spoolss_notify_job_position(int snum,
2899 struct spoolss_Notify *data,
2900 print_queue_struct *queue,
2901 struct spoolss_PrinterInfo2 *pinfo2,
2902 TALLOC_CTX *mem_ctx)
2904 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2907 /*******************************************************************
2908 Fill a notify_info_data with submitted time.
2909 ********************************************************************/
2911 static void spoolss_notify_submitted_time(int snum,
2912 struct spoolss_Notify *data,
2913 print_queue_struct *queue,
2914 struct spoolss_PrinterInfo2 *pinfo2,
2915 TALLOC_CTX *mem_ctx)
2917 data->data.string.string = NULL;
2918 data->data.string.size = 0;
2920 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2921 &data->data.string.string,
2922 &data->data.string.size);
2926 struct s_notify_info_data_table
2928 enum spoolss_NotifyType type;
2931 enum spoolss_NotifyTable variable_type;
2932 void (*fn) (int snum, struct spoolss_Notify *data,
2933 print_queue_struct *queue,
2934 struct spoolss_PrinterInfo2 *pinfo2,
2935 TALLOC_CTX *mem_ctx);
2938 /* A table describing the various print notification constants and
2939 whether the notification data is a pointer to a variable sized
2940 buffer, a one value uint32_t or a two value uint32_t. */
2942 static const struct s_notify_info_data_table notify_info_data_table[] =
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2950 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2951 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2952 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2953 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2954 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2955 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2956 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2957 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2958 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2959 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2960 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2961 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2962 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2963 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2964 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2965 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2966 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2967 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2968 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2969 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2970 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2971 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2972 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2973 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2974 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2975 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2976 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2977 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2978 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2979 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2980 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2981 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2982 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2983 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2984 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2985 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2986 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2987 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2988 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2989 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2990 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2991 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2992 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2995 /*******************************************************************
2996 Return the variable_type of info_data structure.
2997 ********************************************************************/
2999 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3004 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3005 if ( (notify_info_data_table[i].type == type) &&
3006 (notify_info_data_table[i].field == field) ) {
3007 return notify_info_data_table[i].variable_type;
3011 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3016 /****************************************************************************
3017 ****************************************************************************/
3019 static bool search_notify(enum spoolss_NotifyType type,
3025 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3026 if (notify_info_data_table[i].type == type &&
3027 notify_info_data_table[i].field == field &&
3028 notify_info_data_table[i].fn != NULL) {
3037 /****************************************************************************
3038 ****************************************************************************/
3040 static void construct_info_data(struct spoolss_Notify *info_data,
3041 enum spoolss_NotifyType type,
3042 uint16_t field, int id)
3044 info_data->type = type;
3045 info_data->field.field = field;
3046 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3047 info_data->job_id = id;
3050 /*******************************************************************
3052 * fill a notify_info struct with info asked
3054 ********************************************************************/
3056 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3057 struct spoolss_NotifyInfo *info,
3058 struct spoolss_PrinterInfo2 *pinfo2,
3060 const struct spoolss_NotifyOptionType *option_type,
3062 TALLOC_CTX *mem_ctx)
3065 enum spoolss_NotifyType type;
3068 struct spoolss_Notify *current_data;
3069 print_queue_struct *queue=NULL;
3071 type = option_type->type;
3073 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3074 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3075 option_type->count, lp_servicename(snum)));
3077 for(field_num=0; field_num < option_type->count; field_num++) {
3078 field = option_type->fields[field_num].field;
3080 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3082 if (!search_notify(type, field, &j) )
3085 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3086 struct spoolss_Notify,
3088 if (info->notifies == NULL) {
3089 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3093 current_data = &info->notifies[info->count];
3095 construct_info_data(current_data, type, field, id);
3097 DEBUG(10, ("construct_notify_printer_info: "
3098 "calling [%s] snum=%d printername=[%s])\n",
3099 notify_info_data_table[j].name, snum,
3100 pinfo2->printername));
3102 notify_info_data_table[j].fn(snum, current_data, queue,
3111 /*******************************************************************
3113 * fill a notify_info struct with info asked
3115 ********************************************************************/
3117 static bool construct_notify_jobs_info(print_queue_struct *queue,
3118 struct spoolss_NotifyInfo *info,
3119 struct spoolss_PrinterInfo2 *pinfo2,
3121 const struct spoolss_NotifyOptionType *option_type,
3123 TALLOC_CTX *mem_ctx)
3126 enum spoolss_NotifyType type;
3128 struct spoolss_Notify *current_data;
3130 DEBUG(4,("construct_notify_jobs_info\n"));
3132 type = option_type->type;
3134 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3135 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3136 option_type->count));
3138 for(field_num=0; field_num<option_type->count; field_num++) {
3139 field = option_type->fields[field_num].field;
3141 if (!search_notify(type, field, &j) )
3144 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3145 struct spoolss_Notify,
3147 if (info->notifies == NULL) {
3148 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3152 current_data=&(info->notifies[info->count]);
3154 construct_info_data(current_data, type, field, id);
3155 notify_info_data_table[j].fn(snum, current_data, queue,
3164 * JFM: The enumeration is not that simple, it's even non obvious.
3166 * let's take an example: I want to monitor the PRINTER SERVER for
3167 * the printer's name and the number of jobs currently queued.
3168 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3169 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3171 * I have 3 printers on the back of my server.
3173 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3176 * 1 printer 1 name 1
3177 * 2 printer 1 cjob 1
3178 * 3 printer 2 name 2
3179 * 4 printer 2 cjob 2
3180 * 5 printer 3 name 3
3181 * 6 printer 3 name 3
3183 * that's the print server case, the printer case is even worse.
3186 /*******************************************************************
3188 * enumerate all printers on the printserver
3189 * fill a notify_info struct with info asked
3191 ********************************************************************/
3193 static WERROR printserver_notify_info(struct pipes_struct *p,
3194 struct policy_handle *hnd,
3195 struct spoolss_NotifyInfo *info,
3196 TALLOC_CTX *mem_ctx)
3199 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3200 int n_services=lp_numservices();
3202 struct spoolss_NotifyOption *option;
3203 struct spoolss_NotifyOptionType option_type;
3204 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3207 DEBUG(4,("printserver_notify_info\n"));
3212 option = Printer->notify.option;
3215 info->notifies = NULL;
3218 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3219 sending a ffpcn() request first */
3224 for (i=0; i<option->count; i++) {
3225 option_type = option->types[i];
3227 if (option_type.type != PRINTER_NOTIFY_TYPE)
3230 for (snum = 0; snum < n_services; snum++) {
3231 if (!lp_browseable(snum) ||
3232 !lp_snum_ok(snum) ||
3233 !lp_print_ok(snum)) {
3234 continue; /* skip */
3237 /* Maybe we should use the SYSTEM server_info here... */
3238 result = winreg_get_printer(mem_ctx, p->server_info,
3240 Printer->servername,
3241 lp_servicename(snum),
3243 if (!W_ERROR_IS_OK(result)) {
3244 DEBUG(4, ("printserver_notify_info: "
3245 "Failed to get printer [%s]\n",
3246 lp_servicename(snum)));
3251 construct_notify_printer_info(Printer, info,
3256 TALLOC_FREE(pinfo2);
3262 * Debugging information, don't delete.
3265 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3266 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3267 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3269 for (i=0; i<info->count; i++) {
3270 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3271 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3272 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3279 /*******************************************************************
3281 * fill a notify_info struct with info asked
3283 ********************************************************************/
3285 static WERROR printer_notify_info(struct pipes_struct *p,
3286 struct policy_handle *hnd,
3287 struct spoolss_NotifyInfo *info,
3288 TALLOC_CTX *mem_ctx)
3291 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3294 struct spoolss_NotifyOption *option;
3295 struct spoolss_NotifyOptionType option_type;
3297 print_queue_struct *queue=NULL;
3298 print_status_struct status;
3299 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3302 DEBUG(4,("printer_notify_info\n"));
3307 option = Printer->notify.option;
3311 info->notifies = NULL;
3314 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3315 sending a ffpcn() request first */
3320 get_printer_snum(p, hnd, &snum, NULL);
3322 /* Maybe we should use the SYSTEM server_info here... */
3323 result = winreg_get_printer(mem_ctx, p->server_info, p->msg_ctx,
3324 Printer->servername,
3325 lp_servicename(snum), &pinfo2);
3326 if (!W_ERROR_IS_OK(result)) {
3330 for (i=0; i<option->count; i++) {
3331 option_type = option->types[i];
3333 switch (option_type.type) {
3334 case PRINTER_NOTIFY_TYPE:
3335 if (construct_notify_printer_info(Printer, info,
3343 case JOB_NOTIFY_TYPE:
3345 count = print_queue_status(snum, &queue, &status);
3347 for (j=0; j<count; j++) {
3348 construct_notify_jobs_info(&queue[j], info,
3361 * Debugging information, don't delete.
3364 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3365 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3366 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3368 for (i=0; i<info->count; i++) {
3369 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3370 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3371 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3375 talloc_free(pinfo2);
3379 /****************************************************************
3380 _spoolss_RouterRefreshPrinterChangeNotify
3381 ****************************************************************/
3383 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3384 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3386 struct spoolss_NotifyInfo *info;
3388 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3389 WERROR result = WERR_BADFID;
3391 /* we always have a spoolss_NotifyInfo struct */
3392 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3394 result = WERR_NOMEM;
3398 *r->out.info = info;
3401 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3402 "Invalid handle (%s:%u:%u).\n",
3403 OUR_HANDLE(r->in.handle)));
3407 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3410 * We are now using the change value, and
3411 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3412 * I don't have a global notification system, I'm sending back all the
3413 * informations even when _NOTHING_ has changed.
3416 /* We need to keep track of the change value to send back in
3417 RRPCN replies otherwise our updates are ignored. */
3419 Printer->notify.fnpcn = true;
3421 if (Printer->notify.client_connected) {
3422 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3423 "Saving change value in request [%x]\n",
3425 Printer->notify.change = r->in.change_low;
3428 /* just ignore the spoolss_NotifyOption */
3430 switch (Printer->printer_type) {
3432 result = printserver_notify_info(p, r->in.handle,
3436 case SPLHND_PRINTER:
3437 result = printer_notify_info(p, r->in.handle,
3442 Printer->notify.fnpcn = false;
3448 /********************************************************************
3449 * construct_printer_info_0
3450 * fill a printer_info_0 struct
3451 ********************************************************************/
3453 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3454 struct auth_serversupplied_info *server_info,
3455 struct spoolss_PrinterInfo2 *info2,
3456 struct spoolss_PrinterInfo0 *r,
3460 counter_printer_0 *session_counter;
3461 struct timeval setuptime;
3462 print_status_struct status;
3464 r->printername = talloc_strdup(mem_ctx, info2->printername);
3465 W_ERROR_HAVE_NO_MEMORY(r->printername);
3467 r->servername = talloc_strdup(mem_ctx, info2->servername);
3468 W_ERROR_HAVE_NO_MEMORY(r->servername);
3470 count = print_queue_length(snum, &status);
3472 /* check if we already have a counter for this printer */
3473 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3474 if (session_counter->snum == snum)
3478 /* it's the first time, add it to the list */
3479 if (session_counter == NULL) {
3480 session_counter = SMB_MALLOC_P(counter_printer_0);
3481 W_ERROR_HAVE_NO_MEMORY(session_counter);
3482 ZERO_STRUCTP(session_counter);
3483 session_counter->snum = snum;
3484 session_counter->counter = 0;
3485 DLIST_ADD(counter_list, session_counter);
3489 session_counter->counter++;
3495 get_startup_time(&setuptime);
3496 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3499 * the global_counter should be stored in a TDB as it's common to all the clients
3500 * and should be zeroed on samba startup
3502 r->global_counter = session_counter->counter;
3504 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3505 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3506 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3507 r->free_build = SPOOLSS_RELEASE_BUILD;
3509 r->max_spooling = 0;
3510 r->session_counter = session_counter->counter;
3511 r->num_error_out_of_paper = 0x0;
3512 r->num_error_not_ready = 0x0; /* number of print failure */
3514 r->number_of_processors = 0x1;
3515 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3516 r->high_part_total_bytes = 0x0;
3518 /* ChangeID in milliseconds*/
3519 winreg_printer_get_changeid(mem_ctx, server_info,
3520 smbd_messaging_context(),
3521 info2->sharename, &r->change_id);
3523 r->last_error = WERR_OK;
3524 r->status = nt_printq_status(status.status);
3525 r->enumerate_network_printers = 0x0;
3526 r->c_setprinter = 0x0;
3527 r->processor_architecture = 0x0;
3528 r->processor_level = 0x6; /* 6 ???*/
3537 /********************************************************************
3538 * construct_printer_info1
3539 * fill a spoolss_PrinterInfo1 struct
3540 ********************************************************************/
3542 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3543 const struct spoolss_PrinterInfo2 *info2,
3545 struct spoolss_PrinterInfo1 *r,
3550 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3554 W_ERROR_HAVE_NO_MEMORY(r->description);
3556 if (info2->comment == NULL || info2->comment[0] == '\0') {
3557 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3559 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3561 W_ERROR_HAVE_NO_MEMORY(r->comment);
3563 r->name = talloc_strdup(mem_ctx, info2->printername);
3564 W_ERROR_HAVE_NO_MEMORY(r->name);
3569 /********************************************************************
3570 * construct_printer_info2
3571 * fill a spoolss_PrinterInfo2 struct
3572 ********************************************************************/
3574 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3575 const struct spoolss_PrinterInfo2 *info2,
3576 struct spoolss_PrinterInfo2 *r,
3580 print_status_struct status;
3582 count = print_queue_length(snum, &status);
3584 r->servername = talloc_strdup(mem_ctx, info2->servername);
3585 W_ERROR_HAVE_NO_MEMORY(r->servername);
3586 r->printername = talloc_strdup(mem_ctx, info2->printername);
3587 W_ERROR_HAVE_NO_MEMORY(r->printername);
3588 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3589 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3590 r->portname = talloc_strdup(mem_ctx, info2->portname);
3591 W_ERROR_HAVE_NO_MEMORY(r->portname);
3592 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3593 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3595 if (info2->comment[0] == '\0') {
3596 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3598 r->comment = talloc_strdup(mem_ctx, info2->comment);
3600 W_ERROR_HAVE_NO_MEMORY(r->comment);
3602 r->location = talloc_strdup(mem_ctx, info2->location);
3603 W_ERROR_HAVE_NO_MEMORY(r->location);
3604 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3605 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3606 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3607 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3608 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3609 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3610 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3611 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3613 r->attributes = info2->attributes;
3615 r->priority = info2->priority;
3616 r->defaultpriority = info2->defaultpriority;
3617 r->starttime = info2->starttime;
3618 r->untiltime = info2->untiltime;
3619 r->status = nt_printq_status(status.status);
3621 r->averageppm = info2->averageppm;
3623 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3625 DEBUG(8,("Returning NULL Devicemode!\n"));
3630 if (info2->secdesc != NULL) {
3631 /* don't use talloc_steal() here unless you do a deep steal of all
3632 the SEC_DESC members */
3634 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3640 /********************************************************************
3641 * construct_printer_info3
3642 * fill a spoolss_PrinterInfo3 struct
3643 ********************************************************************/
3645 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3646 const struct spoolss_PrinterInfo2 *info2,
3647 struct spoolss_PrinterInfo3 *r,
3650 /* These are the components of the SD we are returning. */
3652 if (info2->secdesc != NULL) {
3653 /* don't use talloc_steal() here unless you do a deep steal of all
3654 the SEC_DESC members */
3656 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3657 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3663 /********************************************************************
3664 * construct_printer_info4
3665 * fill a spoolss_PrinterInfo4 struct
3666 ********************************************************************/
3668 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3669 const struct spoolss_PrinterInfo2 *info2,
3670 struct spoolss_PrinterInfo4 *r,
3673 r->printername = talloc_strdup(mem_ctx, info2->printername);
3674 W_ERROR_HAVE_NO_MEMORY(r->printername);
3675 r->servername = talloc_strdup(mem_ctx, info2->servername);
3676 W_ERROR_HAVE_NO_MEMORY(r->servername);
3678 r->attributes = info2->attributes;
3683 /********************************************************************
3684 * construct_printer_info5
3685 * fill a spoolss_PrinterInfo5 struct
3686 ********************************************************************/
3688 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3689 const struct spoolss_PrinterInfo2 *info2,
3690 struct spoolss_PrinterInfo5 *r,
3693 r->printername = talloc_strdup(mem_ctx, info2->printername);
3694 W_ERROR_HAVE_NO_MEMORY(r->printername);
3695 r->portname = talloc_strdup(mem_ctx, info2->portname);
3696 W_ERROR_HAVE_NO_MEMORY(r->portname);
3698 r->attributes = info2->attributes;
3700 /* these two are not used by NT+ according to MSDN */
3701 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3702 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3707 /********************************************************************
3708 * construct_printer_info_6
3709 * fill a spoolss_PrinterInfo6 struct
3710 ********************************************************************/
3712 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3713 const struct spoolss_PrinterInfo2 *info2,
3714 struct spoolss_PrinterInfo6 *r,
3718 print_status_struct status;
3720 count = print_queue_length(snum, &status);
3722 r->status = nt_printq_status(status.status);
3727 /********************************************************************
3728 * construct_printer_info7
3729 * fill a spoolss_PrinterInfo7 struct
3730 ********************************************************************/
3732 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3733 Printer_entry *print_hnd,
3734 struct spoolss_PrinterInfo7 *r,
3737 struct auth_serversupplied_info *server_info;
3741 status = make_server_info_system(mem_ctx, &server_info);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 DEBUG(0, ("construct_printer_info7: "
3744 "Could not create system server_info\n"));
3748 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3749 lp_servicename(snum), &guid, NULL)) {
3750 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3751 r->action = DSPRINT_PUBLISH;
3753 r->guid = talloc_strdup(mem_ctx, "");
3754 r->action = DSPRINT_UNPUBLISH;
3756 W_ERROR_HAVE_NO_MEMORY(r->guid);
3758 TALLOC_FREE(server_info);
3762 /********************************************************************
3763 * construct_printer_info8
3764 * fill a spoolss_PrinterInfo8 struct
3765 ********************************************************************/
3767 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3768 const struct spoolss_PrinterInfo2 *info2,
3769 struct spoolss_DeviceModeInfo *r,
3772 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3774 DEBUG(8,("Returning NULL Devicemode!\n"));
3781 /********************************************************************
3782 ********************************************************************/
3784 static bool snum_is_shared_printer(int snum)
3786 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3789 /********************************************************************
3790 Spoolss_enumprinters.
3791 ********************************************************************/
3793 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3794 struct auth_serversupplied_info *server_info,
3797 union spoolss_PrinterInfo **info_p,
3801 int n_services = lp_numservices();
3802 union spoolss_PrinterInfo *info = NULL;
3804 WERROR result = WERR_OK;
3809 for (snum = 0; snum < n_services; snum++) {
3811 const char *printer;
3812 struct spoolss_PrinterInfo2 *info2;
3814 if (!snum_is_shared_printer(snum)) {
3818 printer = lp_const_servicename(snum);
3820 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3823 result = winreg_create_printer(mem_ctx,
3825 smbd_messaging_context(),
3828 if (!W_ERROR_IS_OK(result)) {
3832 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3833 union spoolss_PrinterInfo,
3836 result = WERR_NOMEM;
3840 result = winreg_get_printer(mem_ctx, server_info,
3841 smbd_messaging_context(),
3842 NULL, printer, &info2);
3843 if (!W_ERROR_IS_OK(result)) {
3849 result = construct_printer_info0(info, server_info, info2,
3850 &info[count].info0, snum);
3853 result = construct_printer_info1(info, info2, flags,
3854 &info[count].info1, snum);
3857 result = construct_printer_info2(info, info2,
3858 &info[count].info2, snum);
3861 result = construct_printer_info4(info, info2,
3862 &info[count].info4, snum);
3865 result = construct_printer_info5(info, info2,
3866 &info[count].info5, snum);
3870 result = WERR_UNKNOWN_LEVEL;
3874 if (!W_ERROR_IS_OK(result)) {
3885 if (!W_ERROR_IS_OK(result)) {
3895 /********************************************************************
3896 * handle enumeration of printers at level 0
3897 ********************************************************************/
3899 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3900 struct auth_serversupplied_info *server_info,
3902 const char *servername,
3903 union spoolss_PrinterInfo **info,
3906 DEBUG(4,("enum_all_printers_info_0\n"));
3908 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3912 /********************************************************************
3913 ********************************************************************/
3915 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3916 struct auth_serversupplied_info *server_info,
3918 union spoolss_PrinterInfo **info,
3921 DEBUG(4,("enum_all_printers_info_1\n"));
3923 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3926 /********************************************************************
3927 enum_all_printers_info_1_local.
3928 *********************************************************************/
3930 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3931 struct auth_serversupplied_info *server_info,
3932 union spoolss_PrinterInfo **info,
3935 DEBUG(4,("enum_all_printers_info_1_local\n"));
3937 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3940 /********************************************************************
3941 enum_all_printers_info_1_name.
3942 *********************************************************************/
3944 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3945 struct auth_serversupplied_info *server_info,
3947 union spoolss_PrinterInfo **info,
3950 const char *s = name;
3952 DEBUG(4,("enum_all_printers_info_1_name\n"));
3954 if ((name[0] == '\\') && (name[1] == '\\')) {
3958 if (!is_myname_or_ipaddr(s)) {
3959 return WERR_INVALID_NAME;
3962 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3965 /********************************************************************
3966 enum_all_printers_info_1_network.
3967 *********************************************************************/
3969 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3970 struct auth_serversupplied_info *server_info,
3972 union spoolss_PrinterInfo **info,
3975 const char *s = name;
3977 DEBUG(4,("enum_all_printers_info_1_network\n"));
3979 /* If we respond to a enum_printers level 1 on our name with flags
3980 set to PRINTER_ENUM_REMOTE with a list of printers then these
3981 printers incorrectly appear in the APW browse list.
3982 Specifically the printers for the server appear at the workgroup
3983 level where all the other servers in the domain are
3984 listed. Windows responds to this call with a
3985 WERR_CAN_NOT_COMPLETE so we should do the same. */
3987 if (name[0] == '\\' && name[1] == '\\') {
3991 if (is_myname_or_ipaddr(s)) {
3992 return WERR_CAN_NOT_COMPLETE;
3995 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3998 /********************************************************************
3999 * api_spoolss_enumprinters
4001 * called from api_spoolss_enumprinters (see this to understand)
4002 ********************************************************************/
4004 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4005 struct auth_serversupplied_info *server_info,
4006 union spoolss_PrinterInfo **info,
4009 DEBUG(4,("enum_all_printers_info_2\n"));
4011 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
4014 /********************************************************************
4015 * handle enumeration of printers at level 1
4016 ********************************************************************/
4018 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4019 struct auth_serversupplied_info *server_info,
4022 union spoolss_PrinterInfo **info,
4025 /* Not all the flags are equals */
4027 if (flags & PRINTER_ENUM_LOCAL) {
4028 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4031 if (flags & PRINTER_ENUM_NAME) {
4032 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4035 if (flags & PRINTER_ENUM_NETWORK) {
4036 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4039 return WERR_OK; /* NT4sp5 does that */
4042 /********************************************************************
4043 * handle enumeration of printers at level 2
4044 ********************************************************************/
4046 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4047 struct auth_serversupplied_info *server_info,
4049 const char *servername,
4050 union spoolss_PrinterInfo **info,
4053 if (flags & PRINTER_ENUM_LOCAL) {
4054 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4057 if (flags & PRINTER_ENUM_NAME) {
4058 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4059 return WERR_INVALID_NAME;
4062 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4065 if (flags & PRINTER_ENUM_REMOTE) {
4066 return WERR_UNKNOWN_LEVEL;
4072 /********************************************************************
4073 * handle enumeration of printers at level 4
4074 ********************************************************************/
4076 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4077 struct auth_serversupplied_info *server_info,
4079 const char *servername,
4080 union spoolss_PrinterInfo **info,
4083 DEBUG(4,("enum_all_printers_info_4\n"));
4085 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4089 /********************************************************************
4090 * handle enumeration of printers at level 5
4091 ********************************************************************/
4093 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4094 struct auth_serversupplied_info *server_info,
4096 const char *servername,
4097 union spoolss_PrinterInfo **info,
4100 DEBUG(4,("enum_all_printers_info_5\n"));
4102 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4105 /****************************************************************
4106 _spoolss_EnumPrinters
4107 ****************************************************************/
4109 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4110 struct spoolss_EnumPrinters *r)
4112 const char *name = NULL;
4115 /* that's an [in out] buffer */
4117 if (!r->in.buffer && (r->in.offered != 0)) {
4118 return WERR_INVALID_PARAM;
4121 DEBUG(4,("_spoolss_EnumPrinters\n"));
4125 *r->out.info = NULL;
4129 * flags==PRINTER_ENUM_NAME
4130 * if name=="" then enumerates all printers
4131 * if name!="" then enumerate the printer
4132 * flags==PRINTER_ENUM_REMOTE
4133 * name is NULL, enumerate printers
4134 * Level 2: name!="" enumerates printers, name can't be NULL
4135 * Level 3: doesn't exist
4136 * Level 4: does a local registry lookup
4137 * Level 5: same as Level 2
4141 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4142 W_ERROR_HAVE_NO_MEMORY(name);
4145 switch (r->in.level) {
4147 result = enumprinters_level0(p->mem_ctx, p->server_info,
4149 r->out.info, r->out.count);
4152 result = enumprinters_level1(p->mem_ctx, p->server_info,
4154 r->out.info, r->out.count);
4157 result = enumprinters_level2(p->mem_ctx, p->server_info,
4159 r->out.info, r->out.count);
4162 result = enumprinters_level4(p->mem_ctx, p->server_info,
4164 r->out.info, r->out.count);
4167 result = enumprinters_level5(p->mem_ctx, p->server_info,
4169 r->out.info, r->out.count);
4172 return WERR_UNKNOWN_LEVEL;
4175 if (!W_ERROR_IS_OK(result)) {
4179 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4180 spoolss_EnumPrinters,
4181 *r->out.info, r->in.level,
4183 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4184 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4186 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4189 /****************************************************************
4191 ****************************************************************/
4193 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4194 struct spoolss_GetPrinter *r)
4196 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4197 struct spoolss_PrinterInfo2 *info2 = NULL;
4198 WERROR result = WERR_OK;
4199 const char *servername = NULL;
4202 /* that's an [in out] buffer */
4204 if (!r->in.buffer && (r->in.offered != 0)) {
4205 return WERR_INVALID_PARAM;
4210 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4214 if (Printer != NULL || Printer->servername != NULL) {
4215 servername = Printer->servername;
4218 result = winreg_get_printer(p->mem_ctx,
4222 lp_const_servicename(snum),
4224 if (!W_ERROR_IS_OK(result)) {
4228 switch (r->in.level) {
4230 result = construct_printer_info0(p->mem_ctx, p->server_info,
4232 &r->out.info->info0, snum);
4235 result = construct_printer_info1(p->mem_ctx, info2,
4237 &r->out.info->info1, snum);
4240 result = construct_printer_info2(p->mem_ctx, info2,
4241 &r->out.info->info2, snum);
4244 result = construct_printer_info3(p->mem_ctx, info2,
4245 &r->out.info->info3, snum);
4248 result = construct_printer_info4(p->mem_ctx, info2,
4249 &r->out.info->info4, snum);
4252 result = construct_printer_info5(p->mem_ctx, info2,
4253 &r->out.info->info5, snum);
4256 result = construct_printer_info6(p->mem_ctx, info2,
4257 &r->out.info->info6, snum);
4260 result = construct_printer_info7(p->mem_ctx, Printer,
4261 &r->out.info->info7, snum);
4264 result = construct_printer_info8(p->mem_ctx, info2,
4265 &r->out.info->info8, snum);
4268 result = WERR_UNKNOWN_LEVEL;
4272 if (!W_ERROR_IS_OK(result)) {
4273 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4274 r->in.level, win_errstr(result)));
4275 TALLOC_FREE(r->out.info);
4279 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4280 r->out.info, r->in.level);
4281 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4283 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4286 /********************************************************************
4287 ********************************************************************/
4289 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4291 if (in && strlen(in)) { \
4292 out = talloc_strdup(mem_ctx, in); \
4294 out = talloc_strdup(mem_ctx, ""); \
4296 W_ERROR_HAVE_NO_MEMORY(out); \
4299 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4301 if (in && strlen(in)) { \
4302 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4304 out = talloc_strdup(mem_ctx, ""); \
4306 W_ERROR_HAVE_NO_MEMORY(out); \
4309 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4310 const char **string_array,
4311 const char ***presult,
4312 const char *cservername,
4316 int i, num_strings = 0;
4317 const char **array = NULL;
4319 if (string_array == NULL) {
4320 return WERR_INVALID_PARAMETER;;
4323 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4324 const char *str = NULL;
4326 if (cservername == NULL || arch == NULL) {
4327 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4329 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4332 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4339 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4340 &array, &num_strings);
4350 /********************************************************************
4351 * fill a spoolss_DriverInfo1 struct
4352 ********************************************************************/
4354 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4355 struct spoolss_DriverInfo1 *r,
4356 const struct spoolss_DriverInfo8 *driver,
4357 const char *servername)
4359 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4360 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4365 /********************************************************************
4366 * fill a spoolss_DriverInfo2 struct
4367 ********************************************************************/
4369 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4370 struct spoolss_DriverInfo2 *r,
4371 const struct spoolss_DriverInfo8 *driver,
4372 const char *servername)
4375 const char *cservername = canon_servername(servername);
4377 r->version = driver->version;
4379 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4380 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4381 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4382 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4384 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4385 driver->architecture,
4387 driver->driver_path,
4390 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4391 driver->architecture,
4396 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4397 driver->architecture,
4399 driver->config_file,
4405 /********************************************************************
4406 * fill a spoolss_DriverInfo3 struct
4407 ********************************************************************/
4409 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4410 struct spoolss_DriverInfo3 *r,
4411 const struct spoolss_DriverInfo8 *driver,
4412 const char *servername)
4414 const char *cservername = canon_servername(servername);
4416 r->version = driver->version;
4418 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4419 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4420 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4421 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4423 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4424 driver->architecture,
4426 driver->driver_path,
4429 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4430 driver->architecture,
4435 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4436 driver->architecture,
4438 driver->config_file,
4441 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4442 driver->architecture,
4447 FILL_DRIVER_STRING(mem_ctx,
4448 driver->monitor_name,
4451 FILL_DRIVER_STRING(mem_ctx,
4452 driver->default_datatype,
4453 r->default_datatype);
4455 return string_array_from_driver_info(mem_ctx,
4456 driver->dependent_files,
4457 &r->dependent_files,
4459 driver->architecture,
4463 /********************************************************************
4464 * fill a spoolss_DriverInfo4 struct
4465 ********************************************************************/
4467 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4468 struct spoolss_DriverInfo4 *r,
4469 const struct spoolss_DriverInfo8 *driver,
4470 const char *servername)
4472 const char *cservername = canon_servername(servername);
4475 r->version = driver->version;
4477 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4478 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4479 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4480 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4482 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4483 driver->architecture,
4485 driver->driver_path,
4488 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4489 driver->architecture,
4494 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4495 driver->architecture,
4497 driver->config_file,
4500 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4501 driver->architecture,
4506 result = string_array_from_driver_info(mem_ctx,
4507 driver->dependent_files,
4508 &r->dependent_files,
4510 driver->architecture,
4512 if (!W_ERROR_IS_OK(result)) {
4516 FILL_DRIVER_STRING(mem_ctx,
4517 driver->monitor_name,
4520 FILL_DRIVER_STRING(mem_ctx,
4521 driver->default_datatype,
4522 r->default_datatype);
4525 result = string_array_from_driver_info(mem_ctx,
4526 driver->previous_names,
4533 /********************************************************************
4534 * fill a spoolss_DriverInfo5 struct
4535 ********************************************************************/
4537 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4538 struct spoolss_DriverInfo5 *r,
4539 const struct spoolss_DriverInfo8 *driver,
4540 const char *servername)
4542 const char *cservername = canon_servername(servername);
4544 r->version = driver->version;
4546 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4547 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4548 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4549 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4551 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4552 driver->architecture,
4554 driver->driver_path,
4557 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4558 driver->architecture,
4563 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4564 driver->architecture,
4566 driver->config_file,
4569 r->driver_attributes = 0;
4570 r->config_version = 0;
4571 r->driver_version = 0;
4575 /********************************************************************
4576 * fill a spoolss_DriverInfo6 struct
4577 ********************************************************************/
4579 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4580 struct spoolss_DriverInfo6 *r,
4581 const struct spoolss_DriverInfo8 *driver,
4582 const char *servername)
4584 const char *cservername = canon_servername(servername);
4587 r->version = driver->version;
4589 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4590 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4591 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4592 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4594 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4595 driver->architecture,
4597 driver->driver_path,
4600 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4601 driver->architecture,
4606 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4607 driver->architecture,
4609 driver->config_file,
4612 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4613 driver->architecture,
4618 FILL_DRIVER_STRING(mem_ctx,
4619 driver->monitor_name,
4622 FILL_DRIVER_STRING(mem_ctx,
4623 driver->default_datatype,
4624 r->default_datatype);
4626 result = string_array_from_driver_info(mem_ctx,
4627 driver->dependent_files,
4628 &r->dependent_files,
4630 driver->architecture,
4632 if (!W_ERROR_IS_OK(result)) {
4636 result = string_array_from_driver_info(mem_ctx,
4637 driver->previous_names,
4640 if (!W_ERROR_IS_OK(result)) {
4644 r->driver_date = driver->driver_date;
4645 r->driver_version = driver->driver_version;
4647 FILL_DRIVER_STRING(mem_ctx,
4648 driver->manufacturer_name,
4649 r->manufacturer_name);
4650 FILL_DRIVER_STRING(mem_ctx,
4651 driver->manufacturer_url,
4652 r->manufacturer_url);
4653 FILL_DRIVER_STRING(mem_ctx,
4654 driver->hardware_id,
4656 FILL_DRIVER_STRING(mem_ctx,
4663 /********************************************************************
4664 * fill a spoolss_DriverInfo8 struct
4665 ********************************************************************/
4667 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4668 struct spoolss_DriverInfo8 *r,
4669 const struct spoolss_DriverInfo8 *driver,
4670 const char *servername)
4672 const char *cservername = canon_servername(servername);
4675 r->version = driver->version;
4677 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4678 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4679 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4680 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4682 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4683 driver->architecture,
4685 driver->driver_path,
4688 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4689 driver->architecture,
4694 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4695 driver->architecture,
4697 driver->config_file,
4700 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4701 driver->architecture,
4706 FILL_DRIVER_STRING(mem_ctx,
4707 driver->monitor_name,
4710 FILL_DRIVER_STRING(mem_ctx,
4711 driver->default_datatype,
4712 r->default_datatype);
4714 result = string_array_from_driver_info(mem_ctx,
4715 driver->dependent_files,
4716 &r->dependent_files,
4718 driver->architecture,
4720 if (!W_ERROR_IS_OK(result)) {
4724 result = string_array_from_driver_info(mem_ctx,
4725 driver->previous_names,
4728 if (!W_ERROR_IS_OK(result)) {
4732 r->driver_date = driver->driver_date;
4733 r->driver_version = driver->driver_version;
4735 FILL_DRIVER_STRING(mem_ctx,
4736 driver->manufacturer_name,
4737 r->manufacturer_name);
4738 FILL_DRIVER_STRING(mem_ctx,
4739 driver->manufacturer_url,
4740 r->manufacturer_url);
4741 FILL_DRIVER_STRING(mem_ctx,
4742 driver->hardware_id,
4744 FILL_DRIVER_STRING(mem_ctx,
4748 FILL_DRIVER_STRING(mem_ctx,
4749 driver->print_processor,
4750 r->print_processor);
4751 FILL_DRIVER_STRING(mem_ctx,
4752 driver->vendor_setup,
4755 result = string_array_from_driver_info(mem_ctx,
4756 driver->color_profiles,
4759 if (!W_ERROR_IS_OK(result)) {
4763 FILL_DRIVER_STRING(mem_ctx,
4767 r->printer_driver_attributes = driver->printer_driver_attributes;
4769 result = string_array_from_driver_info(mem_ctx,
4770 driver->core_driver_dependencies,
4771 &r->core_driver_dependencies,
4773 if (!W_ERROR_IS_OK(result)) {
4777 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4778 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4783 #if 0 /* disabled until marshalling issues are resolved - gd */
4784 /********************************************************************
4785 ********************************************************************/
4787 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4788 struct spoolss_DriverFileInfo *r,
4789 const char *cservername,
4790 const char *file_name,
4791 enum spoolss_DriverFileType file_type,
4792 uint32_t file_version)
4794 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4795 cservername, file_name);
4796 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4797 r->file_type = file_type;
4798 r->file_version = file_version;
4803 /********************************************************************
4804 ********************************************************************/
4806 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4807 const struct spoolss_DriverInfo8 *driver,
4808 const char *cservername,
4809 struct spoolss_DriverFileInfo **info_p,
4812 struct spoolss_DriverFileInfo *info = NULL;
4820 if (strlen(driver->driver_path)) {
4821 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4822 struct spoolss_DriverFileInfo,
4824 W_ERROR_HAVE_NO_MEMORY(info);
4825 result = fill_spoolss_DriverFileInfo(info,
4828 driver->driver_path,
4829 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4831 W_ERROR_NOT_OK_RETURN(result);
4835 if (strlen(driver->config_file)) {
4836 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4837 struct spoolss_DriverFileInfo,
4839 W_ERROR_HAVE_NO_MEMORY(info);
4840 result = fill_spoolss_DriverFileInfo(info,
4843 driver->config_file,
4844 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4846 W_ERROR_NOT_OK_RETURN(result);
4850 if (strlen(driver->data_file)) {
4851 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4852 struct spoolss_DriverFileInfo,
4854 W_ERROR_HAVE_NO_MEMORY(info);
4855 result = fill_spoolss_DriverFileInfo(info,
4859 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4861 W_ERROR_NOT_OK_RETURN(result);
4865 if (strlen(driver->help_file)) {
4866 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4867 struct spoolss_DriverFileInfo,
4869 W_ERROR_HAVE_NO_MEMORY(info);
4870 result = fill_spoolss_DriverFileInfo(info,
4874 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4876 W_ERROR_NOT_OK_RETURN(result);
4880 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4881 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4882 struct spoolss_DriverFileInfo,
4884 W_ERROR_HAVE_NO_MEMORY(info);
4885 result = fill_spoolss_DriverFileInfo(info,
4888 driver->dependent_files[i],
4889 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4891 W_ERROR_NOT_OK_RETURN(result);
4901 /********************************************************************
4902 * fill a spoolss_DriverInfo101 struct
4903 ********************************************************************/
4905 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4906 struct spoolss_DriverInfo101 *r,
4907 const struct spoolss_DriverInfo8 *driver,
4908 const char *servername)
4910 const char *cservername = canon_servername(servername);
4913 r->version = driver->version;
4915 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4916 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4917 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4918 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4920 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4924 if (!W_ERROR_IS_OK(result)) {
4928 FILL_DRIVER_STRING(mem_ctx,
4929 driver->monitor_name,
4932 FILL_DRIVER_STRING(mem_ctx,
4933 driver->default_datatype,
4934 r->default_datatype);
4936 result = string_array_from_driver_info(mem_ctx,
4937 driver->previous_names,
4940 if (!W_ERROR_IS_OK(result)) {
4944 r->driver_date = driver->driver_date;
4945 r->driver_version = driver->driver_version;
4947 FILL_DRIVER_STRING(mem_ctx,
4948 driver->manufacturer_name,
4949 r->manufacturer_name);
4950 FILL_DRIVER_STRING(mem_ctx,
4951 driver->manufacturer_url,
4952 r->manufacturer_url);
4953 FILL_DRIVER_STRING(mem_ctx,
4954 driver->hardware_id,
4956 FILL_DRIVER_STRING(mem_ctx,
4963 /********************************************************************
4964 ********************************************************************/
4966 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4967 struct auth_serversupplied_info *server_info,
4969 union spoolss_DriverInfo *r,
4971 const char *servername,
4972 const char *architecture,
4975 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4976 struct spoolss_DriverInfo8 *driver;
4979 result = winreg_get_printer(mem_ctx,
4981 smbd_messaging_context(),
4983 lp_const_servicename(snum),
4986 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4987 win_errstr(result)));
4989 if (!W_ERROR_IS_OK(result)) {
4990 return WERR_INVALID_PRINTER_NAME;
4993 result = winreg_get_driver(mem_ctx, server_info, architecture,
4994 pinfo2->drivername, version, &driver);
4996 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4997 win_errstr(result)));
4999 if (!W_ERROR_IS_OK(result)) {
5001 * Is this a W2k client ?
5005 talloc_free(pinfo2);
5006 return WERR_UNKNOWN_PRINTER_DRIVER;
5009 /* Yes - try again with a WinNT driver. */
5011 result = winreg_get_driver(mem_ctx, server_info, architecture,
5014 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5015 win_errstr(result)));
5016 if (!W_ERROR_IS_OK(result)) {
5017 talloc_free(pinfo2);
5018 return WERR_UNKNOWN_PRINTER_DRIVER;
5024 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5027 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5030 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5033 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5036 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5039 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5042 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5044 #if 0 /* disabled until marshalling issues are resolved - gd */
5046 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5050 result = WERR_UNKNOWN_LEVEL;
5054 talloc_free(pinfo2);
5055 talloc_free(driver);
5060 /****************************************************************
5061 _spoolss_GetPrinterDriver2
5062 ****************************************************************/
5064 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5065 struct spoolss_GetPrinterDriver2 *r)
5067 Printer_entry *printer;
5072 /* that's an [in out] buffer */
5074 if (!r->in.buffer && (r->in.offered != 0)) {
5075 return WERR_INVALID_PARAM;
5078 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5080 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5081 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5082 return WERR_INVALID_PRINTER_NAME;
5086 *r->out.server_major_version = 0;
5087 *r->out.server_minor_version = 0;
5089 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5093 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5094 r->in.level, r->out.info,
5095 snum, printer->servername,
5097 r->in.client_major_version);
5098 if (!W_ERROR_IS_OK(result)) {
5099 TALLOC_FREE(r->out.info);
5103 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5104 r->out.info, r->in.level);
5105 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5107 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5111 /****************************************************************
5112 _spoolss_StartPagePrinter
5113 ****************************************************************/
5115 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5116 struct spoolss_StartPagePrinter *r)
5118 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5121 DEBUG(3,("_spoolss_StartPagePrinter: "
5122 "Error in startpageprinter printer handle\n"));
5126 Printer->page_started = true;
5130 /****************************************************************
5131 _spoolss_EndPagePrinter
5132 ****************************************************************/
5134 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5135 struct spoolss_EndPagePrinter *r)
5139 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5142 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5143 OUR_HANDLE(r->in.handle)));
5147 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5150 Printer->page_started = false;
5151 print_job_endpage(snum, Printer->jobid);
5156 /****************************************************************
5157 _spoolss_StartDocPrinter
5158 ****************************************************************/
5160 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5161 struct spoolss_StartDocPrinter *r)
5163 struct spoolss_DocumentInfo1 *info_1;
5165 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5169 DEBUG(2,("_spoolss_StartDocPrinter: "
5170 "Invalid handle (%s:%u:%u)\n",
5171 OUR_HANDLE(r->in.handle)));
5175 if (Printer->jobid) {
5176 DEBUG(2, ("_spoolss_StartDocPrinter: "
5177 "StartDocPrinter called twice! "
5178 "(existing jobid = %d)\n", Printer->jobid));
5179 return WERR_INVALID_HANDLE;
5182 if (r->in.level != 1) {
5183 return WERR_UNKNOWN_LEVEL;
5186 info_1 = r->in.info.info1;
5189 * a nice thing with NT is it doesn't listen to what you tell it.
5190 * when asked to send _only_ RAW datas, it tries to send datas
5193 * So I add checks like in NT Server ...
5196 if (info_1->datatype) {
5197 if (strcmp(info_1->datatype, "RAW") != 0) {
5199 return WERR_INVALID_DATATYPE;
5203 /* get the share number of the printer */
5204 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5208 werr = print_job_start(p->server_info, snum,
5209 info_1->document_name, info_1->output_file,
5210 Printer->devmode, &Printer->jobid);
5212 /* An error occured in print_job_start() so return an appropriate
5215 if (!W_ERROR_IS_OK(werr)) {
5219 Printer->document_started = true;
5220 *r->out.job_id = Printer->jobid;
5225 /****************************************************************
5226 _spoolss_EndDocPrinter
5227 ****************************************************************/
5229 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5230 struct spoolss_EndDocPrinter *r)
5232 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5237 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5238 OUR_HANDLE(r->in.handle)));
5242 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5246 Printer->document_started = false;
5247 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5248 if (!NT_STATUS_IS_OK(status)) {
5249 DEBUG(2, ("_spoolss_EndDocPrinter: "
5250 "print_job_end failed [%s]\n",
5251 nt_errstr(status)));
5255 return ntstatus_to_werror(status);
5258 /****************************************************************
5259 _spoolss_WritePrinter
5260 ****************************************************************/
5262 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5263 struct spoolss_WritePrinter *r)
5265 ssize_t buffer_written;
5267 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5270 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5271 OUR_HANDLE(r->in.handle)));
5272 *r->out.num_written = r->in._data_size;
5276 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5279 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5280 buffer_written = print_job_write(snum, Printer->jobid,
5281 (const char *)r->in.data.data,
5283 (size_t)r->in._data_size);
5284 if (buffer_written == (ssize_t)-1) {
5285 *r->out.num_written = 0;
5286 if (errno == ENOSPC)
5287 return WERR_NO_SPOOL_SPACE;
5289 return WERR_ACCESS_DENIED;
5292 *r->out.num_written = r->in._data_size;
5297 /********************************************************************
5298 * api_spoolss_getprinter
5299 * called from the spoolss dispatcher
5301 ********************************************************************/
5303 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5304 struct pipes_struct *p)
5307 WERROR errcode = WERR_BADFUNC;
5308 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5311 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5312 OUR_HANDLE(handle)));
5316 if (!get_printer_snum(p, handle, &snum, NULL))
5320 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5321 errcode = print_queue_pause(p->server_info, snum);
5323 case SPOOLSS_PRINTER_CONTROL_RESUME:
5324 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5325 errcode = print_queue_resume(p->server_info, snum);
5327 case SPOOLSS_PRINTER_CONTROL_PURGE:
5328 errcode = print_queue_purge(p->server_info, snum);
5331 return WERR_UNKNOWN_LEVEL;
5338 /****************************************************************
5339 _spoolss_AbortPrinter
5340 * From MSDN: "Deletes printer's spool file if printer is configured
5342 ****************************************************************/
5344 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5345 struct spoolss_AbortPrinter *r)
5347 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5349 WERROR errcode = WERR_OK;
5352 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5353 OUR_HANDLE(r->in.handle)));
5357 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5360 if (!Printer->document_started) {
5361 return WERR_SPL_NO_STARTDOC;
5364 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5369 /********************************************************************
5370 * called by spoolss_api_setprinter
5371 * when updating a printer description
5372 ********************************************************************/
5374 static WERROR update_printer_sec(struct policy_handle *handle,
5375 struct pipes_struct *p,
5376 struct sec_desc_buf *secdesc_ctr)
5378 struct spoolss_security_descriptor *new_secdesc = NULL;
5379 struct spoolss_security_descriptor *old_secdesc = NULL;
5380 const char *printer;
5384 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5386 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5387 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5388 OUR_HANDLE(handle)));
5390 result = WERR_BADFID;
5394 if (secdesc_ctr == NULL) {
5395 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5396 result = WERR_INVALID_PARAM;
5399 printer = lp_const_servicename(snum);
5401 /* Check the user has permissions to change the security
5402 descriptor. By experimentation with two NT machines, the user
5403 requires Full Access to the printer to change security
5406 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5407 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5408 result = WERR_ACCESS_DENIED;
5412 /* NT seems to like setting the security descriptor even though
5413 nothing may have actually changed. */
5414 result = winreg_get_printer_secdesc(p->mem_ctx,
5419 if (!W_ERROR_IS_OK(result)) {
5420 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5421 result = WERR_BADFID;
5425 if (DEBUGLEVEL >= 10) {
5426 struct security_acl *the_acl;
5429 the_acl = old_secdesc->dacl;
5430 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5431 printer, the_acl->num_aces));
5433 for (i = 0; i < the_acl->num_aces; i++) {
5434 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5435 &the_acl->aces[i].trustee),
5436 the_acl->aces[i].access_mask));
5439 the_acl = secdesc_ctr->sd->dacl;
5442 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5443 printer, the_acl->num_aces));
5445 for (i = 0; i < the_acl->num_aces; i++) {
5446 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5447 &the_acl->aces[i].trustee),
5448 the_acl->aces[i].access_mask));
5451 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5455 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5456 if (new_secdesc == NULL) {
5457 result = WERR_NOMEM;
5461 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5466 result = winreg_set_printer_secdesc(p->mem_ctx,
5476 /********************************************************************
5477 Canonicalize printer info from a client
5478 ********************************************************************/
5480 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5481 struct spoolss_SetPrinterInfo2 *info2,
5484 fstring printername;
5487 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5488 "portname=%s drivername=%s comment=%s location=%s\n",
5489 info2->servername, info2->printername, info2->sharename,
5490 info2->portname, info2->drivername, info2->comment,
5493 /* we force some elements to "correct" values */
5494 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5495 if (info2->servername == NULL) {
5498 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5499 if (info2->sharename == NULL) {
5503 /* check to see if we allow printername != sharename */
5504 if (lp_force_printername(snum)) {
5505 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5506 global_myname(), info2->sharename);
5508 /* make sure printername is in \\server\printername format */
5509 fstrcpy(printername, info2->printername);
5511 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5512 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5516 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5517 global_myname(), p);
5519 if (info2->printername == NULL) {
5523 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5524 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5529 /****************************************************************************
5530 ****************************************************************************/
5532 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5534 char *cmd = lp_addport_cmd();
5535 char *command = NULL;
5537 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5538 bool is_print_op = false;
5541 return WERR_ACCESS_DENIED;
5544 command = talloc_asprintf(ctx,
5545 "%s \"%s\" \"%s\"", cmd, portname, uri );
5551 is_print_op = user_has_privileges( token, &se_printop );
5553 DEBUG(10,("Running [%s]\n", command));
5555 /********* BEGIN SePrintOperatorPrivilege **********/
5560 ret = smbrun(command, NULL);
5565 /********* END SePrintOperatorPrivilege **********/
5567 DEBUGADD(10,("returned [%d]\n", ret));
5569 TALLOC_FREE(command);
5572 return WERR_ACCESS_DENIED;
5578 /****************************************************************************
5579 ****************************************************************************/
5581 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5582 struct spoolss_SetPrinterInfo2 *info2,
5583 const char *remote_machine,
5584 struct messaging_context *msg_ctx)
5586 char *cmd = lp_addprinter_cmd();
5588 char *command = NULL;
5592 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5593 bool is_print_op = false;
5595 if (!remote_machine) {
5599 command = talloc_asprintf(ctx,
5600 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5601 cmd, info2->printername, info2->sharename,
5602 info2->portname, info2->drivername,
5603 info2->location, info2->comment, remote_machine);
5609 is_print_op = user_has_privileges( token, &se_printop );
5611 DEBUG(10,("Running [%s]\n", command));
5613 /********* BEGIN SePrintOperatorPrivilege **********/
5618 if ( (ret = smbrun(command, &fd)) == 0 ) {
5619 /* Tell everyone we updated smb.conf. */
5620 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5626 /********* END SePrintOperatorPrivilege **********/
5628 DEBUGADD(10,("returned [%d]\n", ret));
5630 TALLOC_FREE(command);
5638 /* reload our services immediately */
5640 reload_services(false);
5644 /* Get lines and convert them back to dos-codepage */
5645 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5646 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5649 /* Set the portname to what the script says the portname should be. */
5650 /* but don't require anything to be return from the script exit a good error code */
5653 /* Set the portname to what the script says the portname should be. */
5654 info2->portname = talloc_strdup(ctx, qlines[0]);
5655 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5658 TALLOC_FREE(qlines);
5662 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5663 struct auth_serversupplied_info *server_info,
5665 struct spoolss_SetPrinterInfo2 *printer,
5666 struct spoolss_PrinterInfo2 *old_printer)
5668 bool force_update = (old_printer == NULL);
5669 const char *dnsdomname;
5670 const char *longname;
5671 const char *uncname;
5672 const char *spooling;
5674 WERROR result = WERR_OK;
5676 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5677 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5678 winreg_set_printer_dataex(mem_ctx,
5680 smbd_messaging_context(),
5682 SPOOL_DSSPOOLER_KEY,
5683 SPOOL_REG_DRIVERNAME,
5688 if (!force_update) {
5689 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5690 printer->drivername));
5692 notify_printer_driver(snum, printer->drivername);
5696 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5697 push_reg_sz(mem_ctx, &buffer, printer->comment);
5698 winreg_set_printer_dataex(mem_ctx,
5700 smbd_messaging_context(),
5702 SPOOL_DSSPOOLER_KEY,
5703 SPOOL_REG_DESCRIPTION,
5708 if (!force_update) {
5709 notify_printer_comment(snum, printer->comment);
5713 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5714 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5715 winreg_set_printer_dataex(mem_ctx,
5717 smbd_messaging_context(),
5719 SPOOL_DSSPOOLER_KEY,
5720 SPOOL_REG_PRINTSHARENAME,
5725 if (!force_update) {
5726 notify_printer_sharename(snum, printer->sharename);
5730 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5733 p = strrchr(printer->printername, '\\' );
5737 p = printer->printername;
5740 push_reg_sz(mem_ctx, &buffer, p);
5741 winreg_set_printer_dataex(mem_ctx,
5743 smbd_messaging_context(),
5745 SPOOL_DSSPOOLER_KEY,
5746 SPOOL_REG_PRINTERNAME,
5751 if (!force_update) {
5752 notify_printer_printername(snum, p);
5756 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5757 push_reg_sz(mem_ctx, &buffer, printer->portname);
5758 winreg_set_printer_dataex(mem_ctx,
5760 smbd_messaging_context(),
5762 SPOOL_DSSPOOLER_KEY,
5768 if (!force_update) {
5769 notify_printer_port(snum, printer->portname);
5773 if (force_update || !strequal(printer->location, old_printer->location)) {
5774 push_reg_sz(mem_ctx, &buffer, printer->location);
5775 winreg_set_printer_dataex(mem_ctx,
5777 smbd_messaging_context(),
5779 SPOOL_DSSPOOLER_KEY,
5785 if (!force_update) {
5786 notify_printer_location(snum, printer->location);
5790 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5791 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5792 winreg_set_printer_dataex(mem_ctx,
5794 smbd_messaging_context(),
5796 SPOOL_DSSPOOLER_KEY,
5797 SPOOL_REG_PRINTSEPARATORFILE,
5802 if (!force_update) {
5803 notify_printer_location(snum, printer->location);
5807 if (force_update || printer->starttime != old_printer->starttime) {
5808 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5809 SIVAL(buffer.data, 0, printer->starttime);
5810 winreg_set_printer_dataex(mem_ctx,
5812 smbd_messaging_context(),
5814 SPOOL_DSSPOOLER_KEY,
5815 SPOOL_REG_PRINTSTARTTIME,
5821 if (force_update || printer->untiltime != old_printer->untiltime) {
5822 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5823 SIVAL(buffer.data, 0, printer->untiltime);
5824 winreg_set_printer_dataex(mem_ctx,
5826 smbd_messaging_context(),
5828 SPOOL_DSSPOOLER_KEY,
5829 SPOOL_REG_PRINTENDTIME,
5835 if (force_update || printer->priority != old_printer->priority) {
5836 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5837 SIVAL(buffer.data, 0, printer->priority);
5838 winreg_set_printer_dataex(mem_ctx,
5840 smbd_messaging_context(),
5842 SPOOL_DSSPOOLER_KEY,
5849 if (force_update || printer->attributes != old_printer->attributes) {
5850 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5851 SIVAL(buffer.data, 0, (printer->attributes &
5852 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5853 winreg_set_printer_dataex(mem_ctx,
5855 smbd_messaging_context(),
5857 SPOOL_DSSPOOLER_KEY,
5858 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5863 switch (printer->attributes & 0x3) {
5865 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5868 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5871 spooling = SPOOL_REGVAL_PRINTDIRECT;
5874 spooling = "unknown";
5876 push_reg_sz(mem_ctx, &buffer, spooling);
5877 winreg_set_printer_dataex(mem_ctx,
5879 smbd_messaging_context(),
5881 SPOOL_DSSPOOLER_KEY,
5882 SPOOL_REG_PRINTSPOOLING,
5888 push_reg_sz(mem_ctx, &buffer, global_myname());
5889 winreg_set_printer_dataex(mem_ctx,
5891 smbd_messaging_context(),
5893 SPOOL_DSSPOOLER_KEY,
5894 SPOOL_REG_SHORTSERVERNAME,
5899 dnsdomname = get_mydnsfullname();
5900 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5901 longname = talloc_strdup(mem_ctx, dnsdomname);
5903 longname = talloc_strdup(mem_ctx, global_myname());
5905 if (longname == NULL) {
5906 result = WERR_NOMEM;
5910 push_reg_sz(mem_ctx, &buffer, longname);
5911 winreg_set_printer_dataex(mem_ctx,
5913 smbd_messaging_context(),
5915 SPOOL_DSSPOOLER_KEY,
5916 SPOOL_REG_SERVERNAME,
5921 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5922 global_myname(), printer->sharename);
5923 push_reg_sz(mem_ctx, &buffer, uncname);
5924 winreg_set_printer_dataex(mem_ctx,
5926 smbd_messaging_context(),
5928 SPOOL_DSSPOOLER_KEY,
5938 /********************************************************************
5939 * Called by spoolss_api_setprinter
5940 * when updating a printer description.
5941 ********************************************************************/
5943 static WERROR update_printer(struct pipes_struct *p,
5944 struct policy_handle *handle,
5945 struct spoolss_SetPrinterInfoCtr *info_ctr,
5946 struct spoolss_DeviceMode *devmode)
5948 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5949 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5950 struct spoolss_PrinterInfo2 *old_printer;
5951 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5952 const char *servername = NULL;
5954 WERROR result = WERR_OK;
5955 TALLOC_CTX *tmp_ctx;
5957 DEBUG(8,("update_printer\n"));
5959 tmp_ctx = talloc_new(p->mem_ctx);
5960 if (tmp_ctx == NULL) {
5965 result = WERR_BADFID;
5969 if (!get_printer_snum(p, handle, &snum, NULL)) {
5970 result = WERR_BADFID;
5974 if (Printer != NULL || Printer->servername != NULL) {
5975 servername = Printer->servername;
5978 result = winreg_get_printer(tmp_ctx,
5982 lp_const_servicename(snum),
5984 if (!W_ERROR_IS_OK(result)) {
5985 result = WERR_BADFID;
5989 /* Do sanity check on the requested changes for Samba */
5990 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5991 result = WERR_INVALID_PARAM;
5995 /* FIXME!!! If the driver has changed we really should verify that
5996 it is installed before doing much else --jerry */
5998 /* Check calling user has permission to update printer description */
5999 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6000 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6001 result = WERR_ACCESS_DENIED;
6005 /* Call addprinter hook */
6006 /* Check changes to see if this is really needed */
6008 if (*lp_addprinter_cmd() &&
6009 (!strequal(printer->drivername, old_printer->drivername) ||
6010 !strequal(printer->comment, old_printer->comment) ||
6011 !strequal(printer->portname, old_printer->portname) ||
6012 !strequal(printer->location, old_printer->location)) )
6014 /* add_printer_hook() will call reload_services() */
6015 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6016 printer, p->client_address,
6018 result = WERR_ACCESS_DENIED;
6023 update_dsspooler(tmp_ctx,
6029 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6031 if (devmode == NULL) {
6032 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6034 result = winreg_update_printer(tmp_ctx,
6044 talloc_free(tmp_ctx);
6049 /****************************************************************************
6050 ****************************************************************************/
6051 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6052 struct policy_handle *handle,
6053 struct spoolss_SetPrinterInfo7 *info7)
6056 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6059 Printer_entry *Printer;
6061 if ( lp_security() != SEC_ADS ) {
6062 return WERR_UNKNOWN_LEVEL;
6065 Printer = find_printer_index_by_hnd(p, handle);
6067 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6072 if (!get_printer_snum(p, handle, &snum, NULL))
6075 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6076 Printer->servername,
6077 lp_servicename(snum), &pinfo2);
6078 if (!W_ERROR_IS_OK(result)) {
6082 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6084 TALLOC_FREE(pinfo2);
6087 return WERR_UNKNOWN_LEVEL;
6091 /********************************************************************
6092 ********************************************************************/
6094 static WERROR update_printer_devmode(struct pipes_struct *p,
6095 struct policy_handle *handle,
6096 struct spoolss_DeviceMode *devmode)
6099 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6100 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6102 DEBUG(8,("update_printer_devmode\n"));
6108 if (!get_printer_snum(p, handle, &snum, NULL)) {
6112 /* Check calling user has permission to update printer description */
6113 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6114 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6115 return WERR_ACCESS_DENIED;
6118 return winreg_update_printer(p->mem_ctx,
6121 lp_const_servicename(snum),
6129 /****************************************************************
6131 ****************************************************************/
6133 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6134 struct spoolss_SetPrinter *r)
6138 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6141 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6142 OUR_HANDLE(r->in.handle)));
6146 /* check the level */
6147 switch (r->in.info_ctr->level) {
6149 return control_printer(r->in.handle, r->in.command, p);
6151 result = update_printer(p, r->in.handle,
6153 r->in.devmode_ctr->devmode);
6154 if (!W_ERROR_IS_OK(result))
6156 if (r->in.secdesc_ctr->sd)
6157 result = update_printer_sec(r->in.handle, p,
6161 return update_printer_sec(r->in.handle, p,
6164 return publish_or_unpublish_printer(p, r->in.handle,
6165 r->in.info_ctr->info.info7);
6167 return update_printer_devmode(p, r->in.handle,
6168 r->in.devmode_ctr->devmode);
6170 return WERR_UNKNOWN_LEVEL;
6174 /****************************************************************
6175 _spoolss_FindClosePrinterNotify
6176 ****************************************************************/
6178 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6179 struct spoolss_FindClosePrinterNotify *r)
6181 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6184 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6185 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6189 if (Printer->notify.client_connected == true) {
6192 if ( Printer->printer_type == SPLHND_SERVER)
6194 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6195 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6198 srv_spoolss_replycloseprinter(
6199 snum, &Printer->notify.client_hnd, p->msg_ctx);
6202 Printer->notify.flags=0;
6203 Printer->notify.options=0;
6204 Printer->notify.localmachine[0]='\0';
6205 Printer->notify.printerlocal=0;
6206 TALLOC_FREE(Printer->notify.option);
6207 Printer->notify.client_connected = false;
6212 /****************************************************************
6214 ****************************************************************/
6216 WERROR _spoolss_AddJob(struct pipes_struct *p,
6217 struct spoolss_AddJob *r)
6219 if (!r->in.buffer && (r->in.offered != 0)) {
6220 return WERR_INVALID_PARAM;
6223 /* this is what a NT server returns for AddJob. AddJob must fail on
6224 * non-local printers */
6226 if (r->in.level != 1) {
6227 return WERR_UNKNOWN_LEVEL;
6230 return WERR_INVALID_PARAM;
6233 /****************************************************************************
6235 ****************************************************************************/
6237 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6238 struct spoolss_JobInfo1 *r,
6239 const print_queue_struct *queue,
6240 int position, int snum,
6241 struct spoolss_PrinterInfo2 *pinfo2)
6245 t = gmtime(&queue->time);
6247 r->job_id = queue->job;
6249 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6250 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6251 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6252 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6253 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6254 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6255 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6256 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6257 r->data_type = talloc_strdup(mem_ctx, "RAW");
6258 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6259 r->text_status = talloc_strdup(mem_ctx, "");
6260 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6262 r->status = nt_printj_status(queue->status);
6263 r->priority = queue->priority;
6264 r->position = position;
6265 r->total_pages = queue->page_count;
6266 r->pages_printed = 0; /* ??? */
6268 init_systemtime(&r->submitted, t);
6273 /****************************************************************************
6275 ****************************************************************************/
6277 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6278 struct spoolss_JobInfo2 *r,
6279 const print_queue_struct *queue,
6280 int position, int snum,
6281 struct spoolss_PrinterInfo2 *pinfo2,
6282 struct spoolss_DeviceMode *devmode)
6286 t = gmtime(&queue->time);
6288 r->job_id = queue->job;
6290 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6291 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6292 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6293 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6294 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6295 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6296 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6297 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6298 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6299 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6300 r->data_type = talloc_strdup(mem_ctx, "RAW");
6301 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6302 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6303 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6304 r->parameters = talloc_strdup(mem_ctx, "");
6305 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6306 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6307 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6309 r->devmode = devmode;
6311 r->text_status = talloc_strdup(mem_ctx, "");
6312 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6316 r->status = nt_printj_status(queue->status);
6317 r->priority = queue->priority;
6318 r->position = position;
6321 r->total_pages = queue->page_count;
6322 r->size = queue->size;
6323 init_systemtime(&r->submitted, t);
6325 r->pages_printed = 0; /* ??? */
6330 /****************************************************************************
6332 ****************************************************************************/
6334 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6335 struct spoolss_JobInfo3 *r,
6336 const print_queue_struct *queue,
6337 const print_queue_struct *next_queue,
6338 int position, int snum,
6339 struct spoolss_PrinterInfo2 *pinfo2)
6341 r->job_id = queue->job;
6344 r->next_job_id = next_queue->job;
6351 /****************************************************************************
6352 Enumjobs at level 1.
6353 ****************************************************************************/
6355 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6356 const print_queue_struct *queue,
6357 uint32_t num_queues, int snum,
6358 struct spoolss_PrinterInfo2 *pinfo2,
6359 union spoolss_JobInfo **info_p,
6362 union spoolss_JobInfo *info;
6364 WERROR result = WERR_OK;
6366 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6367 W_ERROR_HAVE_NO_MEMORY(info);
6369 *count = num_queues;
6371 for (i=0; i<*count; i++) {
6372 result = fill_job_info1(info,
6378 if (!W_ERROR_IS_OK(result)) {
6384 if (!W_ERROR_IS_OK(result)) {
6395 /****************************************************************************
6396 Enumjobs at level 2.
6397 ****************************************************************************/
6399 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6400 const print_queue_struct *queue,
6401 uint32_t num_queues, int snum,
6402 struct spoolss_PrinterInfo2 *pinfo2,
6403 union spoolss_JobInfo **info_p,
6406 union spoolss_JobInfo *info;
6408 WERROR result = WERR_OK;
6410 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6411 W_ERROR_HAVE_NO_MEMORY(info);
6413 *count = num_queues;
6415 for (i=0; i<*count; i++) {
6416 struct spoolss_DeviceMode *devmode;
6418 result = spoolss_create_default_devmode(info,
6419 pinfo2->printername,
6421 if (!W_ERROR_IS_OK(result)) {
6422 DEBUG(3, ("Can't proceed w/o a devmode!"));
6426 result = fill_job_info2(info,
6433 if (!W_ERROR_IS_OK(result)) {
6439 if (!W_ERROR_IS_OK(result)) {
6450 /****************************************************************************
6451 Enumjobs at level 3.
6452 ****************************************************************************/
6454 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6455 const print_queue_struct *queue,
6456 uint32_t num_queues, int snum,
6457 struct spoolss_PrinterInfo2 *pinfo2,
6458 union spoolss_JobInfo **info_p,
6461 union spoolss_JobInfo *info;
6463 WERROR result = WERR_OK;
6465 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6466 W_ERROR_HAVE_NO_MEMORY(info);
6468 *count = num_queues;
6470 for (i=0; i<*count; i++) {
6471 const print_queue_struct *next_queue = NULL;
6474 next_queue = &queue[i+1];
6477 result = fill_job_info3(info,
6484 if (!W_ERROR_IS_OK(result)) {
6490 if (!W_ERROR_IS_OK(result)) {
6501 /****************************************************************
6503 ****************************************************************/
6505 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6506 struct spoolss_EnumJobs *r)
6509 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6511 print_status_struct prt_status;
6512 print_queue_struct *queue = NULL;
6515 /* that's an [in out] buffer */
6517 if (!r->in.buffer && (r->in.offered != 0)) {
6518 return WERR_INVALID_PARAM;
6521 DEBUG(4,("_spoolss_EnumJobs\n"));
6525 *r->out.info = NULL;
6527 /* lookup the printer snum and tdb entry */
6529 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6533 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
6534 NULL, lp_servicename(snum), &pinfo2);
6535 if (!W_ERROR_IS_OK(result)) {
6539 count = print_queue_status(snum, &queue, &prt_status);
6540 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6541 count, prt_status.status, prt_status.message));
6545 TALLOC_FREE(pinfo2);
6549 switch (r->in.level) {
6551 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6552 pinfo2, r->out.info, r->out.count);
6555 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6556 pinfo2, r->out.info, r->out.count);
6559 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6560 pinfo2, r->out.info, r->out.count);
6563 result = WERR_UNKNOWN_LEVEL;
6568 TALLOC_FREE(pinfo2);
6570 if (!W_ERROR_IS_OK(result)) {
6574 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6576 *r->out.info, r->in.level,
6578 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6579 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6581 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6584 /****************************************************************
6585 _spoolss_ScheduleJob
6586 ****************************************************************/
6588 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6589 struct spoolss_ScheduleJob *r)
6594 /****************************************************************
6595 ****************************************************************/
6597 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6598 const char *printer_name,
6600 struct spoolss_SetJobInfo1 *r)
6604 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6608 if (strequal(old_doc_name, r->document_name)) {
6612 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6619 /****************************************************************
6621 ****************************************************************/
6623 WERROR _spoolss_SetJob(struct pipes_struct *p,
6624 struct spoolss_SetJob *r)
6627 WERROR errcode = WERR_BADFUNC;
6629 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6633 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6634 return WERR_INVALID_PRINTER_NAME;
6637 switch (r->in.command) {
6638 case SPOOLSS_JOB_CONTROL_CANCEL:
6639 case SPOOLSS_JOB_CONTROL_DELETE:
6640 errcode = print_job_delete(p->server_info,
6641 snum, r->in.job_id);
6642 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6646 case SPOOLSS_JOB_CONTROL_PAUSE:
6647 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6651 case SPOOLSS_JOB_CONTROL_RESTART:
6652 case SPOOLSS_JOB_CONTROL_RESUME:
6653 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6661 return WERR_UNKNOWN_LEVEL;
6664 if (!W_ERROR_IS_OK(errcode)) {
6668 if (r->in.ctr == NULL) {
6672 switch (r->in.ctr->level) {
6674 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6676 r->in.ctr->info.info1);
6682 return WERR_UNKNOWN_LEVEL;
6688 /****************************************************************************
6689 Enumerates all printer drivers by level and architecture.
6690 ****************************************************************************/
6692 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6693 struct auth_serversupplied_info *server_info,
6694 const char *servername,
6695 const char *architecture,
6697 union spoolss_DriverInfo **info_p,
6702 struct spoolss_DriverInfo8 *driver;
6703 union spoolss_DriverInfo *info = NULL;
6705 WERROR result = WERR_OK;
6706 uint32_t num_drivers;
6707 const char **drivers;
6712 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6713 result = winreg_get_driver_list(mem_ctx, server_info,
6714 architecture, version,
6715 &num_drivers, &drivers);
6716 if (!W_ERROR_IS_OK(result)) {
6719 DEBUG(4, ("we have:[%d] drivers in environment"
6720 " [%s] and version [%d]\n",
6721 num_drivers, architecture, version));
6723 if (num_drivers != 0) {
6724 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6725 union spoolss_DriverInfo,
6726 count + num_drivers);
6728 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6729 "failed to enlarge driver info buffer!\n"));
6730 result = WERR_NOMEM;
6735 for (i = 0; i < num_drivers; i++) {
6736 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6738 result = winreg_get_driver(mem_ctx, server_info,
6739 architecture, drivers[i],
6741 if (!W_ERROR_IS_OK(result)) {
6747 result = fill_printer_driver_info1(info, &info[count+i].info1,
6748 driver, servername);
6751 result = fill_printer_driver_info2(info, &info[count+i].info2,
6752 driver, servername);
6755 result = fill_printer_driver_info3(info, &info[count+i].info3,
6756 driver, servername);
6759 result = fill_printer_driver_info4(info, &info[count+i].info4,
6760 driver, servername);
6763 result = fill_printer_driver_info5(info, &info[count+i].info5,
6764 driver, servername);
6767 result = fill_printer_driver_info6(info, &info[count+i].info6,
6768 driver, servername);
6771 result = fill_printer_driver_info8(info, &info[count+i].info8,
6772 driver, servername);
6775 result = WERR_UNKNOWN_LEVEL;
6779 TALLOC_FREE(driver);
6781 if (!W_ERROR_IS_OK(result)) {
6786 count += num_drivers;
6787 TALLOC_FREE(drivers);
6791 TALLOC_FREE(drivers);
6793 if (!W_ERROR_IS_OK(result)) {
6804 /****************************************************************************
6805 Enumerates all printer drivers by level.
6806 ****************************************************************************/
6808 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6809 struct auth_serversupplied_info *server_info,
6810 const char *servername,
6811 const char *architecture,
6813 union spoolss_DriverInfo **info_p,
6817 WERROR result = WERR_OK;
6819 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6821 for (a=0; archi_table[a].long_archi != NULL; a++) {
6823 union spoolss_DriverInfo *info = NULL;
6826 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6829 archi_table[a].long_archi,
6833 if (!W_ERROR_IS_OK(result)) {
6837 for (i=0; i < count; i++) {
6838 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6839 info[i], info_p, count_p);
6846 return enumprinterdrivers_level_by_architecture(mem_ctx,
6855 /****************************************************************
6856 _spoolss_EnumPrinterDrivers
6857 ****************************************************************/
6859 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6860 struct spoolss_EnumPrinterDrivers *r)
6862 const char *cservername;
6865 /* that's an [in out] buffer */
6867 if (!r->in.buffer && (r->in.offered != 0)) {
6868 return WERR_INVALID_PARAM;
6871 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6875 *r->out.info = NULL;
6877 cservername = canon_servername(r->in.server);
6879 if (!is_myname_or_ipaddr(cservername)) {
6880 return WERR_UNKNOWN_PRINTER_DRIVER;
6883 result = enumprinterdrivers_level(p->mem_ctx,
6890 if (!W_ERROR_IS_OK(result)) {
6894 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6895 spoolss_EnumPrinterDrivers,
6896 *r->out.info, r->in.level,
6898 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6899 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6901 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6904 /****************************************************************
6906 ****************************************************************/
6908 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6909 struct spoolss_EnumForms *r)
6915 *r->out.info = NULL;
6917 /* that's an [in out] buffer */
6919 if (!r->in.buffer && (r->in.offered != 0) ) {
6920 return WERR_INVALID_PARAM;
6923 DEBUG(4,("_spoolss_EnumForms\n"));
6924 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6925 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6927 switch (r->in.level) {
6929 result = winreg_printer_enumforms1(p->mem_ctx,
6936 result = WERR_UNKNOWN_LEVEL;
6940 if (!W_ERROR_IS_OK(result)) {
6944 if (*r->out.count == 0) {
6945 return WERR_NO_MORE_ITEMS;
6948 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6950 *r->out.info, r->in.level,
6952 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6953 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6955 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6958 /****************************************************************
6960 ****************************************************************/
6962 WERROR _spoolss_GetForm(struct pipes_struct *p,
6963 struct spoolss_GetForm *r)
6967 /* that's an [in out] buffer */
6969 if (!r->in.buffer && (r->in.offered != 0)) {
6970 return WERR_INVALID_PARAM;
6973 DEBUG(4,("_spoolss_GetForm\n"));
6974 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6975 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6977 switch (r->in.level) {
6979 result = winreg_printer_getform1(p->mem_ctx,
6983 &r->out.info->info1);
6986 result = WERR_UNKNOWN_LEVEL;
6990 if (!W_ERROR_IS_OK(result)) {
6991 TALLOC_FREE(r->out.info);
6995 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6996 r->out.info, r->in.level);
6997 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6999 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7002 /****************************************************************************
7003 ****************************************************************************/
7005 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
7006 struct spoolss_PortInfo1 *r,
7009 r->port_name = talloc_strdup(mem_ctx, name);
7010 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7015 /****************************************************************************
7016 TODO: This probably needs distinguish between TCP/IP and Local ports
7018 ****************************************************************************/
7020 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7021 struct spoolss_PortInfo2 *r,
7024 r->port_name = talloc_strdup(mem_ctx, name);
7025 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7027 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7028 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7030 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7031 W_ERROR_HAVE_NO_MEMORY(r->description);
7033 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7040 /****************************************************************************
7041 wrapper around the enumer ports command
7042 ****************************************************************************/
7044 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7046 char *cmd = lp_enumports_cmd();
7047 char **qlines = NULL;
7048 char *command = NULL;
7056 /* if no hook then just fill in the default port */
7059 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7062 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7063 TALLOC_FREE(qlines);
7070 /* we have a valid enumport command */
7072 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7077 DEBUG(10,("Running [%s]\n", command));
7078 ret = smbrun(command, &fd);
7079 DEBUG(10,("Returned [%d]\n", ret));
7080 TALLOC_FREE(command);
7085 return WERR_ACCESS_DENIED;
7089 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7090 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7100 /****************************************************************************
7102 ****************************************************************************/
7104 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7105 union spoolss_PortInfo **info_p,
7108 union spoolss_PortInfo *info = NULL;
7110 WERROR result = WERR_OK;
7111 char **qlines = NULL;
7114 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7115 if (!W_ERROR_IS_OK(result)) {
7120 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7122 DEBUG(10,("Returning WERR_NOMEM\n"));
7123 result = WERR_NOMEM;
7127 for (i=0; i<numlines; i++) {
7128 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7129 result = fill_port_1(info, &info[i].info1, qlines[i]);
7130 if (!W_ERROR_IS_OK(result)) {
7135 TALLOC_FREE(qlines);
7138 if (!W_ERROR_IS_OK(result)) {
7140 TALLOC_FREE(qlines);
7152 /****************************************************************************
7154 ****************************************************************************/
7156 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7157 union spoolss_PortInfo **info_p,
7160 union spoolss_PortInfo *info = NULL;
7162 WERROR result = WERR_OK;
7163 char **qlines = NULL;
7166 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7167 if (!W_ERROR_IS_OK(result)) {
7172 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7174 DEBUG(10,("Returning WERR_NOMEM\n"));
7175 result = WERR_NOMEM;
7179 for (i=0; i<numlines; i++) {
7180 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7181 result = fill_port_2(info, &info[i].info2, qlines[i]);
7182 if (!W_ERROR_IS_OK(result)) {
7187 TALLOC_FREE(qlines);
7190 if (!W_ERROR_IS_OK(result)) {
7192 TALLOC_FREE(qlines);
7204 /****************************************************************
7206 ****************************************************************/
7208 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7209 struct spoolss_EnumPorts *r)
7213 /* that's an [in out] buffer */
7215 if (!r->in.buffer && (r->in.offered != 0)) {
7216 return WERR_INVALID_PARAM;
7219 DEBUG(4,("_spoolss_EnumPorts\n"));
7223 *r->out.info = NULL;
7225 switch (r->in.level) {
7227 result = enumports_level_1(p->mem_ctx, r->out.info,
7231 result = enumports_level_2(p->mem_ctx, r->out.info,
7235 return WERR_UNKNOWN_LEVEL;
7238 if (!W_ERROR_IS_OK(result)) {
7242 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7244 *r->out.info, r->in.level,
7246 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7247 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7249 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7252 /****************************************************************************
7253 ****************************************************************************/
7255 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7257 struct spoolss_SetPrinterInfoCtr *info_ctr,
7258 struct spoolss_DeviceMode *devmode,
7259 struct security_descriptor *secdesc,
7260 struct spoolss_UserLevelCtr *user_ctr,
7261 struct policy_handle *handle)
7263 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7264 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7266 WERROR err = WERR_OK;
7268 /* samba does not have a concept of local, non-shared printers yet, so
7269 * make sure we always setup sharename - gd */
7270 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7271 (info2->printername != NULL && info2->printername[0] != '\0')) {
7272 DEBUG(5, ("spoolss_addprinterex_level_2: "
7273 "no sharename has been set, setting printername %s as sharename\n",
7274 info2->printername));
7275 info2->sharename = info2->printername;
7278 /* check to see if the printer already exists */
7279 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7280 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7282 return WERR_PRINTER_ALREADY_EXISTS;
7285 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7286 if ((snum = print_queue_snum(info2->printername)) != -1) {
7287 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7288 info2->printername));
7289 return WERR_PRINTER_ALREADY_EXISTS;
7293 /* validate printer info struct */
7294 if (!info2->printername || strlen(info2->printername) == 0) {
7295 return WERR_INVALID_PRINTER_NAME;
7297 if (!info2->portname || strlen(info2->portname) == 0) {
7298 return WERR_UNKNOWN_PORT;
7300 if (!info2->drivername || strlen(info2->drivername) == 0) {
7301 return WERR_UNKNOWN_PRINTER_DRIVER;
7303 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7304 return WERR_UNKNOWN_PRINTPROCESSOR;
7307 /* FIXME!!! smbd should check to see if the driver is installed before
7308 trying to add a printer like this --jerry */
7310 if (*lp_addprinter_cmd() ) {
7311 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7312 info2, p->client_address,
7314 return WERR_ACCESS_DENIED;
7317 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7318 "smb.conf parameter \"addprinter command\" is defined. This"
7319 "parameter must exist for this call to succeed\n",
7320 info2->sharename ));
7323 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7324 return WERR_ACCESS_DENIED;
7327 /* you must be a printer admin to add a new printer */
7328 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7329 return WERR_ACCESS_DENIED;
7333 * Do sanity check on the requested changes for Samba.
7336 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7337 return WERR_INVALID_PARAM;
7340 if (devmode == NULL) {
7341 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7344 update_dsspooler(p->mem_ctx,
7350 err = winreg_update_printer(p->mem_ctx,
7358 if (!W_ERROR_IS_OK(err)) {
7362 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7363 /* Handle open failed - remove addition. */
7364 ZERO_STRUCTP(handle);
7365 return WERR_ACCESS_DENIED;
7371 /****************************************************************
7372 _spoolss_AddPrinterEx
7373 ****************************************************************/
7375 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7376 struct spoolss_AddPrinterEx *r)
7378 switch (r->in.info_ctr->level) {
7380 /* we don't handle yet */
7381 /* but I know what to do ... */
7382 return WERR_UNKNOWN_LEVEL;
7384 return spoolss_addprinterex_level_2(p, r->in.server,
7386 r->in.devmode_ctr->devmode,
7387 r->in.secdesc_ctr->sd,
7388 r->in.userlevel_ctr,
7391 return WERR_UNKNOWN_LEVEL;
7395 /****************************************************************
7397 ****************************************************************/
7399 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7400 struct spoolss_AddPrinter *r)
7402 struct spoolss_AddPrinterEx a;
7403 struct spoolss_UserLevelCtr userlevel_ctr;
7405 ZERO_STRUCT(userlevel_ctr);
7407 userlevel_ctr.level = 1;
7409 a.in.server = r->in.server;
7410 a.in.info_ctr = r->in.info_ctr;
7411 a.in.devmode_ctr = r->in.devmode_ctr;
7412 a.in.secdesc_ctr = r->in.secdesc_ctr;
7413 a.in.userlevel_ctr = &userlevel_ctr;
7414 a.out.handle = r->out.handle;
7416 return _spoolss_AddPrinterEx(p, &a);
7419 /****************************************************************
7420 _spoolss_AddPrinterDriverEx
7421 ****************************************************************/
7423 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7424 struct spoolss_AddPrinterDriverEx *r)
7426 WERROR err = WERR_OK;
7427 const char *driver_name = NULL;
7432 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7433 fn = "_spoolss_AddPrinterDriver";
7435 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7436 fn = "_spoolss_AddPrinterDriverEx";
7439 return WERR_INVALID_PARAM;
7443 * we only support the semantics of AddPrinterDriver()
7444 * i.e. only copy files that are newer than existing ones
7447 if (r->in.flags == 0) {
7448 return WERR_INVALID_PARAM;
7451 if (r->in.flags != APD_COPY_NEW_FILES) {
7452 return WERR_ACCESS_DENIED;
7456 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7457 /* Clever hack from Martin Zielinski <mz@seh.de>
7458 * to allow downgrade from level 8 (Vista).
7460 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7461 r->in.info_ctr->level));
7462 return WERR_UNKNOWN_LEVEL;
7465 DEBUG(5,("Cleaning driver's information\n"));
7466 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7467 if (!W_ERROR_IS_OK(err))
7470 DEBUG(5,("Moving driver to final destination\n"));
7471 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7476 err = winreg_add_driver(p->mem_ctx, p->server_info, p->msg_ctx,
7477 r->in.info_ctr, &driver_name, &version);
7478 if (!W_ERROR_IS_OK(err)) {
7483 * I think this is where he DrvUpgradePrinter() hook would be
7484 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7485 * server. Right now, we just need to send ourselves a message
7486 * to update each printer bound to this driver. --jerry
7489 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7490 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7498 /****************************************************************
7499 _spoolss_AddPrinterDriver
7500 ****************************************************************/
7502 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7503 struct spoolss_AddPrinterDriver *r)
7505 struct spoolss_AddPrinterDriverEx a;
7507 switch (r->in.info_ctr->level) {
7514 return WERR_UNKNOWN_LEVEL;
7517 a.in.servername = r->in.servername;
7518 a.in.info_ctr = r->in.info_ctr;
7519 a.in.flags = APD_COPY_NEW_FILES;
7521 return _spoolss_AddPrinterDriverEx(p, &a);
7524 /****************************************************************************
7525 ****************************************************************************/
7527 struct _spoolss_paths {
7533 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7535 static const struct _spoolss_paths spoolss_paths[]= {
7536 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7537 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7540 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7541 const char *servername,
7542 const char *environment,
7546 const char *pservername = NULL;
7547 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7548 const char *short_archi;
7552 /* environment may be empty */
7553 if (environment && strlen(environment)) {
7554 long_archi = environment;
7557 /* servername may be empty */
7558 if (servername && strlen(servername)) {
7559 pservername = canon_servername(servername);
7561 if (!is_myname_or_ipaddr(pservername)) {
7562 return WERR_INVALID_PARAM;
7566 if (!(short_archi = get_short_archi(long_archi))) {
7567 return WERR_INVALID_ENVIRONMENT;
7570 switch (component) {
7571 case SPOOLSS_PRTPROCS_PATH:
7572 case SPOOLSS_DRIVER_PATH:
7574 *path = talloc_asprintf(mem_ctx,
7577 spoolss_paths[component].share,
7580 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7581 SPOOLSS_DEFAULT_SERVER_PATH,
7582 spoolss_paths[component].dir,
7587 return WERR_INVALID_PARAM;
7597 /****************************************************************************
7598 ****************************************************************************/
7600 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7601 const char *servername,
7602 const char *environment,
7603 struct spoolss_DriverDirectoryInfo1 *r)
7608 werr = compose_spoolss_server_path(mem_ctx,
7611 SPOOLSS_DRIVER_PATH,
7613 if (!W_ERROR_IS_OK(werr)) {
7617 DEBUG(4,("printer driver directory: [%s]\n", path));
7619 r->directory_name = path;
7624 /****************************************************************
7625 _spoolss_GetPrinterDriverDirectory
7626 ****************************************************************/
7628 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7629 struct spoolss_GetPrinterDriverDirectory *r)
7633 /* that's an [in out] buffer */
7635 if (!r->in.buffer && (r->in.offered != 0)) {
7636 return WERR_INVALID_PARAM;
7639 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7644 /* r->in.level is ignored */
7646 werror = getprinterdriverdir_level_1(p->mem_ctx,
7649 &r->out.info->info1);
7650 if (!W_ERROR_IS_OK(werror)) {
7651 TALLOC_FREE(r->out.info);
7655 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7656 r->out.info, r->in.level);
7657 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7659 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7662 /****************************************************************
7663 _spoolss_EnumPrinterData
7664 ****************************************************************/
7666 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7667 struct spoolss_EnumPrinterData *r)
7670 struct spoolss_EnumPrinterDataEx r2;
7672 struct spoolss_PrinterEnumValues *info, *val = NULL;
7675 r2.in.handle = r->in.handle;
7676 r2.in.key_name = "PrinterDriverData";
7678 r2.out.count = &count;
7679 r2.out.info = &info;
7680 r2.out.needed = &needed;
7682 result = _spoolss_EnumPrinterDataEx(p, &r2);
7683 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7684 r2.in.offered = needed;
7685 result = _spoolss_EnumPrinterDataEx(p, &r2);
7687 if (!W_ERROR_IS_OK(result)) {
7692 * The NT machine wants to know the biggest size of value and data
7694 * cf: MSDN EnumPrinterData remark section
7697 if (!r->in.value_offered && !r->in.data_offered) {
7698 uint32_t biggest_valuesize = 0;
7699 uint32_t biggest_datasize = 0;
7702 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7704 for (i=0; i<count; i++) {
7706 name_length = strlen(info[i].value_name);
7707 if (strlen(info[i].value_name) > biggest_valuesize) {
7708 biggest_valuesize = name_length;
7711 if (info[i].data_length > biggest_datasize) {
7712 biggest_datasize = info[i].data_length;
7715 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7719 /* the value is an UNICODE string but real_value_size is the length
7720 in bytes including the trailing 0 */
7722 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7723 *r->out.data_needed = biggest_datasize;
7725 DEBUG(6,("final values: [%d], [%d]\n",
7726 *r->out.value_needed, *r->out.data_needed));
7731 if (r->in.enum_index < count) {
7732 val = &info[r->in.enum_index];
7736 /* out_value should default to "" or else NT4 has
7737 problems unmarshalling the response */
7739 if (r->in.value_offered) {
7740 *r->out.value_needed = 1;
7741 r->out.value_name = talloc_strdup(r, "");
7742 if (!r->out.value_name) {
7746 r->out.value_name = NULL;
7747 *r->out.value_needed = 0;
7750 /* the data is counted in bytes */
7752 *r->out.data_needed = r->in.data_offered;
7754 result = WERR_NO_MORE_ITEMS;
7758 * - counted in bytes in the request
7759 * - counted in UNICODE chars in the max reply
7760 * - counted in bytes in the real size
7762 * take a pause *before* coding not *during* coding
7766 if (r->in.value_offered) {
7767 r->out.value_name = talloc_strdup(r, val->value_name);
7768 if (!r->out.value_name) {
7771 *r->out.value_needed = val->value_name_len;
7773 r->out.value_name = NULL;
7774 *r->out.value_needed = 0;
7779 *r->out.type = val->type;
7781 /* data - counted in bytes */
7784 * See the section "Dynamically Typed Query Parameters"
7788 if (r->out.data && val->data && val->data->data &&
7789 val->data_length && r->in.data_offered) {
7790 memcpy(r->out.data, val->data->data,
7791 MIN(val->data_length,r->in.data_offered));
7794 *r->out.data_needed = val->data_length;
7802 /****************************************************************
7803 _spoolss_SetPrinterData
7804 ****************************************************************/
7806 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7807 struct spoolss_SetPrinterData *r)
7809 struct spoolss_SetPrinterDataEx r2;
7811 r2.in.handle = r->in.handle;
7812 r2.in.key_name = "PrinterDriverData";
7813 r2.in.value_name = r->in.value_name;
7814 r2.in.type = r->in.type;
7815 r2.in.data = r->in.data;
7816 r2.in.offered = r->in.offered;
7818 return _spoolss_SetPrinterDataEx(p, &r2);
7821 /****************************************************************
7822 _spoolss_ResetPrinter
7823 ****************************************************************/
7825 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7826 struct spoolss_ResetPrinter *r)
7828 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7831 DEBUG(5,("_spoolss_ResetPrinter\n"));
7834 * All we do is to check to see if the handle and queue is valid.
7835 * This call really doesn't mean anything to us because we only
7836 * support RAW printing. --jerry
7840 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7841 OUR_HANDLE(r->in.handle)));
7845 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7849 /* blindly return success */
7853 /****************************************************************
7854 _spoolss_DeletePrinterData
7855 ****************************************************************/
7857 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7858 struct spoolss_DeletePrinterData *r)
7860 struct spoolss_DeletePrinterDataEx r2;
7862 r2.in.handle = r->in.handle;
7863 r2.in.key_name = "PrinterDriverData";
7864 r2.in.value_name = r->in.value_name;
7866 return _spoolss_DeletePrinterDataEx(p, &r2);
7869 /****************************************************************
7871 ****************************************************************/
7873 WERROR _spoolss_AddForm(struct pipes_struct *p,
7874 struct spoolss_AddForm *r)
7876 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7878 WERROR status = WERR_OK;
7879 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7881 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7883 DEBUG(5,("_spoolss_AddForm\n"));
7886 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7887 OUR_HANDLE(r->in.handle)));
7891 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7892 and not a printer admin, then fail */
7894 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7895 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7896 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7897 p->server_info->info3->base.domain.string,
7899 p->server_info->ptok,
7900 lp_printer_admin(snum))) {
7901 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7902 return WERR_ACCESS_DENIED;
7905 switch (form->flags) {
7906 case SPOOLSS_FORM_USER:
7907 case SPOOLSS_FORM_BUILTIN:
7908 case SPOOLSS_FORM_PRINTER:
7911 return WERR_INVALID_PARAM;
7914 status = winreg_printer_addform1(p->mem_ctx, p->server_info,
7916 if (!W_ERROR_IS_OK(status)) {
7921 * ChangeID must always be set if this is a printer
7923 if (Printer->printer_type == SPLHND_PRINTER) {
7924 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7928 status = winreg_printer_update_changeid(p->mem_ctx,
7931 lp_const_servicename(snum));
7932 if (!W_ERROR_IS_OK(status)) {
7940 /****************************************************************
7942 ****************************************************************/
7944 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7945 struct spoolss_DeleteForm *r)
7947 const char *form_name = r->in.form_name;
7948 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7950 WERROR status = WERR_OK;
7951 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7953 DEBUG(5,("_spoolss_DeleteForm\n"));
7956 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7957 OUR_HANDLE(r->in.handle)));
7961 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7962 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7963 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7964 p->server_info->info3->base.domain.string,
7966 p->server_info->ptok,
7967 lp_printer_admin(snum))) {
7968 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7969 return WERR_ACCESS_DENIED;
7972 status = winreg_printer_deleteform1(p->mem_ctx,
7976 if (!W_ERROR_IS_OK(status)) {
7981 * ChangeID must always be set if this is a printer
7983 if (Printer->printer_type == SPLHND_PRINTER) {
7984 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7988 status = winreg_printer_update_changeid(p->mem_ctx,
7991 lp_const_servicename(snum));
7992 if (!W_ERROR_IS_OK(status)) {
8000 /****************************************************************
8002 ****************************************************************/
8004 WERROR _spoolss_SetForm(struct pipes_struct *p,
8005 struct spoolss_SetForm *r)
8007 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8008 const char *form_name = r->in.form_name;
8010 WERROR status = WERR_OK;
8011 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8013 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8015 DEBUG(5,("_spoolss_SetForm\n"));
8018 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8019 OUR_HANDLE(r->in.handle)));
8023 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8024 and not a printer admin, then fail */
8026 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8027 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8028 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8029 p->server_info->info3->base.domain.string,
8031 p->server_info->ptok,
8032 lp_printer_admin(snum))) {
8033 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8034 return WERR_ACCESS_DENIED;
8037 status = winreg_printer_setform1(p->mem_ctx,
8042 if (!W_ERROR_IS_OK(status)) {
8047 * ChangeID must always be set if this is a printer
8049 if (Printer->printer_type == SPLHND_PRINTER) {
8050 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8054 status = winreg_printer_update_changeid(p->mem_ctx,
8057 lp_const_servicename(snum));
8058 if (!W_ERROR_IS_OK(status)) {
8066 /****************************************************************************
8067 fill_print_processor1
8068 ****************************************************************************/
8070 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8071 struct spoolss_PrintProcessorInfo1 *r,
8072 const char *print_processor_name)
8074 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8075 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8080 /****************************************************************************
8081 enumprintprocessors level 1.
8082 ****************************************************************************/
8084 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8085 union spoolss_PrintProcessorInfo **info_p,
8088 union spoolss_PrintProcessorInfo *info;
8091 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8092 W_ERROR_HAVE_NO_MEMORY(info);
8096 result = fill_print_processor1(info, &info[0].info1, "winprint");
8097 if (!W_ERROR_IS_OK(result)) {
8102 if (!W_ERROR_IS_OK(result)) {
8113 /****************************************************************
8114 _spoolss_EnumPrintProcessors
8115 ****************************************************************/
8117 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8118 struct spoolss_EnumPrintProcessors *r)
8122 /* that's an [in out] buffer */
8124 if (!r->in.buffer && (r->in.offered != 0)) {
8125 return WERR_INVALID_PARAM;
8128 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8131 * Enumerate the print processors ...
8133 * Just reply with "winprint", to keep NT happy
8134 * and I can use my nice printer checker.
8139 *r->out.info = NULL;
8141 switch (r->in.level) {
8143 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8147 return WERR_UNKNOWN_LEVEL;
8150 if (!W_ERROR_IS_OK(result)) {
8154 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8155 spoolss_EnumPrintProcessors,
8156 *r->out.info, r->in.level,
8158 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8159 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8161 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8164 /****************************************************************************
8165 fill_printprocdatatype1
8166 ****************************************************************************/
8168 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8169 struct spoolss_PrintProcDataTypesInfo1 *r,
8170 const char *name_array)
8172 r->name_array = talloc_strdup(mem_ctx, name_array);
8173 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8178 /****************************************************************************
8179 enumprintprocdatatypes level 1.
8180 ****************************************************************************/
8182 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8183 union spoolss_PrintProcDataTypesInfo **info_p,
8187 union spoolss_PrintProcDataTypesInfo *info;
8189 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8190 W_ERROR_HAVE_NO_MEMORY(info);
8194 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8195 if (!W_ERROR_IS_OK(result)) {
8200 if (!W_ERROR_IS_OK(result)) {
8211 /****************************************************************
8212 _spoolss_EnumPrintProcDataTypes
8213 ****************************************************************/
8215 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8216 struct spoolss_EnumPrintProcDataTypes *r)
8220 /* that's an [in out] buffer */
8222 if (!r->in.buffer && (r->in.offered != 0)) {
8223 return WERR_INVALID_PARAM;
8226 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8230 *r->out.info = NULL;
8232 switch (r->in.level) {
8234 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8238 return WERR_UNKNOWN_LEVEL;
8241 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8242 spoolss_EnumPrintProcDataTypes,
8243 *r->out.info, r->in.level,
8245 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8246 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8248 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8251 /****************************************************************************
8253 ****************************************************************************/
8255 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8256 struct spoolss_MonitorInfo1 *r,
8257 const char *monitor_name)
8259 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8260 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8265 /****************************************************************************
8267 ****************************************************************************/
8269 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8270 struct spoolss_MonitorInfo2 *r,
8271 const char *monitor_name,
8272 const char *environment,
8273 const char *dll_name)
8275 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8276 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8277 r->environment = talloc_strdup(mem_ctx, environment);
8278 W_ERROR_HAVE_NO_MEMORY(r->environment);
8279 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8280 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8285 /****************************************************************************
8286 enumprintmonitors level 1.
8287 ****************************************************************************/
8289 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8290 union spoolss_MonitorInfo **info_p,
8293 union spoolss_MonitorInfo *info;
8294 WERROR result = WERR_OK;
8296 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8297 W_ERROR_HAVE_NO_MEMORY(info);
8301 result = fill_monitor_1(info, &info[0].info1,
8303 if (!W_ERROR_IS_OK(result)) {
8307 result = fill_monitor_1(info, &info[1].info1,
8309 if (!W_ERROR_IS_OK(result)) {
8314 if (!W_ERROR_IS_OK(result)) {
8325 /****************************************************************************
8326 enumprintmonitors level 2.
8327 ****************************************************************************/
8329 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8330 union spoolss_MonitorInfo **info_p,
8333 union spoolss_MonitorInfo *info;
8334 WERROR result = WERR_OK;
8336 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8337 W_ERROR_HAVE_NO_MEMORY(info);
8341 result = fill_monitor_2(info, &info[0].info2,
8343 "Windows NT X86", /* FIXME */
8345 if (!W_ERROR_IS_OK(result)) {
8349 result = fill_monitor_2(info, &info[1].info2,
8351 "Windows NT X86", /* FIXME */
8353 if (!W_ERROR_IS_OK(result)) {
8358 if (!W_ERROR_IS_OK(result)) {
8369 /****************************************************************
8370 _spoolss_EnumMonitors
8371 ****************************************************************/
8373 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8374 struct spoolss_EnumMonitors *r)
8378 /* that's an [in out] buffer */
8380 if (!r->in.buffer && (r->in.offered != 0)) {
8381 return WERR_INVALID_PARAM;
8384 DEBUG(5,("_spoolss_EnumMonitors\n"));
8387 * Enumerate the print monitors ...
8389 * Just reply with "Local Port", to keep NT happy
8390 * and I can use my nice printer checker.
8395 *r->out.info = NULL;
8397 switch (r->in.level) {
8399 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8403 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8407 return WERR_UNKNOWN_LEVEL;
8410 if (!W_ERROR_IS_OK(result)) {
8414 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8415 spoolss_EnumMonitors,
8416 *r->out.info, r->in.level,
8418 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8419 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8421 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8424 /****************************************************************************
8425 ****************************************************************************/
8427 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8428 const print_queue_struct *queue,
8429 int count, int snum,
8430 struct spoolss_PrinterInfo2 *pinfo2,
8432 struct spoolss_JobInfo1 *r)
8437 for (i=0; i<count; i++) {
8438 if (queue[i].job == (int)jobid) {
8444 if (found == false) {
8445 /* NT treats not found as bad param... yet another bad choice */
8446 return WERR_INVALID_PARAM;
8449 return fill_job_info1(mem_ctx,
8457 /****************************************************************************
8458 ****************************************************************************/
8460 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8461 const print_queue_struct *queue,
8462 int count, int snum,
8463 struct spoolss_PrinterInfo2 *pinfo2,
8465 struct spoolss_JobInfo2 *r)
8469 struct spoolss_DeviceMode *devmode;
8472 for (i=0; i<count; i++) {
8473 if (queue[i].job == (int)jobid) {
8479 if (found == false) {
8480 /* NT treats not found as bad param... yet another bad
8482 return WERR_INVALID_PARAM;
8486 * if the print job does not have a DEVMODE associated with it,
8487 * just use the one for the printer. A NULL devicemode is not
8488 * a failure condition
8491 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8493 result = spoolss_create_default_devmode(mem_ctx,
8494 pinfo2->printername,
8496 if (!W_ERROR_IS_OK(result)) {
8497 DEBUG(3, ("Can't proceed w/o a devmode!"));
8502 return fill_job_info2(mem_ctx,
8511 /****************************************************************
8513 ****************************************************************/
8515 WERROR _spoolss_GetJob(struct pipes_struct *p,
8516 struct spoolss_GetJob *r)
8518 WERROR result = WERR_OK;
8519 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8522 print_queue_struct *queue = NULL;
8523 print_status_struct prt_status;
8525 /* that's an [in out] buffer */
8527 if (!r->in.buffer && (r->in.offered != 0)) {
8528 return WERR_INVALID_PARAM;
8531 DEBUG(5,("_spoolss_GetJob\n"));
8535 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8539 result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
8540 NULL, lp_servicename(snum), &pinfo2);
8541 if (!W_ERROR_IS_OK(result)) {
8545 count = print_queue_status(snum, &queue, &prt_status);
8547 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8548 count, prt_status.status, prt_status.message));
8550 switch (r->in.level) {
8552 result = getjob_level_1(p->mem_ctx,
8553 queue, count, snum, pinfo2,
8554 r->in.job_id, &r->out.info->info1);
8557 result = getjob_level_2(p->mem_ctx,
8558 queue, count, snum, pinfo2,
8559 r->in.job_id, &r->out.info->info2);
8562 result = WERR_UNKNOWN_LEVEL;
8567 TALLOC_FREE(pinfo2);
8569 if (!W_ERROR_IS_OK(result)) {
8570 TALLOC_FREE(r->out.info);
8574 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8576 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8578 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8581 /****************************************************************
8582 _spoolss_GetPrinterDataEx
8583 ****************************************************************/
8585 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8586 struct spoolss_GetPrinterDataEx *r)
8589 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8590 const char *printer;
8592 WERROR result = WERR_OK;
8594 enum winreg_Type val_type;
8599 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8601 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8602 r->in.key_name, r->in.value_name));
8604 /* in case of problem, return some default values */
8607 *r->out.type = REG_NONE;
8610 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8611 OUR_HANDLE(r->in.handle)));
8612 result = WERR_BADFID;
8616 /* Is the handle to a printer or to the server? */
8618 if (Printer->printer_type == SPLHND_SERVER) {
8620 union spoolss_PrinterData data;
8622 result = getprinterdata_printer_server(p->mem_ctx,
8626 if (!W_ERROR_IS_OK(result)) {
8630 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8631 *r->out.type, &data);
8632 if (!W_ERROR_IS_OK(result)) {
8636 *r->out.needed = blob.length;
8638 if (r->in.offered >= *r->out.needed) {
8639 memcpy(r->out.data, blob.data, blob.length);
8642 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8645 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8648 printer = lp_const_servicename(snum);
8650 /* check to see if the keyname is valid */
8651 if (!strlen(r->in.key_name)) {
8652 return WERR_INVALID_PARAM;
8655 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8656 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8657 strequal(r->in.value_name, "ChangeId")) {
8658 *r->out.type = REG_DWORD;
8660 if (r->in.offered >= *r->out.needed) {
8661 uint32_t changeid = 0;
8663 result = winreg_printer_get_changeid(p->mem_ctx,
8668 if (!W_ERROR_IS_OK(result)) {
8672 SIVAL(r->out.data, 0, changeid);
8678 result = winreg_get_printer_dataex(p->mem_ctx,
8687 if (!W_ERROR_IS_OK(result)) {
8691 *r->out.needed = val_size;
8692 *r->out.type = val_type;
8694 if (r->in.offered >= *r->out.needed) {
8695 memcpy(r->out.data, val_data, val_size);
8699 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8700 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8702 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8705 /****************************************************************
8706 _spoolss_SetPrinterDataEx
8707 ****************************************************************/
8709 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8710 struct spoolss_SetPrinterDataEx *r)
8712 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8714 WERROR result = WERR_OK;
8715 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8718 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8720 /* From MSDN documentation of SetPrinterDataEx: pass request to
8721 SetPrinterData if key is "PrinterDriverData" */
8724 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8725 OUR_HANDLE(r->in.handle)));
8729 if (Printer->printer_type == SPLHND_SERVER) {
8730 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8731 "Not implemented for server handles yet\n"));
8732 return WERR_INVALID_PARAM;
8735 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8740 * Access check : NT returns "access denied" if you make a
8741 * SetPrinterData call without the necessary privildge.
8742 * we were originally returning OK if nothing changed
8743 * which made Win2k issue **a lot** of SetPrinterData
8744 * when connecting to a printer --jerry
8747 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8748 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8749 "change denied by handle access permissions\n"));
8750 return WERR_ACCESS_DENIED;
8753 result = winreg_get_printer(Printer, p->server_info, p->msg_ctx,
8754 Printer->servername,
8755 lp_servicename(snum),
8757 if (!W_ERROR_IS_OK(result)) {
8761 /* check for OID in valuename */
8763 oid_string = strchr(r->in.value_name, ',');
8769 /* save the registry data */
8771 result = winreg_set_printer_dataex(p->mem_ctx,
8781 if (W_ERROR_IS_OK(result)) {
8782 /* save the OID if one was specified */
8784 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8785 r->in.key_name, SPOOL_OID_KEY);
8787 result = WERR_NOMEM;
8792 * I'm not checking the status here on purpose. Don't know
8793 * if this is right, but I'm returning the status from the
8794 * previous set_printer_dataex() call. I have no idea if
8795 * this is right. --jerry
8797 winreg_set_printer_dataex(p->mem_ctx,
8804 (uint8_t *) oid_string,
8805 strlen(oid_string) + 1);
8808 result = winreg_printer_update_changeid(p->mem_ctx,
8811 lp_const_servicename(snum));
8816 talloc_free(pinfo2);
8820 /****************************************************************
8821 _spoolss_DeletePrinterDataEx
8822 ****************************************************************/
8824 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8825 struct spoolss_DeletePrinterDataEx *r)
8827 const char *printer;
8829 WERROR status = WERR_OK;
8830 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8832 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8835 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8836 "Invalid handle (%s:%u:%u).\n",
8837 OUR_HANDLE(r->in.handle)));
8841 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8842 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8843 "printer properties change denied by handle\n"));
8844 return WERR_ACCESS_DENIED;
8847 if (!r->in.value_name || !r->in.key_name) {
8851 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8854 printer = lp_const_servicename(snum);
8856 status = winreg_delete_printer_dataex(p->mem_ctx,
8862 if (W_ERROR_IS_OK(status)) {
8863 status = winreg_printer_update_changeid(p->mem_ctx,
8872 /****************************************************************
8873 _spoolss_EnumPrinterKey
8874 ****************************************************************/
8876 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8877 struct spoolss_EnumPrinterKey *r)
8880 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8882 WERROR result = WERR_BADFILE;
8883 const char **array = NULL;
8886 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8889 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8890 OUR_HANDLE(r->in.handle)));
8894 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8898 result = winreg_enum_printer_key(p->mem_ctx,
8901 lp_const_servicename(snum),
8905 if (!W_ERROR_IS_OK(result)) {
8909 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8910 result = WERR_NOMEM;
8914 *r->out._ndr_size = r->in.offered / 2;
8915 *r->out.needed = blob.length;
8917 if (r->in.offered < *r->out.needed) {
8918 result = WERR_MORE_DATA;
8921 r->out.key_buffer->string_array = array;
8925 if (!W_ERROR_IS_OK(result)) {
8927 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8935 /****************************************************************
8936 _spoolss_DeletePrinterKey
8937 ****************************************************************/
8939 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8940 struct spoolss_DeletePrinterKey *r)
8942 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8945 const char *printer;
8947 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8950 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8951 OUR_HANDLE(r->in.handle)));
8955 /* if keyname == NULL, return error */
8956 if ( !r->in.key_name )
8957 return WERR_INVALID_PARAM;
8959 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8963 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8964 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8965 "printer properties change denied by handle\n"));
8966 return WERR_ACCESS_DENIED;
8969 printer = lp_const_servicename(snum);
8971 /* delete the key and all subkeys */
8972 status = winreg_delete_printer_key(p->mem_ctx,
8977 if (W_ERROR_IS_OK(status)) {
8978 status = winreg_printer_update_changeid(p->mem_ctx,
8987 /****************************************************************
8988 _spoolss_EnumPrinterDataEx
8989 ****************************************************************/
8991 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8992 struct spoolss_EnumPrinterDataEx *r)
8995 struct spoolss_PrinterEnumValues *info = NULL;
8996 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9000 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9004 *r->out.info = NULL;
9007 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9008 OUR_HANDLE(r->in.handle)));
9013 * first check for a keyname of NULL or "". Win2k seems to send
9014 * this a lot and we should send back WERR_INVALID_PARAM
9015 * no need to spend time looking up the printer in this case.
9019 if (!strlen(r->in.key_name)) {
9020 result = WERR_INVALID_PARAM;
9024 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9028 /* now look for a match on the key name */
9029 result = winreg_enum_printer_dataex(p->mem_ctx,
9032 lp_const_servicename(snum),
9036 if (!W_ERROR_IS_OK(result)) {
9040 #if 0 /* FIXME - gd */
9041 /* housekeeping information in the reply */
9043 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9044 * the hand marshalled container size is a multiple
9045 * of 4 bytes for RPC alignment.
9049 needed += 4-(needed % 4);
9052 *r->out.count = count;
9053 *r->out.info = info;
9056 if (!W_ERROR_IS_OK(result)) {
9060 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9061 spoolss_EnumPrinterDataEx,
9064 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9065 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9067 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9070 /****************************************************************************
9071 ****************************************************************************/
9073 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9074 const char *servername,
9075 const char *environment,
9076 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9081 werr = compose_spoolss_server_path(mem_ctx,
9084 SPOOLSS_PRTPROCS_PATH,
9086 if (!W_ERROR_IS_OK(werr)) {
9090 DEBUG(4,("print processor directory: [%s]\n", path));
9092 r->directory_name = path;
9097 /****************************************************************
9098 _spoolss_GetPrintProcessorDirectory
9099 ****************************************************************/
9101 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9102 struct spoolss_GetPrintProcessorDirectory *r)
9106 /* that's an [in out] buffer */
9108 if (!r->in.buffer && (r->in.offered != 0)) {
9109 return WERR_INVALID_PARAM;
9112 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9117 /* r->in.level is ignored */
9119 /* We always should reply with a local print processor directory so that
9120 * users are not forced to have a [prnproc$] share on the Samba spoolss
9121 * server - Guenther */
9123 result = getprintprocessordirectory_level_1(p->mem_ctx,
9124 NULL, /* r->in.server */
9126 &r->out.info->info1);
9127 if (!W_ERROR_IS_OK(result)) {
9128 TALLOC_FREE(r->out.info);
9132 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9133 r->out.info, r->in.level);
9134 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9136 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9139 /*******************************************************************
9140 ********************************************************************/
9142 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9143 const char *dllname)
9145 enum ndr_err_code ndr_err;
9146 struct spoolss_MonitorUi ui;
9148 ui.dll_name = dllname;
9150 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9151 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9152 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9153 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9155 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9158 /*******************************************************************
9159 Streams the monitor UI DLL name in UNICODE
9160 *******************************************************************/
9162 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9163 NT_USER_TOKEN *token, DATA_BLOB *in,
9164 DATA_BLOB *out, uint32_t *needed)
9166 const char *dllname = "tcpmonui.dll";
9168 *needed = (strlen(dllname)+1) * 2;
9170 if (out->length < *needed) {
9171 return WERR_INSUFFICIENT_BUFFER;
9174 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9181 /*******************************************************************
9182 ********************************************************************/
9184 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9185 struct spoolss_PortData1 *port1,
9186 const DATA_BLOB *buf)
9188 enum ndr_err_code ndr_err;
9189 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9190 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9191 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9192 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9194 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9197 /*******************************************************************
9198 ********************************************************************/
9200 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9201 struct spoolss_PortData2 *port2,
9202 const DATA_BLOB *buf)
9204 enum ndr_err_code ndr_err;
9205 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9206 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9207 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9208 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9210 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9213 /*******************************************************************
9214 Create a new TCP/IP port
9215 *******************************************************************/
9217 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9218 NT_USER_TOKEN *token, DATA_BLOB *in,
9219 DATA_BLOB *out, uint32_t *needed)
9221 struct spoolss_PortData1 port1;
9222 struct spoolss_PortData2 port2;
9223 char *device_uri = NULL;
9226 const char *portname;
9227 const char *hostaddress;
9229 uint32_t port_number;
9232 /* peek for spoolss_PortData version */
9234 if (!in || (in->length < (128 + 4))) {
9235 return WERR_GENERAL_FAILURE;
9238 version = IVAL(in->data, 128);
9244 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9248 portname = port1.portname;
9249 hostaddress = port1.hostaddress;
9250 queue = port1.queue;
9251 protocol = port1.protocol;
9252 port_number = port1.port_number;
9258 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9262 portname = port2.portname;
9263 hostaddress = port2.hostaddress;
9264 queue = port2.queue;
9265 protocol = port2.protocol;
9266 port_number = port2.port_number;
9270 DEBUG(1,("xcvtcp_addport: "
9271 "unknown version of port_data: %d\n", version));
9272 return WERR_UNKNOWN_PORT;
9275 /* create the device URI and call the add_port_hook() */
9278 case PROTOCOL_RAWTCP_TYPE:
9279 device_uri = talloc_asprintf(mem_ctx,
9280 "socket://%s:%d/", hostaddress,
9284 case PROTOCOL_LPR_TYPE:
9285 device_uri = talloc_asprintf(mem_ctx,
9286 "lpr://%s/%s", hostaddress, queue );
9290 return WERR_UNKNOWN_PORT;
9297 return add_port_hook(mem_ctx, token, portname, device_uri);
9300 /*******************************************************************
9301 *******************************************************************/
9303 struct xcv_api_table xcvtcp_cmds[] = {
9304 { "MonitorUI", xcvtcp_monitorui },
9305 { "AddPort", xcvtcp_addport},
9309 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9310 NT_USER_TOKEN *token, const char *command,
9317 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9319 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9320 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9321 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9324 return WERR_BADFUNC;
9327 /*******************************************************************
9328 *******************************************************************/
9329 #if 0 /* don't support management using the "Local Port" monitor */
9331 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9332 NT_USER_TOKEN *token, DATA_BLOB *in,
9333 DATA_BLOB *out, uint32_t *needed)
9335 const char *dllname = "localui.dll";
9337 *needed = (strlen(dllname)+1) * 2;
9339 if (out->length < *needed) {
9340 return WERR_INSUFFICIENT_BUFFER;
9343 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9350 /*******************************************************************
9351 *******************************************************************/
9353 struct xcv_api_table xcvlocal_cmds[] = {
9354 { "MonitorUI", xcvlocal_monitorui },
9358 struct xcv_api_table xcvlocal_cmds[] = {
9365 /*******************************************************************
9366 *******************************************************************/
9368 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9369 NT_USER_TOKEN *token, const char *command,
9370 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9375 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9377 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9378 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9379 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9381 return WERR_BADFUNC;
9384 /****************************************************************
9386 ****************************************************************/
9388 WERROR _spoolss_XcvData(struct pipes_struct *p,
9389 struct spoolss_XcvData *r)
9391 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9392 DATA_BLOB out_data = data_blob_null;
9396 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9397 OUR_HANDLE(r->in.handle)));
9401 /* Has to be a handle to the TCP/IP port monitor */
9403 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9404 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9408 /* requires administrative access to the server */
9410 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9411 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9412 return WERR_ACCESS_DENIED;
9415 /* Allocate the outgoing buffer */
9417 if (r->in.out_data_size) {
9418 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9419 if (out_data.data == NULL) {
9424 switch ( Printer->printer_type ) {
9425 case SPLHND_PORTMON_TCP:
9426 werror = process_xcvtcp_command(p->mem_ctx,
9427 p->server_info->ptok,
9428 r->in.function_name,
9429 &r->in.in_data, &out_data,
9432 case SPLHND_PORTMON_LOCAL:
9433 werror = process_xcvlocal_command(p->mem_ctx,
9434 p->server_info->ptok,
9435 r->in.function_name,
9436 &r->in.in_data, &out_data,
9440 werror = WERR_INVALID_PRINT_MONITOR;
9443 if (!W_ERROR_IS_OK(werror)) {
9447 *r->out.status_code = 0;
9449 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9450 memcpy(r->out.out_data, out_data.data,
9451 MIN(r->in.out_data_size, out_data.length));
9457 /****************************************************************
9458 _spoolss_AddPrintProcessor
9459 ****************************************************************/
9461 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9462 struct spoolss_AddPrintProcessor *r)
9464 /* for now, just indicate success and ignore the add. We'll
9465 automatically set the winprint processor for printer
9466 entries later. Used to debug the LexMark Optra S 1855 PCL
9472 /****************************************************************
9474 ****************************************************************/
9476 WERROR _spoolss_AddPort(struct pipes_struct *p,
9477 struct spoolss_AddPort *r)
9479 /* do what w2k3 does */
9481 return WERR_NOT_SUPPORTED;
9484 /****************************************************************
9485 _spoolss_GetPrinterDriver
9486 ****************************************************************/
9488 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9489 struct spoolss_GetPrinterDriver *r)
9491 p->rng_fault_state = true;
9492 return WERR_NOT_SUPPORTED;
9495 /****************************************************************
9496 _spoolss_ReadPrinter
9497 ****************************************************************/
9499 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9500 struct spoolss_ReadPrinter *r)
9502 p->rng_fault_state = true;
9503 return WERR_NOT_SUPPORTED;
9506 /****************************************************************
9507 _spoolss_WaitForPrinterChange
9508 ****************************************************************/
9510 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9511 struct spoolss_WaitForPrinterChange *r)
9513 p->rng_fault_state = true;
9514 return WERR_NOT_SUPPORTED;
9517 /****************************************************************
9518 _spoolss_ConfigurePort
9519 ****************************************************************/
9521 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9522 struct spoolss_ConfigurePort *r)
9524 p->rng_fault_state = true;
9525 return WERR_NOT_SUPPORTED;
9528 /****************************************************************
9530 ****************************************************************/
9532 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9533 struct spoolss_DeletePort *r)
9535 p->rng_fault_state = true;
9536 return WERR_NOT_SUPPORTED;
9539 /****************************************************************
9540 _spoolss_CreatePrinterIC
9541 ****************************************************************/
9543 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9544 struct spoolss_CreatePrinterIC *r)
9546 p->rng_fault_state = true;
9547 return WERR_NOT_SUPPORTED;
9550 /****************************************************************
9551 _spoolss_PlayGDIScriptOnPrinterIC
9552 ****************************************************************/
9554 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9555 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9557 p->rng_fault_state = true;
9558 return WERR_NOT_SUPPORTED;
9561 /****************************************************************
9562 _spoolss_DeletePrinterIC
9563 ****************************************************************/
9565 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9566 struct spoolss_DeletePrinterIC *r)
9568 p->rng_fault_state = true;
9569 return WERR_NOT_SUPPORTED;
9572 /****************************************************************
9573 _spoolss_AddPrinterConnection
9574 ****************************************************************/
9576 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9577 struct spoolss_AddPrinterConnection *r)
9579 p->rng_fault_state = true;
9580 return WERR_NOT_SUPPORTED;
9583 /****************************************************************
9584 _spoolss_DeletePrinterConnection
9585 ****************************************************************/
9587 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9588 struct spoolss_DeletePrinterConnection *r)
9590 p->rng_fault_state = true;
9591 return WERR_NOT_SUPPORTED;
9594 /****************************************************************
9595 _spoolss_PrinterMessageBox
9596 ****************************************************************/
9598 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9599 struct spoolss_PrinterMessageBox *r)
9601 p->rng_fault_state = true;
9602 return WERR_NOT_SUPPORTED;
9605 /****************************************************************
9607 ****************************************************************/
9609 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9610 struct spoolss_AddMonitor *r)
9612 p->rng_fault_state = true;
9613 return WERR_NOT_SUPPORTED;
9616 /****************************************************************
9617 _spoolss_DeleteMonitor
9618 ****************************************************************/
9620 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9621 struct spoolss_DeleteMonitor *r)
9623 p->rng_fault_state = true;
9624 return WERR_NOT_SUPPORTED;
9627 /****************************************************************
9628 _spoolss_DeletePrintProcessor
9629 ****************************************************************/
9631 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9632 struct spoolss_DeletePrintProcessor *r)
9634 p->rng_fault_state = true;
9635 return WERR_NOT_SUPPORTED;
9638 /****************************************************************
9639 _spoolss_AddPrintProvidor
9640 ****************************************************************/
9642 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9643 struct spoolss_AddPrintProvidor *r)
9645 p->rng_fault_state = true;
9646 return WERR_NOT_SUPPORTED;
9649 /****************************************************************
9650 _spoolss_DeletePrintProvidor
9651 ****************************************************************/
9653 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9654 struct spoolss_DeletePrintProvidor *r)
9656 p->rng_fault_state = true;
9657 return WERR_NOT_SUPPORTED;
9660 /****************************************************************
9661 _spoolss_FindFirstPrinterChangeNotification
9662 ****************************************************************/
9664 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9665 struct spoolss_FindFirstPrinterChangeNotification *r)
9667 p->rng_fault_state = true;
9668 return WERR_NOT_SUPPORTED;
9671 /****************************************************************
9672 _spoolss_FindNextPrinterChangeNotification
9673 ****************************************************************/
9675 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9676 struct spoolss_FindNextPrinterChangeNotification *r)
9678 p->rng_fault_state = true;
9679 return WERR_NOT_SUPPORTED;
9682 /****************************************************************
9683 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9684 ****************************************************************/
9686 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9687 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9689 p->rng_fault_state = true;
9690 return WERR_NOT_SUPPORTED;
9693 /****************************************************************
9694 _spoolss_ReplyOpenPrinter
9695 ****************************************************************/
9697 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9698 struct spoolss_ReplyOpenPrinter *r)
9700 p->rng_fault_state = true;
9701 return WERR_NOT_SUPPORTED;
9704 /****************************************************************
9705 _spoolss_RouterReplyPrinter
9706 ****************************************************************/
9708 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9709 struct spoolss_RouterReplyPrinter *r)
9711 p->rng_fault_state = true;
9712 return WERR_NOT_SUPPORTED;
9715 /****************************************************************
9716 _spoolss_ReplyClosePrinter
9717 ****************************************************************/
9719 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9720 struct spoolss_ReplyClosePrinter *r)
9722 p->rng_fault_state = true;
9723 return WERR_NOT_SUPPORTED;
9726 /****************************************************************
9728 ****************************************************************/
9730 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9731 struct spoolss_AddPortEx *r)
9733 p->rng_fault_state = true;
9734 return WERR_NOT_SUPPORTED;
9737 /****************************************************************
9738 _spoolss_RouterFindFirstPrinterChangeNotification
9739 ****************************************************************/
9741 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9742 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9744 p->rng_fault_state = true;
9745 return WERR_NOT_SUPPORTED;
9748 /****************************************************************
9749 _spoolss_SpoolerInit
9750 ****************************************************************/
9752 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9753 struct spoolss_SpoolerInit *r)
9755 p->rng_fault_state = true;
9756 return WERR_NOT_SUPPORTED;
9759 /****************************************************************
9760 _spoolss_ResetPrinterEx
9761 ****************************************************************/
9763 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9764 struct spoolss_ResetPrinterEx *r)
9766 p->rng_fault_state = true;
9767 return WERR_NOT_SUPPORTED;
9770 /****************************************************************
9771 _spoolss_RouterReplyPrinterEx
9772 ****************************************************************/
9774 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9775 struct spoolss_RouterReplyPrinterEx *r)
9777 p->rng_fault_state = true;
9778 return WERR_NOT_SUPPORTED;
9781 /****************************************************************
9783 ****************************************************************/
9785 WERROR _spoolss_44(struct pipes_struct *p,
9786 struct spoolss_44 *r)
9788 p->rng_fault_state = true;
9789 return WERR_NOT_SUPPORTED;
9792 /****************************************************************
9794 ****************************************************************/
9796 WERROR _spoolss_47(struct pipes_struct *p,
9797 struct spoolss_47 *r)
9799 p->rng_fault_state = true;
9800 return WERR_NOT_SUPPORTED;
9803 /****************************************************************
9805 ****************************************************************/
9807 WERROR _spoolss_4a(struct pipes_struct *p,
9808 struct spoolss_4a *r)
9810 p->rng_fault_state = true;
9811 return WERR_NOT_SUPPORTED;
9814 /****************************************************************
9816 ****************************************************************/
9818 WERROR _spoolss_4b(struct pipes_struct *p,
9819 struct spoolss_4b *r)
9821 p->rng_fault_state = true;
9822 return WERR_NOT_SUPPORTED;
9825 /****************************************************************
9827 ****************************************************************/
9829 WERROR _spoolss_4c(struct pipes_struct *p,
9830 struct spoolss_4c *r)
9832 p->rng_fault_state = true;
9833 return WERR_NOT_SUPPORTED;
9836 /****************************************************************
9838 ****************************************************************/
9840 WERROR _spoolss_53(struct pipes_struct *p,
9841 struct spoolss_53 *r)
9843 p->rng_fault_state = true;
9844 return WERR_NOT_SUPPORTED;
9847 /****************************************************************
9849 ****************************************************************/
9851 WERROR _spoolss_55(struct pipes_struct *p,
9852 struct spoolss_55 *r)
9854 p->rng_fault_state = true;
9855 return WERR_NOT_SUPPORTED;
9858 /****************************************************************
9860 ****************************************************************/
9862 WERROR _spoolss_56(struct pipes_struct *p,
9863 struct spoolss_56 *r)
9865 p->rng_fault_state = true;
9866 return WERR_NOT_SUPPORTED;
9869 /****************************************************************
9871 ****************************************************************/
9873 WERROR _spoolss_57(struct pipes_struct *p,
9874 struct spoolss_57 *r)
9876 p->rng_fault_state = true;
9877 return WERR_NOT_SUPPORTED;
9880 /****************************************************************
9882 ****************************************************************/
9884 WERROR _spoolss_5a(struct pipes_struct *p,
9885 struct spoolss_5a *r)
9887 p->rng_fault_state = true;
9888 return WERR_NOT_SUPPORTED;
9891 /****************************************************************
9893 ****************************************************************/
9895 WERROR _spoolss_5b(struct pipes_struct *p,
9896 struct spoolss_5b *r)
9898 p->rng_fault_state = true;
9899 return WERR_NOT_SUPPORTED;
9902 /****************************************************************
9904 ****************************************************************/
9906 WERROR _spoolss_5c(struct pipes_struct *p,
9907 struct spoolss_5c *r)
9909 p->rng_fault_state = true;
9910 return WERR_NOT_SUPPORTED;
9913 /****************************************************************
9915 ****************************************************************/
9917 WERROR _spoolss_5d(struct pipes_struct *p,
9918 struct spoolss_5d *r)
9920 p->rng_fault_state = true;
9921 return WERR_NOT_SUPPORTED;
9924 /****************************************************************
9926 ****************************************************************/
9928 WERROR _spoolss_5e(struct pipes_struct *p,
9929 struct spoolss_5e *r)
9931 p->rng_fault_state = true;
9932 return WERR_NOT_SUPPORTED;
9935 /****************************************************************
9937 ****************************************************************/
9939 WERROR _spoolss_5f(struct pipes_struct *p,
9940 struct spoolss_5f *r)
9942 p->rng_fault_state = true;
9943 return WERR_NOT_SUPPORTED;
9946 /****************************************************************
9948 ****************************************************************/
9950 WERROR _spoolss_60(struct pipes_struct *p,
9951 struct spoolss_60 *r)
9953 p->rng_fault_state = true;
9954 return WERR_NOT_SUPPORTED;
9957 /****************************************************************
9959 ****************************************************************/
9961 WERROR _spoolss_61(struct pipes_struct *p,
9962 struct spoolss_61 *r)
9964 p->rng_fault_state = true;
9965 return WERR_NOT_SUPPORTED;
9968 /****************************************************************
9970 ****************************************************************/
9972 WERROR _spoolss_62(struct pipes_struct *p,
9973 struct spoolss_62 *r)
9975 p->rng_fault_state = true;
9976 return WERR_NOT_SUPPORTED;
9979 /****************************************************************
9981 ****************************************************************/
9983 WERROR _spoolss_63(struct pipes_struct *p,
9984 struct spoolss_63 *r)
9986 p->rng_fault_state = true;
9987 return WERR_NOT_SUPPORTED;
9990 /****************************************************************
9992 ****************************************************************/
9994 WERROR _spoolss_64(struct pipes_struct *p,
9995 struct spoolss_64 *r)
9997 p->rng_fault_state = true;
9998 return WERR_NOT_SUPPORTED;
10001 /****************************************************************
10003 ****************************************************************/
10005 WERROR _spoolss_65(struct pipes_struct *p,
10006 struct spoolss_65 *r)
10008 p->rng_fault_state = true;
10009 return WERR_NOT_SUPPORTED;
10012 /****************************************************************
10013 _spoolss_GetCorePrinterDrivers
10014 ****************************************************************/
10016 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
10017 struct spoolss_GetCorePrinterDrivers *r)
10019 p->rng_fault_state = true;
10020 return WERR_NOT_SUPPORTED;
10023 /****************************************************************
10025 ****************************************************************/
10027 WERROR _spoolss_67(struct pipes_struct *p,
10028 struct spoolss_67 *r)
10030 p->rng_fault_state = true;
10031 return WERR_NOT_SUPPORTED;
10034 /****************************************************************
10035 _spoolss_GetPrinterDriverPackagePath
10036 ****************************************************************/
10038 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10039 struct spoolss_GetPrinterDriverPackagePath *r)
10041 p->rng_fault_state = true;
10042 return WERR_NOT_SUPPORTED;
10045 /****************************************************************
10047 ****************************************************************/
10049 WERROR _spoolss_69(struct pipes_struct *p,
10050 struct spoolss_69 *r)
10052 p->rng_fault_state = true;
10053 return WERR_NOT_SUPPORTED;
10056 /****************************************************************
10058 ****************************************************************/
10060 WERROR _spoolss_6a(struct pipes_struct *p,
10061 struct spoolss_6a *r)
10063 p->rng_fault_state = true;
10064 return WERR_NOT_SUPPORTED;
10067 /****************************************************************
10069 ****************************************************************/
10071 WERROR _spoolss_6b(struct pipes_struct *p,
10072 struct spoolss_6b *r)
10074 p->rng_fault_state = true;
10075 return WERR_NOT_SUPPORTED;
10078 /****************************************************************
10080 ****************************************************************/
10082 WERROR _spoolss_6c(struct pipes_struct *p,
10083 struct spoolss_6c *r)
10085 p->rng_fault_state = true;
10086 return WERR_NOT_SUPPORTED;
10089 /****************************************************************
10091 ****************************************************************/
10093 WERROR _spoolss_6d(struct pipes_struct *p,
10094 struct spoolss_6d *r)
10096 p->rng_fault_state = true;
10097 return WERR_NOT_SUPPORTED;