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"
45 /* macros stolen from s4 spoolss server */
46 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
47 ((info)?ndr_size_##fn(info, level, 0):0)
49 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
50 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
52 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
53 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
55 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
58 #define DBGC_CLASS DBGC_RPC_SRV
60 #ifndef MAX_OPEN_PRINTER_EXS
61 #define MAX_OPEN_PRINTER_EXS 50
64 struct notify_back_channel;
66 /* structure to store the printer handles */
67 /* and a reference to what it's pointing to */
68 /* and the notify info asked about */
69 /* that's the central struct */
70 struct printer_handle {
71 struct printer_handle *prev, *next;
72 bool document_started;
74 uint32 jobid; /* jobid in printing backend */
79 uint32 access_granted;
85 struct spoolss_NotifyOption *option;
86 struct policy_handle cli_hnd;
87 struct notify_back_channel *cli_chan;
89 /* are we in a FindNextPrinterChangeNotify() call? */
91 struct messaging_context *msg_ctx;
98 /* devmode sent in the OpenPrinter() call */
99 struct spoolss_DeviceMode *devmode;
101 /* TODO cache the printer info2 structure */
102 struct spoolss_PrinterInfo2 *info2;
106 static struct printer_handle *printers_list;
108 struct printer_session_counter {
109 struct printer_session_counter *next;
110 struct printer_session_counter *prev;
116 static struct printer_session_counter *counter_list;
118 struct notify_back_channel {
119 struct notify_back_channel *prev, *next;
121 /* associated client */
122 struct sockaddr_storage client_address;
124 /* print notify back-channel pipe handle*/
125 struct rpc_pipe_client *cli_pipe;
126 uint32_t active_connections;
129 static struct notify_back_channel *back_channels;
131 /* Map generic permissions to printer object specific permissions */
133 const struct standard_mapping printer_std_mapping = {
140 /* Map generic permissions to print server object specific permissions */
142 const struct standard_mapping printserver_std_mapping = {
149 /* API table for Xcv Monitor functions */
151 struct xcv_api_table {
153 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
156 static void prune_printername_cache(void);
158 /********************************************************************
159 * Canonicalize servername.
160 ********************************************************************/
162 static const char *canon_servername(const char *servername)
164 const char *pservername = servername;
165 while (*pservername == '\\') {
171 /* translate between internal status numbers and NT status numbers */
172 static int nt_printj_status(int v)
178 return JOB_STATUS_PAUSED;
180 return JOB_STATUS_SPOOLING;
182 return JOB_STATUS_PRINTING;
184 return JOB_STATUS_ERROR;
186 return JOB_STATUS_DELETING;
188 return JOB_STATUS_OFFLINE;
190 return JOB_STATUS_PAPEROUT;
192 return JOB_STATUS_PRINTED;
194 return JOB_STATUS_DELETED;
196 return JOB_STATUS_BLOCKED_DEVQ;
197 case LPQ_USER_INTERVENTION:
198 return JOB_STATUS_USER_INTERVENTION;
203 static int nt_printq_status(int v)
207 return PRINTER_STATUS_PAUSED;
216 /***************************************************************************
217 Disconnect from the client
218 ****************************************************************************/
220 static void srv_spoolss_replycloseprinter(int snum,
221 struct printer_handle *prn_hnd)
227 * Tell the specific printing tdb we no longer want messages for this printer
228 * by deregistering our PID.
231 if (!print_notify_deregister_pid(snum)) {
232 DEBUG(0, ("Failed to register our pid for printer %s\n",
233 lp_const_servicename(snum)));
236 /* weird if the test succeeds !!! */
237 if (prn_hnd->notify.cli_chan == NULL ||
238 prn_hnd->notify.cli_chan->active_connections == 0) {
239 DEBUG(0, ("Trying to close unexisting backchannel!\n"));
240 DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
241 TALLOC_FREE(prn_hnd->notify.cli_chan);
245 status = rpccli_spoolss_ReplyClosePrinter(
246 prn_hnd->notify.cli_chan->cli_pipe,
248 &prn_hnd->notify.cli_hnd,
250 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
251 DEBUG(0, ("reply_close_printer failed [%s].\n",
252 win_errstr(result)));
255 /* if it's the last connection, deconnect the IPC$ share */
256 if (prn_hnd->notify.cli_chan->active_connections == 1) {
258 cli_shutdown(rpc_pipe_np_smb_conn(prn_hnd->notify.cli_chan->cli_pipe));
259 DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
260 TALLOC_FREE(prn_hnd->notify.cli_chan);
262 if (prn_hnd->notify.msg_ctx != NULL) {
263 messaging_deregister(prn_hnd->notify.msg_ctx,
264 MSG_PRINTER_NOTIFY2, NULL);
267 * Tell the serverid.tdb we're no longer
268 * interested in printer notify messages.
271 serverid_register_msg_flags(
272 messaging_server_id(prn_hnd->notify.msg_ctx),
273 false, FLAG_MSG_PRINT_NOTIFY);
277 if (prn_hnd->notify.cli_chan) {
278 prn_hnd->notify.cli_chan->active_connections--;
282 /****************************************************************************
283 Functions to free a printer entry datastruct.
284 ****************************************************************************/
286 static int printer_entry_destructor(struct printer_handle *Printer)
288 if (Printer->notify.cli_chan != NULL &&
289 Printer->notify.cli_chan->active_connections > 0) {
292 switch(Printer->printer_type) {
294 srv_spoolss_replycloseprinter(snum, Printer);
298 snum = print_queue_snum(Printer->sharename);
300 srv_spoolss_replycloseprinter(snum, Printer);
308 Printer->notify.flags=0;
309 Printer->notify.options=0;
310 Printer->notify.localmachine[0]='\0';
311 Printer->notify.printerlocal=0;
312 TALLOC_FREE(Printer->notify.option);
313 TALLOC_FREE(Printer->devmode);
315 /* Remove from the internal list. */
316 DLIST_REMOVE(printers_list, Printer);
320 /****************************************************************************
321 find printer index by handle
322 ****************************************************************************/
324 static struct printer_handle *find_printer_index_by_hnd(struct pipes_struct *p,
325 struct policy_handle *hnd)
327 struct printer_handle *find_printer = NULL;
329 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
330 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
337 /****************************************************************************
338 Close printer index by handle.
339 ****************************************************************************/
341 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
343 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
346 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
351 close_policy_hnd(p, hnd);
356 /****************************************************************************
357 Delete a printer given a handle.
358 ****************************************************************************/
360 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
361 const char *sharename,
362 struct messaging_context *msg_ctx)
364 char *cmd = lp_deleteprinter_cmd();
365 char *command = NULL;
367 SE_PRIV se_printop = SE_PRINT_OPERATOR;
368 bool is_print_op = false;
370 /* can't fail if we don't try */
375 command = talloc_asprintf(ctx,
382 is_print_op = user_has_privileges( token, &se_printop );
384 DEBUG(10,("Running [%s]\n", command));
386 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
391 if ( (ret = smbrun(command, NULL)) == 0 ) {
392 /* Tell everyone we updated smb.conf. */
393 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
399 /********** END SePrintOperatorPrivlege BLOCK **********/
401 DEBUGADD(10,("returned [%d]\n", ret));
403 TALLOC_FREE(command);
406 return WERR_BADFID; /* What to return here? */
408 /* go ahead and re-read the services immediately */
410 reload_services(msg_ctx, -1, false);
413 if ( lp_servicenumber( sharename ) > 0 )
414 return WERR_ACCESS_DENIED;
419 /****************************************************************************
420 Delete a printer given a handle.
421 ****************************************************************************/
423 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
425 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
429 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
435 * It turns out that Windows allows delete printer on a handle
436 * opened by an admin user, then used on a pipe handle created
437 * by an anonymous user..... but they're working on security.... riiight !
441 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
442 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
443 return WERR_ACCESS_DENIED;
446 /* this does not need a become root since the access check has been
447 done on the handle already */
449 result = winreg_delete_printer_key(p->mem_ctx,
450 get_server_info_system(),
454 if (!W_ERROR_IS_OK(result)) {
455 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
459 result = delete_printer_hook(p->mem_ctx, p->server_info->ptok,
460 Printer->sharename, p->msg_ctx);
461 if (!W_ERROR_IS_OK(result)) {
464 prune_printername_cache();
468 /****************************************************************************
469 Return the snum of a printer corresponding to an handle.
470 ****************************************************************************/
472 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
473 int *number, struct share_params **params)
475 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
478 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
483 switch (Printer->printer_type) {
485 DEBUG(4,("short name:%s\n", Printer->sharename));
486 *number = print_queue_snum(Printer->sharename);
487 return (*number != -1);
495 /****************************************************************************
496 Set printer handle type.
497 Check if it's \\server or \\server\printer
498 ****************************************************************************/
500 static bool set_printer_hnd_printertype(struct printer_handle *Printer, const char *handlename)
502 DEBUG(3,("Setting printer type=%s\n", handlename));
504 /* it's a print server */
505 if (handlename && *handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
506 DEBUGADD(4,("Printer is a print server\n"));
507 Printer->printer_type = SPLHND_SERVER;
509 /* it's a printer (set_printer_hnd_name() will handle port monitors */
511 DEBUGADD(4,("Printer is a printer\n"));
512 Printer->printer_type = SPLHND_PRINTER;
518 static void prune_printername_cache_fn(const char *key, const char *value,
519 time_t timeout, void *private_data)
524 static void prune_printername_cache(void)
526 gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
529 /****************************************************************************
530 Set printer handle name.. Accept names like \\server, \\server\printer,
531 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
532 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
533 XcvDataPort() interface.
534 ****************************************************************************/
536 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
537 const struct auth_serversupplied_info *server_info,
538 struct messaging_context *msg_ctx,
539 struct printer_handle *Printer,
540 const char *handlename)
543 int n_services=lp_numservices();
545 const char *printername;
546 const char *servername = NULL;
549 struct spoolss_PrinterInfo2 *info2 = NULL;
553 * Hopefully nobody names his printers like this. Maybe \ or ,
554 * are illegal in printer names even?
556 const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
560 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
561 (unsigned long)strlen(handlename)));
563 aprinter = CONST_DISCARD(char *, handlename);
564 if ( *handlename == '\\' ) {
565 servername = canon_servername(handlename);
566 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
570 if (!is_myname_or_ipaddr(servername)) {
574 fstrcpy(Printer->servername, servername);
577 if (Printer->printer_type == SPLHND_SERVER) {
581 if (Printer->printer_type != SPLHND_PRINTER) {
585 DEBUGADD(5, ("searching for [%s]\n", aprinter));
587 /* check for the Port Monitor Interface */
588 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
589 Printer->printer_type = SPLHND_PORTMON_TCP;
590 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
593 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
594 Printer->printer_type = SPLHND_PORTMON_LOCAL;
595 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
600 * With hundreds of printers, the "for" loop iterating all
601 * shares can be quite expensive, as it is done on every
602 * OpenPrinter. The loop maps "aprinter" to "sname", the
603 * result of which we cache in gencache.
606 cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
608 if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
610 found = (strcmp(tmp, printer_not_found) != 0);
612 DEBUG(4, ("Printer %s not found\n", aprinter));
620 /* Search all sharenames first as this is easier than pulling
621 the printer_info_2 off of disk. Don't use find_service() since
622 that calls out to map_username() */
624 /* do another loop to look for printernames */
625 for (snum = 0; !found && snum < n_services; snum++) {
626 const char *printer = lp_const_servicename(snum);
628 /* no point going on if this is not a printer */
629 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
633 /* ignore [printers] share */
634 if (strequal(printer, "printers")) {
638 fstrcpy(sname, printer);
639 if (strequal(aprinter, printer)) {
644 /* no point looking up the printer object if
645 we aren't allowing printername != sharename */
646 if (lp_force_printername(snum)) {
650 result = winreg_get_printer(mem_ctx,
656 if ( !W_ERROR_IS_OK(result) ) {
657 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
658 sname, win_errstr(result)));
662 printername = strrchr(info2->printername, '\\');
663 if (printername == NULL) {
664 printername = info2->printername;
669 if (strequal(printername, aprinter)) {
674 DEBUGADD(10, ("printername: %s\n", printername));
680 if (cache_key != NULL) {
681 gencache_set(cache_key, printer_not_found,
683 TALLOC_FREE(cache_key);
685 DEBUGADD(4,("Printer not found\n"));
689 if (cache_key != NULL) {
690 gencache_set(cache_key, sname, time(NULL)+300);
691 TALLOC_FREE(cache_key);
694 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
696 fstrcpy(Printer->sharename, sname);
701 /****************************************************************************
702 Find first available printer slot. creates a printer handle for you.
703 ****************************************************************************/
705 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
706 const char *name, uint32_t access_granted)
708 struct printer_handle *new_printer;
710 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
712 new_printer = talloc_zero(p->mem_ctx, struct printer_handle);
713 if (new_printer == NULL) {
716 talloc_set_destructor(new_printer, printer_entry_destructor);
718 /* This also steals the printer_handle on the policy_handle */
719 if (!create_policy_hnd(p, hnd, new_printer)) {
720 TALLOC_FREE(new_printer);
724 /* Add to the internal list. */
725 DLIST_ADD(printers_list, new_printer);
727 new_printer->notify.option=NULL;
729 if (!set_printer_hnd_printertype(new_printer, name)) {
730 close_printer_handle(p, hnd);
734 if (!set_printer_hnd_name(p->mem_ctx,
735 get_server_info_system(),
737 new_printer, name)) {
738 close_printer_handle(p, hnd);
742 new_printer->access_granted = access_granted;
744 DEBUG(5, ("%d printer handles active\n",
745 (int)num_pipe_handles(p)));
750 /***************************************************************************
751 check to see if the client motify handle is monitoring the notification
752 given by (notify_type, notify_field).
753 **************************************************************************/
755 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
756 uint16_t notify_field)
761 static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type,
762 uint16_t notify_field)
764 struct spoolss_NotifyOption *option = p->notify.option;
768 * Flags should always be zero when the change notify
769 * is registered by the client's spooler. A user Win32 app
770 * might use the flags though instead of the NOTIFY_OPTION_INFO
779 return is_monitoring_event_flags(
780 p->notify.flags, notify_type, notify_field);
782 for (i = 0; i < option->count; i++) {
784 /* Check match for notify_type */
786 if (option->types[i].type != notify_type)
789 /* Check match for field */
791 for (j = 0; j < option->types[i].count; j++) {
792 if (option->types[i].fields[j].field == notify_field) {
798 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
799 p->servername, p->sharename, notify_type, notify_field));
804 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
805 _data->data.integer[0] = _integer; \
806 _data->data.integer[1] = 0;
809 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
810 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
811 if (!_data->data.string.string) {\
812 _data->data.string.size = 0; \
814 _data->data.string.size = strlen_m_term(_p) * 2;
816 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
817 _data->data.devmode.devmode = _devmode;
819 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
820 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
821 if (!_data->data.sd.sd) { \
822 _data->data.sd.sd_size = 0; \
824 _data->data.sd.sd_size = \
825 ndr_size_security_descriptor(_data->data.sd.sd, 0);
827 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
832 struct spoolss_Time st;
836 if (!init_systemtime(&st, t)) {
840 p = talloc_array(mem_ctx, char, len);
846 * Systemtime must be linearized as a set of UINT16's.
847 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
850 SSVAL(p, 0, st.year);
851 SSVAL(p, 2, st.month);
852 SSVAL(p, 4, st.day_of_week);
854 SSVAL(p, 8, st.hour);
855 SSVAL(p, 10, st.minute);
856 SSVAL(p, 12, st.second);
857 SSVAL(p, 14, st.millisecond);
863 /* Convert a notification message to a struct spoolss_Notify */
865 static void notify_one_value(struct spoolss_notify_msg *msg,
866 struct spoolss_Notify *data,
869 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
872 static void notify_string(struct spoolss_notify_msg *msg,
873 struct spoolss_Notify *data,
876 /* The length of the message includes the trailing \0 */
878 data->data.string.size = msg->len * 2;
879 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
880 if (!data->data.string.string) {
881 data->data.string.size = 0;
886 static void notify_system_time(struct spoolss_notify_msg *msg,
887 struct spoolss_Notify *data,
890 data->data.string.string = NULL;
891 data->data.string.size = 0;
893 if (msg->len != sizeof(time_t)) {
894 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
899 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
900 &data->data.string.string,
901 &data->data.string.size);
904 struct notify2_message_table {
906 void (*fn)(struct spoolss_notify_msg *msg,
907 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
910 static struct notify2_message_table printer_notify_table[] = {
911 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
912 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
913 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
914 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
915 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
916 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
917 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
918 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
919 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
920 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
921 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
922 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
923 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
924 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
925 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
926 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
927 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
928 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
929 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
932 static struct notify2_message_table job_notify_table[] = {
933 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
934 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
935 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
936 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
937 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
938 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
939 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
940 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
941 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
942 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
943 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
944 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
945 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
946 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
947 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
948 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
949 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
950 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
951 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
952 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
953 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
954 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
955 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
956 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
960 /***********************************************************************
961 Allocate talloc context for container object
962 **********************************************************************/
964 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
969 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
974 /***********************************************************************
975 release all allocated memory and zero out structure
976 **********************************************************************/
978 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
984 talloc_destroy(ctr->ctx);
991 /***********************************************************************
992 **********************************************************************/
994 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
1002 /***********************************************************************
1003 **********************************************************************/
1005 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1007 if ( !ctr || !ctr->msg_groups )
1010 if ( idx >= ctr->num_groups )
1013 return &ctr->msg_groups[idx];
1017 /***********************************************************************
1018 How many groups of change messages do we have ?
1019 **********************************************************************/
1021 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
1026 return ctr->num_groups;
1029 /***********************************************************************
1030 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
1031 **********************************************************************/
1033 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
1035 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
1036 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
1037 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
1043 /* loop over all groups looking for a matching printer name */
1045 for ( i=0; i<ctr->num_groups; i++ ) {
1046 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
1050 /* add a new group? */
1052 if ( i == ctr->num_groups ) {
1055 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
1056 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
1059 ctr->msg_groups = groups;
1061 /* clear the new entry and set the printer name */
1063 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
1064 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
1067 /* add the change messages; 'i' is the correct index now regardless */
1069 msg_grp = &ctr->msg_groups[i];
1071 msg_grp->num_msgs++;
1073 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
1074 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
1077 msg_grp->msgs = msg_list;
1079 new_slot = msg_grp->num_msgs-1;
1080 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
1082 /* need to allocate own copy of data */
1084 if ( msg->len != 0 )
1085 msg_grp->msgs[new_slot].notify.data = (char *)
1086 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
1088 return ctr->num_groups;
1091 static void construct_info_data(struct spoolss_Notify *info_data,
1092 enum spoolss_NotifyType type,
1093 uint16_t field, int id);
1095 /***********************************************************************
1096 Send a change notication message on all handles which have a call
1098 **********************************************************************/
1100 static int build_notify2_messages(TALLOC_CTX *mem_ctx,
1101 struct printer_handle *prn_hnd,
1102 SPOOLSS_NOTIFY_MSG *messages,
1104 struct spoolss_Notify **_notifies,
1107 struct spoolss_Notify *notifies;
1108 SPOOLSS_NOTIFY_MSG *msg;
1113 notifies = talloc_zero_array(mem_ctx,
1114 struct spoolss_Notify, num_msgs);
1119 for (i = 0; i < num_msgs; i++) {
1123 /* Are we monitoring this event? */
1125 if (!is_monitoring_event(prn_hnd, msg->type, msg->field)) {
1129 DEBUG(10, ("Sending message type [0x%x] field [0x%2x] "
1130 "for printer [%s]\n",
1131 msg->type, msg->field, prn_hnd->sharename));
1134 * if the is a printer notification handle and not a job
1135 * notification type, then set the id to 0.
1136 * Otherwise just use what was specified in the message.
1138 * When registering change notification on a print server
1139 * handle we always need to send back the id (snum) matching
1140 * the printer for which the change took place.
1141 * For change notify registered on a printer handle,
1142 * this does not matter and the id should be 0.
1147 if ((msg->type == PRINTER_NOTIFY_TYPE) &&
1148 (prn_hnd->printer_type == SPLHND_PRINTER)) {
1154 /* Convert unix jobid to smb jobid */
1156 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1157 id = sysjob_to_jobid(msg->id);
1160 DEBUG(3, ("no such unix jobid %d\n",
1166 construct_info_data(¬ifies[count],
1167 msg->type, msg->field, id);
1170 case PRINTER_NOTIFY_TYPE:
1171 if (printer_notify_table[msg->field].fn) {
1172 printer_notify_table[msg->field].fn(msg,
1173 ¬ifies[count], mem_ctx);
1177 case JOB_NOTIFY_TYPE:
1178 if (job_notify_table[msg->field].fn) {
1179 job_notify_table[msg->field].fn(msg,
1180 ¬ifies[count], mem_ctx);
1185 DEBUG(5, ("Unknown notification type %d\n",
1193 *_notifies = notifies;
1199 static int send_notify2_printer(TALLOC_CTX *mem_ctx,
1200 struct printer_handle *prn_hnd,
1201 SPOOLSS_NOTIFY_MSG_GROUP *msg_group)
1203 struct spoolss_Notify *notifies;
1205 union spoolss_ReplyPrinterInfo info;
1206 struct spoolss_NotifyInfo info0;
1207 uint32_t reply_result;
1212 /* Is there notification on this handle? */
1213 if (prn_hnd->notify.cli_chan == NULL ||
1214 prn_hnd->notify.cli_chan->active_connections == 0) {
1218 DEBUG(10, ("Client connected! [\\\\%s\\%s]\n",
1219 prn_hnd->servername, prn_hnd->sharename));
1221 /* For this printer? Print servers always receive notifications. */
1222 if ((prn_hnd->printer_type == SPLHND_PRINTER) &&
1223 (!strequal(msg_group->printername, prn_hnd->sharename))) {
1227 DEBUG(10,("Our printer\n"));
1229 /* build the array of change notifications */
1230 ret = build_notify2_messages(mem_ctx, prn_hnd,
1232 msg_group->num_msgs,
1238 info0.version = 0x2;
1239 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1240 info0.count = count;
1241 info0.notifies = notifies;
1243 info.info0 = &info0;
1245 status = rpccli_spoolss_RouterReplyPrinterEx(
1246 prn_hnd->notify.cli_chan->cli_pipe,
1248 &prn_hnd->notify.cli_hnd,
1249 prn_hnd->notify.change, /* color */
1250 prn_hnd->notify.flags,
1252 0, /* reply_type, must be 0 */
1254 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1255 DEBUG(1, ("RouterReplyPrinterEx to client: %s "
1257 prn_hnd->notify.cli_chan->cli_pipe->srv_name_slash,
1260 switch (reply_result) {
1263 case PRINTER_NOTIFY_INFO_DISCARDED:
1264 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1265 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1274 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1276 struct printer_handle *p;
1277 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
1278 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
1282 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1286 if (!msg_group->msgs) {
1287 DEBUG(5, ("send_notify2_changes() called with no messages!\n"));
1291 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1293 /* loop over all printers */
1295 for (p = printers_list; p; p = p->next) {
1296 ret = send_notify2_printer(mem_ctx, p, msg_group);
1303 DEBUG(8,("send_notify2_changes: Exit...\n"));
1307 /***********************************************************************
1308 **********************************************************************/
1310 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1313 uint32_t tv_sec, tv_usec;
1316 /* Unpack message */
1318 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1321 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1323 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1326 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1327 &msg->notify.value[0], &msg->notify.value[1]);
1329 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1330 &msg->len, &msg->notify.data);
1332 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1333 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1335 tv->tv_sec = tv_sec;
1336 tv->tv_usec = tv_usec;
1339 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1340 msg->notify.value[1]));
1342 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1347 /********************************************************************
1348 Receive a notify2 message list
1349 ********************************************************************/
1351 static void receive_notify2_message_list(struct messaging_context *msg,
1354 struct server_id server_id,
1357 size_t msg_count, i;
1358 char *buf = (char *)data->data;
1361 SPOOLSS_NOTIFY_MSG notify;
1362 SPOOLSS_NOTIFY_MSG_CTR messages;
1365 if (data->length < 4) {
1366 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1370 msg_count = IVAL(buf, 0);
1373 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1375 if (msg_count == 0) {
1376 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1380 /* initialize the container */
1382 ZERO_STRUCT( messages );
1383 notify_msg_ctr_init( &messages );
1386 * build message groups for each printer identified
1387 * in a change_notify msg. Remember that a PCN message
1388 * includes the handle returned for the srv_spoolss_replyopenprinter()
1389 * call. Therefore messages are grouped according to printer handle.
1392 for ( i=0; i<msg_count; i++ ) {
1393 struct timeval msg_tv;
1395 if (msg_ptr + 4 - buf > data->length) {
1396 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1400 msg_len = IVAL(msg_ptr,0);
1403 if (msg_ptr + msg_len - buf > data->length) {
1404 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1408 /* unpack messages */
1410 ZERO_STRUCT( notify );
1411 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1414 /* add to correct list in container */
1416 notify_msg_ctr_addmsg( &messages, ¬ify );
1418 /* free memory that might have been allocated by notify2_unpack_msg() */
1420 if ( notify.len != 0 )
1421 SAFE_FREE( notify.notify.data );
1424 /* process each group of messages */
1426 num_groups = notify_msg_ctr_numgroups( &messages );
1427 for ( i=0; i<num_groups; i++ )
1428 send_notify2_changes( &messages, i );
1433 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1434 (uint32_t)msg_count ));
1436 notify_msg_ctr_destroy( &messages );
1441 /********************************************************************
1442 Send a message to ourself about new driver being installed
1443 so we can upgrade the information for each printer bound to this
1445 ********************************************************************/
1447 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1448 struct messaging_context *msg_ctx)
1450 int len = strlen(drivername);
1455 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1458 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1459 MSG_PRINTER_DRVUPGRADE,
1460 (uint8_t *)drivername, len+1);
1465 /**********************************************************************
1466 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1467 over all printers, upgrading ones as necessary
1468 **********************************************************************/
1470 void do_drv_upgrade_printer(struct messaging_context *msg,
1473 struct server_id server_id,
1476 TALLOC_CTX *tmp_ctx;
1477 struct auth_serversupplied_info *server_info = NULL;
1478 struct spoolss_PrinterInfo2 *pinfo2;
1481 const char *drivername;
1483 int n_services = lp_numservices();
1486 tmp_ctx = talloc_new(NULL);
1487 if (!tmp_ctx) return;
1489 status = make_server_info_system(tmp_ctx, &server_info);
1490 if (!NT_STATUS_IS_OK(status)) {
1491 DEBUG(0, ("do_drv_upgrade_printer: "
1492 "Could not create system server_info\n"));
1496 len = MIN(data->length,sizeof(drivername)-1);
1497 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1499 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1503 DEBUG(10, ("do_drv_upgrade_printer: "
1504 "Got message for new driver [%s]\n", drivername));
1506 /* Iterate the printer list */
1508 for (snum = 0; snum < n_services; snum++) {
1509 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1513 result = winreg_get_printer(tmp_ctx, server_info, msg,
1515 lp_const_servicename(snum),
1518 if (!W_ERROR_IS_OK(result)) {
1522 if (!pinfo2->drivername) {
1526 if (strcmp(drivername, pinfo2->drivername) != 0) {
1530 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1532 /* all we care about currently is the change_id */
1533 result = winreg_printer_update_changeid(tmp_ctx,
1536 pinfo2->printername);
1538 if (!W_ERROR_IS_OK(result)) {
1539 DEBUG(3, ("do_drv_upgrade_printer: "
1540 "Failed to update changeid [%s]\n",
1541 win_errstr(result)));
1547 talloc_free(tmp_ctx);
1550 /********************************************************************
1551 Update the cache for all printq's with a registered client
1553 ********************************************************************/
1555 void update_monitored_printq_cache(struct messaging_context *msg_ctx)
1557 struct printer_handle *printer = printers_list;
1560 /* loop through all printers and update the cache where
1561 a client is connected */
1563 if ((printer->printer_type == SPLHND_PRINTER) &&
1564 ((printer->notify.cli_chan != NULL) &&
1565 (printer->notify.cli_chan->active_connections > 0))) {
1566 snum = print_queue_snum(printer->sharename);
1567 print_queue_status(msg_ctx, snum, NULL, NULL);
1570 printer = printer->next;
1576 /****************************************************************
1577 _spoolss_OpenPrinter
1578 ****************************************************************/
1580 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1581 struct spoolss_OpenPrinter *r)
1583 struct spoolss_OpenPrinterEx e;
1586 ZERO_STRUCT(e.in.userlevel);
1588 e.in.printername = r->in.printername;
1589 e.in.datatype = r->in.datatype;
1590 e.in.devmode_ctr = r->in.devmode_ctr;
1591 e.in.access_mask = r->in.access_mask;
1594 e.out.handle = r->out.handle;
1596 werr = _spoolss_OpenPrinterEx(p, &e);
1598 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1599 /* OpenPrinterEx returns this for a bad
1600 * printer name. We must return WERR_INVALID_PRINTER_NAME
1603 werr = WERR_INVALID_PRINTER_NAME;
1609 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1610 struct spoolss_DeviceMode *orig,
1611 struct spoolss_DeviceMode **dest)
1613 struct spoolss_DeviceMode *dm;
1615 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1620 /* copy all values, then duplicate strings and structs */
1623 dm->devicename = talloc_strdup(dm, orig->devicename);
1624 if (!dm->devicename) {
1627 dm->formname = talloc_strdup(dm, orig->formname);
1628 if (!dm->formname) {
1631 if (orig->driverextra_data.data) {
1632 dm->driverextra_data.data =
1633 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1634 orig->driverextra_data.length);
1635 if (!dm->driverextra_data.data) {
1644 /****************************************************************
1645 _spoolss_OpenPrinterEx
1646 ****************************************************************/
1648 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1649 struct spoolss_OpenPrinterEx *r)
1652 struct printer_handle *Printer=NULL;
1654 if (!r->in.printername) {
1655 return WERR_INVALID_PARAM;
1658 /* some sanity check because you can open a printer or a print server */
1659 /* aka: \\server\printer or \\server */
1661 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1663 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1664 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1665 "for printer %s\n", r->in.printername));
1666 ZERO_STRUCTP(r->out.handle);
1667 return WERR_INVALID_PARAM;
1670 Printer = find_printer_index_by_hnd(p, r->out.handle);
1672 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1673 "handle we created for printer %s\n", r->in.printername));
1674 close_printer_handle(p, r->out.handle);
1675 ZERO_STRUCTP(r->out.handle);
1676 return WERR_INVALID_PARAM;
1680 * First case: the user is opening the print server:
1682 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1683 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1685 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1686 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1687 * or if the user is listed in the smb.conf printer admin parameter.
1689 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1690 * client view printer folder, but does not show the MSAPW.
1692 * Note: this test needs code to check access rights here too. Jeremy
1693 * could you look at this?
1695 * Second case: the user is opening a printer:
1696 * NT doesn't let us connect to a printer if the connecting user
1697 * doesn't have print permission.
1699 * Third case: user is opening a Port Monitor
1700 * access checks same as opening a handle to the print server.
1703 switch (Printer->printer_type )
1706 case SPLHND_PORTMON_TCP:
1707 case SPLHND_PORTMON_LOCAL:
1708 /* Printserver handles use global struct... */
1712 /* Map standard access rights to object specific access rights */
1714 se_map_standard(&r->in.access_mask,
1715 &printserver_std_mapping);
1717 /* Deny any object specific bits that don't apply to print
1718 servers (i.e printer and job specific bits) */
1720 r->in.access_mask &= SEC_MASK_SPECIFIC;
1722 if (r->in.access_mask &
1723 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1724 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1725 close_printer_handle(p, r->out.handle);
1726 ZERO_STRUCTP(r->out.handle);
1727 return WERR_ACCESS_DENIED;
1730 /* Allow admin access */
1732 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1734 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1736 if (!lp_ms_add_printer_wizard()) {
1737 close_printer_handle(p, r->out.handle);
1738 ZERO_STRUCTP(r->out.handle);
1739 return WERR_ACCESS_DENIED;
1742 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1743 and not a printer admin, then fail */
1745 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1746 !user_has_privileges(p->server_info->ptok,
1748 !token_contains_name_in_list(
1749 uidtoname(p->server_info->utok.uid),
1750 p->server_info->info3->base.domain.string,
1752 p->server_info->ptok,
1753 lp_printer_admin(snum))) {
1754 close_printer_handle(p, r->out.handle);
1755 ZERO_STRUCTP(r->out.handle);
1756 return WERR_ACCESS_DENIED;
1759 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1763 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1766 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1767 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1769 /* We fall through to return WERR_OK */
1772 case SPLHND_PRINTER:
1773 /* NT doesn't let us connect to a printer if the connecting user
1774 doesn't have print permission. */
1776 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1777 close_printer_handle(p, r->out.handle);
1778 ZERO_STRUCTP(r->out.handle);
1782 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1783 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1786 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1788 /* map an empty access mask to the minimum access mask */
1789 if (r->in.access_mask == 0x0)
1790 r->in.access_mask = PRINTER_ACCESS_USE;
1793 * If we are not serving the printer driver for this printer,
1794 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1795 * will keep NT clients happy --jerry
1798 if (lp_use_client_driver(snum)
1799 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1801 r->in.access_mask = PRINTER_ACCESS_USE;
1804 /* check smb.conf parameters and the the sec_desc */
1806 if (!allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
1807 p->client_id->name, p->client_id->addr)) {
1808 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1809 ZERO_STRUCTP(r->out.handle);
1810 return WERR_ACCESS_DENIED;
1813 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1814 p->server_info->ptok, snum) ||
1815 !print_access_check(get_server_info_system(),
1818 r->in.access_mask)) {
1819 DEBUG(3, ("access DENIED for printer open\n"));
1820 close_printer_handle(p, r->out.handle);
1821 ZERO_STRUCTP(r->out.handle);
1822 return WERR_ACCESS_DENIED;
1825 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1826 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1827 close_printer_handle(p, r->out.handle);
1828 ZERO_STRUCTP(r->out.handle);
1829 return WERR_ACCESS_DENIED;
1832 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1833 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1835 r->in.access_mask = PRINTER_ACCESS_USE;
1837 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1838 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1840 winreg_create_printer(p->mem_ctx,
1841 get_server_info_system(),
1843 Printer->servername,
1844 lp_const_servicename(snum));
1849 /* sanity check to prevent programmer error */
1850 ZERO_STRUCTP(r->out.handle);
1854 Printer->access_granted = r->in.access_mask;
1857 * If the client sent a devmode in the OpenPrinter() call, then
1858 * save it here in case we get a job submission on this handle
1861 if ((Printer->printer_type != SPLHND_SERVER) &&
1862 r->in.devmode_ctr.devmode) {
1863 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1867 #if 0 /* JERRY -- I'm doubtful this is really effective */
1868 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1869 optimization in Windows 2000 clients --jerry */
1871 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1872 && (RA_WIN2K == get_remote_arch()) )
1874 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1875 sys_usleep( 500000 );
1882 /****************************************************************
1883 _spoolss_ClosePrinter
1884 ****************************************************************/
1886 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1887 struct spoolss_ClosePrinter *r)
1889 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1891 if (Printer && Printer->document_started) {
1892 struct spoolss_EndDocPrinter e;
1894 e.in.handle = r->in.handle;
1896 _spoolss_EndDocPrinter(p, &e);
1899 if (!close_printer_handle(p, r->in.handle))
1902 /* clear the returned printer handle. Observed behavior
1903 from Win2k server. Don't think this really matters.
1904 Previous code just copied the value of the closed
1907 ZERO_STRUCTP(r->out.handle);
1912 /****************************************************************
1913 _spoolss_DeletePrinter
1914 ****************************************************************/
1916 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1917 struct spoolss_DeletePrinter *r)
1919 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1923 if (Printer && Printer->document_started) {
1924 struct spoolss_EndDocPrinter e;
1926 e.in.handle = r->in.handle;
1928 _spoolss_EndDocPrinter(p, &e);
1931 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1932 winreg_delete_printer_key(p->mem_ctx,
1933 get_server_info_system(),
1935 lp_const_servicename(snum),
1939 result = delete_printer_handle(p, r->in.handle);
1944 /*******************************************************************
1945 * static function to lookup the version id corresponding to an
1946 * long architecture string
1947 ******************************************************************/
1949 static const struct print_architecture_table_node archi_table[]= {
1951 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1952 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1953 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1954 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1955 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1956 {"Windows IA64", SPL_ARCH_IA64, 3 },
1957 {"Windows x64", SPL_ARCH_X64, 3 },
1961 static int get_version_id(const char *arch)
1965 for (i=0; archi_table[i].long_archi != NULL; i++)
1967 if (strcmp(arch, archi_table[i].long_archi) == 0)
1968 return (archi_table[i].version);
1974 /****************************************************************
1975 _spoolss_DeletePrinterDriver
1976 ****************************************************************/
1978 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1979 struct spoolss_DeletePrinterDriver *r)
1982 struct spoolss_DriverInfo8 *info = NULL;
1983 struct spoolss_DriverInfo8 *info_win2k = NULL;
1986 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1988 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1989 and not a printer admin, then fail */
1991 if ( (p->server_info->utok.uid != sec_initial_uid())
1992 && !user_has_privileges(p->server_info->ptok, &se_printop )
1993 && !token_contains_name_in_list(
1994 uidtoname(p->server_info->utok.uid),
1995 p->server_info->info3->base.domain.string,
1997 p->server_info->ptok,
1998 lp_printer_admin(-1)) )
2000 return WERR_ACCESS_DENIED;
2003 /* check that we have a valid driver name first */
2005 if ((version = get_version_id(r->in.architecture)) == -1)
2006 return WERR_INVALID_ENVIRONMENT;
2008 status = winreg_get_driver(p->mem_ctx,
2009 get_server_info_system(),
2011 r->in.architecture, r->in.driver,
2013 if (!W_ERROR_IS_OK(status)) {
2014 /* try for Win2k driver if "Windows NT x86" */
2016 if ( version == 2 ) {
2019 status = winreg_get_driver(p->mem_ctx,
2020 get_server_info_system(),
2025 if (!W_ERROR_IS_OK(status)) {
2026 status = WERR_UNKNOWN_PRINTER_DRIVER;
2030 /* otherwise it was a failure */
2032 status = WERR_UNKNOWN_PRINTER_DRIVER;
2038 if (printer_driver_in_use(p->mem_ctx,
2039 get_server_info_system(),
2042 status = WERR_PRINTER_DRIVER_IN_USE;
2047 status = winreg_get_driver(p->mem_ctx,
2048 get_server_info_system(),
2051 r->in.driver, 3, &info_win2k);
2052 if (W_ERROR_IS_OK(status)) {
2053 /* if we get to here, we now have 2 driver info structures to remove */
2054 /* remove the Win2k driver first*/
2056 status = winreg_del_driver(p->mem_ctx,
2057 get_server_info_system(),
2060 talloc_free(info_win2k);
2062 /* this should not have failed---if it did, report to client */
2063 if (!W_ERROR_IS_OK(status)) {
2069 status = winreg_del_driver(p->mem_ctx,
2070 get_server_info_system(),
2080 /****************************************************************
2081 _spoolss_DeletePrinterDriverEx
2082 ****************************************************************/
2084 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
2085 struct spoolss_DeletePrinterDriverEx *r)
2087 struct spoolss_DriverInfo8 *info = NULL;
2088 struct spoolss_DriverInfo8 *info_win2k = NULL;
2092 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2094 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2095 and not a printer admin, then fail */
2097 if ( (p->server_info->utok.uid != sec_initial_uid())
2098 && !user_has_privileges(p->server_info->ptok, &se_printop )
2099 && !token_contains_name_in_list(
2100 uidtoname(p->server_info->utok.uid),
2101 p->server_info->info3->base.domain.string,
2103 p->server_info->ptok, lp_printer_admin(-1)) )
2105 return WERR_ACCESS_DENIED;
2108 /* check that we have a valid driver name first */
2109 if ((version = get_version_id(r->in.architecture)) == -1) {
2110 /* this is what NT returns */
2111 return WERR_INVALID_ENVIRONMENT;
2114 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2115 version = r->in.version;
2117 status = winreg_get_driver(p->mem_ctx,
2118 get_server_info_system(),
2124 if (!W_ERROR_IS_OK(status)) {
2125 status = WERR_UNKNOWN_PRINTER_DRIVER;
2128 * if the client asked for a specific version,
2129 * or this is something other than Windows NT x86,
2133 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2136 /* try for Win2k driver if "Windows NT x86" */
2139 status = winreg_get_driver(info,
2140 get_server_info_system(),
2145 if (!W_ERROR_IS_OK(status)) {
2146 status = WERR_UNKNOWN_PRINTER_DRIVER;
2151 if (printer_driver_in_use(info,
2152 get_server_info_system(),
2155 status = WERR_PRINTER_DRIVER_IN_USE;
2160 * we have a couple of cases to consider.
2161 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2162 * then the delete should fail if **any** files overlap with
2164 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2165 * non-overlapping files
2166 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2167 * is set, the do not delete any files
2168 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2171 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2173 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2176 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2177 printer_driver_files_in_use(info,
2178 get_server_info_system(),
2181 /* no idea of the correct error here */
2182 status = WERR_ACCESS_DENIED;
2187 /* also check for W32X86/3 if necessary; maybe we already have? */
2189 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2190 status = winreg_get_driver(info,
2191 get_server_info_system(),
2194 r->in.driver, 3, &info_win2k);
2195 if (W_ERROR_IS_OK(status)) {
2198 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2199 printer_driver_files_in_use(info,
2200 get_server_info_system(),
2203 /* no idea of the correct error here */
2204 talloc_free(info_win2k);
2205 status = WERR_ACCESS_DENIED;
2209 /* if we get to here, we now have 2 driver info structures to remove */
2210 /* remove the Win2k driver first*/
2212 status = winreg_del_driver(info,
2213 get_server_info_system(),
2218 /* this should not have failed---if it did, report to client */
2220 if (!W_ERROR_IS_OK(status)) {
2225 * now delete any associated files if delete_files is
2226 * true. Even if this part failes, we return succes
2227 * because the driver doesn not exist any more
2230 delete_driver_files(get_server_info_system(),
2236 status = winreg_del_driver(info,
2237 get_server_info_system(),
2241 if (!W_ERROR_IS_OK(status)) {
2246 * now delete any associated files if delete_files is
2247 * true. Even if this part failes, we return succes
2248 * because the driver doesn not exist any more
2251 delete_driver_files(get_server_info_system(), info);
2260 /********************************************************************
2261 GetPrinterData on a printer server Handle.
2262 ********************************************************************/
2264 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2266 enum winreg_Type *type,
2267 union spoolss_PrinterData *data)
2269 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2271 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2277 if (!StrCaseCmp(value, "BeepEnabled")) {
2283 if (!StrCaseCmp(value, "EventLog")) {
2285 /* formally was 0x1b */
2290 if (!StrCaseCmp(value, "NetPopup")) {
2296 if (!StrCaseCmp(value, "MajorVersion")) {
2299 /* Windows NT 4.0 seems to not allow uploading of drivers
2300 to a server that reports 0x3 as the MajorVersion.
2301 need to investigate more how Win2k gets around this .
2304 if (RA_WINNT == get_remote_arch()) {
2313 if (!StrCaseCmp(value, "MinorVersion")) {
2320 * uint32_t size = 0x114
2321 * uint32_t major = 5
2322 * uint32_t minor = [0|1]
2323 * uint32_t build = [2195|2600]
2324 * extra unicode string = e.g. "Service Pack 3"
2326 if (!StrCaseCmp(value, "OSVersion")) {
2328 enum ndr_err_code ndr_err;
2329 struct spoolss_OSVersion os;
2331 os.major = 5; /* Windows 2000 == 5.0 */
2333 os.build = 2195; /* build */
2334 os.extra_string = ""; /* leave extra string empty */
2336 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2337 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2338 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2339 return WERR_GENERAL_FAILURE;
2343 data->binary = blob;
2349 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2352 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2353 W_ERROR_HAVE_NO_MEMORY(data->string);
2358 if (!StrCaseCmp(value, "Architecture")) {
2360 data->string = talloc_strdup(mem_ctx,
2361 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2362 W_ERROR_HAVE_NO_MEMORY(data->string);
2367 if (!StrCaseCmp(value, "DsPresent")) {
2370 /* only show the publish check box if we are a
2371 member of a AD domain */
2373 if (lp_security() == SEC_ADS) {
2381 if (!StrCaseCmp(value, "DNSMachineName")) {
2382 const char *hostname = get_mydnsfullname();
2385 return WERR_BADFILE;
2389 data->string = talloc_strdup(mem_ctx, hostname);
2390 W_ERROR_HAVE_NO_MEMORY(data->string);
2397 return WERR_INVALID_PARAM;
2400 /****************************************************************
2401 _spoolss_GetPrinterData
2402 ****************************************************************/
2404 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2405 struct spoolss_GetPrinterData *r)
2407 struct spoolss_GetPrinterDataEx r2;
2409 r2.in.handle = r->in.handle;
2410 r2.in.key_name = "PrinterDriverData";
2411 r2.in.value_name = r->in.value_name;
2412 r2.in.offered = r->in.offered;
2413 r2.out.type = r->out.type;
2414 r2.out.data = r->out.data;
2415 r2.out.needed = r->out.needed;
2417 return _spoolss_GetPrinterDataEx(p, &r2);
2420 /*********************************************************
2421 Connect to the client machine.
2422 **********************************************************/
2424 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2425 struct sockaddr_storage *client_ss, const char *remote_machine)
2428 struct cli_state *the_cli;
2429 struct sockaddr_storage rm_addr;
2430 char addr[INET6_ADDRSTRLEN];
2432 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2433 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2435 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2436 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2439 print_sockaddr(addr, sizeof(addr), &rm_addr);
2441 rm_addr = *client_ss;
2442 print_sockaddr(addr, sizeof(addr), &rm_addr);
2443 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2447 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2448 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2453 /* setup the connection */
2454 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2455 &rm_addr, 0, "IPC$", "IPC",
2459 0, lp_client_signing(), NULL );
2461 if ( !NT_STATUS_IS_OK( ret ) ) {
2462 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2467 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2468 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2469 cli_shutdown(the_cli);
2474 * Ok - we have an anonymous connection to the IPC$ share.
2475 * Now start the NT Domain stuff :-).
2478 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2479 if (!NT_STATUS_IS_OK(ret)) {
2480 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2481 remote_machine, nt_errstr(ret)));
2482 cli_shutdown(the_cli);
2489 /***************************************************************************
2490 Connect to the client.
2491 ****************************************************************************/
2493 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2494 uint32_t localprinter,
2495 enum winreg_Type type,
2496 struct policy_handle *handle,
2497 struct notify_back_channel **_chan,
2498 struct sockaddr_storage *client_ss,
2499 struct messaging_context *msg_ctx)
2503 struct notify_back_channel *chan;
2505 for (chan = back_channels; chan; chan = chan->next) {
2506 if (memcmp(&chan->client_address, client_ss,
2507 sizeof(struct sockaddr_storage)) == 0) {
2513 * If it's the first connection, contact the client
2514 * and connect to the IPC$ share anonymously
2517 fstring unix_printer;
2519 /* the +2 is to strip the leading 2 backslashs */
2520 fstrcpy(unix_printer, printer + 2);
2522 chan = talloc_zero(back_channels, struct notify_back_channel);
2526 chan->client_address = *client_ss;
2528 if (!spoolss_connect_to_client(&chan->cli_pipe, client_ss, unix_printer)) {
2533 DLIST_ADD(back_channels, chan);
2535 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2536 receive_notify2_message_list);
2537 /* Tell the connections db we're now interested in printer
2538 * notify messages. */
2539 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2540 true, FLAG_MSG_PRINT_NOTIFY);
2544 * Tell the specific printing tdb we want messages for this printer
2545 * by registering our PID.
2548 if (!print_notify_register_pid(snum)) {
2549 DEBUG(0, ("Failed to register our pid for printer %s\n",
2553 status = rpccli_spoolss_ReplyOpenPrinter(chan->cli_pipe, talloc_tos(),
2561 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
2562 DEBUG(5, ("Client RPC returned [%s]\n", win_errstr(result)));
2565 chan->active_connections++;
2568 return (W_ERROR_IS_OK(result));
2571 /****************************************************************
2572 ****************************************************************/
2574 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2575 const struct spoolss_NotifyOption *r)
2577 struct spoolss_NotifyOption *option;
2584 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2591 if (!option->count) {
2595 option->types = talloc_zero_array(option,
2596 struct spoolss_NotifyOptionType, option->count);
2597 if (!option->types) {
2598 talloc_free(option);
2602 for (i=0; i < option->count; i++) {
2603 option->types[i] = r->types[i];
2605 if (option->types[i].count) {
2606 option->types[i].fields = talloc_zero_array(option,
2607 union spoolss_Field, option->types[i].count);
2608 if (!option->types[i].fields) {
2609 talloc_free(option);
2612 for (k=0; k<option->types[i].count; k++) {
2613 option->types[i].fields[k] =
2614 r->types[i].fields[k];
2622 /****************************************************************
2623 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2625 * before replying OK: status=0 a rpc call is made to the workstation
2626 * asking ReplyOpenPrinter
2628 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2629 * called from api_spoolss_rffpcnex
2630 ****************************************************************/
2632 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2633 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2636 struct spoolss_NotifyOption *option = r->in.notify_options;
2637 struct sockaddr_storage client_ss;
2639 /* store the notify value in the printer struct */
2641 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
2644 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2645 "Invalid handle (%s:%u:%u).\n",
2646 OUR_HANDLE(r->in.handle)));
2650 Printer->notify.flags = r->in.flags;
2651 Printer->notify.options = r->in.options;
2652 Printer->notify.printerlocal = r->in.printer_local;
2653 Printer->notify.msg_ctx = p->msg_ctx;
2655 TALLOC_FREE(Printer->notify.option);
2656 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2658 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2660 /* Connect to the client machine and send a ReplyOpenPrinter */
2662 if ( Printer->printer_type == SPLHND_SERVER)
2664 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2665 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2668 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2669 "client_address is %s\n", p->client_id->addr));
2671 if (!interpret_string_addr(&client_ss, p->client_id->addr,
2673 return WERR_SERVER_UNAVAILABLE;
2676 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2677 Printer->notify.printerlocal, REG_SZ,
2678 &Printer->notify.cli_hnd,
2679 &Printer->notify.cli_chan,
2680 &client_ss, p->msg_ctx)) {
2681 return WERR_SERVER_UNAVAILABLE;
2687 /*******************************************************************
2688 * fill a notify_info_data with the servername
2689 ********************************************************************/
2691 static void spoolss_notify_server_name(struct messaging_context *msg_ctx,
2693 struct spoolss_Notify *data,
2694 print_queue_struct *queue,
2695 struct spoolss_PrinterInfo2 *pinfo2,
2696 TALLOC_CTX *mem_ctx)
2698 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2701 /*******************************************************************
2702 * fill a notify_info_data with the printername (not including the servername).
2703 ********************************************************************/
2705 static void spoolss_notify_printer_name(struct messaging_context *msg_ctx,
2707 struct spoolss_Notify *data,
2708 print_queue_struct *queue,
2709 struct spoolss_PrinterInfo2 *pinfo2,
2710 TALLOC_CTX *mem_ctx)
2712 /* the notify name should not contain the \\server\ part */
2713 const char *p = strrchr(pinfo2->printername, '\\');
2716 p = pinfo2->printername;
2721 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2724 /*******************************************************************
2725 * fill a notify_info_data with the servicename
2726 ********************************************************************/
2728 static void spoolss_notify_share_name(struct messaging_context *msg_ctx,
2730 struct spoolss_Notify *data,
2731 print_queue_struct *queue,
2732 struct spoolss_PrinterInfo2 *pinfo2,
2733 TALLOC_CTX *mem_ctx)
2735 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2738 /*******************************************************************
2739 * fill a notify_info_data with the port name
2740 ********************************************************************/
2742 static void spoolss_notify_port_name(struct messaging_context *msg_ctx,
2744 struct spoolss_Notify *data,
2745 print_queue_struct *queue,
2746 struct spoolss_PrinterInfo2 *pinfo2,
2747 TALLOC_CTX *mem_ctx)
2749 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2752 /*******************************************************************
2753 * fill a notify_info_data with the printername
2754 * but it doesn't exist, have to see what to do
2755 ********************************************************************/
2757 static void spoolss_notify_driver_name(struct messaging_context *msg_ctx,
2759 struct spoolss_Notify *data,
2760 print_queue_struct *queue,
2761 struct spoolss_PrinterInfo2 *pinfo2,
2762 TALLOC_CTX *mem_ctx)
2764 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2767 /*******************************************************************
2768 * fill a notify_info_data with the comment
2769 ********************************************************************/
2771 static void spoolss_notify_comment(struct messaging_context *msg_ctx,
2773 struct spoolss_Notify *data,
2774 print_queue_struct *queue,
2775 struct spoolss_PrinterInfo2 *pinfo2,
2776 TALLOC_CTX *mem_ctx)
2780 if (*pinfo2->comment == '\0') {
2781 p = lp_comment(snum);
2783 p = pinfo2->comment;
2786 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2789 /*******************************************************************
2790 * fill a notify_info_data with the comment
2791 * location = "Room 1, floor 2, building 3"
2792 ********************************************************************/
2794 static void spoolss_notify_location(struct messaging_context *msg_ctx,
2796 struct spoolss_Notify *data,
2797 print_queue_struct *queue,
2798 struct spoolss_PrinterInfo2 *pinfo2,
2799 TALLOC_CTX *mem_ctx)
2801 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2804 /*******************************************************************
2805 * fill a notify_info_data with the device mode
2806 * jfm:xxxx don't to it for know but that's a real problem !!!
2807 ********************************************************************/
2809 static void spoolss_notify_devmode(struct messaging_context *msg_ctx,
2811 struct spoolss_Notify *data,
2812 print_queue_struct *queue,
2813 struct spoolss_PrinterInfo2 *pinfo2,
2814 TALLOC_CTX *mem_ctx)
2816 /* for a dummy implementation we have to zero the fields */
2817 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2820 /*******************************************************************
2821 * fill a notify_info_data with the separator file name
2822 ********************************************************************/
2824 static void spoolss_notify_sepfile(struct messaging_context *msg_ctx,
2826 struct spoolss_Notify *data,
2827 print_queue_struct *queue,
2828 struct spoolss_PrinterInfo2 *pinfo2,
2829 TALLOC_CTX *mem_ctx)
2831 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2834 /*******************************************************************
2835 * fill a notify_info_data with the print processor
2836 * jfm:xxxx return always winprint to indicate we don't do anything to it
2837 ********************************************************************/
2839 static void spoolss_notify_print_processor(struct messaging_context *msg_ctx,
2841 struct spoolss_Notify *data,
2842 print_queue_struct *queue,
2843 struct spoolss_PrinterInfo2 *pinfo2,
2844 TALLOC_CTX *mem_ctx)
2846 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2849 /*******************************************************************
2850 * fill a notify_info_data with the print processor options
2851 * jfm:xxxx send an empty string
2852 ********************************************************************/
2854 static void spoolss_notify_parameters(struct messaging_context *msg_ctx,
2856 struct spoolss_Notify *data,
2857 print_queue_struct *queue,
2858 struct spoolss_PrinterInfo2 *pinfo2,
2859 TALLOC_CTX *mem_ctx)
2861 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2864 /*******************************************************************
2865 * fill a notify_info_data with the data type
2866 * jfm:xxxx always send RAW as data type
2867 ********************************************************************/
2869 static void spoolss_notify_datatype(struct messaging_context *msg_ctx,
2871 struct spoolss_Notify *data,
2872 print_queue_struct *queue,
2873 struct spoolss_PrinterInfo2 *pinfo2,
2874 TALLOC_CTX *mem_ctx)
2876 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2879 /*******************************************************************
2880 * fill a notify_info_data with the security descriptor
2881 * jfm:xxxx send an null pointer to say no security desc
2882 * have to implement security before !
2883 ********************************************************************/
2885 static void spoolss_notify_security_desc(struct messaging_context *msg_ctx,
2887 struct spoolss_Notify *data,
2888 print_queue_struct *queue,
2889 struct spoolss_PrinterInfo2 *pinfo2,
2890 TALLOC_CTX *mem_ctx)
2892 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2895 /*******************************************************************
2896 * fill a notify_info_data with the attributes
2897 * jfm:xxxx a samba printer is always shared
2898 ********************************************************************/
2900 static void spoolss_notify_attributes(struct messaging_context *msg_ctx,
2902 struct spoolss_Notify *data,
2903 print_queue_struct *queue,
2904 struct spoolss_PrinterInfo2 *pinfo2,
2905 TALLOC_CTX *mem_ctx)
2907 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2910 /*******************************************************************
2911 * fill a notify_info_data with the priority
2912 ********************************************************************/
2914 static void spoolss_notify_priority(struct messaging_context *msg_ctx,
2916 struct spoolss_Notify *data,
2917 print_queue_struct *queue,
2918 struct spoolss_PrinterInfo2 *pinfo2,
2919 TALLOC_CTX *mem_ctx)
2921 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2924 /*******************************************************************
2925 * fill a notify_info_data with the default priority
2926 ********************************************************************/
2928 static void spoolss_notify_default_priority(struct messaging_context *msg_ctx,
2930 struct spoolss_Notify *data,
2931 print_queue_struct *queue,
2932 struct spoolss_PrinterInfo2 *pinfo2,
2933 TALLOC_CTX *mem_ctx)
2935 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2938 /*******************************************************************
2939 * fill a notify_info_data with the start time
2940 ********************************************************************/
2942 static void spoolss_notify_start_time(struct messaging_context *msg_ctx,
2944 struct spoolss_Notify *data,
2945 print_queue_struct *queue,
2946 struct spoolss_PrinterInfo2 *pinfo2,
2947 TALLOC_CTX *mem_ctx)
2949 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2952 /*******************************************************************
2953 * fill a notify_info_data with the until time
2954 ********************************************************************/
2956 static void spoolss_notify_until_time(struct messaging_context *msg_ctx,
2958 struct spoolss_Notify *data,
2959 print_queue_struct *queue,
2960 struct spoolss_PrinterInfo2 *pinfo2,
2961 TALLOC_CTX *mem_ctx)
2963 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2966 /*******************************************************************
2967 * fill a notify_info_data with the status
2968 ********************************************************************/
2970 static void spoolss_notify_status(struct messaging_context *msg_ctx,
2972 struct spoolss_Notify *data,
2973 print_queue_struct *queue,
2974 struct spoolss_PrinterInfo2 *pinfo2,
2975 TALLOC_CTX *mem_ctx)
2977 print_status_struct status;
2979 print_queue_length(msg_ctx, snum, &status);
2980 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2983 /*******************************************************************
2984 * fill a notify_info_data with the number of jobs queued
2985 ********************************************************************/
2987 static void spoolss_notify_cjobs(struct messaging_context *msg_ctx,
2989 struct spoolss_Notify *data,
2990 print_queue_struct *queue,
2991 struct spoolss_PrinterInfo2 *pinfo2,
2992 TALLOC_CTX *mem_ctx)
2994 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(
2995 data, print_queue_length(msg_ctx, snum, NULL));
2998 /*******************************************************************
2999 * fill a notify_info_data with the average ppm
3000 ********************************************************************/
3002 static void spoolss_notify_average_ppm(struct messaging_context *msg_ctx,
3004 struct spoolss_Notify *data,
3005 print_queue_struct *queue,
3006 struct spoolss_PrinterInfo2 *pinfo2,
3007 TALLOC_CTX *mem_ctx)
3009 /* always respond 8 pages per minutes */
3010 /* a little hard ! */
3011 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
3014 /*******************************************************************
3015 * fill a notify_info_data with username
3016 ********************************************************************/
3018 static void spoolss_notify_username(struct messaging_context *msg_ctx,
3020 struct spoolss_Notify *data,
3021 print_queue_struct *queue,
3022 struct spoolss_PrinterInfo2 *pinfo2,
3023 TALLOC_CTX *mem_ctx)
3025 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
3028 /*******************************************************************
3029 * fill a notify_info_data with job status
3030 ********************************************************************/
3032 static void spoolss_notify_job_status(struct messaging_context *msg_ctx,
3034 struct spoolss_Notify *data,
3035 print_queue_struct *queue,
3036 struct spoolss_PrinterInfo2 *pinfo2,
3037 TALLOC_CTX *mem_ctx)
3039 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
3042 /*******************************************************************
3043 * fill a notify_info_data with job name
3044 ********************************************************************/
3046 static void spoolss_notify_job_name(struct messaging_context *msg_ctx,
3048 struct spoolss_Notify *data,
3049 print_queue_struct *queue,
3050 struct spoolss_PrinterInfo2 *pinfo2,
3051 TALLOC_CTX *mem_ctx)
3053 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
3056 /*******************************************************************
3057 * fill a notify_info_data with job status
3058 ********************************************************************/
3060 static void spoolss_notify_job_status_string(struct messaging_context *msg_ctx,
3062 struct spoolss_Notify *data,
3063 print_queue_struct *queue,
3064 struct spoolss_PrinterInfo2 *pinfo2,
3065 TALLOC_CTX *mem_ctx)
3068 * Now we're returning job status codes we just return a "" here. JRA.
3073 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3076 switch (queue->status) {
3081 p = ""; /* NT provides the paused string */
3090 #endif /* NO LONGER NEEDED. */
3092 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3095 /*******************************************************************
3096 * fill a notify_info_data with job time
3097 ********************************************************************/
3099 static void spoolss_notify_job_time(struct messaging_context *msg_ctx,
3101 struct spoolss_Notify *data,
3102 print_queue_struct *queue,
3103 struct spoolss_PrinterInfo2 *pinfo2,
3104 TALLOC_CTX *mem_ctx)
3106 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3109 /*******************************************************************
3110 * fill a notify_info_data with job size
3111 ********************************************************************/
3113 static void spoolss_notify_job_size(struct messaging_context *msg_ctx,
3115 struct spoolss_Notify *data,
3116 print_queue_struct *queue,
3117 struct spoolss_PrinterInfo2 *pinfo2,
3118 TALLOC_CTX *mem_ctx)
3120 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3123 /*******************************************************************
3124 * fill a notify_info_data with page info
3125 ********************************************************************/
3126 static void spoolss_notify_total_pages(struct messaging_context *msg_ctx,
3128 struct spoolss_Notify *data,
3129 print_queue_struct *queue,
3130 struct spoolss_PrinterInfo2 *pinfo2,
3131 TALLOC_CTX *mem_ctx)
3133 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3136 /*******************************************************************
3137 * fill a notify_info_data with pages printed info.
3138 ********************************************************************/
3139 static void spoolss_notify_pages_printed(struct messaging_context *msg_ctx,
3141 struct spoolss_Notify *data,
3142 print_queue_struct *queue,
3143 struct spoolss_PrinterInfo2 *pinfo2,
3144 TALLOC_CTX *mem_ctx)
3146 /* Add code when back-end tracks this */
3147 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3150 /*******************************************************************
3151 Fill a notify_info_data with job position.
3152 ********************************************************************/
3154 static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
3156 struct spoolss_Notify *data,
3157 print_queue_struct *queue,
3158 struct spoolss_PrinterInfo2 *pinfo2,
3159 TALLOC_CTX *mem_ctx)
3161 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3164 /*******************************************************************
3165 Fill a notify_info_data with submitted time.
3166 ********************************************************************/
3168 static void spoolss_notify_submitted_time(struct messaging_context *msg_ctx,
3170 struct spoolss_Notify *data,
3171 print_queue_struct *queue,
3172 struct spoolss_PrinterInfo2 *pinfo2,
3173 TALLOC_CTX *mem_ctx)
3175 data->data.string.string = NULL;
3176 data->data.string.size = 0;
3178 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3179 &data->data.string.string,
3180 &data->data.string.size);
3184 struct s_notify_info_data_table
3186 enum spoolss_NotifyType type;
3189 enum spoolss_NotifyTable variable_type;
3190 void (*fn) (struct messaging_context *msg_ctx,
3191 int snum, struct spoolss_Notify *data,
3192 print_queue_struct *queue,
3193 struct spoolss_PrinterInfo2 *pinfo2,
3194 TALLOC_CTX *mem_ctx);
3197 /* A table describing the various print notification constants and
3198 whether the notification data is a pointer to a variable sized
3199 buffer, a one value uint32_t or a two value uint32_t. */
3201 static const struct s_notify_info_data_table notify_info_data_table[] =
3203 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3204 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3205 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3206 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3207 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3208 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3209 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3210 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3211 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3212 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3213 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3214 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3215 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3216 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3217 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3218 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3219 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3220 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3221 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3222 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3223 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3224 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3225 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3226 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3227 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3228 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3229 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3230 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3231 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3232 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3233 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3234 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3235 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3236 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3237 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3238 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3239 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3240 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3241 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3242 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3243 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3244 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3245 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3246 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3247 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3248 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3249 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3250 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3251 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3254 /*******************************************************************
3255 Return the variable_type of info_data structure.
3256 ********************************************************************/
3258 static enum spoolss_NotifyTable variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3263 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3264 if ( (notify_info_data_table[i].type == type) &&
3265 (notify_info_data_table[i].field == field) ) {
3266 return notify_info_data_table[i].variable_type;
3270 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3272 return (enum spoolss_NotifyTable) 0;
3275 /****************************************************************************
3276 ****************************************************************************/
3278 static bool search_notify(enum spoolss_NotifyType type,
3284 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3285 if (notify_info_data_table[i].type == type &&
3286 notify_info_data_table[i].field == field &&
3287 notify_info_data_table[i].fn != NULL) {
3296 /****************************************************************************
3297 ****************************************************************************/
3299 static void construct_info_data(struct spoolss_Notify *info_data,
3300 enum spoolss_NotifyType type,
3301 uint16_t field, int id)
3303 info_data->type = type;
3304 info_data->field.field = field;
3305 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3306 info_data->job_id = id;
3309 /*******************************************************************
3311 * fill a notify_info struct with info asked
3313 ********************************************************************/
3315 static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
3316 struct printer_handle *print_hnd,
3317 struct spoolss_NotifyInfo *info,
3318 struct spoolss_PrinterInfo2 *pinfo2,
3320 const struct spoolss_NotifyOptionType *option_type,
3322 TALLOC_CTX *mem_ctx)
3325 enum spoolss_NotifyType type;
3328 struct spoolss_Notify *current_data;
3329 print_queue_struct *queue=NULL;
3331 type = option_type->type;
3333 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3334 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3335 option_type->count, lp_servicename(snum)));
3337 for(field_num=0; field_num < option_type->count; field_num++) {
3338 field = option_type->fields[field_num].field;
3340 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3342 if (!search_notify(type, field, &j) )
3345 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3346 struct spoolss_Notify,
3348 if (info->notifies == NULL) {
3349 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3353 current_data = &info->notifies[info->count];
3355 construct_info_data(current_data, type, field, id);
3357 DEBUG(10, ("construct_notify_printer_info: "
3358 "calling [%s] snum=%d printername=[%s])\n",
3359 notify_info_data_table[j].name, snum,
3360 pinfo2->printername));
3362 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3363 queue, pinfo2, mem_ctx);
3371 /*******************************************************************
3373 * fill a notify_info struct with info asked
3375 ********************************************************************/
3377 static bool construct_notify_jobs_info(struct messaging_context *msg_ctx,
3378 print_queue_struct *queue,
3379 struct spoolss_NotifyInfo *info,
3380 struct spoolss_PrinterInfo2 *pinfo2,
3382 const struct spoolss_NotifyOptionType *option_type,
3384 TALLOC_CTX *mem_ctx)
3387 enum spoolss_NotifyType type;
3389 struct spoolss_Notify *current_data;
3391 DEBUG(4,("construct_notify_jobs_info\n"));
3393 type = option_type->type;
3395 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3396 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3397 option_type->count));
3399 for(field_num=0; field_num<option_type->count; field_num++) {
3400 field = option_type->fields[field_num].field;
3402 if (!search_notify(type, field, &j) )
3405 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3406 struct spoolss_Notify,
3408 if (info->notifies == NULL) {
3409 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3413 current_data=&(info->notifies[info->count]);
3415 construct_info_data(current_data, type, field, id);
3416 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3417 queue, pinfo2, mem_ctx);
3425 * JFM: The enumeration is not that simple, it's even non obvious.
3427 * let's take an example: I want to monitor the PRINTER SERVER for
3428 * the printer's name and the number of jobs currently queued.
3429 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3430 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3432 * I have 3 printers on the back of my server.
3434 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3437 * 1 printer 1 name 1
3438 * 2 printer 1 cjob 1
3439 * 3 printer 2 name 2
3440 * 4 printer 2 cjob 2
3441 * 5 printer 3 name 3
3442 * 6 printer 3 name 3
3444 * that's the print server case, the printer case is even worse.
3447 /*******************************************************************
3449 * enumerate all printers on the printserver
3450 * fill a notify_info struct with info asked
3452 ********************************************************************/
3454 static WERROR printserver_notify_info(struct pipes_struct *p,
3455 struct policy_handle *hnd,
3456 struct spoolss_NotifyInfo *info,
3457 TALLOC_CTX *mem_ctx)
3460 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3461 int n_services=lp_numservices();
3463 struct spoolss_NotifyOption *option;
3464 struct spoolss_NotifyOptionType option_type;
3465 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3468 DEBUG(4,("printserver_notify_info\n"));
3473 option = Printer->notify.option;
3476 info->notifies = NULL;
3479 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3480 sending a ffpcn() request first */
3485 for (i=0; i<option->count; i++) {
3486 option_type = option->types[i];
3488 if (option_type.type != PRINTER_NOTIFY_TYPE)
3491 for (snum = 0; snum < n_services; snum++) {
3492 if (!lp_browseable(snum) ||
3493 !lp_snum_ok(snum) ||
3494 !lp_print_ok(snum)) {
3495 continue; /* skip */
3498 /* Maybe we should use the SYSTEM server_info here... */
3499 result = winreg_get_printer(mem_ctx,
3500 get_server_info_system(),
3502 Printer->servername,
3503 lp_servicename(snum),
3505 if (!W_ERROR_IS_OK(result)) {
3506 DEBUG(4, ("printserver_notify_info: "
3507 "Failed to get printer [%s]\n",
3508 lp_servicename(snum)));
3513 construct_notify_printer_info(p->msg_ctx,
3519 TALLOC_FREE(pinfo2);
3525 * Debugging information, don't delete.
3528 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3529 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3530 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3532 for (i=0; i<info->count; i++) {
3533 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3534 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3535 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3542 /*******************************************************************
3544 * fill a notify_info struct with info asked
3546 ********************************************************************/
3548 static WERROR printer_notify_info(struct pipes_struct *p,
3549 struct policy_handle *hnd,
3550 struct spoolss_NotifyInfo *info,
3551 TALLOC_CTX *mem_ctx)
3554 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3557 struct spoolss_NotifyOption *option;
3558 struct spoolss_NotifyOptionType option_type;
3560 print_queue_struct *queue=NULL;
3561 print_status_struct status;
3562 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3565 DEBUG(4,("printer_notify_info\n"));
3570 option = Printer->notify.option;
3574 info->notifies = NULL;
3577 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3578 sending a ffpcn() request first */
3583 get_printer_snum(p, hnd, &snum, NULL);
3585 /* Maybe we should use the SYSTEM server_info here... */
3586 result = winreg_get_printer(mem_ctx,
3587 get_server_info_system(),
3589 Printer->servername,
3590 lp_servicename(snum), &pinfo2);
3591 if (!W_ERROR_IS_OK(result)) {
3595 for (i=0; i<option->count; i++) {
3596 option_type = option->types[i];
3598 switch (option_type.type) {
3599 case PRINTER_NOTIFY_TYPE:
3600 if (construct_notify_printer_info(p->msg_ctx,
3609 case JOB_NOTIFY_TYPE:
3611 count = print_queue_status(p->msg_ctx, snum, &queue,
3614 for (j=0; j<count; j++) {
3615 construct_notify_jobs_info(p->msg_ctx,
3629 * Debugging information, don't delete.
3632 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3633 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3634 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3636 for (i=0; i<info->count; i++) {
3637 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3638 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3639 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3643 talloc_free(pinfo2);
3647 /****************************************************************
3648 _spoolss_RouterRefreshPrinterChangeNotify
3649 ****************************************************************/
3651 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3652 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3654 struct spoolss_NotifyInfo *info;
3656 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
3657 WERROR result = WERR_BADFID;
3659 /* we always have a spoolss_NotifyInfo struct */
3660 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3662 result = WERR_NOMEM;
3666 *r->out.info = info;
3669 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3670 "Invalid handle (%s:%u:%u).\n",
3671 OUR_HANDLE(r->in.handle)));
3675 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3678 * We are now using the change value, and
3679 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3680 * I don't have a global notification system, I'm sending back all the
3681 * informations even when _NOTHING_ has changed.
3684 /* We need to keep track of the change value to send back in
3685 RRPCN replies otherwise our updates are ignored. */
3687 Printer->notify.fnpcn = true;
3689 if (Printer->notify.cli_chan != NULL &&
3690 Printer->notify.cli_chan->active_connections > 0) {
3691 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3692 "Saving change value in request [%x]\n",
3694 Printer->notify.change = r->in.change_low;
3697 /* just ignore the spoolss_NotifyOption */
3699 switch (Printer->printer_type) {
3701 result = printserver_notify_info(p, r->in.handle,
3705 case SPLHND_PRINTER:
3706 result = printer_notify_info(p, r->in.handle,
3711 Printer->notify.fnpcn = false;
3717 /********************************************************************
3718 * construct_printer_info_0
3719 * fill a printer_info_0 struct
3720 ********************************************************************/
3722 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3723 const struct auth_serversupplied_info *server_info,
3724 struct messaging_context *msg_ctx,
3725 struct spoolss_PrinterInfo2 *info2,
3726 struct spoolss_PrinterInfo0 *r,
3730 struct printer_session_counter *session_counter;
3731 struct timeval setuptime;
3732 print_status_struct status;
3734 r->printername = talloc_strdup(mem_ctx, info2->printername);
3735 W_ERROR_HAVE_NO_MEMORY(r->printername);
3737 r->servername = talloc_strdup(mem_ctx, info2->servername);
3738 W_ERROR_HAVE_NO_MEMORY(r->servername);
3740 count = print_queue_length(msg_ctx, snum, &status);
3742 /* check if we already have a counter for this printer */
3743 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3744 if (session_counter->snum == snum)
3748 /* it's the first time, add it to the list */
3749 if (session_counter == NULL) {
3750 session_counter = talloc_zero(counter_list, struct printer_session_counter);
3751 W_ERROR_HAVE_NO_MEMORY(session_counter);
3752 session_counter->snum = snum;
3753 session_counter->counter = 0;
3754 DLIST_ADD(counter_list, session_counter);
3758 session_counter->counter++;
3764 get_startup_time(&setuptime);
3765 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3768 * the global_counter should be stored in a TDB as it's common to all the clients
3769 * and should be zeroed on samba startup
3771 r->global_counter = session_counter->counter;
3773 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3774 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3775 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3776 r->free_build = SPOOLSS_RELEASE_BUILD;
3778 r->max_spooling = 0;
3779 r->session_counter = session_counter->counter;
3780 r->num_error_out_of_paper = 0x0;
3781 r->num_error_not_ready = 0x0; /* number of print failure */
3783 r->number_of_processors = 0x1;
3784 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3785 r->high_part_total_bytes = 0x0;
3787 /* ChangeID in milliseconds*/
3788 winreg_printer_get_changeid(mem_ctx, server_info, msg_ctx,
3789 info2->sharename, &r->change_id);
3791 r->last_error = WERR_OK;
3792 r->status = nt_printq_status(status.status);
3793 r->enumerate_network_printers = 0x0;
3794 r->c_setprinter = 0x0;
3795 r->processor_architecture = PROCESSOR_ARCHITECTURE_INTEL;
3796 r->processor_level = 0x6; /* 6 ???*/
3805 /********************************************************************
3806 * construct_printer_info1
3807 * fill a spoolss_PrinterInfo1 struct
3808 ********************************************************************/
3810 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3811 const struct spoolss_PrinterInfo2 *info2,
3813 struct spoolss_PrinterInfo1 *r,
3818 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3822 W_ERROR_HAVE_NO_MEMORY(r->description);
3824 if (info2->comment == NULL || info2->comment[0] == '\0') {
3825 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3827 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3829 W_ERROR_HAVE_NO_MEMORY(r->comment);
3831 r->name = talloc_strdup(mem_ctx, info2->printername);
3832 W_ERROR_HAVE_NO_MEMORY(r->name);
3837 /********************************************************************
3838 * construct_printer_info2
3839 * fill a spoolss_PrinterInfo2 struct
3840 ********************************************************************/
3842 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3843 struct messaging_context *msg_ctx,
3844 const struct spoolss_PrinterInfo2 *info2,
3845 struct spoolss_PrinterInfo2 *r,
3849 print_status_struct status;
3851 count = print_queue_length(msg_ctx, snum, &status);
3853 r->servername = talloc_strdup(mem_ctx, info2->servername);
3854 W_ERROR_HAVE_NO_MEMORY(r->servername);
3855 r->printername = talloc_strdup(mem_ctx, info2->printername);
3856 W_ERROR_HAVE_NO_MEMORY(r->printername);
3857 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3858 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3859 r->portname = talloc_strdup(mem_ctx, info2->portname);
3860 W_ERROR_HAVE_NO_MEMORY(r->portname);
3861 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3862 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3864 if (info2->comment[0] == '\0') {
3865 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3867 r->comment = talloc_strdup(mem_ctx, info2->comment);
3869 W_ERROR_HAVE_NO_MEMORY(r->comment);
3871 r->location = talloc_strdup(mem_ctx, info2->location);
3872 W_ERROR_HAVE_NO_MEMORY(r->location);
3873 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3874 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3875 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3876 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3877 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3878 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3879 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3880 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3882 r->attributes = info2->attributes;
3884 r->priority = info2->priority;
3885 r->defaultpriority = info2->defaultpriority;
3886 r->starttime = info2->starttime;
3887 r->untiltime = info2->untiltime;
3888 r->status = nt_printq_status(status.status);
3890 r->averageppm = info2->averageppm;
3892 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3894 DEBUG(8,("Returning NULL Devicemode!\n"));
3899 if (info2->secdesc != NULL) {
3900 /* don't use talloc_steal() here unless you do a deep steal of all
3901 the SEC_DESC members */
3903 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3909 /********************************************************************
3910 * construct_printer_info3
3911 * fill a spoolss_PrinterInfo3 struct
3912 ********************************************************************/
3914 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3915 const struct spoolss_PrinterInfo2 *info2,
3916 struct spoolss_PrinterInfo3 *r,
3919 /* These are the components of the SD we are returning. */
3921 if (info2->secdesc != NULL) {
3922 /* don't use talloc_steal() here unless you do a deep steal of all
3923 the SEC_DESC members */
3925 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3926 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3932 /********************************************************************
3933 * construct_printer_info4
3934 * fill a spoolss_PrinterInfo4 struct
3935 ********************************************************************/
3937 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3938 const struct spoolss_PrinterInfo2 *info2,
3939 struct spoolss_PrinterInfo4 *r,
3942 r->printername = talloc_strdup(mem_ctx, info2->printername);
3943 W_ERROR_HAVE_NO_MEMORY(r->printername);
3944 r->servername = talloc_strdup(mem_ctx, info2->servername);
3945 W_ERROR_HAVE_NO_MEMORY(r->servername);
3947 r->attributes = info2->attributes;
3952 /********************************************************************
3953 * construct_printer_info5
3954 * fill a spoolss_PrinterInfo5 struct
3955 ********************************************************************/
3957 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3958 const struct spoolss_PrinterInfo2 *info2,
3959 struct spoolss_PrinterInfo5 *r,
3962 r->printername = talloc_strdup(mem_ctx, info2->printername);
3963 W_ERROR_HAVE_NO_MEMORY(r->printername);
3964 r->portname = talloc_strdup(mem_ctx, info2->portname);
3965 W_ERROR_HAVE_NO_MEMORY(r->portname);
3967 r->attributes = info2->attributes;
3969 /* these two are not used by NT+ according to MSDN */
3970 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3971 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3976 /********************************************************************
3977 * construct_printer_info_6
3978 * fill a spoolss_PrinterInfo6 struct
3979 ********************************************************************/
3981 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3982 struct messaging_context *msg_ctx,
3983 const struct spoolss_PrinterInfo2 *info2,
3984 struct spoolss_PrinterInfo6 *r,
3988 print_status_struct status;
3990 count = print_queue_length(msg_ctx, snum, &status);
3992 r->status = nt_printq_status(status.status);
3997 /********************************************************************
3998 * construct_printer_info7
3999 * fill a spoolss_PrinterInfo7 struct
4000 ********************************************************************/
4002 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
4003 struct messaging_context *msg_ctx,
4004 struct printer_handle *print_hnd,
4005 struct spoolss_PrinterInfo7 *r,
4008 struct auth_serversupplied_info *server_info;
4012 status = make_server_info_system(mem_ctx, &server_info);
4013 if (!NT_STATUS_IS_OK(status)) {
4014 DEBUG(0, ("construct_printer_info7: "
4015 "Could not create system server_info\n"));
4019 if (is_printer_published(mem_ctx, server_info, msg_ctx,
4020 print_hnd->servername,
4021 lp_servicename(snum), &guid, NULL)) {
4022 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
4023 r->action = DSPRINT_PUBLISH;
4025 r->guid = talloc_strdup(mem_ctx, "");
4026 r->action = DSPRINT_UNPUBLISH;
4028 W_ERROR_HAVE_NO_MEMORY(r->guid);
4030 TALLOC_FREE(server_info);
4034 /********************************************************************
4035 * construct_printer_info8
4036 * fill a spoolss_PrinterInfo8 struct
4037 ********************************************************************/
4039 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
4040 const struct spoolss_PrinterInfo2 *info2,
4041 struct spoolss_DeviceModeInfo *r,
4044 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
4046 DEBUG(8,("Returning NULL Devicemode!\n"));
4053 /********************************************************************
4054 ********************************************************************/
4056 static bool snum_is_shared_printer(int snum)
4058 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
4061 /********************************************************************
4062 Spoolss_enumprinters.
4063 ********************************************************************/
4065 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
4066 const struct auth_serversupplied_info *server_info,
4067 struct messaging_context *msg_ctx,
4070 union spoolss_PrinterInfo **info_p,
4074 int n_services = lp_numservices();
4075 union spoolss_PrinterInfo *info = NULL;
4077 WERROR result = WERR_OK;
4082 for (snum = 0; snum < n_services; snum++) {
4084 const char *printer;
4085 struct spoolss_PrinterInfo2 *info2;
4087 if (!snum_is_shared_printer(snum)) {
4091 printer = lp_const_servicename(snum);
4093 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4096 result = winreg_create_printer(mem_ctx,
4101 if (!W_ERROR_IS_OK(result)) {
4105 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4106 union spoolss_PrinterInfo,
4109 result = WERR_NOMEM;
4113 result = winreg_get_printer(mem_ctx, server_info, msg_ctx,
4114 NULL, printer, &info2);
4115 if (!W_ERROR_IS_OK(result)) {
4121 result = construct_printer_info0(info, server_info,
4123 &info[count].info0, snum);
4126 result = construct_printer_info1(info, info2, flags,
4127 &info[count].info1, snum);
4130 result = construct_printer_info2(info, msg_ctx, info2,
4131 &info[count].info2, snum);
4134 result = construct_printer_info4(info, info2,
4135 &info[count].info4, snum);
4138 result = construct_printer_info5(info, info2,
4139 &info[count].info5, snum);
4143 result = WERR_UNKNOWN_LEVEL;
4147 if (!W_ERROR_IS_OK(result)) {
4158 if (!W_ERROR_IS_OK(result)) {
4168 /********************************************************************
4169 * handle enumeration of printers at level 0
4170 ********************************************************************/
4172 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4173 const struct auth_serversupplied_info *server_info,
4174 struct messaging_context *msg_ctx,
4176 const char *servername,
4177 union spoolss_PrinterInfo **info,
4180 DEBUG(4,("enum_all_printers_info_0\n"));
4182 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4183 0, flags, info, count);
4187 /********************************************************************
4188 ********************************************************************/
4190 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4191 const struct auth_serversupplied_info *server_info,
4192 struct messaging_context *msg_ctx,
4194 union spoolss_PrinterInfo **info,
4197 DEBUG(4,("enum_all_printers_info_1\n"));
4199 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4200 1, flags, info, count);
4203 /********************************************************************
4204 enum_all_printers_info_1_local.
4205 *********************************************************************/
4207 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4208 const struct auth_serversupplied_info *server_info,
4209 struct messaging_context *msg_ctx,
4210 union spoolss_PrinterInfo **info,
4213 DEBUG(4,("enum_all_printers_info_1_local\n"));
4215 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4216 PRINTER_ENUM_ICON8, info, count);
4219 /********************************************************************
4220 enum_all_printers_info_1_name.
4221 *********************************************************************/
4223 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4224 const struct auth_serversupplied_info *server_info,
4225 struct messaging_context *msg_ctx,
4227 union spoolss_PrinterInfo **info,
4230 const char *s = name;
4232 DEBUG(4,("enum_all_printers_info_1_name\n"));
4234 if ((name[0] == '\\') && (name[1] == '\\')) {
4238 if (!is_myname_or_ipaddr(s)) {
4239 return WERR_INVALID_NAME;
4242 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4243 PRINTER_ENUM_ICON8, info, count);
4246 /********************************************************************
4247 enum_all_printers_info_1_network.
4248 *********************************************************************/
4250 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4251 const struct auth_serversupplied_info *server_info,
4252 struct messaging_context *msg_ctx,
4254 union spoolss_PrinterInfo **info,
4257 const char *s = name;
4259 DEBUG(4,("enum_all_printers_info_1_network\n"));
4261 /* If we respond to a enum_printers level 1 on our name with flags
4262 set to PRINTER_ENUM_REMOTE with a list of printers then these
4263 printers incorrectly appear in the APW browse list.
4264 Specifically the printers for the server appear at the workgroup
4265 level where all the other servers in the domain are
4266 listed. Windows responds to this call with a
4267 WERR_CAN_NOT_COMPLETE so we should do the same. */
4269 if (name[0] == '\\' && name[1] == '\\') {
4273 if (is_myname_or_ipaddr(s)) {
4274 return WERR_CAN_NOT_COMPLETE;
4277 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4278 PRINTER_ENUM_NAME, info, count);
4281 /********************************************************************
4282 * api_spoolss_enumprinters
4284 * called from api_spoolss_enumprinters (see this to understand)
4285 ********************************************************************/
4287 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4288 const struct auth_serversupplied_info *server_info,
4289 struct messaging_context *msg_ctx,
4290 union spoolss_PrinterInfo **info,
4293 DEBUG(4,("enum_all_printers_info_2\n"));
4295 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4299 /********************************************************************
4300 * handle enumeration of printers at level 1
4301 ********************************************************************/
4303 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4304 const struct auth_serversupplied_info *server_info,
4305 struct messaging_context *msg_ctx,
4308 union spoolss_PrinterInfo **info,
4311 /* Not all the flags are equals */
4313 if (flags & PRINTER_ENUM_LOCAL) {
4314 return enum_all_printers_info_1_local(mem_ctx, server_info,
4315 msg_ctx, info, count);
4318 if (flags & PRINTER_ENUM_NAME) {
4319 return enum_all_printers_info_1_name(mem_ctx, server_info,
4320 msg_ctx, name, info,
4324 if (flags & PRINTER_ENUM_NETWORK) {
4325 return enum_all_printers_info_1_network(mem_ctx, server_info,
4326 msg_ctx, name, info,
4330 return WERR_OK; /* NT4sp5 does that */
4333 /********************************************************************
4334 * handle enumeration of printers at level 2
4335 ********************************************************************/
4337 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4338 const struct auth_serversupplied_info *server_info,
4339 struct messaging_context *msg_ctx,
4341 const char *servername,
4342 union spoolss_PrinterInfo **info,
4345 if (flags & PRINTER_ENUM_LOCAL) {
4346 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4350 if (flags & PRINTER_ENUM_NAME) {
4351 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4352 return WERR_INVALID_NAME;
4355 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4359 if (flags & PRINTER_ENUM_REMOTE) {
4360 return WERR_UNKNOWN_LEVEL;
4366 /********************************************************************
4367 * handle enumeration of printers at level 4
4368 ********************************************************************/
4370 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4371 const struct auth_serversupplied_info *server_info,
4372 struct messaging_context *msg_ctx,
4374 const char *servername,
4375 union spoolss_PrinterInfo **info,
4378 DEBUG(4,("enum_all_printers_info_4\n"));
4380 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4381 4, flags, info, count);
4385 /********************************************************************
4386 * handle enumeration of printers at level 5
4387 ********************************************************************/
4389 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4390 const struct auth_serversupplied_info *server_info,
4391 struct messaging_context *msg_ctx,
4393 const char *servername,
4394 union spoolss_PrinterInfo **info,
4397 DEBUG(4,("enum_all_printers_info_5\n"));
4399 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4400 5, flags, info, count);
4403 /****************************************************************
4404 _spoolss_EnumPrinters
4405 ****************************************************************/
4407 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4408 struct spoolss_EnumPrinters *r)
4410 const struct auth_serversupplied_info *server_info = get_server_info_system();
4411 const char *name = NULL;
4414 /* that's an [in out] buffer */
4416 if (!r->in.buffer && (r->in.offered != 0)) {
4417 return WERR_INVALID_PARAM;
4420 DEBUG(4,("_spoolss_EnumPrinters\n"));
4424 *r->out.info = NULL;
4428 * flags==PRINTER_ENUM_NAME
4429 * if name=="" then enumerates all printers
4430 * if name!="" then enumerate the printer
4431 * flags==PRINTER_ENUM_REMOTE
4432 * name is NULL, enumerate printers
4433 * Level 2: name!="" enumerates printers, name can't be NULL
4434 * Level 3: doesn't exist
4435 * Level 4: does a local registry lookup
4436 * Level 5: same as Level 2
4440 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4441 W_ERROR_HAVE_NO_MEMORY(name);
4444 switch (r->in.level) {
4446 result = enumprinters_level0(p->mem_ctx, server_info,
4447 p->msg_ctx, r->in.flags, name,
4448 r->out.info, r->out.count);
4451 result = enumprinters_level1(p->mem_ctx, server_info,
4452 p->msg_ctx, r->in.flags, name,
4453 r->out.info, r->out.count);
4456 result = enumprinters_level2(p->mem_ctx, server_info,
4457 p->msg_ctx, r->in.flags, name,
4458 r->out.info, r->out.count);
4461 result = enumprinters_level4(p->mem_ctx, server_info,
4462 p->msg_ctx, r->in.flags, name,
4463 r->out.info, r->out.count);
4466 result = enumprinters_level5(p->mem_ctx, server_info,
4467 p->msg_ctx, r->in.flags, name,
4468 r->out.info, r->out.count);
4471 return WERR_UNKNOWN_LEVEL;
4474 if (!W_ERROR_IS_OK(result)) {
4478 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4479 spoolss_EnumPrinters,
4480 *r->out.info, r->in.level,
4482 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4483 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4485 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4488 /****************************************************************
4490 ****************************************************************/
4492 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4493 struct spoolss_GetPrinter *r)
4495 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
4496 struct spoolss_PrinterInfo2 *info2 = NULL;
4497 WERROR result = WERR_OK;
4498 const char *servername = NULL;
4501 /* that's an [in out] buffer */
4503 if (!r->in.buffer && (r->in.offered != 0)) {
4504 return WERR_INVALID_PARAM;
4509 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4513 if (Printer != NULL || Printer->servername != NULL) {
4514 servername = Printer->servername;
4517 result = winreg_get_printer(p->mem_ctx,
4518 get_server_info_system(),
4521 lp_const_servicename(snum),
4523 if (!W_ERROR_IS_OK(result)) {
4527 switch (r->in.level) {
4529 result = construct_printer_info0(p->mem_ctx,
4530 get_server_info_system(),
4533 &r->out.info->info0,
4537 result = construct_printer_info1(p->mem_ctx, info2,
4539 &r->out.info->info1, snum);
4542 result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
4543 &r->out.info->info2, snum);
4546 result = construct_printer_info3(p->mem_ctx, info2,
4547 &r->out.info->info3, snum);
4550 result = construct_printer_info4(p->mem_ctx, info2,
4551 &r->out.info->info4, snum);
4554 result = construct_printer_info5(p->mem_ctx, info2,
4555 &r->out.info->info5, snum);
4558 result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
4559 &r->out.info->info6, snum);
4562 result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
4564 &r->out.info->info7, snum);
4567 result = construct_printer_info8(p->mem_ctx, info2,
4568 &r->out.info->info8, snum);
4571 result = WERR_UNKNOWN_LEVEL;
4575 if (!W_ERROR_IS_OK(result)) {
4576 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4577 r->in.level, win_errstr(result)));
4578 TALLOC_FREE(r->out.info);
4582 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4583 r->out.info, r->in.level);
4584 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4586 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4589 /********************************************************************
4590 ********************************************************************/
4592 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4594 if (in && strlen(in)) { \
4595 out = talloc_strdup(mem_ctx, in); \
4597 out = talloc_strdup(mem_ctx, ""); \
4599 W_ERROR_HAVE_NO_MEMORY(out); \
4602 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4604 if (in && strlen(in)) { \
4605 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4607 out = talloc_strdup(mem_ctx, ""); \
4609 W_ERROR_HAVE_NO_MEMORY(out); \
4612 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4613 const char **string_array,
4614 const char ***presult,
4615 const char *cservername,
4619 int i, num_strings = 0;
4620 const char **array = NULL;
4622 if (string_array == NULL) {
4623 return WERR_INVALID_PARAMETER;;
4626 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4627 const char *str = NULL;
4629 if (cservername == NULL || arch == NULL) {
4630 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4632 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4635 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4642 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4643 &array, &num_strings);
4653 /********************************************************************
4654 * fill a spoolss_DriverInfo1 struct
4655 ********************************************************************/
4657 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4658 struct spoolss_DriverInfo1 *r,
4659 const struct spoolss_DriverInfo8 *driver,
4660 const char *servername)
4662 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4663 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4668 /********************************************************************
4669 * fill a spoolss_DriverInfo2 struct
4670 ********************************************************************/
4672 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4673 struct spoolss_DriverInfo2 *r,
4674 const struct spoolss_DriverInfo8 *driver,
4675 const char *servername)
4678 const char *cservername = canon_servername(servername);
4680 r->version = driver->version;
4682 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4683 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4684 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4685 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4687 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4688 driver->architecture,
4690 driver->driver_path,
4693 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4694 driver->architecture,
4699 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4700 driver->architecture,
4702 driver->config_file,
4708 /********************************************************************
4709 * fill a spoolss_DriverInfo3 struct
4710 ********************************************************************/
4712 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4713 struct spoolss_DriverInfo3 *r,
4714 const struct spoolss_DriverInfo8 *driver,
4715 const char *servername)
4717 const char *cservername = canon_servername(servername);
4719 r->version = driver->version;
4721 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4722 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4723 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4724 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4726 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4727 driver->architecture,
4729 driver->driver_path,
4732 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4733 driver->architecture,
4738 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4739 driver->architecture,
4741 driver->config_file,
4744 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4745 driver->architecture,
4750 FILL_DRIVER_STRING(mem_ctx,
4751 driver->monitor_name,
4754 FILL_DRIVER_STRING(mem_ctx,
4755 driver->default_datatype,
4756 r->default_datatype);
4758 return string_array_from_driver_info(mem_ctx,
4759 driver->dependent_files,
4760 &r->dependent_files,
4762 driver->architecture,
4766 /********************************************************************
4767 * fill a spoolss_DriverInfo4 struct
4768 ********************************************************************/
4770 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4771 struct spoolss_DriverInfo4 *r,
4772 const struct spoolss_DriverInfo8 *driver,
4773 const char *servername)
4775 const char *cservername = canon_servername(servername);
4778 r->version = driver->version;
4780 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4781 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4782 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4783 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4785 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4786 driver->architecture,
4788 driver->driver_path,
4791 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4792 driver->architecture,
4797 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4798 driver->architecture,
4800 driver->config_file,
4803 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4804 driver->architecture,
4809 result = string_array_from_driver_info(mem_ctx,
4810 driver->dependent_files,
4811 &r->dependent_files,
4813 driver->architecture,
4815 if (!W_ERROR_IS_OK(result)) {
4819 FILL_DRIVER_STRING(mem_ctx,
4820 driver->monitor_name,
4823 FILL_DRIVER_STRING(mem_ctx,
4824 driver->default_datatype,
4825 r->default_datatype);
4828 result = string_array_from_driver_info(mem_ctx,
4829 driver->previous_names,
4836 /********************************************************************
4837 * fill a spoolss_DriverInfo5 struct
4838 ********************************************************************/
4840 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4841 struct spoolss_DriverInfo5 *r,
4842 const struct spoolss_DriverInfo8 *driver,
4843 const char *servername)
4845 const char *cservername = canon_servername(servername);
4847 r->version = driver->version;
4849 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4850 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4851 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4852 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4854 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4855 driver->architecture,
4857 driver->driver_path,
4860 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4861 driver->architecture,
4866 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4867 driver->architecture,
4869 driver->config_file,
4872 r->driver_attributes = 0;
4873 r->config_version = 0;
4874 r->driver_version = 0;
4878 /********************************************************************
4879 * fill a spoolss_DriverInfo6 struct
4880 ********************************************************************/
4882 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4883 struct spoolss_DriverInfo6 *r,
4884 const struct spoolss_DriverInfo8 *driver,
4885 const char *servername)
4887 const char *cservername = canon_servername(servername);
4890 r->version = driver->version;
4892 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4893 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4894 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4895 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4897 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4898 driver->architecture,
4900 driver->driver_path,
4903 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4904 driver->architecture,
4909 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4910 driver->architecture,
4912 driver->config_file,
4915 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4916 driver->architecture,
4921 FILL_DRIVER_STRING(mem_ctx,
4922 driver->monitor_name,
4925 FILL_DRIVER_STRING(mem_ctx,
4926 driver->default_datatype,
4927 r->default_datatype);
4929 result = string_array_from_driver_info(mem_ctx,
4930 driver->dependent_files,
4931 &r->dependent_files,
4933 driver->architecture,
4935 if (!W_ERROR_IS_OK(result)) {
4939 result = string_array_from_driver_info(mem_ctx,
4940 driver->previous_names,
4943 if (!W_ERROR_IS_OK(result)) {
4947 r->driver_date = driver->driver_date;
4948 r->driver_version = driver->driver_version;
4950 FILL_DRIVER_STRING(mem_ctx,
4951 driver->manufacturer_name,
4952 r->manufacturer_name);
4953 FILL_DRIVER_STRING(mem_ctx,
4954 driver->manufacturer_url,
4955 r->manufacturer_url);
4956 FILL_DRIVER_STRING(mem_ctx,
4957 driver->hardware_id,
4959 FILL_DRIVER_STRING(mem_ctx,
4966 /********************************************************************
4967 * fill a spoolss_DriverInfo8 struct
4968 ********************************************************************/
4970 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4971 struct spoolss_DriverInfo8 *r,
4972 const struct spoolss_DriverInfo8 *driver,
4973 const char *servername)
4975 const char *cservername = canon_servername(servername);
4978 r->version = driver->version;
4980 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4981 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4982 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4983 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4985 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4986 driver->architecture,
4988 driver->driver_path,
4991 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4992 driver->architecture,
4997 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4998 driver->architecture,
5000 driver->config_file,
5003 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5004 driver->architecture,
5009 FILL_DRIVER_STRING(mem_ctx,
5010 driver->monitor_name,
5013 FILL_DRIVER_STRING(mem_ctx,
5014 driver->default_datatype,
5015 r->default_datatype);
5017 result = string_array_from_driver_info(mem_ctx,
5018 driver->dependent_files,
5019 &r->dependent_files,
5021 driver->architecture,
5023 if (!W_ERROR_IS_OK(result)) {
5027 result = string_array_from_driver_info(mem_ctx,
5028 driver->previous_names,
5031 if (!W_ERROR_IS_OK(result)) {
5035 r->driver_date = driver->driver_date;
5036 r->driver_version = driver->driver_version;
5038 FILL_DRIVER_STRING(mem_ctx,
5039 driver->manufacturer_name,
5040 r->manufacturer_name);
5041 FILL_DRIVER_STRING(mem_ctx,
5042 driver->manufacturer_url,
5043 r->manufacturer_url);
5044 FILL_DRIVER_STRING(mem_ctx,
5045 driver->hardware_id,
5047 FILL_DRIVER_STRING(mem_ctx,
5051 FILL_DRIVER_STRING(mem_ctx,
5052 driver->print_processor,
5053 r->print_processor);
5054 FILL_DRIVER_STRING(mem_ctx,
5055 driver->vendor_setup,
5058 result = string_array_from_driver_info(mem_ctx,
5059 driver->color_profiles,
5062 if (!W_ERROR_IS_OK(result)) {
5066 FILL_DRIVER_STRING(mem_ctx,
5070 r->printer_driver_attributes = driver->printer_driver_attributes;
5072 result = string_array_from_driver_info(mem_ctx,
5073 driver->core_driver_dependencies,
5074 &r->core_driver_dependencies,
5076 if (!W_ERROR_IS_OK(result)) {
5080 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
5081 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
5086 #if 0 /* disabled until marshalling issues are resolved - gd */
5087 /********************************************************************
5088 ********************************************************************/
5090 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
5091 struct spoolss_DriverFileInfo *r,
5092 const char *cservername,
5093 const char *file_name,
5094 enum spoolss_DriverFileType file_type,
5095 uint32_t file_version)
5097 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
5098 cservername, file_name);
5099 W_ERROR_HAVE_NO_MEMORY(r->file_name);
5100 r->file_type = file_type;
5101 r->file_version = file_version;
5106 /********************************************************************
5107 ********************************************************************/
5109 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
5110 const struct spoolss_DriverInfo8 *driver,
5111 const char *cservername,
5112 struct spoolss_DriverFileInfo **info_p,
5115 struct spoolss_DriverFileInfo *info = NULL;
5123 if (strlen(driver->driver_path)) {
5124 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5125 struct spoolss_DriverFileInfo,
5127 W_ERROR_HAVE_NO_MEMORY(info);
5128 result = fill_spoolss_DriverFileInfo(info,
5131 driver->driver_path,
5132 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
5134 W_ERROR_NOT_OK_RETURN(result);
5138 if (strlen(driver->config_file)) {
5139 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5140 struct spoolss_DriverFileInfo,
5142 W_ERROR_HAVE_NO_MEMORY(info);
5143 result = fill_spoolss_DriverFileInfo(info,
5146 driver->config_file,
5147 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
5149 W_ERROR_NOT_OK_RETURN(result);
5153 if (strlen(driver->data_file)) {
5154 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5155 struct spoolss_DriverFileInfo,
5157 W_ERROR_HAVE_NO_MEMORY(info);
5158 result = fill_spoolss_DriverFileInfo(info,
5162 SPOOLSS_DRIVER_FILE_TYPE_DATA,
5164 W_ERROR_NOT_OK_RETURN(result);
5168 if (strlen(driver->help_file)) {
5169 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5170 struct spoolss_DriverFileInfo,
5172 W_ERROR_HAVE_NO_MEMORY(info);
5173 result = fill_spoolss_DriverFileInfo(info,
5177 SPOOLSS_DRIVER_FILE_TYPE_HELP,
5179 W_ERROR_NOT_OK_RETURN(result);
5183 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
5184 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5185 struct spoolss_DriverFileInfo,
5187 W_ERROR_HAVE_NO_MEMORY(info);
5188 result = fill_spoolss_DriverFileInfo(info,
5191 driver->dependent_files[i],
5192 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
5194 W_ERROR_NOT_OK_RETURN(result);
5204 /********************************************************************
5205 * fill a spoolss_DriverInfo101 struct
5206 ********************************************************************/
5208 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
5209 struct spoolss_DriverInfo101 *r,
5210 const struct spoolss_DriverInfo8 *driver,
5211 const char *servername)
5213 const char *cservername = canon_servername(servername);
5216 r->version = driver->version;
5218 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5219 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5220 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5221 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5223 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5227 if (!W_ERROR_IS_OK(result)) {
5231 FILL_DRIVER_STRING(mem_ctx,
5232 driver->monitor_name,
5235 FILL_DRIVER_STRING(mem_ctx,
5236 driver->default_datatype,
5237 r->default_datatype);
5239 result = string_array_from_driver_info(mem_ctx,
5240 driver->previous_names,
5243 if (!W_ERROR_IS_OK(result)) {
5247 r->driver_date = driver->driver_date;
5248 r->driver_version = driver->driver_version;
5250 FILL_DRIVER_STRING(mem_ctx,
5251 driver->manufacturer_name,
5252 r->manufacturer_name);
5253 FILL_DRIVER_STRING(mem_ctx,
5254 driver->manufacturer_url,
5255 r->manufacturer_url);
5256 FILL_DRIVER_STRING(mem_ctx,
5257 driver->hardware_id,
5259 FILL_DRIVER_STRING(mem_ctx,
5266 /********************************************************************
5267 ********************************************************************/
5269 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5270 const struct auth_serversupplied_info *server_info,
5271 struct messaging_context *msg_ctx,
5273 union spoolss_DriverInfo *r,
5275 const char *servername,
5276 const char *architecture,
5279 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5280 struct spoolss_DriverInfo8 *driver;
5283 result = winreg_get_printer(mem_ctx,
5287 lp_const_servicename(snum),
5290 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5291 win_errstr(result)));
5293 if (!W_ERROR_IS_OK(result)) {
5294 return WERR_INVALID_PRINTER_NAME;
5297 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5299 pinfo2->drivername, version, &driver);
5301 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5302 win_errstr(result)));
5304 if (!W_ERROR_IS_OK(result)) {
5306 * Is this a W2k client ?
5310 talloc_free(pinfo2);
5311 return WERR_UNKNOWN_PRINTER_DRIVER;
5314 /* Yes - try again with a WinNT driver. */
5316 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5320 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5321 win_errstr(result)));
5322 if (!W_ERROR_IS_OK(result)) {
5323 talloc_free(pinfo2);
5324 return WERR_UNKNOWN_PRINTER_DRIVER;
5330 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5333 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5336 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5339 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5342 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5345 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5348 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5350 #if 0 /* disabled until marshalling issues are resolved - gd */
5352 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5356 result = WERR_UNKNOWN_LEVEL;
5360 talloc_free(pinfo2);
5361 talloc_free(driver);
5366 /****************************************************************
5367 _spoolss_GetPrinterDriver2
5368 ****************************************************************/
5370 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5371 struct spoolss_GetPrinterDriver2 *r)
5373 struct printer_handle *printer;
5378 /* that's an [in out] buffer */
5380 if (!r->in.buffer && (r->in.offered != 0)) {
5381 return WERR_INVALID_PARAM;
5384 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5386 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5387 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5388 return WERR_INVALID_PRINTER_NAME;
5392 *r->out.server_major_version = 0;
5393 *r->out.server_minor_version = 0;
5395 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5399 result = construct_printer_driver_info_level(p->mem_ctx,
5400 get_server_info_system(),
5402 r->in.level, r->out.info,
5403 snum, printer->servername,
5405 r->in.client_major_version);
5406 if (!W_ERROR_IS_OK(result)) {
5407 TALLOC_FREE(r->out.info);
5411 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5412 r->out.info, r->in.level);
5413 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5415 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5419 /****************************************************************
5420 _spoolss_StartPagePrinter
5421 ****************************************************************/
5423 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5424 struct spoolss_StartPagePrinter *r)
5426 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5429 DEBUG(3,("_spoolss_StartPagePrinter: "
5430 "Error in startpageprinter printer handle\n"));
5434 Printer->page_started = true;
5438 /****************************************************************
5439 _spoolss_EndPagePrinter
5440 ****************************************************************/
5442 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5443 struct spoolss_EndPagePrinter *r)
5447 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5450 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5451 OUR_HANDLE(r->in.handle)));
5455 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5458 Printer->page_started = false;
5459 print_job_endpage(p->msg_ctx, snum, Printer->jobid);
5464 /****************************************************************
5465 _spoolss_StartDocPrinter
5466 ****************************************************************/
5468 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5469 struct spoolss_StartDocPrinter *r)
5471 struct spoolss_DocumentInfo1 *info_1;
5473 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5477 DEBUG(2,("_spoolss_StartDocPrinter: "
5478 "Invalid handle (%s:%u:%u)\n",
5479 OUR_HANDLE(r->in.handle)));
5483 if (Printer->jobid) {
5484 DEBUG(2, ("_spoolss_StartDocPrinter: "
5485 "StartDocPrinter called twice! "
5486 "(existing jobid = %d)\n", Printer->jobid));
5487 return WERR_INVALID_HANDLE;
5490 if (r->in.level != 1) {
5491 return WERR_UNKNOWN_LEVEL;
5494 info_1 = r->in.info.info1;
5497 * a nice thing with NT is it doesn't listen to what you tell it.
5498 * when asked to send _only_ RAW datas, it tries to send datas
5501 * So I add checks like in NT Server ...
5504 if (info_1->datatype) {
5505 if (strcmp(info_1->datatype, "RAW") != 0) {
5507 return WERR_INVALID_DATATYPE;
5511 /* get the share number of the printer */
5512 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5516 werr = print_job_start(get_server_info_system(),
5520 info_1->document_name,
5521 info_1->output_file,
5525 /* An error occured in print_job_start() so return an appropriate
5528 if (!W_ERROR_IS_OK(werr)) {
5532 Printer->document_started = true;
5533 *r->out.job_id = Printer->jobid;
5538 /****************************************************************
5539 _spoolss_EndDocPrinter
5540 ****************************************************************/
5542 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5543 struct spoolss_EndDocPrinter *r)
5545 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5550 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5551 OUR_HANDLE(r->in.handle)));
5555 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5559 Printer->document_started = false;
5560 status = print_job_end(p->msg_ctx, snum, Printer->jobid, NORMAL_CLOSE);
5561 if (!NT_STATUS_IS_OK(status)) {
5562 DEBUG(2, ("_spoolss_EndDocPrinter: "
5563 "print_job_end failed [%s]\n",
5564 nt_errstr(status)));
5568 return ntstatus_to_werror(status);
5571 /****************************************************************
5572 _spoolss_WritePrinter
5573 ****************************************************************/
5575 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5576 struct spoolss_WritePrinter *r)
5578 ssize_t buffer_written;
5580 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5583 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5584 OUR_HANDLE(r->in.handle)));
5585 *r->out.num_written = r->in._data_size;
5589 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5592 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5593 buffer_written = print_job_write(server_event_context(),p->msg_ctx,
5594 snum, Printer->jobid,
5595 (const char *)r->in.data.data,
5596 (size_t)r->in._data_size);
5597 if (buffer_written == (ssize_t)-1) {
5598 *r->out.num_written = 0;
5599 if (errno == ENOSPC)
5600 return WERR_NO_SPOOL_SPACE;
5602 return WERR_ACCESS_DENIED;
5605 *r->out.num_written = r->in._data_size;
5610 /********************************************************************
5611 * api_spoolss_getprinter
5612 * called from the spoolss dispatcher
5614 ********************************************************************/
5616 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5617 struct pipes_struct *p)
5619 const struct auth_serversupplied_info *server_info = get_server_info_system();
5621 WERROR errcode = WERR_BADFUNC;
5622 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
5625 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5626 OUR_HANDLE(handle)));
5630 if (!get_printer_snum(p, handle, &snum, NULL))
5634 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5635 errcode = print_queue_pause(server_info, p->msg_ctx, snum);
5637 case SPOOLSS_PRINTER_CONTROL_RESUME:
5638 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5639 errcode = print_queue_resume(server_info, p->msg_ctx, snum);
5641 case SPOOLSS_PRINTER_CONTROL_PURGE:
5642 errcode = print_queue_purge(server_info, p->msg_ctx, snum);
5645 return WERR_UNKNOWN_LEVEL;
5652 /****************************************************************
5653 _spoolss_AbortPrinter
5654 * From MSDN: "Deletes printer's spool file if printer is configured
5656 ****************************************************************/
5658 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5659 struct spoolss_AbortPrinter *r)
5661 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5663 WERROR errcode = WERR_OK;
5666 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5667 OUR_HANDLE(r->in.handle)));
5671 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5674 if (!Printer->document_started) {
5675 return WERR_SPL_NO_STARTDOC;
5678 errcode = print_job_delete(get_server_info_system(),
5686 /********************************************************************
5687 * called by spoolss_api_setprinter
5688 * when updating a printer description
5689 ********************************************************************/
5691 static WERROR update_printer_sec(struct policy_handle *handle,
5692 struct pipes_struct *p,
5693 struct sec_desc_buf *secdesc_ctr)
5695 struct spoolss_security_descriptor *new_secdesc = NULL;
5696 struct spoolss_security_descriptor *old_secdesc = NULL;
5697 const char *printer;
5701 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
5703 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5704 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5705 OUR_HANDLE(handle)));
5707 result = WERR_BADFID;
5711 if (secdesc_ctr == NULL) {
5712 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5713 result = WERR_INVALID_PARAM;
5716 printer = lp_const_servicename(snum);
5718 /* Check the user has permissions to change the security
5719 descriptor. By experimentation with two NT machines, the user
5720 requires Full Access to the printer to change security
5723 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5724 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5725 result = WERR_ACCESS_DENIED;
5729 /* NT seems to like setting the security descriptor even though
5730 nothing may have actually changed. */
5731 result = winreg_get_printer_secdesc(p->mem_ctx,
5732 get_server_info_system(),
5736 if (!W_ERROR_IS_OK(result)) {
5737 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5738 result = WERR_BADFID;
5742 if (DEBUGLEVEL >= 10) {
5743 struct security_acl *the_acl;
5746 the_acl = old_secdesc->dacl;
5747 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5748 printer, the_acl->num_aces));
5750 for (i = 0; i < the_acl->num_aces; i++) {
5751 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5752 &the_acl->aces[i].trustee),
5753 the_acl->aces[i].access_mask));
5756 the_acl = secdesc_ctr->sd->dacl;
5759 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5760 printer, the_acl->num_aces));
5762 for (i = 0; i < the_acl->num_aces; i++) {
5763 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5764 &the_acl->aces[i].trustee),
5765 the_acl->aces[i].access_mask));
5768 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5772 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5773 if (new_secdesc == NULL) {
5774 result = WERR_NOMEM;
5778 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5783 result = winreg_set_printer_secdesc(p->mem_ctx,
5784 get_server_info_system(),
5793 /********************************************************************
5794 Canonicalize printer info from a client
5795 ********************************************************************/
5797 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5798 struct spoolss_SetPrinterInfo2 *info2,
5801 fstring printername;
5804 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5805 "portname=%s drivername=%s comment=%s location=%s\n",
5806 info2->servername, info2->printername, info2->sharename,
5807 info2->portname, info2->drivername, info2->comment,
5810 /* we force some elements to "correct" values */
5811 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5812 if (info2->servername == NULL) {
5815 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5816 if (info2->sharename == NULL) {
5820 /* check to see if we allow printername != sharename */
5821 if (lp_force_printername(snum)) {
5822 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5823 global_myname(), info2->sharename);
5825 /* make sure printername is in \\server\printername format */
5826 fstrcpy(printername, info2->printername);
5828 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5829 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5833 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5834 global_myname(), p);
5836 if (info2->printername == NULL) {
5840 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5841 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5846 /****************************************************************************
5847 ****************************************************************************/
5849 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5851 char *cmd = lp_addport_cmd();
5852 char *command = NULL;
5854 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5855 bool is_print_op = false;
5858 return WERR_ACCESS_DENIED;
5861 command = talloc_asprintf(ctx,
5862 "%s \"%s\" \"%s\"", cmd, portname, uri );
5868 is_print_op = user_has_privileges( token, &se_printop );
5870 DEBUG(10,("Running [%s]\n", command));
5872 /********* BEGIN SePrintOperatorPrivilege **********/
5877 ret = smbrun(command, NULL);
5882 /********* END SePrintOperatorPrivilege **********/
5884 DEBUGADD(10,("returned [%d]\n", ret));
5886 TALLOC_FREE(command);
5889 return WERR_ACCESS_DENIED;
5895 /****************************************************************************
5896 ****************************************************************************/
5898 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5899 struct spoolss_SetPrinterInfo2 *info2,
5900 const char *remote_machine,
5901 struct messaging_context *msg_ctx)
5903 char *cmd = lp_addprinter_cmd();
5905 char *command = NULL;
5909 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5910 bool is_print_op = false;
5912 if (!remote_machine) {
5916 command = talloc_asprintf(ctx,
5917 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5918 cmd, info2->printername, info2->sharename,
5919 info2->portname, info2->drivername,
5920 info2->location, info2->comment, remote_machine);
5926 is_print_op = user_has_privileges( token, &se_printop );
5928 DEBUG(10,("Running [%s]\n", command));
5930 /********* BEGIN SePrintOperatorPrivilege **********/
5935 if ( (ret = smbrun(command, &fd)) == 0 ) {
5936 /* Tell everyone we updated smb.conf. */
5937 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5943 /********* END SePrintOperatorPrivilege **********/
5945 DEBUGADD(10,("returned [%d]\n", ret));
5947 TALLOC_FREE(command);
5955 /* reload our services immediately */
5957 reload_services(msg_ctx, -1, false);
5961 /* Get lines and convert them back to dos-codepage */
5962 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5963 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5966 /* Set the portname to what the script says the portname should be. */
5967 /* but don't require anything to be return from the script exit a good error code */
5970 /* Set the portname to what the script says the portname should be. */
5971 info2->portname = talloc_strdup(ctx, qlines[0]);
5972 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5975 TALLOC_FREE(qlines);
5979 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5980 const struct auth_serversupplied_info *server_info,
5981 struct messaging_context *msg_ctx,
5983 struct spoolss_SetPrinterInfo2 *printer,
5984 struct spoolss_PrinterInfo2 *old_printer)
5986 bool force_update = (old_printer == NULL);
5987 const char *dnsdomname;
5988 const char *longname;
5989 const char *uncname;
5990 const char *spooling;
5992 WERROR result = WERR_OK;
5994 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5995 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5996 winreg_set_printer_dataex(mem_ctx,
6000 SPOOL_DSSPOOLER_KEY,
6001 SPOOL_REG_DRIVERNAME,
6006 if (!force_update) {
6007 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6008 printer->drivername));
6010 notify_printer_driver(server_event_context(), msg_ctx,
6011 snum, printer->drivername);
6015 if (force_update || !strequal(printer->comment, old_printer->comment)) {
6016 push_reg_sz(mem_ctx, &buffer, printer->comment);
6017 winreg_set_printer_dataex(mem_ctx,
6021 SPOOL_DSSPOOLER_KEY,
6022 SPOOL_REG_DESCRIPTION,
6027 if (!force_update) {
6028 notify_printer_comment(server_event_context(), msg_ctx,
6029 snum, printer->comment);
6033 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
6034 push_reg_sz(mem_ctx, &buffer, printer->sharename);
6035 winreg_set_printer_dataex(mem_ctx,
6039 SPOOL_DSSPOOLER_KEY,
6040 SPOOL_REG_PRINTSHARENAME,
6045 if (!force_update) {
6046 notify_printer_sharename(server_event_context(),
6048 snum, printer->sharename);
6052 if (force_update || !strequal(printer->printername, old_printer->printername)) {
6055 p = strrchr(printer->printername, '\\' );
6059 p = printer->printername;
6062 push_reg_sz(mem_ctx, &buffer, p);
6063 winreg_set_printer_dataex(mem_ctx,
6067 SPOOL_DSSPOOLER_KEY,
6068 SPOOL_REG_PRINTERNAME,
6073 if (!force_update) {
6074 notify_printer_printername(server_event_context(),
6079 if (force_update || !strequal(printer->portname, old_printer->portname)) {
6080 push_reg_sz(mem_ctx, &buffer, printer->portname);
6081 winreg_set_printer_dataex(mem_ctx,
6085 SPOOL_DSSPOOLER_KEY,
6091 if (!force_update) {
6092 notify_printer_port(server_event_context(),
6093 msg_ctx, snum, printer->portname);
6097 if (force_update || !strequal(printer->location, old_printer->location)) {
6098 push_reg_sz(mem_ctx, &buffer, printer->location);
6099 winreg_set_printer_dataex(mem_ctx,
6103 SPOOL_DSSPOOLER_KEY,
6109 if (!force_update) {
6110 notify_printer_location(server_event_context(),
6116 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
6117 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
6118 winreg_set_printer_dataex(mem_ctx,
6122 SPOOL_DSSPOOLER_KEY,
6123 SPOOL_REG_PRINTSEPARATORFILE,
6128 if (!force_update) {
6129 notify_printer_location(server_event_context(),
6135 if (force_update || printer->starttime != old_printer->starttime) {
6136 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6137 SIVAL(buffer.data, 0, printer->starttime);
6138 winreg_set_printer_dataex(mem_ctx,
6142 SPOOL_DSSPOOLER_KEY,
6143 SPOOL_REG_PRINTSTARTTIME,
6149 if (force_update || printer->untiltime != old_printer->untiltime) {
6150 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6151 SIVAL(buffer.data, 0, printer->untiltime);
6152 winreg_set_printer_dataex(mem_ctx,
6156 SPOOL_DSSPOOLER_KEY,
6157 SPOOL_REG_PRINTENDTIME,
6163 if (force_update || printer->priority != old_printer->priority) {
6164 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6165 SIVAL(buffer.data, 0, printer->priority);
6166 winreg_set_printer_dataex(mem_ctx,
6170 SPOOL_DSSPOOLER_KEY,
6177 if (force_update || printer->attributes != old_printer->attributes) {
6178 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6179 SIVAL(buffer.data, 0, (printer->attributes &
6180 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
6181 winreg_set_printer_dataex(mem_ctx,
6185 SPOOL_DSSPOOLER_KEY,
6186 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
6191 switch (printer->attributes & 0x3) {
6193 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
6196 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
6199 spooling = SPOOL_REGVAL_PRINTDIRECT;
6202 spooling = "unknown";
6204 push_reg_sz(mem_ctx, &buffer, spooling);
6205 winreg_set_printer_dataex(mem_ctx,
6209 SPOOL_DSSPOOLER_KEY,
6210 SPOOL_REG_PRINTSPOOLING,
6216 push_reg_sz(mem_ctx, &buffer, global_myname());
6217 winreg_set_printer_dataex(mem_ctx,
6221 SPOOL_DSSPOOLER_KEY,
6222 SPOOL_REG_SHORTSERVERNAME,
6227 dnsdomname = get_mydnsfullname();
6228 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
6229 longname = talloc_strdup(mem_ctx, dnsdomname);
6231 longname = talloc_strdup(mem_ctx, global_myname());
6233 if (longname == NULL) {
6234 result = WERR_NOMEM;
6238 push_reg_sz(mem_ctx, &buffer, longname);
6239 winreg_set_printer_dataex(mem_ctx,
6243 SPOOL_DSSPOOLER_KEY,
6244 SPOOL_REG_SERVERNAME,
6249 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
6250 global_myname(), printer->sharename);
6251 push_reg_sz(mem_ctx, &buffer, uncname);
6252 winreg_set_printer_dataex(mem_ctx,
6256 SPOOL_DSSPOOLER_KEY,
6266 /********************************************************************
6267 * Called by spoolss_api_setprinter
6268 * when updating a printer description.
6269 ********************************************************************/
6271 static WERROR update_printer(struct pipes_struct *p,
6272 struct policy_handle *handle,
6273 struct spoolss_SetPrinterInfoCtr *info_ctr,
6274 struct spoolss_DeviceMode *devmode)
6276 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
6277 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
6278 struct spoolss_PrinterInfo2 *old_printer;
6279 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6280 const char *servername = NULL;
6282 WERROR result = WERR_OK;
6283 TALLOC_CTX *tmp_ctx;
6285 DEBUG(8,("update_printer\n"));
6287 tmp_ctx = talloc_new(p->mem_ctx);
6288 if (tmp_ctx == NULL) {
6293 result = WERR_BADFID;
6297 if (!get_printer_snum(p, handle, &snum, NULL)) {
6298 result = WERR_BADFID;
6302 if (Printer != NULL || Printer->servername != NULL) {
6303 servername = Printer->servername;
6306 result = winreg_get_printer(tmp_ctx,
6307 get_server_info_system(),
6310 lp_const_servicename(snum),
6312 if (!W_ERROR_IS_OK(result)) {
6313 result = WERR_BADFID;
6317 /* Do sanity check on the requested changes for Samba */
6318 if (!check_printer_ok(tmp_ctx, printer, snum)) {
6319 result = WERR_INVALID_PARAM;
6323 /* FIXME!!! If the driver has changed we really should verify that
6324 it is installed before doing much else --jerry */
6326 /* Check calling user has permission to update printer description */
6327 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6328 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6329 result = WERR_ACCESS_DENIED;
6333 /* Call addprinter hook */
6334 /* Check changes to see if this is really needed */
6336 if (*lp_addprinter_cmd() &&
6337 (!strequal(printer->drivername, old_printer->drivername) ||
6338 !strequal(printer->comment, old_printer->comment) ||
6339 !strequal(printer->portname, old_printer->portname) ||
6340 !strequal(printer->location, old_printer->location)) )
6342 /* add_printer_hook() will call reload_services() */
6343 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6344 printer, p->client_id->addr,
6346 result = WERR_ACCESS_DENIED;
6351 update_dsspooler(tmp_ctx,
6352 get_server_info_system(),
6358 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6360 if (devmode == NULL) {
6361 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6363 result = winreg_update_printer(tmp_ctx,
6364 get_server_info_system(),
6373 talloc_free(tmp_ctx);
6378 /****************************************************************************
6379 ****************************************************************************/
6380 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6381 struct policy_handle *handle,
6382 struct spoolss_SetPrinterInfo7 *info7)
6385 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6388 struct printer_handle *Printer;
6390 if ( lp_security() != SEC_ADS ) {
6391 return WERR_UNKNOWN_LEVEL;
6394 Printer = find_printer_index_by_hnd(p, handle);
6396 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6401 if (!get_printer_snum(p, handle, &snum, NULL))
6404 result = winreg_get_printer(p->mem_ctx,
6405 get_server_info_system(),
6407 Printer->servername,
6408 lp_servicename(snum),
6410 if (!W_ERROR_IS_OK(result)) {
6414 nt_printer_publish(pinfo2,
6415 get_server_info_system(),
6420 TALLOC_FREE(pinfo2);
6423 return WERR_UNKNOWN_LEVEL;
6427 /********************************************************************
6428 ********************************************************************/
6430 static WERROR update_printer_devmode(struct pipes_struct *p,
6431 struct policy_handle *handle,
6432 struct spoolss_DeviceMode *devmode)
6435 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6436 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6438 DEBUG(8,("update_printer_devmode\n"));
6444 if (!get_printer_snum(p, handle, &snum, NULL)) {
6448 /* Check calling user has permission to update printer description */
6449 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6450 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6451 return WERR_ACCESS_DENIED;
6454 return winreg_update_printer(p->mem_ctx,
6455 get_server_info_system(),
6457 lp_const_servicename(snum),
6465 /****************************************************************
6467 ****************************************************************/
6469 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6470 struct spoolss_SetPrinter *r)
6474 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6477 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6478 OUR_HANDLE(r->in.handle)));
6482 /* check the level */
6483 switch (r->in.info_ctr->level) {
6485 return control_printer(r->in.handle, r->in.command, p);
6487 result = update_printer(p, r->in.handle,
6489 r->in.devmode_ctr->devmode);
6490 if (!W_ERROR_IS_OK(result))
6492 if (r->in.secdesc_ctr->sd)
6493 result = update_printer_sec(r->in.handle, p,
6497 return update_printer_sec(r->in.handle, p,
6500 return publish_or_unpublish_printer(p, r->in.handle,
6501 r->in.info_ctr->info.info7);
6503 return update_printer_devmode(p, r->in.handle,
6504 r->in.devmode_ctr->devmode);
6506 return WERR_UNKNOWN_LEVEL;
6510 /****************************************************************
6511 _spoolss_FindClosePrinterNotify
6512 ****************************************************************/
6514 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6515 struct spoolss_FindClosePrinterNotify *r)
6517 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6520 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6521 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6525 if (Printer->notify.cli_chan != NULL &&
6526 Printer->notify.cli_chan->active_connections > 0) {
6529 if (Printer->printer_type == SPLHND_PRINTER) {
6530 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6535 srv_spoolss_replycloseprinter(snum, Printer);
6538 Printer->notify.flags=0;
6539 Printer->notify.options=0;
6540 Printer->notify.localmachine[0]='\0';
6541 Printer->notify.printerlocal=0;
6542 TALLOC_FREE(Printer->notify.option);
6547 /****************************************************************
6549 ****************************************************************/
6551 WERROR _spoolss_AddJob(struct pipes_struct *p,
6552 struct spoolss_AddJob *r)
6554 if (!r->in.buffer && (r->in.offered != 0)) {
6555 return WERR_INVALID_PARAM;
6558 /* this is what a NT server returns for AddJob. AddJob must fail on
6559 * non-local printers */
6561 if (r->in.level != 1) {
6562 return WERR_UNKNOWN_LEVEL;
6565 return WERR_INVALID_PARAM;
6568 /****************************************************************************
6570 ****************************************************************************/
6572 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6573 struct spoolss_JobInfo1 *r,
6574 const print_queue_struct *queue,
6575 int position, int snum,
6576 struct spoolss_PrinterInfo2 *pinfo2)
6580 t = gmtime(&queue->time);
6582 r->job_id = queue->job;
6584 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6585 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6586 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6587 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6588 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6589 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6590 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6591 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6592 r->data_type = talloc_strdup(mem_ctx, "RAW");
6593 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6594 r->text_status = talloc_strdup(mem_ctx, "");
6595 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6597 r->status = nt_printj_status(queue->status);
6598 r->priority = queue->priority;
6599 r->position = position;
6600 r->total_pages = queue->page_count;
6601 r->pages_printed = 0; /* ??? */
6603 init_systemtime(&r->submitted, t);
6608 /****************************************************************************
6610 ****************************************************************************/
6612 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6613 struct spoolss_JobInfo2 *r,
6614 const print_queue_struct *queue,
6615 int position, int snum,
6616 struct spoolss_PrinterInfo2 *pinfo2,
6617 struct spoolss_DeviceMode *devmode)
6621 t = gmtime(&queue->time);
6623 r->job_id = queue->job;
6625 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6626 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6627 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6628 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6629 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6630 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6631 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6632 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6633 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6634 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6635 r->data_type = talloc_strdup(mem_ctx, "RAW");
6636 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6637 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6638 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6639 r->parameters = talloc_strdup(mem_ctx, "");
6640 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6641 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6642 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6644 r->devmode = devmode;
6646 r->text_status = talloc_strdup(mem_ctx, "");
6647 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6651 r->status = nt_printj_status(queue->status);
6652 r->priority = queue->priority;
6653 r->position = position;
6656 r->total_pages = queue->page_count;
6657 r->size = queue->size;
6658 init_systemtime(&r->submitted, t);
6660 r->pages_printed = 0; /* ??? */
6665 /****************************************************************************
6667 ****************************************************************************/
6669 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6670 struct spoolss_JobInfo3 *r,
6671 const print_queue_struct *queue,
6672 const print_queue_struct *next_queue,
6673 int position, int snum,
6674 struct spoolss_PrinterInfo2 *pinfo2)
6676 r->job_id = queue->job;
6679 r->next_job_id = next_queue->job;
6686 /****************************************************************************
6687 Enumjobs at level 1.
6688 ****************************************************************************/
6690 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6691 const print_queue_struct *queue,
6692 uint32_t num_queues, int snum,
6693 struct spoolss_PrinterInfo2 *pinfo2,
6694 union spoolss_JobInfo **info_p,
6697 union spoolss_JobInfo *info;
6699 WERROR result = WERR_OK;
6701 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6702 W_ERROR_HAVE_NO_MEMORY(info);
6704 *count = num_queues;
6706 for (i=0; i<*count; i++) {
6707 result = fill_job_info1(info,
6713 if (!W_ERROR_IS_OK(result)) {
6719 if (!W_ERROR_IS_OK(result)) {
6730 /****************************************************************************
6731 Enumjobs at level 2.
6732 ****************************************************************************/
6734 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6735 const print_queue_struct *queue,
6736 uint32_t num_queues, int snum,
6737 struct spoolss_PrinterInfo2 *pinfo2,
6738 union spoolss_JobInfo **info_p,
6741 union spoolss_JobInfo *info;
6743 WERROR result = WERR_OK;
6745 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6746 W_ERROR_HAVE_NO_MEMORY(info);
6748 *count = num_queues;
6750 for (i=0; i<*count; i++) {
6751 struct spoolss_DeviceMode *devmode;
6753 result = spoolss_create_default_devmode(info,
6754 pinfo2->printername,
6756 if (!W_ERROR_IS_OK(result)) {
6757 DEBUG(3, ("Can't proceed w/o a devmode!"));
6761 result = fill_job_info2(info,
6768 if (!W_ERROR_IS_OK(result)) {
6774 if (!W_ERROR_IS_OK(result)) {
6785 /****************************************************************************
6786 Enumjobs at level 3.
6787 ****************************************************************************/
6789 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6790 const print_queue_struct *queue,
6791 uint32_t num_queues, int snum,
6792 struct spoolss_PrinterInfo2 *pinfo2,
6793 union spoolss_JobInfo **info_p,
6796 union spoolss_JobInfo *info;
6798 WERROR result = WERR_OK;
6800 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6801 W_ERROR_HAVE_NO_MEMORY(info);
6803 *count = num_queues;
6805 for (i=0; i<*count; i++) {
6806 const print_queue_struct *next_queue = NULL;
6809 next_queue = &queue[i+1];
6812 result = fill_job_info3(info,
6819 if (!W_ERROR_IS_OK(result)) {
6825 if (!W_ERROR_IS_OK(result)) {
6836 /****************************************************************
6838 ****************************************************************/
6840 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6841 struct spoolss_EnumJobs *r)
6844 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6846 print_status_struct prt_status;
6847 print_queue_struct *queue = NULL;
6850 /* that's an [in out] buffer */
6852 if (!r->in.buffer && (r->in.offered != 0)) {
6853 return WERR_INVALID_PARAM;
6856 DEBUG(4,("_spoolss_EnumJobs\n"));
6860 *r->out.info = NULL;
6862 /* lookup the printer snum and tdb entry */
6864 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6868 result = winreg_get_printer(p->mem_ctx,
6869 get_server_info_system(),
6872 lp_const_servicename(snum),
6874 if (!W_ERROR_IS_OK(result)) {
6878 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
6879 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6880 count, prt_status.status, prt_status.message));
6884 TALLOC_FREE(pinfo2);
6888 switch (r->in.level) {
6890 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6891 pinfo2, r->out.info, r->out.count);
6894 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6895 pinfo2, r->out.info, r->out.count);
6898 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6899 pinfo2, r->out.info, r->out.count);
6902 result = WERR_UNKNOWN_LEVEL;
6907 TALLOC_FREE(pinfo2);
6909 if (!W_ERROR_IS_OK(result)) {
6913 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6915 *r->out.info, r->in.level,
6917 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6918 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6920 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6923 /****************************************************************
6924 _spoolss_ScheduleJob
6925 ****************************************************************/
6927 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6928 struct spoolss_ScheduleJob *r)
6933 /****************************************************************
6934 ****************************************************************/
6936 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6937 struct messaging_context *msg_ctx,
6938 const char *printer_name,
6940 struct spoolss_SetJobInfo1 *r)
6944 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6948 if (strequal(old_doc_name, r->document_name)) {
6952 if (!print_job_set_name(server_event_context(), msg_ctx,
6953 printer_name, job_id, r->document_name)) {
6960 /****************************************************************
6962 ****************************************************************/
6964 WERROR _spoolss_SetJob(struct pipes_struct *p,
6965 struct spoolss_SetJob *r)
6967 const struct auth_serversupplied_info *server_info = get_server_info_system();
6969 WERROR errcode = WERR_BADFUNC;
6971 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6975 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6976 return WERR_INVALID_PRINTER_NAME;
6979 switch (r->in.command) {
6980 case SPOOLSS_JOB_CONTROL_CANCEL:
6981 case SPOOLSS_JOB_CONTROL_DELETE:
6982 errcode = print_job_delete(server_info, p->msg_ctx,
6983 snum, r->in.job_id);
6984 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6988 case SPOOLSS_JOB_CONTROL_PAUSE:
6989 if (print_job_pause(server_info, p->msg_ctx,
6990 snum, r->in.job_id, &errcode)) {
6994 case SPOOLSS_JOB_CONTROL_RESTART:
6995 case SPOOLSS_JOB_CONTROL_RESUME:
6996 if (print_job_resume(server_info, p->msg_ctx,
6997 snum, r->in.job_id, &errcode)) {
7005 return WERR_UNKNOWN_LEVEL;
7008 if (!W_ERROR_IS_OK(errcode)) {
7012 if (r->in.ctr == NULL) {
7016 switch (r->in.ctr->level) {
7018 errcode = spoolss_setjob_1(p->mem_ctx, p->msg_ctx,
7019 lp_const_servicename(snum),
7021 r->in.ctr->info.info1);
7027 return WERR_UNKNOWN_LEVEL;
7033 /****************************************************************************
7034 Enumerates all printer drivers by level and architecture.
7035 ****************************************************************************/
7037 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
7038 const struct auth_serversupplied_info *server_info,
7039 struct messaging_context *msg_ctx,
7040 const char *servername,
7041 const char *architecture,
7043 union spoolss_DriverInfo **info_p,
7048 struct spoolss_DriverInfo8 *driver;
7049 union spoolss_DriverInfo *info = NULL;
7051 WERROR result = WERR_OK;
7052 uint32_t num_drivers;
7053 const char **drivers;
7058 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7059 result = winreg_get_driver_list(mem_ctx, server_info, msg_ctx,
7060 architecture, version,
7061 &num_drivers, &drivers);
7062 if (!W_ERROR_IS_OK(result)) {
7065 DEBUG(4, ("we have:[%d] drivers in environment"
7066 " [%s] and version [%d]\n",
7067 num_drivers, architecture, version));
7069 if (num_drivers != 0) {
7070 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
7071 union spoolss_DriverInfo,
7072 count + num_drivers);
7074 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
7075 "failed to enlarge driver info buffer!\n"));
7076 result = WERR_NOMEM;
7081 for (i = 0; i < num_drivers; i++) {
7082 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
7084 result = winreg_get_driver(mem_ctx, server_info,
7086 architecture, drivers[i],
7088 if (!W_ERROR_IS_OK(result)) {
7094 result = fill_printer_driver_info1(info, &info[count+i].info1,
7095 driver, servername);
7098 result = fill_printer_driver_info2(info, &info[count+i].info2,
7099 driver, servername);
7102 result = fill_printer_driver_info3(info, &info[count+i].info3,
7103 driver, servername);
7106 result = fill_printer_driver_info4(info, &info[count+i].info4,
7107 driver, servername);
7110 result = fill_printer_driver_info5(info, &info[count+i].info5,
7111 driver, servername);
7114 result = fill_printer_driver_info6(info, &info[count+i].info6,
7115 driver, servername);
7118 result = fill_printer_driver_info8(info, &info[count+i].info8,
7119 driver, servername);
7122 result = WERR_UNKNOWN_LEVEL;
7126 TALLOC_FREE(driver);
7128 if (!W_ERROR_IS_OK(result)) {
7133 count += num_drivers;
7134 TALLOC_FREE(drivers);
7138 TALLOC_FREE(drivers);
7140 if (!W_ERROR_IS_OK(result)) {
7151 /****************************************************************************
7152 Enumerates all printer drivers by level.
7153 ****************************************************************************/
7155 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
7156 const struct auth_serversupplied_info *server_info,
7157 struct messaging_context *msg_ctx,
7158 const char *servername,
7159 const char *architecture,
7161 union spoolss_DriverInfo **info_p,
7165 WERROR result = WERR_OK;
7167 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
7169 for (a=0; archi_table[a].long_archi != NULL; a++) {
7171 union spoolss_DriverInfo *info = NULL;
7174 result = enumprinterdrivers_level_by_architecture(mem_ctx,
7178 archi_table[a].long_archi,
7182 if (!W_ERROR_IS_OK(result)) {
7186 for (i=0; i < count; i++) {
7187 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
7188 info[i], info_p, count_p);
7195 return enumprinterdrivers_level_by_architecture(mem_ctx,
7205 /****************************************************************
7206 _spoolss_EnumPrinterDrivers
7207 ****************************************************************/
7209 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
7210 struct spoolss_EnumPrinterDrivers *r)
7212 const char *cservername;
7215 /* that's an [in out] buffer */
7217 if (!r->in.buffer && (r->in.offered != 0)) {
7218 return WERR_INVALID_PARAM;
7221 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
7225 *r->out.info = NULL;
7227 cservername = canon_servername(r->in.server);
7229 if (!is_myname_or_ipaddr(cservername)) {
7230 return WERR_UNKNOWN_PRINTER_DRIVER;
7233 result = enumprinterdrivers_level(p->mem_ctx,
7234 get_server_info_system(),
7241 if (!W_ERROR_IS_OK(result)) {
7245 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7246 spoolss_EnumPrinterDrivers,
7247 *r->out.info, r->in.level,
7249 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7250 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7252 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7255 /****************************************************************
7257 ****************************************************************/
7259 WERROR _spoolss_EnumForms(struct pipes_struct *p,
7260 struct spoolss_EnumForms *r)
7266 *r->out.info = NULL;
7268 /* that's an [in out] buffer */
7270 if (!r->in.buffer && (r->in.offered != 0) ) {
7271 return WERR_INVALID_PARAM;
7274 DEBUG(4,("_spoolss_EnumForms\n"));
7275 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7276 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7278 switch (r->in.level) {
7280 result = winreg_printer_enumforms1(p->mem_ctx,
7281 get_server_info_system(),
7287 result = WERR_UNKNOWN_LEVEL;
7291 if (!W_ERROR_IS_OK(result)) {
7295 if (*r->out.count == 0) {
7296 return WERR_NO_MORE_ITEMS;
7299 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7301 *r->out.info, r->in.level,
7303 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7304 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7306 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7309 /****************************************************************
7311 ****************************************************************/
7313 WERROR _spoolss_GetForm(struct pipes_struct *p,
7314 struct spoolss_GetForm *r)
7318 /* that's an [in out] buffer */
7320 if (!r->in.buffer && (r->in.offered != 0)) {
7321 return WERR_INVALID_PARAM;
7324 DEBUG(4,("_spoolss_GetForm\n"));
7325 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7326 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7328 switch (r->in.level) {
7330 result = winreg_printer_getform1(p->mem_ctx,
7331 get_server_info_system(),
7334 &r->out.info->info1);
7337 result = WERR_UNKNOWN_LEVEL;
7341 if (!W_ERROR_IS_OK(result)) {
7342 TALLOC_FREE(r->out.info);
7346 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
7347 r->out.info, r->in.level);
7348 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7350 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7353 /****************************************************************************
7354 ****************************************************************************/
7356 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
7357 struct spoolss_PortInfo1 *r,
7360 r->port_name = talloc_strdup(mem_ctx, name);
7361 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7366 /****************************************************************************
7367 TODO: This probably needs distinguish between TCP/IP and Local ports
7369 ****************************************************************************/
7371 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7372 struct spoolss_PortInfo2 *r,
7375 r->port_name = talloc_strdup(mem_ctx, name);
7376 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7378 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7379 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7381 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7382 W_ERROR_HAVE_NO_MEMORY(r->description);
7384 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7391 /****************************************************************************
7392 wrapper around the enumer ports command
7393 ****************************************************************************/
7395 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7397 char *cmd = lp_enumports_cmd();
7398 char **qlines = NULL;
7399 char *command = NULL;
7407 /* if no hook then just fill in the default port */
7410 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7413 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7414 TALLOC_FREE(qlines);
7421 /* we have a valid enumport command */
7423 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7428 DEBUG(10,("Running [%s]\n", command));
7429 ret = smbrun(command, &fd);
7430 DEBUG(10,("Returned [%d]\n", ret));
7431 TALLOC_FREE(command);
7436 return WERR_ACCESS_DENIED;
7440 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7441 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7451 /****************************************************************************
7453 ****************************************************************************/
7455 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7456 union spoolss_PortInfo **info_p,
7459 union spoolss_PortInfo *info = NULL;
7461 WERROR result = WERR_OK;
7462 char **qlines = NULL;
7465 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7466 if (!W_ERROR_IS_OK(result)) {
7471 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7473 DEBUG(10,("Returning WERR_NOMEM\n"));
7474 result = WERR_NOMEM;
7478 for (i=0; i<numlines; i++) {
7479 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7480 result = fill_port_1(info, &info[i].info1, qlines[i]);
7481 if (!W_ERROR_IS_OK(result)) {
7486 TALLOC_FREE(qlines);
7489 if (!W_ERROR_IS_OK(result)) {
7491 TALLOC_FREE(qlines);
7503 /****************************************************************************
7505 ****************************************************************************/
7507 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7508 union spoolss_PortInfo **info_p,
7511 union spoolss_PortInfo *info = NULL;
7513 WERROR result = WERR_OK;
7514 char **qlines = NULL;
7517 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7518 if (!W_ERROR_IS_OK(result)) {
7523 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7525 DEBUG(10,("Returning WERR_NOMEM\n"));
7526 result = WERR_NOMEM;
7530 for (i=0; i<numlines; i++) {
7531 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7532 result = fill_port_2(info, &info[i].info2, qlines[i]);
7533 if (!W_ERROR_IS_OK(result)) {
7538 TALLOC_FREE(qlines);
7541 if (!W_ERROR_IS_OK(result)) {
7543 TALLOC_FREE(qlines);
7555 /****************************************************************
7557 ****************************************************************/
7559 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7560 struct spoolss_EnumPorts *r)
7564 /* that's an [in out] buffer */
7566 if (!r->in.buffer && (r->in.offered != 0)) {
7567 return WERR_INVALID_PARAM;
7570 DEBUG(4,("_spoolss_EnumPorts\n"));
7574 *r->out.info = NULL;
7576 switch (r->in.level) {
7578 result = enumports_level_1(p->mem_ctx, r->out.info,
7582 result = enumports_level_2(p->mem_ctx, r->out.info,
7586 return WERR_UNKNOWN_LEVEL;
7589 if (!W_ERROR_IS_OK(result)) {
7593 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7595 *r->out.info, r->in.level,
7597 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7598 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7600 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7603 /****************************************************************************
7604 ****************************************************************************/
7606 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7608 struct spoolss_SetPrinterInfoCtr *info_ctr,
7609 struct spoolss_DeviceMode *devmode,
7610 struct security_descriptor *secdesc,
7611 struct spoolss_UserLevelCtr *user_ctr,
7612 struct policy_handle *handle)
7614 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7615 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7617 WERROR err = WERR_OK;
7619 /* samba does not have a concept of local, non-shared printers yet, so
7620 * make sure we always setup sharename - gd */
7621 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7622 (info2->printername != NULL && info2->printername[0] != '\0')) {
7623 DEBUG(5, ("spoolss_addprinterex_level_2: "
7624 "no sharename has been set, setting printername %s as sharename\n",
7625 info2->printername));
7626 info2->sharename = info2->printername;
7629 /* check to see if the printer already exists */
7630 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7631 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7633 return WERR_PRINTER_ALREADY_EXISTS;
7636 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7637 if ((snum = print_queue_snum(info2->printername)) != -1) {
7638 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7639 info2->printername));
7640 return WERR_PRINTER_ALREADY_EXISTS;
7644 /* validate printer info struct */
7645 if (!info2->printername || strlen(info2->printername) == 0) {
7646 return WERR_INVALID_PRINTER_NAME;
7648 if (!info2->portname || strlen(info2->portname) == 0) {
7649 return WERR_UNKNOWN_PORT;
7651 if (!info2->drivername || strlen(info2->drivername) == 0) {
7652 return WERR_UNKNOWN_PRINTER_DRIVER;
7654 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7655 return WERR_UNKNOWN_PRINTPROCESSOR;
7658 /* FIXME!!! smbd should check to see if the driver is installed before
7659 trying to add a printer like this --jerry */
7661 if (*lp_addprinter_cmd() ) {
7662 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7663 info2, p->client_id->addr,
7665 return WERR_ACCESS_DENIED;
7668 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7669 "smb.conf parameter \"addprinter command\" is defined. This"
7670 "parameter must exist for this call to succeed\n",
7671 info2->sharename ));
7674 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7675 return WERR_ACCESS_DENIED;
7678 /* you must be a printer admin to add a new printer */
7679 if (!print_access_check(get_server_info_system(),
7682 PRINTER_ACCESS_ADMINISTER)) {
7683 return WERR_ACCESS_DENIED;
7687 * Do sanity check on the requested changes for Samba.
7690 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7691 return WERR_INVALID_PARAM;
7694 if (devmode == NULL) {
7695 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7698 update_dsspooler(p->mem_ctx,
7699 get_server_info_system(),
7705 err = winreg_update_printer(p->mem_ctx,
7706 get_server_info_system(),
7713 if (!W_ERROR_IS_OK(err)) {
7717 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7718 /* Handle open failed - remove addition. */
7719 ZERO_STRUCTP(handle);
7720 return WERR_ACCESS_DENIED;
7726 /****************************************************************
7727 _spoolss_AddPrinterEx
7728 ****************************************************************/
7730 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7731 struct spoolss_AddPrinterEx *r)
7733 switch (r->in.info_ctr->level) {
7735 /* we don't handle yet */
7736 /* but I know what to do ... */
7737 return WERR_UNKNOWN_LEVEL;
7739 return spoolss_addprinterex_level_2(p, r->in.server,
7741 r->in.devmode_ctr->devmode,
7742 r->in.secdesc_ctr->sd,
7743 r->in.userlevel_ctr,
7746 return WERR_UNKNOWN_LEVEL;
7750 /****************************************************************
7752 ****************************************************************/
7754 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7755 struct spoolss_AddPrinter *r)
7757 struct spoolss_AddPrinterEx a;
7758 struct spoolss_UserLevelCtr userlevel_ctr;
7760 ZERO_STRUCT(userlevel_ctr);
7762 userlevel_ctr.level = 1;
7764 a.in.server = r->in.server;
7765 a.in.info_ctr = r->in.info_ctr;
7766 a.in.devmode_ctr = r->in.devmode_ctr;
7767 a.in.secdesc_ctr = r->in.secdesc_ctr;
7768 a.in.userlevel_ctr = &userlevel_ctr;
7769 a.out.handle = r->out.handle;
7771 return _spoolss_AddPrinterEx(p, &a);
7774 /****************************************************************
7775 _spoolss_AddPrinterDriverEx
7776 ****************************************************************/
7778 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7779 struct spoolss_AddPrinterDriverEx *r)
7781 WERROR err = WERR_OK;
7782 const char *driver_name = NULL;
7787 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7788 fn = "_spoolss_AddPrinterDriver";
7790 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7791 fn = "_spoolss_AddPrinterDriverEx";
7794 return WERR_INVALID_PARAM;
7798 * we only support the semantics of AddPrinterDriver()
7799 * i.e. only copy files that are newer than existing ones
7802 if (r->in.flags == 0) {
7803 return WERR_INVALID_PARAM;
7806 if (r->in.flags != APD_COPY_NEW_FILES) {
7807 return WERR_ACCESS_DENIED;
7811 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7812 /* Clever hack from Martin Zielinski <mz@seh.de>
7813 * to allow downgrade from level 8 (Vista).
7815 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7816 r->in.info_ctr->level));
7817 return WERR_UNKNOWN_LEVEL;
7820 DEBUG(5,("Cleaning driver's information\n"));
7821 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7822 if (!W_ERROR_IS_OK(err))
7825 DEBUG(5,("Moving driver to final destination\n"));
7826 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7831 err = winreg_add_driver(p->mem_ctx,
7832 get_server_info_system(),
7837 if (!W_ERROR_IS_OK(err)) {
7842 * I think this is where he DrvUpgradePrinter() hook would be
7843 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7844 * server. Right now, we just need to send ourselves a message
7845 * to update each printer bound to this driver. --jerry
7848 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7849 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7857 /****************************************************************
7858 _spoolss_AddPrinterDriver
7859 ****************************************************************/
7861 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7862 struct spoolss_AddPrinterDriver *r)
7864 struct spoolss_AddPrinterDriverEx a;
7866 switch (r->in.info_ctr->level) {
7873 return WERR_UNKNOWN_LEVEL;
7876 a.in.servername = r->in.servername;
7877 a.in.info_ctr = r->in.info_ctr;
7878 a.in.flags = APD_COPY_NEW_FILES;
7880 return _spoolss_AddPrinterDriverEx(p, &a);
7883 /****************************************************************************
7884 ****************************************************************************/
7886 struct _spoolss_paths {
7892 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7894 static const struct _spoolss_paths spoolss_paths[]= {
7895 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7896 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7899 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7900 const char *servername,
7901 const char *environment,
7905 const char *pservername = NULL;
7906 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7907 const char *short_archi;
7911 /* environment may be empty */
7912 if (environment && strlen(environment)) {
7913 long_archi = environment;
7916 /* servername may be empty */
7917 if (servername && strlen(servername)) {
7918 pservername = canon_servername(servername);
7920 if (!is_myname_or_ipaddr(pservername)) {
7921 return WERR_INVALID_PARAM;
7925 if (!(short_archi = get_short_archi(long_archi))) {
7926 return WERR_INVALID_ENVIRONMENT;
7929 switch (component) {
7930 case SPOOLSS_PRTPROCS_PATH:
7931 case SPOOLSS_DRIVER_PATH:
7933 *path = talloc_asprintf(mem_ctx,
7936 spoolss_paths[component].share,
7939 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7940 SPOOLSS_DEFAULT_SERVER_PATH,
7941 spoolss_paths[component].dir,
7946 return WERR_INVALID_PARAM;
7956 /****************************************************************************
7957 ****************************************************************************/
7959 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7960 const char *servername,
7961 const char *environment,
7962 struct spoolss_DriverDirectoryInfo1 *r)
7967 werr = compose_spoolss_server_path(mem_ctx,
7970 SPOOLSS_DRIVER_PATH,
7972 if (!W_ERROR_IS_OK(werr)) {
7976 DEBUG(4,("printer driver directory: [%s]\n", path));
7978 r->directory_name = path;
7983 /****************************************************************
7984 _spoolss_GetPrinterDriverDirectory
7985 ****************************************************************/
7987 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7988 struct spoolss_GetPrinterDriverDirectory *r)
7992 /* that's an [in out] buffer */
7994 if (!r->in.buffer && (r->in.offered != 0)) {
7995 return WERR_INVALID_PARAM;
7998 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
8003 /* r->in.level is ignored */
8005 werror = getprinterdriverdir_level_1(p->mem_ctx,
8008 &r->out.info->info1);
8009 if (!W_ERROR_IS_OK(werror)) {
8010 TALLOC_FREE(r->out.info);
8014 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
8015 r->out.info, r->in.level);
8016 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8018 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8021 /****************************************************************
8022 _spoolss_EnumPrinterData
8023 ****************************************************************/
8025 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
8026 struct spoolss_EnumPrinterData *r)
8029 struct spoolss_EnumPrinterDataEx r2;
8031 struct spoolss_PrinterEnumValues *info, *val = NULL;
8034 r2.in.handle = r->in.handle;
8035 r2.in.key_name = "PrinterDriverData";
8037 r2.out.count = &count;
8038 r2.out.info = &info;
8039 r2.out.needed = &needed;
8041 result = _spoolss_EnumPrinterDataEx(p, &r2);
8042 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8043 r2.in.offered = needed;
8044 result = _spoolss_EnumPrinterDataEx(p, &r2);
8046 if (!W_ERROR_IS_OK(result)) {
8051 * The NT machine wants to know the biggest size of value and data
8053 * cf: MSDN EnumPrinterData remark section
8056 if (!r->in.value_offered && !r->in.data_offered) {
8057 uint32_t biggest_valuesize = 0;
8058 uint32_t biggest_datasize = 0;
8061 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8063 for (i=0; i<count; i++) {
8065 name_length = strlen(info[i].value_name);
8066 if (strlen(info[i].value_name) > biggest_valuesize) {
8067 biggest_valuesize = name_length;
8070 if (info[i].data_length > biggest_datasize) {
8071 biggest_datasize = info[i].data_length;
8074 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8078 /* the value is an UNICODE string but real_value_size is the length
8079 in bytes including the trailing 0 */
8081 *r->out.value_needed = 2 * (1 + biggest_valuesize);
8082 *r->out.data_needed = biggest_datasize;
8084 DEBUG(6,("final values: [%d], [%d]\n",
8085 *r->out.value_needed, *r->out.data_needed));
8090 if (r->in.enum_index < count) {
8091 val = &info[r->in.enum_index];
8095 /* out_value should default to "" or else NT4 has
8096 problems unmarshalling the response */
8098 if (r->in.value_offered) {
8099 *r->out.value_needed = 1;
8100 r->out.value_name = talloc_strdup(r, "");
8101 if (!r->out.value_name) {
8105 r->out.value_name = NULL;
8106 *r->out.value_needed = 0;
8109 /* the data is counted in bytes */
8111 *r->out.data_needed = r->in.data_offered;
8113 result = WERR_NO_MORE_ITEMS;
8117 * - counted in bytes in the request
8118 * - counted in UNICODE chars in the max reply
8119 * - counted in bytes in the real size
8121 * take a pause *before* coding not *during* coding
8125 if (r->in.value_offered) {
8126 r->out.value_name = talloc_strdup(r, val->value_name);
8127 if (!r->out.value_name) {
8130 *r->out.value_needed = val->value_name_len;
8132 r->out.value_name = NULL;
8133 *r->out.value_needed = 0;
8138 *r->out.type = val->type;
8140 /* data - counted in bytes */
8143 * See the section "Dynamically Typed Query Parameters"
8147 if (r->out.data && val->data && val->data->data &&
8148 val->data_length && r->in.data_offered) {
8149 memcpy(r->out.data, val->data->data,
8150 MIN(val->data_length,r->in.data_offered));
8153 *r->out.data_needed = val->data_length;
8161 /****************************************************************
8162 _spoolss_SetPrinterData
8163 ****************************************************************/
8165 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
8166 struct spoolss_SetPrinterData *r)
8168 struct spoolss_SetPrinterDataEx r2;
8170 r2.in.handle = r->in.handle;
8171 r2.in.key_name = "PrinterDriverData";
8172 r2.in.value_name = r->in.value_name;
8173 r2.in.type = r->in.type;
8174 r2.in.data = r->in.data;
8175 r2.in.offered = r->in.offered;
8177 return _spoolss_SetPrinterDataEx(p, &r2);
8180 /****************************************************************
8181 _spoolss_ResetPrinter
8182 ****************************************************************/
8184 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
8185 struct spoolss_ResetPrinter *r)
8187 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8190 DEBUG(5,("_spoolss_ResetPrinter\n"));
8193 * All we do is to check to see if the handle and queue is valid.
8194 * This call really doesn't mean anything to us because we only
8195 * support RAW printing. --jerry
8199 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8200 OUR_HANDLE(r->in.handle)));
8204 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8208 /* blindly return success */
8212 /****************************************************************
8213 _spoolss_DeletePrinterData
8214 ****************************************************************/
8216 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
8217 struct spoolss_DeletePrinterData *r)
8219 struct spoolss_DeletePrinterDataEx r2;
8221 r2.in.handle = r->in.handle;
8222 r2.in.key_name = "PrinterDriverData";
8223 r2.in.value_name = r->in.value_name;
8225 return _spoolss_DeletePrinterDataEx(p, &r2);
8228 /****************************************************************
8230 ****************************************************************/
8232 WERROR _spoolss_AddForm(struct pipes_struct *p,
8233 struct spoolss_AddForm *r)
8235 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8237 WERROR status = WERR_OK;
8238 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8240 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8242 DEBUG(5,("_spoolss_AddForm\n"));
8245 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8246 OUR_HANDLE(r->in.handle)));
8250 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8251 and not a printer admin, then fail */
8253 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8254 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8255 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8256 p->server_info->info3->base.domain.string,
8258 p->server_info->ptok,
8259 lp_printer_admin(snum))) {
8260 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
8261 return WERR_ACCESS_DENIED;
8264 switch (form->flags) {
8265 case SPOOLSS_FORM_USER:
8266 case SPOOLSS_FORM_BUILTIN:
8267 case SPOOLSS_FORM_PRINTER:
8270 return WERR_INVALID_PARAM;
8273 status = winreg_printer_addform1(p->mem_ctx,
8274 get_server_info_system(),
8277 if (!W_ERROR_IS_OK(status)) {
8282 * ChangeID must always be set if this is a printer
8284 if (Printer->printer_type == SPLHND_PRINTER) {
8285 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8289 status = winreg_printer_update_changeid(p->mem_ctx,
8290 get_server_info_system(),
8292 lp_const_servicename(snum));
8293 if (!W_ERROR_IS_OK(status)) {
8301 /****************************************************************
8303 ****************************************************************/
8305 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
8306 struct spoolss_DeleteForm *r)
8308 const char *form_name = r->in.form_name;
8309 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8311 WERROR status = WERR_OK;
8312 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8314 DEBUG(5,("_spoolss_DeleteForm\n"));
8317 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8318 OUR_HANDLE(r->in.handle)));
8322 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8323 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8324 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8325 p->server_info->info3->base.domain.string,
8327 p->server_info->ptok,
8328 lp_printer_admin(snum))) {
8329 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8330 return WERR_ACCESS_DENIED;
8333 status = winreg_printer_deleteform1(p->mem_ctx,
8334 get_server_info_system(),
8337 if (!W_ERROR_IS_OK(status)) {
8342 * ChangeID must always be set if this is a printer
8344 if (Printer->printer_type == SPLHND_PRINTER) {
8345 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8349 status = winreg_printer_update_changeid(p->mem_ctx,
8350 get_server_info_system(),
8352 lp_const_servicename(snum));
8353 if (!W_ERROR_IS_OK(status)) {
8361 /****************************************************************
8363 ****************************************************************/
8365 WERROR _spoolss_SetForm(struct pipes_struct *p,
8366 struct spoolss_SetForm *r)
8368 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8369 const char *form_name = r->in.form_name;
8371 WERROR status = WERR_OK;
8372 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8374 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8376 DEBUG(5,("_spoolss_SetForm\n"));
8379 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8380 OUR_HANDLE(r->in.handle)));
8384 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8385 and not a printer admin, then fail */
8387 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8388 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8389 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8390 p->server_info->info3->base.domain.string,
8392 p->server_info->ptok,
8393 lp_printer_admin(snum))) {
8394 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8395 return WERR_ACCESS_DENIED;
8398 status = winreg_printer_setform1(p->mem_ctx,
8399 get_server_info_system(),
8403 if (!W_ERROR_IS_OK(status)) {
8408 * ChangeID must always be set if this is a printer
8410 if (Printer->printer_type == SPLHND_PRINTER) {
8411 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8415 status = winreg_printer_update_changeid(p->mem_ctx,
8416 get_server_info_system(),
8418 lp_const_servicename(snum));
8419 if (!W_ERROR_IS_OK(status)) {
8427 /****************************************************************************
8428 fill_print_processor1
8429 ****************************************************************************/
8431 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8432 struct spoolss_PrintProcessorInfo1 *r,
8433 const char *print_processor_name)
8435 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8436 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8441 /****************************************************************************
8442 enumprintprocessors level 1.
8443 ****************************************************************************/
8445 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8446 union spoolss_PrintProcessorInfo **info_p,
8449 union spoolss_PrintProcessorInfo *info;
8452 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8453 W_ERROR_HAVE_NO_MEMORY(info);
8457 result = fill_print_processor1(info, &info[0].info1, "winprint");
8458 if (!W_ERROR_IS_OK(result)) {
8463 if (!W_ERROR_IS_OK(result)) {
8474 /****************************************************************
8475 _spoolss_EnumPrintProcessors
8476 ****************************************************************/
8478 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8479 struct spoolss_EnumPrintProcessors *r)
8483 /* that's an [in out] buffer */
8485 if (!r->in.buffer && (r->in.offered != 0)) {
8486 return WERR_INVALID_PARAM;
8489 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8492 * Enumerate the print processors ...
8494 * Just reply with "winprint", to keep NT happy
8495 * and I can use my nice printer checker.
8500 *r->out.info = NULL;
8502 switch (r->in.level) {
8504 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8508 return WERR_UNKNOWN_LEVEL;
8511 if (!W_ERROR_IS_OK(result)) {
8515 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8516 spoolss_EnumPrintProcessors,
8517 *r->out.info, r->in.level,
8519 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8520 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8522 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8525 /****************************************************************************
8526 fill_printprocdatatype1
8527 ****************************************************************************/
8529 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8530 struct spoolss_PrintProcDataTypesInfo1 *r,
8531 const char *name_array)
8533 r->name_array = talloc_strdup(mem_ctx, name_array);
8534 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8539 /****************************************************************************
8540 enumprintprocdatatypes level 1.
8541 ****************************************************************************/
8543 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8544 union spoolss_PrintProcDataTypesInfo **info_p,
8548 union spoolss_PrintProcDataTypesInfo *info;
8550 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8551 W_ERROR_HAVE_NO_MEMORY(info);
8555 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8556 if (!W_ERROR_IS_OK(result)) {
8561 if (!W_ERROR_IS_OK(result)) {
8572 /****************************************************************
8573 _spoolss_EnumPrintProcDataTypes
8574 ****************************************************************/
8576 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8577 struct spoolss_EnumPrintProcDataTypes *r)
8581 /* that's an [in out] buffer */
8583 if (!r->in.buffer && (r->in.offered != 0)) {
8584 return WERR_INVALID_PARAM;
8587 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8591 *r->out.info = NULL;
8593 switch (r->in.level) {
8595 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8599 return WERR_UNKNOWN_LEVEL;
8602 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8603 spoolss_EnumPrintProcDataTypes,
8604 *r->out.info, r->in.level,
8606 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8607 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8609 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8612 /****************************************************************************
8614 ****************************************************************************/
8616 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8617 struct spoolss_MonitorInfo1 *r,
8618 const char *monitor_name)
8620 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8621 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8626 /****************************************************************************
8628 ****************************************************************************/
8630 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8631 struct spoolss_MonitorInfo2 *r,
8632 const char *monitor_name,
8633 const char *environment,
8634 const char *dll_name)
8636 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8637 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8638 r->environment = talloc_strdup(mem_ctx, environment);
8639 W_ERROR_HAVE_NO_MEMORY(r->environment);
8640 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8641 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8646 /****************************************************************************
8647 enumprintmonitors level 1.
8648 ****************************************************************************/
8650 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8651 union spoolss_MonitorInfo **info_p,
8654 union spoolss_MonitorInfo *info;
8655 WERROR result = WERR_OK;
8657 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8658 W_ERROR_HAVE_NO_MEMORY(info);
8662 result = fill_monitor_1(info, &info[0].info1,
8664 if (!W_ERROR_IS_OK(result)) {
8668 result = fill_monitor_1(info, &info[1].info1,
8670 if (!W_ERROR_IS_OK(result)) {
8675 if (!W_ERROR_IS_OK(result)) {
8686 /****************************************************************************
8687 enumprintmonitors level 2.
8688 ****************************************************************************/
8690 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8691 union spoolss_MonitorInfo **info_p,
8694 union spoolss_MonitorInfo *info;
8695 WERROR result = WERR_OK;
8697 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8698 W_ERROR_HAVE_NO_MEMORY(info);
8702 result = fill_monitor_2(info, &info[0].info2,
8704 "Windows NT X86", /* FIXME */
8706 if (!W_ERROR_IS_OK(result)) {
8710 result = fill_monitor_2(info, &info[1].info2,
8712 "Windows NT X86", /* FIXME */
8714 if (!W_ERROR_IS_OK(result)) {
8719 if (!W_ERROR_IS_OK(result)) {
8730 /****************************************************************
8731 _spoolss_EnumMonitors
8732 ****************************************************************/
8734 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8735 struct spoolss_EnumMonitors *r)
8739 /* that's an [in out] buffer */
8741 if (!r->in.buffer && (r->in.offered != 0)) {
8742 return WERR_INVALID_PARAM;
8745 DEBUG(5,("_spoolss_EnumMonitors\n"));
8748 * Enumerate the print monitors ...
8750 * Just reply with "Local Port", to keep NT happy
8751 * and I can use my nice printer checker.
8756 *r->out.info = NULL;
8758 switch (r->in.level) {
8760 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8764 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8768 return WERR_UNKNOWN_LEVEL;
8771 if (!W_ERROR_IS_OK(result)) {
8775 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8776 spoolss_EnumMonitors,
8777 *r->out.info, r->in.level,
8779 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8780 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8782 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8785 /****************************************************************************
8786 ****************************************************************************/
8788 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8789 const print_queue_struct *queue,
8790 int count, int snum,
8791 struct spoolss_PrinterInfo2 *pinfo2,
8793 struct spoolss_JobInfo1 *r)
8798 for (i=0; i<count; i++) {
8799 if (queue[i].job == (int)jobid) {
8805 if (found == false) {
8806 /* NT treats not found as bad param... yet another bad choice */
8807 return WERR_INVALID_PARAM;
8810 return fill_job_info1(mem_ctx,
8818 /****************************************************************************
8819 ****************************************************************************/
8821 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8822 const print_queue_struct *queue,
8823 int count, int snum,
8824 struct spoolss_PrinterInfo2 *pinfo2,
8826 struct spoolss_JobInfo2 *r)
8830 struct spoolss_DeviceMode *devmode;
8833 for (i=0; i<count; i++) {
8834 if (queue[i].job == (int)jobid) {
8840 if (found == false) {
8841 /* NT treats not found as bad param... yet another bad
8843 return WERR_INVALID_PARAM;
8847 * if the print job does not have a DEVMODE associated with it,
8848 * just use the one for the printer. A NULL devicemode is not
8849 * a failure condition
8852 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8854 result = spoolss_create_default_devmode(mem_ctx,
8855 pinfo2->printername,
8857 if (!W_ERROR_IS_OK(result)) {
8858 DEBUG(3, ("Can't proceed w/o a devmode!"));
8863 return fill_job_info2(mem_ctx,
8872 /****************************************************************
8874 ****************************************************************/
8876 WERROR _spoolss_GetJob(struct pipes_struct *p,
8877 struct spoolss_GetJob *r)
8879 WERROR result = WERR_OK;
8880 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8883 print_queue_struct *queue = NULL;
8884 print_status_struct prt_status;
8886 /* that's an [in out] buffer */
8888 if (!r->in.buffer && (r->in.offered != 0)) {
8889 return WERR_INVALID_PARAM;
8892 DEBUG(5,("_spoolss_GetJob\n"));
8896 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8900 result = winreg_get_printer(p->mem_ctx,
8901 get_server_info_system(),
8904 lp_const_servicename(snum),
8906 if (!W_ERROR_IS_OK(result)) {
8910 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
8912 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8913 count, prt_status.status, prt_status.message));
8915 switch (r->in.level) {
8917 result = getjob_level_1(p->mem_ctx,
8918 queue, count, snum, pinfo2,
8919 r->in.job_id, &r->out.info->info1);
8922 result = getjob_level_2(p->mem_ctx,
8923 queue, count, snum, pinfo2,
8924 r->in.job_id, &r->out.info->info2);
8927 result = WERR_UNKNOWN_LEVEL;
8932 TALLOC_FREE(pinfo2);
8934 if (!W_ERROR_IS_OK(result)) {
8935 TALLOC_FREE(r->out.info);
8939 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8941 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8943 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8946 /****************************************************************
8947 _spoolss_GetPrinterDataEx
8948 ****************************************************************/
8950 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8951 struct spoolss_GetPrinterDataEx *r)
8954 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8955 const char *printer;
8957 WERROR result = WERR_OK;
8959 enum winreg_Type val_type;
8964 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8966 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8967 r->in.key_name, r->in.value_name));
8969 /* in case of problem, return some default values */
8972 *r->out.type = REG_NONE;
8975 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8976 OUR_HANDLE(r->in.handle)));
8977 result = WERR_BADFID;
8981 /* Is the handle to a printer or to the server? */
8983 if (Printer->printer_type == SPLHND_SERVER) {
8985 union spoolss_PrinterData data;
8987 result = getprinterdata_printer_server(p->mem_ctx,
8991 if (!W_ERROR_IS_OK(result)) {
8995 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8996 *r->out.type, &data);
8997 if (!W_ERROR_IS_OK(result)) {
9001 *r->out.needed = blob.length;
9003 if (r->in.offered >= *r->out.needed) {
9004 memcpy(r->out.data, blob.data, blob.length);
9007 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9010 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9013 printer = lp_const_servicename(snum);
9015 /* check to see if the keyname is valid */
9016 if (!strlen(r->in.key_name)) {
9017 return WERR_INVALID_PARAM;
9020 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
9021 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
9022 strequal(r->in.value_name, "ChangeId")) {
9023 *r->out.type = REG_DWORD;
9025 if (r->in.offered >= *r->out.needed) {
9026 uint32_t changeid = 0;
9028 result = winreg_printer_get_changeid(p->mem_ctx,
9029 get_server_info_system(),
9033 if (!W_ERROR_IS_OK(result)) {
9037 SIVAL(r->out.data, 0, changeid);
9043 result = winreg_get_printer_dataex(p->mem_ctx,
9044 get_server_info_system(),
9052 if (!W_ERROR_IS_OK(result)) {
9056 *r->out.needed = val_size;
9057 *r->out.type = val_type;
9059 if (r->in.offered >= *r->out.needed) {
9060 memcpy(r->out.data, val_data, val_size);
9064 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
9065 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
9067 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9070 /****************************************************************
9071 _spoolss_SetPrinterDataEx
9072 ****************************************************************/
9074 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
9075 struct spoolss_SetPrinterDataEx *r)
9077 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
9079 WERROR result = WERR_OK;
9080 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9083 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9085 /* From MSDN documentation of SetPrinterDataEx: pass request to
9086 SetPrinterData if key is "PrinterDriverData" */
9089 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
9090 OUR_HANDLE(r->in.handle)));
9094 if (Printer->printer_type == SPLHND_SERVER) {
9095 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9096 "Not implemented for server handles yet\n"));
9097 return WERR_INVALID_PARAM;
9100 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9105 * Access check : NT returns "access denied" if you make a
9106 * SetPrinterData call without the necessary privildge.
9107 * we were originally returning OK if nothing changed
9108 * which made Win2k issue **a lot** of SetPrinterData
9109 * when connecting to a printer --jerry
9112 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9113 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9114 "change denied by handle access permissions\n"));
9115 return WERR_ACCESS_DENIED;
9118 result = winreg_get_printer(Printer,
9119 get_server_info_system(),
9121 Printer->servername,
9122 lp_servicename(snum),
9124 if (!W_ERROR_IS_OK(result)) {
9128 /* check for OID in valuename */
9130 oid_string = strchr(r->in.value_name, ',');
9136 /* save the registry data */
9138 result = winreg_set_printer_dataex(p->mem_ctx,
9139 get_server_info_system(),
9148 if (W_ERROR_IS_OK(result)) {
9149 /* save the OID if one was specified */
9151 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9152 r->in.key_name, SPOOL_OID_KEY);
9154 result = WERR_NOMEM;
9159 * I'm not checking the status here on purpose. Don't know
9160 * if this is right, but I'm returning the status from the
9161 * previous set_printer_dataex() call. I have no idea if
9162 * this is right. --jerry
9164 winreg_set_printer_dataex(p->mem_ctx,
9165 get_server_info_system(),
9171 (uint8_t *) oid_string,
9172 strlen(oid_string) + 1);
9175 result = winreg_printer_update_changeid(p->mem_ctx,
9176 get_server_info_system(),
9178 lp_const_servicename(snum));
9183 talloc_free(pinfo2);
9187 /****************************************************************
9188 _spoolss_DeletePrinterDataEx
9189 ****************************************************************/
9191 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
9192 struct spoolss_DeletePrinterDataEx *r)
9194 const char *printer;
9196 WERROR status = WERR_OK;
9197 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9199 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9202 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9203 "Invalid handle (%s:%u:%u).\n",
9204 OUR_HANDLE(r->in.handle)));
9208 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9209 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9210 "printer properties change denied by handle\n"));
9211 return WERR_ACCESS_DENIED;
9214 if (!r->in.value_name || !r->in.key_name) {
9218 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9221 printer = lp_const_servicename(snum);
9223 status = winreg_delete_printer_dataex(p->mem_ctx,
9224 get_server_info_system(),
9229 if (W_ERROR_IS_OK(status)) {
9230 status = winreg_printer_update_changeid(p->mem_ctx,
9231 get_server_info_system(),
9239 /****************************************************************
9240 _spoolss_EnumPrinterKey
9241 ****************************************************************/
9243 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
9244 struct spoolss_EnumPrinterKey *r)
9247 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9249 WERROR result = WERR_BADFILE;
9250 const char **array = NULL;
9253 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9256 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9257 OUR_HANDLE(r->in.handle)));
9261 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9265 result = winreg_enum_printer_key(p->mem_ctx,
9266 get_server_info_system(),
9268 lp_const_servicename(snum),
9272 if (!W_ERROR_IS_OK(result)) {
9276 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
9277 result = WERR_NOMEM;
9281 *r->out._ndr_size = r->in.offered / 2;
9282 *r->out.needed = blob.length;
9284 if (r->in.offered < *r->out.needed) {
9285 result = WERR_MORE_DATA;
9288 r->out.key_buffer->string_array = array;
9292 if (!W_ERROR_IS_OK(result)) {
9294 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9302 /****************************************************************
9303 _spoolss_DeletePrinterKey
9304 ****************************************************************/
9306 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
9307 struct spoolss_DeletePrinterKey *r)
9309 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9312 const char *printer;
9314 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9317 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9318 OUR_HANDLE(r->in.handle)));
9322 /* if keyname == NULL, return error */
9323 if ( !r->in.key_name )
9324 return WERR_INVALID_PARAM;
9326 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9330 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9331 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9332 "printer properties change denied by handle\n"));
9333 return WERR_ACCESS_DENIED;
9336 printer = lp_const_servicename(snum);
9338 /* delete the key and all subkeys */
9339 status = winreg_delete_printer_key(p->mem_ctx,
9340 get_server_info_system(),
9344 if (W_ERROR_IS_OK(status)) {
9345 status = winreg_printer_update_changeid(p->mem_ctx,
9346 get_server_info_system(),
9354 /****************************************************************
9355 _spoolss_EnumPrinterDataEx
9356 ****************************************************************/
9358 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
9359 struct spoolss_EnumPrinterDataEx *r)
9362 struct spoolss_PrinterEnumValues *info = NULL;
9363 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9367 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9371 *r->out.info = NULL;
9374 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9375 OUR_HANDLE(r->in.handle)));
9380 * first check for a keyname of NULL or "". Win2k seems to send
9381 * this a lot and we should send back WERR_INVALID_PARAM
9382 * no need to spend time looking up the printer in this case.
9386 if (!strlen(r->in.key_name)) {
9387 result = WERR_INVALID_PARAM;
9391 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9395 /* now look for a match on the key name */
9396 result = winreg_enum_printer_dataex(p->mem_ctx,
9397 get_server_info_system(),
9399 lp_const_servicename(snum),
9403 if (!W_ERROR_IS_OK(result)) {
9407 #if 0 /* FIXME - gd */
9408 /* housekeeping information in the reply */
9410 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9411 * the hand marshalled container size is a multiple
9412 * of 4 bytes for RPC alignment.
9416 needed += 4-(needed % 4);
9419 *r->out.count = count;
9420 *r->out.info = info;
9423 if (!W_ERROR_IS_OK(result)) {
9427 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9428 spoolss_EnumPrinterDataEx,
9431 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9432 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9434 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9437 /****************************************************************************
9438 ****************************************************************************/
9440 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9441 const char *servername,
9442 const char *environment,
9443 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9448 werr = compose_spoolss_server_path(mem_ctx,
9451 SPOOLSS_PRTPROCS_PATH,
9453 if (!W_ERROR_IS_OK(werr)) {
9457 DEBUG(4,("print processor directory: [%s]\n", path));
9459 r->directory_name = path;
9464 /****************************************************************
9465 _spoolss_GetPrintProcessorDirectory
9466 ****************************************************************/
9468 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9469 struct spoolss_GetPrintProcessorDirectory *r)
9473 /* that's an [in out] buffer */
9475 if (!r->in.buffer && (r->in.offered != 0)) {
9476 return WERR_INVALID_PARAM;
9479 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9484 /* r->in.level is ignored */
9486 /* We always should reply with a local print processor directory so that
9487 * users are not forced to have a [prnproc$] share on the Samba spoolss
9488 * server - Guenther */
9490 result = getprintprocessordirectory_level_1(p->mem_ctx,
9491 NULL, /* r->in.server */
9493 &r->out.info->info1);
9494 if (!W_ERROR_IS_OK(result)) {
9495 TALLOC_FREE(r->out.info);
9499 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9500 r->out.info, r->in.level);
9501 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9503 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9506 /*******************************************************************
9507 ********************************************************************/
9509 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9510 const char *dllname)
9512 enum ndr_err_code ndr_err;
9513 struct spoolss_MonitorUi ui;
9515 ui.dll_name = dllname;
9517 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9518 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9519 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9520 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9522 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9525 /*******************************************************************
9526 Streams the monitor UI DLL name in UNICODE
9527 *******************************************************************/
9529 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9530 NT_USER_TOKEN *token, DATA_BLOB *in,
9531 DATA_BLOB *out, uint32_t *needed)
9533 const char *dllname = "tcpmonui.dll";
9535 *needed = (strlen(dllname)+1) * 2;
9537 if (out->length < *needed) {
9538 return WERR_INSUFFICIENT_BUFFER;
9541 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9548 /*******************************************************************
9549 ********************************************************************/
9551 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9552 struct spoolss_PortData1 *port1,
9553 const DATA_BLOB *buf)
9555 enum ndr_err_code ndr_err;
9556 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9557 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9558 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9559 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9561 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9564 /*******************************************************************
9565 ********************************************************************/
9567 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9568 struct spoolss_PortData2 *port2,
9569 const DATA_BLOB *buf)
9571 enum ndr_err_code ndr_err;
9572 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9573 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9574 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9575 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9577 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9580 /*******************************************************************
9581 Create a new TCP/IP port
9582 *******************************************************************/
9584 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9585 NT_USER_TOKEN *token, DATA_BLOB *in,
9586 DATA_BLOB *out, uint32_t *needed)
9588 struct spoolss_PortData1 port1;
9589 struct spoolss_PortData2 port2;
9590 char *device_uri = NULL;
9593 const char *portname;
9594 const char *hostaddress;
9596 uint32_t port_number;
9599 /* peek for spoolss_PortData version */
9601 if (!in || (in->length < (128 + 4))) {
9602 return WERR_GENERAL_FAILURE;
9605 version = IVAL(in->data, 128);
9611 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9615 portname = port1.portname;
9616 hostaddress = port1.hostaddress;
9617 queue = port1.queue;
9618 protocol = port1.protocol;
9619 port_number = port1.port_number;
9625 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9629 portname = port2.portname;
9630 hostaddress = port2.hostaddress;
9631 queue = port2.queue;
9632 protocol = port2.protocol;
9633 port_number = port2.port_number;
9637 DEBUG(1,("xcvtcp_addport: "
9638 "unknown version of port_data: %d\n", version));
9639 return WERR_UNKNOWN_PORT;
9642 /* create the device URI and call the add_port_hook() */
9645 case PROTOCOL_RAWTCP_TYPE:
9646 device_uri = talloc_asprintf(mem_ctx,
9647 "socket://%s:%d/", hostaddress,
9651 case PROTOCOL_LPR_TYPE:
9652 device_uri = talloc_asprintf(mem_ctx,
9653 "lpr://%s/%s", hostaddress, queue );
9657 return WERR_UNKNOWN_PORT;
9664 return add_port_hook(mem_ctx, token, portname, device_uri);
9667 /*******************************************************************
9668 *******************************************************************/
9670 struct xcv_api_table xcvtcp_cmds[] = {
9671 { "MonitorUI", xcvtcp_monitorui },
9672 { "AddPort", xcvtcp_addport},
9676 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9677 NT_USER_TOKEN *token, const char *command,
9684 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9686 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9687 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9688 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9691 return WERR_BADFUNC;
9694 /*******************************************************************
9695 *******************************************************************/
9696 #if 0 /* don't support management using the "Local Port" monitor */
9698 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9699 NT_USER_TOKEN *token, DATA_BLOB *in,
9700 DATA_BLOB *out, uint32_t *needed)
9702 const char *dllname = "localui.dll";
9704 *needed = (strlen(dllname)+1) * 2;
9706 if (out->length < *needed) {
9707 return WERR_INSUFFICIENT_BUFFER;
9710 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9717 /*******************************************************************
9718 *******************************************************************/
9720 struct xcv_api_table xcvlocal_cmds[] = {
9721 { "MonitorUI", xcvlocal_monitorui },
9725 struct xcv_api_table xcvlocal_cmds[] = {
9732 /*******************************************************************
9733 *******************************************************************/
9735 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9736 NT_USER_TOKEN *token, const char *command,
9737 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9742 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9744 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9745 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9746 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9748 return WERR_BADFUNC;
9751 /****************************************************************
9753 ****************************************************************/
9755 WERROR _spoolss_XcvData(struct pipes_struct *p,
9756 struct spoolss_XcvData *r)
9758 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9759 DATA_BLOB out_data = data_blob_null;
9763 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9764 OUR_HANDLE(r->in.handle)));
9768 /* Has to be a handle to the TCP/IP port monitor */
9770 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9771 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9775 /* requires administrative access to the server */
9777 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9778 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9779 return WERR_ACCESS_DENIED;
9782 /* Allocate the outgoing buffer */
9784 if (r->in.out_data_size) {
9785 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9786 if (out_data.data == NULL) {
9791 switch ( Printer->printer_type ) {
9792 case SPLHND_PORTMON_TCP:
9793 werror = process_xcvtcp_command(p->mem_ctx,
9794 p->server_info->ptok,
9795 r->in.function_name,
9796 &r->in.in_data, &out_data,
9799 case SPLHND_PORTMON_LOCAL:
9800 werror = process_xcvlocal_command(p->mem_ctx,
9801 p->server_info->ptok,
9802 r->in.function_name,
9803 &r->in.in_data, &out_data,
9807 werror = WERR_INVALID_PRINT_MONITOR;
9810 if (!W_ERROR_IS_OK(werror)) {
9814 *r->out.status_code = 0;
9816 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9817 memcpy(r->out.out_data, out_data.data,
9818 MIN(r->in.out_data_size, out_data.length));
9824 /****************************************************************
9825 _spoolss_AddPrintProcessor
9826 ****************************************************************/
9828 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9829 struct spoolss_AddPrintProcessor *r)
9831 /* for now, just indicate success and ignore the add. We'll
9832 automatically set the winprint processor for printer
9833 entries later. Used to debug the LexMark Optra S 1855 PCL
9839 /****************************************************************
9841 ****************************************************************/
9843 WERROR _spoolss_AddPort(struct pipes_struct *p,
9844 struct spoolss_AddPort *r)
9846 /* do what w2k3 does */
9848 return WERR_NOT_SUPPORTED;
9851 /****************************************************************
9852 _spoolss_GetPrinterDriver
9853 ****************************************************************/
9855 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9856 struct spoolss_GetPrinterDriver *r)
9858 p->rng_fault_state = true;
9859 return WERR_NOT_SUPPORTED;
9862 /****************************************************************
9863 _spoolss_ReadPrinter
9864 ****************************************************************/
9866 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9867 struct spoolss_ReadPrinter *r)
9869 p->rng_fault_state = true;
9870 return WERR_NOT_SUPPORTED;
9873 /****************************************************************
9874 _spoolss_WaitForPrinterChange
9875 ****************************************************************/
9877 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9878 struct spoolss_WaitForPrinterChange *r)
9880 p->rng_fault_state = true;
9881 return WERR_NOT_SUPPORTED;
9884 /****************************************************************
9885 _spoolss_ConfigurePort
9886 ****************************************************************/
9888 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9889 struct spoolss_ConfigurePort *r)
9891 p->rng_fault_state = true;
9892 return WERR_NOT_SUPPORTED;
9895 /****************************************************************
9897 ****************************************************************/
9899 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9900 struct spoolss_DeletePort *r)
9902 p->rng_fault_state = true;
9903 return WERR_NOT_SUPPORTED;
9906 /****************************************************************
9907 _spoolss_CreatePrinterIC
9908 ****************************************************************/
9910 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9911 struct spoolss_CreatePrinterIC *r)
9913 p->rng_fault_state = true;
9914 return WERR_NOT_SUPPORTED;
9917 /****************************************************************
9918 _spoolss_PlayGDIScriptOnPrinterIC
9919 ****************************************************************/
9921 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9922 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9924 p->rng_fault_state = true;
9925 return WERR_NOT_SUPPORTED;
9928 /****************************************************************
9929 _spoolss_DeletePrinterIC
9930 ****************************************************************/
9932 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9933 struct spoolss_DeletePrinterIC *r)
9935 p->rng_fault_state = true;
9936 return WERR_NOT_SUPPORTED;
9939 /****************************************************************
9940 _spoolss_AddPrinterConnection
9941 ****************************************************************/
9943 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9944 struct spoolss_AddPrinterConnection *r)
9946 p->rng_fault_state = true;
9947 return WERR_NOT_SUPPORTED;
9950 /****************************************************************
9951 _spoolss_DeletePrinterConnection
9952 ****************************************************************/
9954 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9955 struct spoolss_DeletePrinterConnection *r)
9957 p->rng_fault_state = true;
9958 return WERR_NOT_SUPPORTED;
9961 /****************************************************************
9962 _spoolss_PrinterMessageBox
9963 ****************************************************************/
9965 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9966 struct spoolss_PrinterMessageBox *r)
9968 p->rng_fault_state = true;
9969 return WERR_NOT_SUPPORTED;
9972 /****************************************************************
9974 ****************************************************************/
9976 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9977 struct spoolss_AddMonitor *r)
9979 p->rng_fault_state = true;
9980 return WERR_NOT_SUPPORTED;
9983 /****************************************************************
9984 _spoolss_DeleteMonitor
9985 ****************************************************************/
9987 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9988 struct spoolss_DeleteMonitor *r)
9990 p->rng_fault_state = true;
9991 return WERR_NOT_SUPPORTED;
9994 /****************************************************************
9995 _spoolss_DeletePrintProcessor
9996 ****************************************************************/
9998 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9999 struct spoolss_DeletePrintProcessor *r)
10001 p->rng_fault_state = true;
10002 return WERR_NOT_SUPPORTED;
10005 /****************************************************************
10006 _spoolss_AddPrintProvidor
10007 ****************************************************************/
10009 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
10010 struct spoolss_AddPrintProvidor *r)
10012 p->rng_fault_state = true;
10013 return WERR_NOT_SUPPORTED;
10016 /****************************************************************
10017 _spoolss_DeletePrintProvidor
10018 ****************************************************************/
10020 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
10021 struct spoolss_DeletePrintProvidor *r)
10023 p->rng_fault_state = true;
10024 return WERR_NOT_SUPPORTED;
10027 /****************************************************************
10028 _spoolss_FindFirstPrinterChangeNotification
10029 ****************************************************************/
10031 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
10032 struct spoolss_FindFirstPrinterChangeNotification *r)
10034 p->rng_fault_state = true;
10035 return WERR_NOT_SUPPORTED;
10038 /****************************************************************
10039 _spoolss_FindNextPrinterChangeNotification
10040 ****************************************************************/
10042 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
10043 struct spoolss_FindNextPrinterChangeNotification *r)
10045 p->rng_fault_state = true;
10046 return WERR_NOT_SUPPORTED;
10049 /****************************************************************
10050 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10051 ****************************************************************/
10053 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
10054 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10056 p->rng_fault_state = true;
10057 return WERR_NOT_SUPPORTED;
10060 /****************************************************************
10061 _spoolss_ReplyOpenPrinter
10062 ****************************************************************/
10064 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
10065 struct spoolss_ReplyOpenPrinter *r)
10067 p->rng_fault_state = true;
10068 return WERR_NOT_SUPPORTED;
10071 /****************************************************************
10072 _spoolss_RouterReplyPrinter
10073 ****************************************************************/
10075 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
10076 struct spoolss_RouterReplyPrinter *r)
10078 p->rng_fault_state = true;
10079 return WERR_NOT_SUPPORTED;
10082 /****************************************************************
10083 _spoolss_ReplyClosePrinter
10084 ****************************************************************/
10086 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
10087 struct spoolss_ReplyClosePrinter *r)
10089 p->rng_fault_state = true;
10090 return WERR_NOT_SUPPORTED;
10093 /****************************************************************
10095 ****************************************************************/
10097 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
10098 struct spoolss_AddPortEx *r)
10100 p->rng_fault_state = true;
10101 return WERR_NOT_SUPPORTED;
10104 /****************************************************************
10105 _spoolss_RouterFindFirstPrinterChangeNotification
10106 ****************************************************************/
10108 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
10109 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10111 p->rng_fault_state = true;
10112 return WERR_NOT_SUPPORTED;
10115 /****************************************************************
10116 _spoolss_SpoolerInit
10117 ****************************************************************/
10119 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
10120 struct spoolss_SpoolerInit *r)
10122 p->rng_fault_state = true;
10123 return WERR_NOT_SUPPORTED;
10126 /****************************************************************
10127 _spoolss_ResetPrinterEx
10128 ****************************************************************/
10130 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
10131 struct spoolss_ResetPrinterEx *r)
10133 p->rng_fault_state = true;
10134 return WERR_NOT_SUPPORTED;
10137 /****************************************************************
10138 _spoolss_RouterReplyPrinterEx
10139 ****************************************************************/
10141 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
10142 struct spoolss_RouterReplyPrinterEx *r)
10144 p->rng_fault_state = true;
10145 return WERR_NOT_SUPPORTED;
10148 /****************************************************************
10150 ****************************************************************/
10152 WERROR _spoolss_44(struct pipes_struct *p,
10153 struct spoolss_44 *r)
10155 p->rng_fault_state = true;
10156 return WERR_NOT_SUPPORTED;
10159 /****************************************************************
10161 ****************************************************************/
10163 WERROR _spoolss_47(struct pipes_struct *p,
10164 struct spoolss_47 *r)
10166 p->rng_fault_state = true;
10167 return WERR_NOT_SUPPORTED;
10170 /****************************************************************
10172 ****************************************************************/
10174 WERROR _spoolss_4a(struct pipes_struct *p,
10175 struct spoolss_4a *r)
10177 p->rng_fault_state = true;
10178 return WERR_NOT_SUPPORTED;
10181 /****************************************************************
10183 ****************************************************************/
10185 WERROR _spoolss_4b(struct pipes_struct *p,
10186 struct spoolss_4b *r)
10188 p->rng_fault_state = true;
10189 return WERR_NOT_SUPPORTED;
10192 /****************************************************************
10194 ****************************************************************/
10196 WERROR _spoolss_4c(struct pipes_struct *p,
10197 struct spoolss_4c *r)
10199 p->rng_fault_state = true;
10200 return WERR_NOT_SUPPORTED;
10203 /****************************************************************
10205 ****************************************************************/
10207 WERROR _spoolss_53(struct pipes_struct *p,
10208 struct spoolss_53 *r)
10210 p->rng_fault_state = true;
10211 return WERR_NOT_SUPPORTED;
10214 /****************************************************************
10216 ****************************************************************/
10218 WERROR _spoolss_55(struct pipes_struct *p,
10219 struct spoolss_55 *r)
10221 p->rng_fault_state = true;
10222 return WERR_NOT_SUPPORTED;
10225 /****************************************************************
10227 ****************************************************************/
10229 WERROR _spoolss_56(struct pipes_struct *p,
10230 struct spoolss_56 *r)
10232 p->rng_fault_state = true;
10233 return WERR_NOT_SUPPORTED;
10236 /****************************************************************
10238 ****************************************************************/
10240 WERROR _spoolss_57(struct pipes_struct *p,
10241 struct spoolss_57 *r)
10243 p->rng_fault_state = true;
10244 return WERR_NOT_SUPPORTED;
10247 /****************************************************************
10249 ****************************************************************/
10251 WERROR _spoolss_5a(struct pipes_struct *p,
10252 struct spoolss_5a *r)
10254 p->rng_fault_state = true;
10255 return WERR_NOT_SUPPORTED;
10258 /****************************************************************
10260 ****************************************************************/
10262 WERROR _spoolss_5b(struct pipes_struct *p,
10263 struct spoolss_5b *r)
10265 p->rng_fault_state = true;
10266 return WERR_NOT_SUPPORTED;
10269 /****************************************************************
10271 ****************************************************************/
10273 WERROR _spoolss_5c(struct pipes_struct *p,
10274 struct spoolss_5c *r)
10276 p->rng_fault_state = true;
10277 return WERR_NOT_SUPPORTED;
10280 /****************************************************************
10282 ****************************************************************/
10284 WERROR _spoolss_5d(struct pipes_struct *p,
10285 struct spoolss_5d *r)
10287 p->rng_fault_state = true;
10288 return WERR_NOT_SUPPORTED;
10291 /****************************************************************
10293 ****************************************************************/
10295 WERROR _spoolss_5e(struct pipes_struct *p,
10296 struct spoolss_5e *r)
10298 p->rng_fault_state = true;
10299 return WERR_NOT_SUPPORTED;
10302 /****************************************************************
10304 ****************************************************************/
10306 WERROR _spoolss_5f(struct pipes_struct *p,
10307 struct spoolss_5f *r)
10309 p->rng_fault_state = true;
10310 return WERR_NOT_SUPPORTED;
10313 /****************************************************************
10315 ****************************************************************/
10317 WERROR _spoolss_60(struct pipes_struct *p,
10318 struct spoolss_60 *r)
10320 p->rng_fault_state = true;
10321 return WERR_NOT_SUPPORTED;
10324 /****************************************************************
10326 ****************************************************************/
10328 WERROR _spoolss_61(struct pipes_struct *p,
10329 struct spoolss_61 *r)
10331 p->rng_fault_state = true;
10332 return WERR_NOT_SUPPORTED;
10335 /****************************************************************
10337 ****************************************************************/
10339 WERROR _spoolss_62(struct pipes_struct *p,
10340 struct spoolss_62 *r)
10342 p->rng_fault_state = true;
10343 return WERR_NOT_SUPPORTED;
10346 /****************************************************************
10348 ****************************************************************/
10350 WERROR _spoolss_63(struct pipes_struct *p,
10351 struct spoolss_63 *r)
10353 p->rng_fault_state = true;
10354 return WERR_NOT_SUPPORTED;
10357 /****************************************************************
10359 ****************************************************************/
10361 WERROR _spoolss_64(struct pipes_struct *p,
10362 struct spoolss_64 *r)
10364 p->rng_fault_state = true;
10365 return WERR_NOT_SUPPORTED;
10368 /****************************************************************
10370 ****************************************************************/
10372 WERROR _spoolss_65(struct pipes_struct *p,
10373 struct spoolss_65 *r)
10375 p->rng_fault_state = true;
10376 return WERR_NOT_SUPPORTED;
10379 /****************************************************************
10380 _spoolss_GetCorePrinterDrivers
10381 ****************************************************************/
10383 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
10384 struct spoolss_GetCorePrinterDrivers *r)
10386 p->rng_fault_state = true;
10387 return WERR_NOT_SUPPORTED;
10390 /****************************************************************
10392 ****************************************************************/
10394 WERROR _spoolss_67(struct pipes_struct *p,
10395 struct spoolss_67 *r)
10397 p->rng_fault_state = true;
10398 return WERR_NOT_SUPPORTED;
10401 /****************************************************************
10402 _spoolss_GetPrinterDriverPackagePath
10403 ****************************************************************/
10405 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10406 struct spoolss_GetPrinterDriverPackagePath *r)
10408 p->rng_fault_state = true;
10409 return WERR_NOT_SUPPORTED;
10412 /****************************************************************
10414 ****************************************************************/
10416 WERROR _spoolss_69(struct pipes_struct *p,
10417 struct spoolss_69 *r)
10419 p->rng_fault_state = true;
10420 return WERR_NOT_SUPPORTED;
10423 /****************************************************************
10425 ****************************************************************/
10427 WERROR _spoolss_6a(struct pipes_struct *p,
10428 struct spoolss_6a *r)
10430 p->rng_fault_state = true;
10431 return WERR_NOT_SUPPORTED;
10434 /****************************************************************
10436 ****************************************************************/
10438 WERROR _spoolss_6b(struct pipes_struct *p,
10439 struct spoolss_6b *r)
10441 p->rng_fault_state = true;
10442 return WERR_NOT_SUPPORTED;
10445 /****************************************************************
10447 ****************************************************************/
10449 WERROR _spoolss_6c(struct pipes_struct *p,
10450 struct spoolss_6c *r)
10452 p->rng_fault_state = true;
10453 return WERR_NOT_SUPPORTED;
10456 /****************************************************************
10458 ****************************************************************/
10460 WERROR _spoolss_6d(struct pipes_struct *p,
10461 struct spoolss_6d *r)
10463 p->rng_fault_state = true;
10464 return WERR_NOT_SUPPORTED;