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 /* structure to store the printer handles */
65 /* and a reference to what it's pointing to */
66 /* and the notify info asked about */
67 /* that's the central struct */
68 struct printer_handle {
69 struct printer_handle *prev, *next;
70 bool document_started;
72 uint32 jobid; /* jobid in printing backend */
77 uint32 access_granted;
83 struct spoolss_NotifyOption *option;
84 struct policy_handle client_hnd;
85 bool client_connected;
87 /* are we in a FindNextPrinterChangeNotify() call? */
89 struct messaging_context *msg_ctx;
96 /* devmode sent in the OpenPrinter() call */
97 struct spoolss_DeviceMode *devmode;
99 /* TODO cache the printer info2 structure */
100 struct spoolss_PrinterInfo2 *info2;
104 static struct printer_handle *printers_list;
106 struct printer_session_counter {
107 struct printer_session_counter *next;
108 struct printer_session_counter *prev;
114 static struct printer_session_counter *counter_list;
116 struct notify_back_channel {
117 /* print notify back-channel pipe handle*/
118 struct rpc_pipe_client *cli_pipe;
119 uint32_t active_channels;
122 static struct notify_back_channel back_channel = { NULL, 0 };
124 /* Map generic permissions to printer object specific permissions */
126 const struct standard_mapping printer_std_mapping = {
133 /* Map generic permissions to print server object specific permissions */
135 const struct standard_mapping printserver_std_mapping = {
142 /* API table for Xcv Monitor functions */
144 struct xcv_api_table {
146 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
149 static void prune_printername_cache(void);
151 /********************************************************************
152 * Canonicalize servername.
153 ********************************************************************/
155 static const char *canon_servername(const char *servername)
157 const char *pservername = servername;
158 while (*pservername == '\\') {
164 /* translate between internal status numbers and NT status numbers */
165 static int nt_printj_status(int v)
171 return JOB_STATUS_PAUSED;
173 return JOB_STATUS_SPOOLING;
175 return JOB_STATUS_PRINTING;
177 return JOB_STATUS_ERROR;
179 return JOB_STATUS_DELETING;
181 return JOB_STATUS_OFFLINE;
183 return JOB_STATUS_PAPEROUT;
185 return JOB_STATUS_PRINTED;
187 return JOB_STATUS_DELETED;
189 return JOB_STATUS_BLOCKED_DEVQ;
190 case LPQ_USER_INTERVENTION:
191 return JOB_STATUS_USER_INTERVENTION;
196 static int nt_printq_status(int v)
200 return PRINTER_STATUS_PAUSED;
209 /***************************************************************************
210 Disconnect from the client
211 ****************************************************************************/
213 static void srv_spoolss_replycloseprinter(
214 int snum, struct policy_handle *handle,
215 struct messaging_context *msg_ctx)
221 * Tell the specific printing tdb we no longer want messages for this printer
222 * by deregistering our PID.
225 if (!print_notify_deregister_pid(snum))
226 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
228 /* weird if the test succeeds !!! */
229 if (back_channel.active_channels == 0) {
230 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
234 status = rpccli_spoolss_ReplyClosePrinter(back_channel.cli_pipe, talloc_tos(),
237 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
238 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
239 win_errstr(result)));
241 /* if it's the last connection, deconnect the IPC$ share */
242 if (back_channel.active_channels == 1) {
244 cli_shutdown(rpc_pipe_np_smb_conn(back_channel.cli_pipe));
246 * The above call shuts down the pipe also.
248 back_channel.cli_pipe = NULL;
250 if (msg_ctx != NULL) {
251 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
255 * Tell the serverid.tdb we're no longer
256 * interested in printer notify messages.
259 serverid_register_msg_flags(
260 messaging_server_id(msg_ctx),
261 false, FLAG_MSG_PRINT_NOTIFY);
265 back_channel.active_channels--;
268 /****************************************************************************
269 Functions to free a printer entry datastruct.
270 ****************************************************************************/
272 static int printer_entry_destructor(struct printer_handle *Printer)
274 if (Printer->notify.client_connected == true) {
277 if ( Printer->printer_type == SPLHND_SERVER) {
279 srv_spoolss_replycloseprinter(
280 snum, &Printer->notify.client_hnd,
281 Printer->notify.msg_ctx);
282 } else if (Printer->printer_type == SPLHND_PRINTER) {
283 snum = print_queue_snum(Printer->sharename);
285 srv_spoolss_replycloseprinter(
286 snum, &Printer->notify.client_hnd,
287 Printer->notify.msg_ctx);
291 Printer->notify.flags=0;
292 Printer->notify.options=0;
293 Printer->notify.localmachine[0]='\0';
294 Printer->notify.printerlocal=0;
295 TALLOC_FREE(Printer->notify.option);
296 Printer->notify.client_connected = false;
298 TALLOC_FREE(Printer->devmode);
300 /* Remove from the internal list. */
301 DLIST_REMOVE(printers_list, Printer);
305 /****************************************************************************
306 find printer index by handle
307 ****************************************************************************/
309 static struct printer_handle *find_printer_index_by_hnd(struct pipes_struct *p,
310 struct policy_handle *hnd)
312 struct printer_handle *find_printer = NULL;
314 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
315 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
322 /****************************************************************************
323 Close printer index by handle.
324 ****************************************************************************/
326 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
328 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
331 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
336 close_policy_hnd(p, hnd);
341 /****************************************************************************
342 Delete a printer given a handle.
343 ****************************************************************************/
345 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
346 const char *sharename,
347 struct messaging_context *msg_ctx)
349 char *cmd = lp_deleteprinter_cmd();
350 char *command = NULL;
352 SE_PRIV se_printop = SE_PRINT_OPERATOR;
353 bool is_print_op = false;
355 /* can't fail if we don't try */
360 command = talloc_asprintf(ctx,
367 is_print_op = user_has_privileges( token, &se_printop );
369 DEBUG(10,("Running [%s]\n", command));
371 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
376 if ( (ret = smbrun(command, NULL)) == 0 ) {
377 /* Tell everyone we updated smb.conf. */
378 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
384 /********** END SePrintOperatorPrivlege BLOCK **********/
386 DEBUGADD(10,("returned [%d]\n", ret));
388 TALLOC_FREE(command);
391 return WERR_BADFID; /* What to return here? */
393 /* go ahead and re-read the services immediately */
395 reload_services(msg_ctx, -1, false);
398 if ( lp_servicenumber( sharename ) > 0 )
399 return WERR_ACCESS_DENIED;
404 /****************************************************************************
405 Delete a printer given a handle.
406 ****************************************************************************/
408 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
410 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
414 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
420 * It turns out that Windows allows delete printer on a handle
421 * opened by an admin user, then used on a pipe handle created
422 * by an anonymous user..... but they're working on security.... riiight !
426 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
427 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
428 return WERR_ACCESS_DENIED;
431 /* this does not need a become root since the access check has been
432 done on the handle already */
434 result = winreg_delete_printer_key(p->mem_ctx,
435 get_server_info_system(),
439 if (!W_ERROR_IS_OK(result)) {
440 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
444 result = delete_printer_hook(p->mem_ctx, p->server_info->ptok,
445 Printer->sharename, p->msg_ctx);
446 if (!W_ERROR_IS_OK(result)) {
449 prune_printername_cache();
453 /****************************************************************************
454 Return the snum of a printer corresponding to an handle.
455 ****************************************************************************/
457 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
458 int *number, struct share_params **params)
460 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
463 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
468 switch (Printer->printer_type) {
470 DEBUG(4,("short name:%s\n", Printer->sharename));
471 *number = print_queue_snum(Printer->sharename);
472 return (*number != -1);
480 /****************************************************************************
481 Set printer handle type.
482 Check if it's \\server or \\server\printer
483 ****************************************************************************/
485 static bool set_printer_hnd_printertype(struct printer_handle *Printer, const char *handlename)
487 DEBUG(3,("Setting printer type=%s\n", handlename));
489 /* it's a print server */
490 if (handlename && *handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
491 DEBUGADD(4,("Printer is a print server\n"));
492 Printer->printer_type = SPLHND_SERVER;
494 /* it's a printer (set_printer_hnd_name() will handle port monitors */
496 DEBUGADD(4,("Printer is a printer\n"));
497 Printer->printer_type = SPLHND_PRINTER;
503 static void prune_printername_cache_fn(const char *key, const char *value,
504 time_t timeout, void *private_data)
509 static void prune_printername_cache(void)
511 gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
514 /****************************************************************************
515 Set printer handle name.. Accept names like \\server, \\server\printer,
516 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
517 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
518 XcvDataPort() interface.
519 ****************************************************************************/
521 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
522 const struct auth_serversupplied_info *server_info,
523 struct messaging_context *msg_ctx,
524 struct printer_handle *Printer,
525 const char *handlename)
528 int n_services=lp_numservices();
530 const char *printername;
531 const char *servername = NULL;
534 struct spoolss_PrinterInfo2 *info2 = NULL;
538 * Hopefully nobody names his printers like this. Maybe \ or ,
539 * are illegal in printer names even?
541 const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
545 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
546 (unsigned long)strlen(handlename)));
548 aprinter = CONST_DISCARD(char *, handlename);
549 if ( *handlename == '\\' ) {
550 servername = canon_servername(handlename);
551 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
555 if (!is_myname_or_ipaddr(servername)) {
559 fstrcpy(Printer->servername, servername);
562 if (Printer->printer_type == SPLHND_SERVER) {
566 if (Printer->printer_type != SPLHND_PRINTER) {
570 DEBUGADD(5, ("searching for [%s]\n", aprinter));
572 /* check for the Port Monitor Interface */
573 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
574 Printer->printer_type = SPLHND_PORTMON_TCP;
575 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
578 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
579 Printer->printer_type = SPLHND_PORTMON_LOCAL;
580 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
585 * With hundreds of printers, the "for" loop iterating all
586 * shares can be quite expensive, as it is done on every
587 * OpenPrinter. The loop maps "aprinter" to "sname", the
588 * result of which we cache in gencache.
591 cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
593 if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
595 found = (strcmp(tmp, printer_not_found) != 0);
597 DEBUG(4, ("Printer %s not found\n", aprinter));
605 /* Search all sharenames first as this is easier than pulling
606 the printer_info_2 off of disk. Don't use find_service() since
607 that calls out to map_username() */
609 /* do another loop to look for printernames */
610 for (snum = 0; !found && snum < n_services; snum++) {
611 const char *printer = lp_const_servicename(snum);
613 /* no point going on if this is not a printer */
614 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
618 /* ignore [printers] share */
619 if (strequal(printer, "printers")) {
623 fstrcpy(sname, printer);
624 if (strequal(aprinter, printer)) {
629 /* no point looking up the printer object if
630 we aren't allowing printername != sharename */
631 if (lp_force_printername(snum)) {
635 result = winreg_get_printer(mem_ctx,
641 if ( !W_ERROR_IS_OK(result) ) {
642 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
643 sname, win_errstr(result)));
647 printername = strrchr(info2->printername, '\\');
648 if (printername == NULL) {
649 printername = info2->printername;
654 if (strequal(printername, aprinter)) {
659 DEBUGADD(10, ("printername: %s\n", printername));
665 if (cache_key != NULL) {
666 gencache_set(cache_key, printer_not_found,
668 TALLOC_FREE(cache_key);
670 DEBUGADD(4,("Printer not found\n"));
674 if (cache_key != NULL) {
675 gencache_set(cache_key, sname, time(NULL)+300);
676 TALLOC_FREE(cache_key);
679 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
681 fstrcpy(Printer->sharename, sname);
686 /****************************************************************************
687 Find first available printer slot. creates a printer handle for you.
688 ****************************************************************************/
690 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
691 const char *name, uint32_t access_granted)
693 struct printer_handle *new_printer;
695 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
697 new_printer = talloc_zero(p->mem_ctx, struct printer_handle);
698 if (new_printer == NULL) {
701 talloc_set_destructor(new_printer, printer_entry_destructor);
703 /* This also steals the printer_handle on the policy_handle */
704 if (!create_policy_hnd(p, hnd, new_printer)) {
705 TALLOC_FREE(new_printer);
709 /* Add to the internal list. */
710 DLIST_ADD(printers_list, new_printer);
712 new_printer->notify.option=NULL;
714 if (!set_printer_hnd_printertype(new_printer, name)) {
715 close_printer_handle(p, hnd);
719 if (!set_printer_hnd_name(p->mem_ctx,
720 get_server_info_system(),
722 new_printer, name)) {
723 close_printer_handle(p, hnd);
727 new_printer->access_granted = access_granted;
729 DEBUG(5, ("%d printer handles active\n",
730 (int)num_pipe_handles(p)));
735 /***************************************************************************
736 check to see if the client motify handle is monitoring the notification
737 given by (notify_type, notify_field).
738 **************************************************************************/
740 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
741 uint16_t notify_field)
746 static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type,
747 uint16_t notify_field)
749 struct spoolss_NotifyOption *option = p->notify.option;
753 * Flags should always be zero when the change notify
754 * is registered by the client's spooler. A user Win32 app
755 * might use the flags though instead of the NOTIFY_OPTION_INFO
764 return is_monitoring_event_flags(
765 p->notify.flags, notify_type, notify_field);
767 for (i = 0; i < option->count; i++) {
769 /* Check match for notify_type */
771 if (option->types[i].type != notify_type)
774 /* Check match for field */
776 for (j = 0; j < option->types[i].count; j++) {
777 if (option->types[i].fields[j].field == notify_field) {
783 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
784 p->servername, p->sharename, notify_type, notify_field));
789 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
790 _data->data.integer[0] = _integer; \
791 _data->data.integer[1] = 0;
794 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
795 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
796 if (!_data->data.string.string) {\
797 _data->data.string.size = 0; \
799 _data->data.string.size = strlen_m_term(_p) * 2;
801 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
802 _data->data.devmode.devmode = _devmode;
804 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
805 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
806 if (!_data->data.sd.sd) { \
807 _data->data.sd.sd_size = 0; \
809 _data->data.sd.sd_size = \
810 ndr_size_security_descriptor(_data->data.sd.sd, 0);
812 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
817 struct spoolss_Time st;
821 if (!init_systemtime(&st, t)) {
825 p = talloc_array(mem_ctx, char, len);
831 * Systemtime must be linearized as a set of UINT16's.
832 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
835 SSVAL(p, 0, st.year);
836 SSVAL(p, 2, st.month);
837 SSVAL(p, 4, st.day_of_week);
839 SSVAL(p, 8, st.hour);
840 SSVAL(p, 10, st.minute);
841 SSVAL(p, 12, st.second);
842 SSVAL(p, 14, st.millisecond);
848 /* Convert a notification message to a struct spoolss_Notify */
850 static void notify_one_value(struct spoolss_notify_msg *msg,
851 struct spoolss_Notify *data,
854 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
857 static void notify_string(struct spoolss_notify_msg *msg,
858 struct spoolss_Notify *data,
861 /* The length of the message includes the trailing \0 */
863 data->data.string.size = msg->len * 2;
864 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
865 if (!data->data.string.string) {
866 data->data.string.size = 0;
871 static void notify_system_time(struct spoolss_notify_msg *msg,
872 struct spoolss_Notify *data,
875 data->data.string.string = NULL;
876 data->data.string.size = 0;
878 if (msg->len != sizeof(time_t)) {
879 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
884 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
885 &data->data.string.string,
886 &data->data.string.size);
889 struct notify2_message_table {
891 void (*fn)(struct spoolss_notify_msg *msg,
892 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
895 static struct notify2_message_table printer_notify_table[] = {
896 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
897 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
898 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
899 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
900 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
901 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
902 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
903 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
904 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
905 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
906 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
907 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
908 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
909 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
910 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
911 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
912 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
913 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
914 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
917 static struct notify2_message_table job_notify_table[] = {
918 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
919 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
920 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
921 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
922 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
923 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
924 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
925 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
926 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
927 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
928 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
929 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
930 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
931 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
932 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
933 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
934 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
935 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
936 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
937 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
938 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
939 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
940 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
941 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
945 /***********************************************************************
946 Allocate talloc context for container object
947 **********************************************************************/
949 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
954 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
959 /***********************************************************************
960 release all allocated memory and zero out structure
961 **********************************************************************/
963 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
969 talloc_destroy(ctr->ctx);
976 /***********************************************************************
977 **********************************************************************/
979 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
987 /***********************************************************************
988 **********************************************************************/
990 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
992 if ( !ctr || !ctr->msg_groups )
995 if ( idx >= ctr->num_groups )
998 return &ctr->msg_groups[idx];
1002 /***********************************************************************
1003 How many groups of change messages do we have ?
1004 **********************************************************************/
1006 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
1011 return ctr->num_groups;
1014 /***********************************************************************
1015 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
1016 **********************************************************************/
1018 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
1020 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
1021 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
1022 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
1028 /* loop over all groups looking for a matching printer name */
1030 for ( i=0; i<ctr->num_groups; i++ ) {
1031 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
1035 /* add a new group? */
1037 if ( i == ctr->num_groups ) {
1040 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
1041 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
1044 ctr->msg_groups = groups;
1046 /* clear the new entry and set the printer name */
1048 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
1049 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
1052 /* add the change messages; 'i' is the correct index now regardless */
1054 msg_grp = &ctr->msg_groups[i];
1056 msg_grp->num_msgs++;
1058 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
1059 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
1062 msg_grp->msgs = msg_list;
1064 new_slot = msg_grp->num_msgs-1;
1065 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
1067 /* need to allocate own copy of data */
1069 if ( msg->len != 0 )
1070 msg_grp->msgs[new_slot].notify.data = (char *)
1071 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
1073 return ctr->num_groups;
1076 static void construct_info_data(struct spoolss_Notify *info_data,
1077 enum spoolss_NotifyType type,
1078 uint16_t field, int id);
1080 /***********************************************************************
1081 Send a change notication message on all handles which have a call
1083 **********************************************************************/
1085 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1087 struct printer_handle *p;
1088 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
1089 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
1090 SPOOLSS_NOTIFY_MSG *messages;
1091 int sending_msg_count;
1094 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1098 messages = msg_group->msgs;
1101 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
1105 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1107 /* loop over all printers */
1109 for (p = printers_list; p; p = p->next) {
1110 struct spoolss_Notify *notifies;
1115 /* Is there notification on this handle? */
1117 if ( !p->notify.client_connected )
1120 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1122 /* For this printer? Print servers always receive
1125 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1126 ( !strequal(msg_group->printername, p->sharename) ) )
1129 DEBUG(10,("Our printer\n"));
1131 /* allocate the max entries possible */
1133 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1138 /* build the array of change notifications */
1140 sending_msg_count = 0;
1142 for ( i=0; i<msg_group->num_msgs; i++ ) {
1143 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1145 /* Are we monitoring this event? */
1147 if (!is_monitoring_event(p, msg->type, msg->field))
1150 sending_msg_count++;
1153 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1154 msg->type, msg->field, p->sharename));
1157 * if the is a printer notification handle and not a job notification
1158 * type, then set the id to 0. Other wise just use what was specified
1161 * When registering change notification on a print server handle
1162 * we always need to send back the id (snum) matching the printer
1163 * for which the change took place. For change notify registered
1164 * on a printer handle, this does not matter and the id should be 0.
1169 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1175 /* Convert unix jobid to smb jobid */
1177 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1178 id = sysjob_to_jobid(msg->id);
1181 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1186 construct_info_data(¬ifies[count],
1187 (enum spoolss_NotifyType) msg->type,
1192 case PRINTER_NOTIFY_TYPE:
1193 if ( printer_notify_table[msg->field].fn )
1194 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1197 case JOB_NOTIFY_TYPE:
1198 if ( job_notify_table[msg->field].fn )
1199 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1203 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1210 if ( sending_msg_count ) {
1213 union spoolss_ReplyPrinterInfo info;
1214 struct spoolss_NotifyInfo info0;
1215 uint32_t reply_result;
1217 info0.version = 0x2;
1218 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1219 info0.count = count;
1220 info0.notifies = notifies;
1222 info.info0 = &info0;
1224 status = rpccli_spoolss_RouterReplyPrinterEx(back_channel.cli_pipe, mem_ctx,
1225 &p->notify.client_hnd,
1226 p->notify.change, /* color */
1229 0, /* reply_type, must be 0 */
1232 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1233 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1234 back_channel.cli_pipe->srv_name_slash,
1237 switch (reply_result) {
1240 case PRINTER_NOTIFY_INFO_DISCARDED:
1241 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1242 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1251 DEBUG(8,("send_notify2_changes: Exit...\n"));
1255 /***********************************************************************
1256 **********************************************************************/
1258 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1261 uint32_t tv_sec, tv_usec;
1264 /* Unpack message */
1266 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1269 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1271 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1274 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1275 &msg->notify.value[0], &msg->notify.value[1]);
1277 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1278 &msg->len, &msg->notify.data);
1280 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1281 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1283 tv->tv_sec = tv_sec;
1284 tv->tv_usec = tv_usec;
1287 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1288 msg->notify.value[1]));
1290 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1295 /********************************************************************
1296 Receive a notify2 message list
1297 ********************************************************************/
1299 static void receive_notify2_message_list(struct messaging_context *msg,
1302 struct server_id server_id,
1305 size_t msg_count, i;
1306 char *buf = (char *)data->data;
1309 SPOOLSS_NOTIFY_MSG notify;
1310 SPOOLSS_NOTIFY_MSG_CTR messages;
1313 if (data->length < 4) {
1314 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1318 msg_count = IVAL(buf, 0);
1321 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1323 if (msg_count == 0) {
1324 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1328 /* initialize the container */
1330 ZERO_STRUCT( messages );
1331 notify_msg_ctr_init( &messages );
1334 * build message groups for each printer identified
1335 * in a change_notify msg. Remember that a PCN message
1336 * includes the handle returned for the srv_spoolss_replyopenprinter()
1337 * call. Therefore messages are grouped according to printer handle.
1340 for ( i=0; i<msg_count; i++ ) {
1341 struct timeval msg_tv;
1343 if (msg_ptr + 4 - buf > data->length) {
1344 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1348 msg_len = IVAL(msg_ptr,0);
1351 if (msg_ptr + msg_len - buf > data->length) {
1352 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1356 /* unpack messages */
1358 ZERO_STRUCT( notify );
1359 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1362 /* add to correct list in container */
1364 notify_msg_ctr_addmsg( &messages, ¬ify );
1366 /* free memory that might have been allocated by notify2_unpack_msg() */
1368 if ( notify.len != 0 )
1369 SAFE_FREE( notify.notify.data );
1372 /* process each group of messages */
1374 num_groups = notify_msg_ctr_numgroups( &messages );
1375 for ( i=0; i<num_groups; i++ )
1376 send_notify2_changes( &messages, i );
1381 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1382 (uint32_t)msg_count ));
1384 notify_msg_ctr_destroy( &messages );
1389 /********************************************************************
1390 Send a message to ourself about new driver being installed
1391 so we can upgrade the information for each printer bound to this
1393 ********************************************************************/
1395 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1396 struct messaging_context *msg_ctx)
1398 int len = strlen(drivername);
1403 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1406 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1407 MSG_PRINTER_DRVUPGRADE,
1408 (uint8_t *)drivername, len+1);
1413 /**********************************************************************
1414 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1415 over all printers, upgrading ones as necessary
1416 **********************************************************************/
1418 void do_drv_upgrade_printer(struct messaging_context *msg,
1421 struct server_id server_id,
1424 TALLOC_CTX *tmp_ctx;
1425 struct auth_serversupplied_info *server_info = NULL;
1426 struct spoolss_PrinterInfo2 *pinfo2;
1429 const char *drivername;
1431 int n_services = lp_numservices();
1434 tmp_ctx = talloc_new(NULL);
1435 if (!tmp_ctx) return;
1437 status = make_server_info_system(tmp_ctx, &server_info);
1438 if (!NT_STATUS_IS_OK(status)) {
1439 DEBUG(0, ("do_drv_upgrade_printer: "
1440 "Could not create system server_info\n"));
1444 len = MIN(data->length,sizeof(drivername)-1);
1445 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1447 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1451 DEBUG(10, ("do_drv_upgrade_printer: "
1452 "Got message for new driver [%s]\n", drivername));
1454 /* Iterate the printer list */
1456 for (snum = 0; snum < n_services; snum++) {
1457 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1461 result = winreg_get_printer(tmp_ctx, server_info, msg,
1463 lp_const_servicename(snum),
1466 if (!W_ERROR_IS_OK(result)) {
1470 if (!pinfo2->drivername) {
1474 if (strcmp(drivername, pinfo2->drivername) != 0) {
1478 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1480 /* all we care about currently is the change_id */
1481 result = winreg_printer_update_changeid(tmp_ctx,
1484 pinfo2->printername);
1486 if (!W_ERROR_IS_OK(result)) {
1487 DEBUG(3, ("do_drv_upgrade_printer: "
1488 "Failed to update changeid [%s]\n",
1489 win_errstr(result)));
1495 talloc_free(tmp_ctx);
1498 /********************************************************************
1499 Update the cache for all printq's with a registered client
1501 ********************************************************************/
1503 void update_monitored_printq_cache(struct messaging_context *msg_ctx)
1505 struct printer_handle *printer = printers_list;
1508 /* loop through all printers and update the cache where
1509 client_connected == true */
1512 if ( (printer->printer_type == SPLHND_PRINTER)
1513 && printer->notify.client_connected )
1515 snum = print_queue_snum(printer->sharename);
1516 print_queue_status(msg_ctx, snum, NULL, NULL );
1519 printer = printer->next;
1525 /****************************************************************
1526 _spoolss_OpenPrinter
1527 ****************************************************************/
1529 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1530 struct spoolss_OpenPrinter *r)
1532 struct spoolss_OpenPrinterEx e;
1535 ZERO_STRUCT(e.in.userlevel);
1537 e.in.printername = r->in.printername;
1538 e.in.datatype = r->in.datatype;
1539 e.in.devmode_ctr = r->in.devmode_ctr;
1540 e.in.access_mask = r->in.access_mask;
1543 e.out.handle = r->out.handle;
1545 werr = _spoolss_OpenPrinterEx(p, &e);
1547 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1548 /* OpenPrinterEx returns this for a bad
1549 * printer name. We must return WERR_INVALID_PRINTER_NAME
1552 werr = WERR_INVALID_PRINTER_NAME;
1558 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1559 struct spoolss_DeviceMode *orig,
1560 struct spoolss_DeviceMode **dest)
1562 struct spoolss_DeviceMode *dm;
1564 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1569 /* copy all values, then duplicate strings and structs */
1572 dm->devicename = talloc_strdup(dm, orig->devicename);
1573 if (!dm->devicename) {
1576 dm->formname = talloc_strdup(dm, orig->formname);
1577 if (!dm->formname) {
1580 if (orig->driverextra_data.data) {
1581 dm->driverextra_data.data =
1582 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1583 orig->driverextra_data.length);
1584 if (!dm->driverextra_data.data) {
1593 /****************************************************************
1594 _spoolss_OpenPrinterEx
1595 ****************************************************************/
1597 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1598 struct spoolss_OpenPrinterEx *r)
1601 struct printer_handle *Printer=NULL;
1603 if (!r->in.printername) {
1604 return WERR_INVALID_PARAM;
1607 /* some sanity check because you can open a printer or a print server */
1608 /* aka: \\server\printer or \\server */
1610 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1612 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1613 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1614 "for printer %s\n", r->in.printername));
1615 ZERO_STRUCTP(r->out.handle);
1616 return WERR_INVALID_PARAM;
1619 Printer = find_printer_index_by_hnd(p, r->out.handle);
1621 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1622 "handle we created for printer %s\n", r->in.printername));
1623 close_printer_handle(p, r->out.handle);
1624 ZERO_STRUCTP(r->out.handle);
1625 return WERR_INVALID_PARAM;
1629 * First case: the user is opening the print server:
1631 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1632 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1634 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1635 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1636 * or if the user is listed in the smb.conf printer admin parameter.
1638 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1639 * client view printer folder, but does not show the MSAPW.
1641 * Note: this test needs code to check access rights here too. Jeremy
1642 * could you look at this?
1644 * Second case: the user is opening a printer:
1645 * NT doesn't let us connect to a printer if the connecting user
1646 * doesn't have print permission.
1648 * Third case: user is opening a Port Monitor
1649 * access checks same as opening a handle to the print server.
1652 switch (Printer->printer_type )
1655 case SPLHND_PORTMON_TCP:
1656 case SPLHND_PORTMON_LOCAL:
1657 /* Printserver handles use global struct... */
1661 /* Map standard access rights to object specific access rights */
1663 se_map_standard(&r->in.access_mask,
1664 &printserver_std_mapping);
1666 /* Deny any object specific bits that don't apply to print
1667 servers (i.e printer and job specific bits) */
1669 r->in.access_mask &= SEC_MASK_SPECIFIC;
1671 if (r->in.access_mask &
1672 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1673 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1674 close_printer_handle(p, r->out.handle);
1675 ZERO_STRUCTP(r->out.handle);
1676 return WERR_ACCESS_DENIED;
1679 /* Allow admin access */
1681 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1683 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1685 if (!lp_ms_add_printer_wizard()) {
1686 close_printer_handle(p, r->out.handle);
1687 ZERO_STRUCTP(r->out.handle);
1688 return WERR_ACCESS_DENIED;
1691 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1692 and not a printer admin, then fail */
1694 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1695 !user_has_privileges(p->server_info->ptok,
1697 !token_contains_name_in_list(
1698 uidtoname(p->server_info->utok.uid),
1699 p->server_info->info3->base.domain.string,
1701 p->server_info->ptok,
1702 lp_printer_admin(snum))) {
1703 close_printer_handle(p, r->out.handle);
1704 ZERO_STRUCTP(r->out.handle);
1705 return WERR_ACCESS_DENIED;
1708 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1712 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1715 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1716 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1718 /* We fall through to return WERR_OK */
1721 case SPLHND_PRINTER:
1722 /* NT doesn't let us connect to a printer if the connecting user
1723 doesn't have print permission. */
1725 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1726 close_printer_handle(p, r->out.handle);
1727 ZERO_STRUCTP(r->out.handle);
1731 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1732 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1735 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1737 /* map an empty access mask to the minimum access mask */
1738 if (r->in.access_mask == 0x0)
1739 r->in.access_mask = PRINTER_ACCESS_USE;
1742 * If we are not serving the printer driver for this printer,
1743 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1744 * will keep NT clients happy --jerry
1747 if (lp_use_client_driver(snum)
1748 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1750 r->in.access_mask = PRINTER_ACCESS_USE;
1753 /* check smb.conf parameters and the the sec_desc */
1755 if (!allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
1756 p->client_id->name, p->client_id->addr)) {
1757 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1758 ZERO_STRUCTP(r->out.handle);
1759 return WERR_ACCESS_DENIED;
1762 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1763 p->server_info->ptok, snum) ||
1764 !print_access_check(get_server_info_system(),
1767 r->in.access_mask)) {
1768 DEBUG(3, ("access DENIED for printer open\n"));
1769 close_printer_handle(p, r->out.handle);
1770 ZERO_STRUCTP(r->out.handle);
1771 return WERR_ACCESS_DENIED;
1774 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1775 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1776 close_printer_handle(p, r->out.handle);
1777 ZERO_STRUCTP(r->out.handle);
1778 return WERR_ACCESS_DENIED;
1781 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1782 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1784 r->in.access_mask = PRINTER_ACCESS_USE;
1786 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1787 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1789 winreg_create_printer(p->mem_ctx,
1790 get_server_info_system(),
1792 Printer->servername,
1793 lp_const_servicename(snum));
1798 /* sanity check to prevent programmer error */
1799 ZERO_STRUCTP(r->out.handle);
1803 Printer->access_granted = r->in.access_mask;
1806 * If the client sent a devmode in the OpenPrinter() call, then
1807 * save it here in case we get a job submission on this handle
1810 if ((Printer->printer_type != SPLHND_SERVER) &&
1811 r->in.devmode_ctr.devmode) {
1812 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1816 #if 0 /* JERRY -- I'm doubtful this is really effective */
1817 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1818 optimization in Windows 2000 clients --jerry */
1820 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1821 && (RA_WIN2K == get_remote_arch()) )
1823 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1824 sys_usleep( 500000 );
1831 /****************************************************************
1832 _spoolss_ClosePrinter
1833 ****************************************************************/
1835 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1836 struct spoolss_ClosePrinter *r)
1838 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1840 if (Printer && Printer->document_started) {
1841 struct spoolss_EndDocPrinter e;
1843 e.in.handle = r->in.handle;
1845 _spoolss_EndDocPrinter(p, &e);
1848 if (!close_printer_handle(p, r->in.handle))
1851 /* clear the returned printer handle. Observed behavior
1852 from Win2k server. Don't think this really matters.
1853 Previous code just copied the value of the closed
1856 ZERO_STRUCTP(r->out.handle);
1861 /****************************************************************
1862 _spoolss_DeletePrinter
1863 ****************************************************************/
1865 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1866 struct spoolss_DeletePrinter *r)
1868 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1872 if (Printer && Printer->document_started) {
1873 struct spoolss_EndDocPrinter e;
1875 e.in.handle = r->in.handle;
1877 _spoolss_EndDocPrinter(p, &e);
1880 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1881 winreg_delete_printer_key(p->mem_ctx,
1882 get_server_info_system(),
1884 lp_const_servicename(snum),
1888 result = delete_printer_handle(p, r->in.handle);
1893 /*******************************************************************
1894 * static function to lookup the version id corresponding to an
1895 * long architecture string
1896 ******************************************************************/
1898 static const struct print_architecture_table_node archi_table[]= {
1900 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1901 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1902 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1903 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1904 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1905 {"Windows IA64", SPL_ARCH_IA64, 3 },
1906 {"Windows x64", SPL_ARCH_X64, 3 },
1910 static int get_version_id(const char *arch)
1914 for (i=0; archi_table[i].long_archi != NULL; i++)
1916 if (strcmp(arch, archi_table[i].long_archi) == 0)
1917 return (archi_table[i].version);
1923 /****************************************************************
1924 _spoolss_DeletePrinterDriver
1925 ****************************************************************/
1927 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1928 struct spoolss_DeletePrinterDriver *r)
1931 struct spoolss_DriverInfo8 *info = NULL;
1932 struct spoolss_DriverInfo8 *info_win2k = NULL;
1935 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1937 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1938 and not a printer admin, then fail */
1940 if ( (p->server_info->utok.uid != sec_initial_uid())
1941 && !user_has_privileges(p->server_info->ptok, &se_printop )
1942 && !token_contains_name_in_list(
1943 uidtoname(p->server_info->utok.uid),
1944 p->server_info->info3->base.domain.string,
1946 p->server_info->ptok,
1947 lp_printer_admin(-1)) )
1949 return WERR_ACCESS_DENIED;
1952 /* check that we have a valid driver name first */
1954 if ((version = get_version_id(r->in.architecture)) == -1)
1955 return WERR_INVALID_ENVIRONMENT;
1957 status = winreg_get_driver(p->mem_ctx,
1958 get_server_info_system(),
1960 r->in.architecture, r->in.driver,
1962 if (!W_ERROR_IS_OK(status)) {
1963 /* try for Win2k driver if "Windows NT x86" */
1965 if ( version == 2 ) {
1968 status = winreg_get_driver(p->mem_ctx,
1969 get_server_info_system(),
1974 if (!W_ERROR_IS_OK(status)) {
1975 status = WERR_UNKNOWN_PRINTER_DRIVER;
1979 /* otherwise it was a failure */
1981 status = WERR_UNKNOWN_PRINTER_DRIVER;
1987 if (printer_driver_in_use(p->mem_ctx,
1988 get_server_info_system(),
1991 status = WERR_PRINTER_DRIVER_IN_USE;
1996 status = winreg_get_driver(p->mem_ctx,
1997 get_server_info_system(),
2000 r->in.driver, 3, &info_win2k);
2001 if (W_ERROR_IS_OK(status)) {
2002 /* if we get to here, we now have 2 driver info structures to remove */
2003 /* remove the Win2k driver first*/
2005 status = winreg_del_driver(p->mem_ctx,
2006 get_server_info_system(),
2009 talloc_free(info_win2k);
2011 /* this should not have failed---if it did, report to client */
2012 if (!W_ERROR_IS_OK(status)) {
2018 status = winreg_del_driver(p->mem_ctx,
2019 get_server_info_system(),
2029 /****************************************************************
2030 _spoolss_DeletePrinterDriverEx
2031 ****************************************************************/
2033 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
2034 struct spoolss_DeletePrinterDriverEx *r)
2036 struct spoolss_DriverInfo8 *info = NULL;
2037 struct spoolss_DriverInfo8 *info_win2k = NULL;
2041 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2043 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2044 and not a printer admin, then fail */
2046 if ( (p->server_info->utok.uid != sec_initial_uid())
2047 && !user_has_privileges(p->server_info->ptok, &se_printop )
2048 && !token_contains_name_in_list(
2049 uidtoname(p->server_info->utok.uid),
2050 p->server_info->info3->base.domain.string,
2052 p->server_info->ptok, lp_printer_admin(-1)) )
2054 return WERR_ACCESS_DENIED;
2057 /* check that we have a valid driver name first */
2058 if ((version = get_version_id(r->in.architecture)) == -1) {
2059 /* this is what NT returns */
2060 return WERR_INVALID_ENVIRONMENT;
2063 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2064 version = r->in.version;
2066 status = winreg_get_driver(p->mem_ctx,
2067 get_server_info_system(),
2073 if (!W_ERROR_IS_OK(status)) {
2074 status = WERR_UNKNOWN_PRINTER_DRIVER;
2077 * if the client asked for a specific version,
2078 * or this is something other than Windows NT x86,
2082 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2085 /* try for Win2k driver if "Windows NT x86" */
2088 status = winreg_get_driver(info,
2089 get_server_info_system(),
2094 if (!W_ERROR_IS_OK(status)) {
2095 status = WERR_UNKNOWN_PRINTER_DRIVER;
2100 if (printer_driver_in_use(info,
2101 get_server_info_system(),
2104 status = WERR_PRINTER_DRIVER_IN_USE;
2109 * we have a couple of cases to consider.
2110 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2111 * then the delete should fail if **any** files overlap with
2113 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2114 * non-overlapping files
2115 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2116 * is set, the do not delete any files
2117 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2120 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2122 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2125 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2126 printer_driver_files_in_use(info,
2127 get_server_info_system(),
2130 /* no idea of the correct error here */
2131 status = WERR_ACCESS_DENIED;
2136 /* also check for W32X86/3 if necessary; maybe we already have? */
2138 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2139 status = winreg_get_driver(info,
2140 get_server_info_system(),
2143 r->in.driver, 3, &info_win2k);
2144 if (W_ERROR_IS_OK(status)) {
2147 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2148 printer_driver_files_in_use(info,
2149 get_server_info_system(),
2152 /* no idea of the correct error here */
2153 talloc_free(info_win2k);
2154 status = WERR_ACCESS_DENIED;
2158 /* if we get to here, we now have 2 driver info structures to remove */
2159 /* remove the Win2k driver first*/
2161 status = winreg_del_driver(info,
2162 get_server_info_system(),
2167 /* this should not have failed---if it did, report to client */
2169 if (!W_ERROR_IS_OK(status)) {
2174 * now delete any associated files if delete_files is
2175 * true. Even if this part failes, we return succes
2176 * because the driver doesn not exist any more
2179 delete_driver_files(get_server_info_system(),
2185 status = winreg_del_driver(info,
2186 get_server_info_system(),
2190 if (!W_ERROR_IS_OK(status)) {
2195 * now delete any associated files if delete_files is
2196 * true. Even if this part failes, we return succes
2197 * because the driver doesn not exist any more
2200 delete_driver_files(get_server_info_system(), info);
2209 /********************************************************************
2210 GetPrinterData on a printer server Handle.
2211 ********************************************************************/
2213 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2215 enum winreg_Type *type,
2216 union spoolss_PrinterData *data)
2218 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2220 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2226 if (!StrCaseCmp(value, "BeepEnabled")) {
2232 if (!StrCaseCmp(value, "EventLog")) {
2234 /* formally was 0x1b */
2239 if (!StrCaseCmp(value, "NetPopup")) {
2245 if (!StrCaseCmp(value, "MajorVersion")) {
2248 /* Windows NT 4.0 seems to not allow uploading of drivers
2249 to a server that reports 0x3 as the MajorVersion.
2250 need to investigate more how Win2k gets around this .
2253 if (RA_WINNT == get_remote_arch()) {
2262 if (!StrCaseCmp(value, "MinorVersion")) {
2269 * uint32_t size = 0x114
2270 * uint32_t major = 5
2271 * uint32_t minor = [0|1]
2272 * uint32_t build = [2195|2600]
2273 * extra unicode string = e.g. "Service Pack 3"
2275 if (!StrCaseCmp(value, "OSVersion")) {
2277 enum ndr_err_code ndr_err;
2278 struct spoolss_OSVersion os;
2280 os.major = 5; /* Windows 2000 == 5.0 */
2282 os.build = 2195; /* build */
2283 os.extra_string = ""; /* leave extra string empty */
2285 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2286 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2287 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2288 return WERR_GENERAL_FAILURE;
2292 data->binary = blob;
2298 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2301 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2302 W_ERROR_HAVE_NO_MEMORY(data->string);
2307 if (!StrCaseCmp(value, "Architecture")) {
2309 data->string = talloc_strdup(mem_ctx,
2310 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2311 W_ERROR_HAVE_NO_MEMORY(data->string);
2316 if (!StrCaseCmp(value, "DsPresent")) {
2319 /* only show the publish check box if we are a
2320 member of a AD domain */
2322 if (lp_security() == SEC_ADS) {
2330 if (!StrCaseCmp(value, "DNSMachineName")) {
2331 const char *hostname = get_mydnsfullname();
2334 return WERR_BADFILE;
2338 data->string = talloc_strdup(mem_ctx, hostname);
2339 W_ERROR_HAVE_NO_MEMORY(data->string);
2346 return WERR_INVALID_PARAM;
2349 /****************************************************************
2350 _spoolss_GetPrinterData
2351 ****************************************************************/
2353 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2354 struct spoolss_GetPrinterData *r)
2356 struct spoolss_GetPrinterDataEx r2;
2358 r2.in.handle = r->in.handle;
2359 r2.in.key_name = "PrinterDriverData";
2360 r2.in.value_name = r->in.value_name;
2361 r2.in.offered = r->in.offered;
2362 r2.out.type = r->out.type;
2363 r2.out.data = r->out.data;
2364 r2.out.needed = r->out.needed;
2366 return _spoolss_GetPrinterDataEx(p, &r2);
2369 /*********************************************************
2370 Connect to the client machine.
2371 **********************************************************/
2373 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2374 struct sockaddr_storage *client_ss, const char *remote_machine)
2377 struct cli_state *the_cli;
2378 struct sockaddr_storage rm_addr;
2379 char addr[INET6_ADDRSTRLEN];
2381 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2382 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2384 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2385 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2388 print_sockaddr(addr, sizeof(addr), &rm_addr);
2390 rm_addr = *client_ss;
2391 print_sockaddr(addr, sizeof(addr), &rm_addr);
2392 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2396 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2397 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2402 /* setup the connection */
2403 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2404 &rm_addr, 0, "IPC$", "IPC",
2408 0, lp_client_signing(), NULL );
2410 if ( !NT_STATUS_IS_OK( ret ) ) {
2411 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2416 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2417 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2418 cli_shutdown(the_cli);
2423 * Ok - we have an anonymous connection to the IPC$ share.
2424 * Now start the NT Domain stuff :-).
2427 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2428 if (!NT_STATUS_IS_OK(ret)) {
2429 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2430 remote_machine, nt_errstr(ret)));
2431 cli_shutdown(the_cli);
2438 /***************************************************************************
2439 Connect to the client.
2440 ****************************************************************************/
2442 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2443 uint32_t localprinter,
2444 enum winreg_Type type,
2445 struct policy_handle *handle,
2446 struct sockaddr_storage *client_ss,
2447 struct messaging_context *msg_ctx)
2453 * If it's the first connection, contact the client
2454 * and connect to the IPC$ share anonymously
2456 if (back_channel.active_channels == 0) {
2457 fstring unix_printer;
2459 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2461 if ( !spoolss_connect_to_client( &back_channel.cli_pipe, client_ss, unix_printer ))
2464 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2465 receive_notify2_message_list);
2466 /* Tell the connections db we're now interested in printer
2467 * notify messages. */
2468 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2469 true, FLAG_MSG_PRINT_NOTIFY);
2473 * Tell the specific printing tdb we want messages for this printer
2474 * by registering our PID.
2477 if (!print_notify_register_pid(snum))
2478 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2480 back_channel.active_channels++;
2482 status = rpccli_spoolss_ReplyOpenPrinter(back_channel.cli_pipe, talloc_tos(),
2490 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2491 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2492 win_errstr(result)));
2494 return (W_ERROR_IS_OK(result));
2497 /****************************************************************
2498 ****************************************************************/
2500 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2501 const struct spoolss_NotifyOption *r)
2503 struct spoolss_NotifyOption *option;
2510 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2517 if (!option->count) {
2521 option->types = talloc_zero_array(option,
2522 struct spoolss_NotifyOptionType, option->count);
2523 if (!option->types) {
2524 talloc_free(option);
2528 for (i=0; i < option->count; i++) {
2529 option->types[i] = r->types[i];
2531 if (option->types[i].count) {
2532 option->types[i].fields = talloc_zero_array(option,
2533 union spoolss_Field, option->types[i].count);
2534 if (!option->types[i].fields) {
2535 talloc_free(option);
2538 for (k=0; k<option->types[i].count; k++) {
2539 option->types[i].fields[k] =
2540 r->types[i].fields[k];
2548 /****************************************************************
2549 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2551 * before replying OK: status=0 a rpc call is made to the workstation
2552 * asking ReplyOpenPrinter
2554 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2555 * called from api_spoolss_rffpcnex
2556 ****************************************************************/
2558 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2559 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2562 struct spoolss_NotifyOption *option = r->in.notify_options;
2563 struct sockaddr_storage client_ss;
2565 /* store the notify value in the printer struct */
2567 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
2570 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2571 "Invalid handle (%s:%u:%u).\n",
2572 OUR_HANDLE(r->in.handle)));
2576 Printer->notify.flags = r->in.flags;
2577 Printer->notify.options = r->in.options;
2578 Printer->notify.printerlocal = r->in.printer_local;
2579 Printer->notify.msg_ctx = p->msg_ctx;
2581 TALLOC_FREE(Printer->notify.option);
2582 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2584 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2586 /* Connect to the client machine and send a ReplyOpenPrinter */
2588 if ( Printer->printer_type == SPLHND_SERVER)
2590 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2591 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2594 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2595 "client_address is %s\n", p->client_id->addr));
2597 if (!interpret_string_addr(&client_ss, p->client_id->addr,
2599 return WERR_SERVER_UNAVAILABLE;
2602 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2603 Printer->notify.printerlocal, REG_SZ,
2604 &Printer->notify.client_hnd,
2605 &client_ss, p->msg_ctx))
2606 return WERR_SERVER_UNAVAILABLE;
2608 Printer->notify.client_connected = true;
2613 /*******************************************************************
2614 * fill a notify_info_data with the servername
2615 ********************************************************************/
2617 static void spoolss_notify_server_name(struct messaging_context *msg_ctx,
2619 struct spoolss_Notify *data,
2620 print_queue_struct *queue,
2621 struct spoolss_PrinterInfo2 *pinfo2,
2622 TALLOC_CTX *mem_ctx)
2624 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2627 /*******************************************************************
2628 * fill a notify_info_data with the printername (not including the servername).
2629 ********************************************************************/
2631 static void spoolss_notify_printer_name(struct messaging_context *msg_ctx,
2633 struct spoolss_Notify *data,
2634 print_queue_struct *queue,
2635 struct spoolss_PrinterInfo2 *pinfo2,
2636 TALLOC_CTX *mem_ctx)
2638 /* the notify name should not contain the \\server\ part */
2639 const char *p = strrchr(pinfo2->printername, '\\');
2642 p = pinfo2->printername;
2647 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2650 /*******************************************************************
2651 * fill a notify_info_data with the servicename
2652 ********************************************************************/
2654 static void spoolss_notify_share_name(struct messaging_context *msg_ctx,
2656 struct spoolss_Notify *data,
2657 print_queue_struct *queue,
2658 struct spoolss_PrinterInfo2 *pinfo2,
2659 TALLOC_CTX *mem_ctx)
2661 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2664 /*******************************************************************
2665 * fill a notify_info_data with the port name
2666 ********************************************************************/
2668 static void spoolss_notify_port_name(struct messaging_context *msg_ctx,
2670 struct spoolss_Notify *data,
2671 print_queue_struct *queue,
2672 struct spoolss_PrinterInfo2 *pinfo2,
2673 TALLOC_CTX *mem_ctx)
2675 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2678 /*******************************************************************
2679 * fill a notify_info_data with the printername
2680 * but it doesn't exist, have to see what to do
2681 ********************************************************************/
2683 static void spoolss_notify_driver_name(struct messaging_context *msg_ctx,
2685 struct spoolss_Notify *data,
2686 print_queue_struct *queue,
2687 struct spoolss_PrinterInfo2 *pinfo2,
2688 TALLOC_CTX *mem_ctx)
2690 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2693 /*******************************************************************
2694 * fill a notify_info_data with the comment
2695 ********************************************************************/
2697 static void spoolss_notify_comment(struct messaging_context *msg_ctx,
2699 struct spoolss_Notify *data,
2700 print_queue_struct *queue,
2701 struct spoolss_PrinterInfo2 *pinfo2,
2702 TALLOC_CTX *mem_ctx)
2706 if (*pinfo2->comment == '\0') {
2707 p = lp_comment(snum);
2709 p = pinfo2->comment;
2712 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2715 /*******************************************************************
2716 * fill a notify_info_data with the comment
2717 * location = "Room 1, floor 2, building 3"
2718 ********************************************************************/
2720 static void spoolss_notify_location(struct messaging_context *msg_ctx,
2722 struct spoolss_Notify *data,
2723 print_queue_struct *queue,
2724 struct spoolss_PrinterInfo2 *pinfo2,
2725 TALLOC_CTX *mem_ctx)
2727 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2730 /*******************************************************************
2731 * fill a notify_info_data with the device mode
2732 * jfm:xxxx don't to it for know but that's a real problem !!!
2733 ********************************************************************/
2735 static void spoolss_notify_devmode(struct messaging_context *msg_ctx,
2737 struct spoolss_Notify *data,
2738 print_queue_struct *queue,
2739 struct spoolss_PrinterInfo2 *pinfo2,
2740 TALLOC_CTX *mem_ctx)
2742 /* for a dummy implementation we have to zero the fields */
2743 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2746 /*******************************************************************
2747 * fill a notify_info_data with the separator file name
2748 ********************************************************************/
2750 static void spoolss_notify_sepfile(struct messaging_context *msg_ctx,
2752 struct spoolss_Notify *data,
2753 print_queue_struct *queue,
2754 struct spoolss_PrinterInfo2 *pinfo2,
2755 TALLOC_CTX *mem_ctx)
2757 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2760 /*******************************************************************
2761 * fill a notify_info_data with the print processor
2762 * jfm:xxxx return always winprint to indicate we don't do anything to it
2763 ********************************************************************/
2765 static void spoolss_notify_print_processor(struct messaging_context *msg_ctx,
2767 struct spoolss_Notify *data,
2768 print_queue_struct *queue,
2769 struct spoolss_PrinterInfo2 *pinfo2,
2770 TALLOC_CTX *mem_ctx)
2772 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2775 /*******************************************************************
2776 * fill a notify_info_data with the print processor options
2777 * jfm:xxxx send an empty string
2778 ********************************************************************/
2780 static void spoolss_notify_parameters(struct messaging_context *msg_ctx,
2782 struct spoolss_Notify *data,
2783 print_queue_struct *queue,
2784 struct spoolss_PrinterInfo2 *pinfo2,
2785 TALLOC_CTX *mem_ctx)
2787 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2790 /*******************************************************************
2791 * fill a notify_info_data with the data type
2792 * jfm:xxxx always send RAW as data type
2793 ********************************************************************/
2795 static void spoolss_notify_datatype(struct messaging_context *msg_ctx,
2797 struct spoolss_Notify *data,
2798 print_queue_struct *queue,
2799 struct spoolss_PrinterInfo2 *pinfo2,
2800 TALLOC_CTX *mem_ctx)
2802 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2805 /*******************************************************************
2806 * fill a notify_info_data with the security descriptor
2807 * jfm:xxxx send an null pointer to say no security desc
2808 * have to implement security before !
2809 ********************************************************************/
2811 static void spoolss_notify_security_desc(struct messaging_context *msg_ctx,
2813 struct spoolss_Notify *data,
2814 print_queue_struct *queue,
2815 struct spoolss_PrinterInfo2 *pinfo2,
2816 TALLOC_CTX *mem_ctx)
2818 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2821 /*******************************************************************
2822 * fill a notify_info_data with the attributes
2823 * jfm:xxxx a samba printer is always shared
2824 ********************************************************************/
2826 static void spoolss_notify_attributes(struct messaging_context *msg_ctx,
2828 struct spoolss_Notify *data,
2829 print_queue_struct *queue,
2830 struct spoolss_PrinterInfo2 *pinfo2,
2831 TALLOC_CTX *mem_ctx)
2833 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2836 /*******************************************************************
2837 * fill a notify_info_data with the priority
2838 ********************************************************************/
2840 static void spoolss_notify_priority(struct messaging_context *msg_ctx,
2842 struct spoolss_Notify *data,
2843 print_queue_struct *queue,
2844 struct spoolss_PrinterInfo2 *pinfo2,
2845 TALLOC_CTX *mem_ctx)
2847 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2850 /*******************************************************************
2851 * fill a notify_info_data with the default priority
2852 ********************************************************************/
2854 static void spoolss_notify_default_priority(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_INTEGER(data, pinfo2->defaultpriority);
2864 /*******************************************************************
2865 * fill a notify_info_data with the start time
2866 ********************************************************************/
2868 static void spoolss_notify_start_time(struct messaging_context *msg_ctx,
2870 struct spoolss_Notify *data,
2871 print_queue_struct *queue,
2872 struct spoolss_PrinterInfo2 *pinfo2,
2873 TALLOC_CTX *mem_ctx)
2875 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2878 /*******************************************************************
2879 * fill a notify_info_data with the until time
2880 ********************************************************************/
2882 static void spoolss_notify_until_time(struct messaging_context *msg_ctx,
2884 struct spoolss_Notify *data,
2885 print_queue_struct *queue,
2886 struct spoolss_PrinterInfo2 *pinfo2,
2887 TALLOC_CTX *mem_ctx)
2889 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2892 /*******************************************************************
2893 * fill a notify_info_data with the status
2894 ********************************************************************/
2896 static void spoolss_notify_status(struct messaging_context *msg_ctx,
2898 struct spoolss_Notify *data,
2899 print_queue_struct *queue,
2900 struct spoolss_PrinterInfo2 *pinfo2,
2901 TALLOC_CTX *mem_ctx)
2903 print_status_struct status;
2905 print_queue_length(msg_ctx, snum, &status);
2906 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2909 /*******************************************************************
2910 * fill a notify_info_data with the number of jobs queued
2911 ********************************************************************/
2913 static void spoolss_notify_cjobs(struct messaging_context *msg_ctx,
2915 struct spoolss_Notify *data,
2916 print_queue_struct *queue,
2917 struct spoolss_PrinterInfo2 *pinfo2,
2918 TALLOC_CTX *mem_ctx)
2920 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(
2921 data, print_queue_length(msg_ctx, snum, NULL));
2924 /*******************************************************************
2925 * fill a notify_info_data with the average ppm
2926 ********************************************************************/
2928 static void spoolss_notify_average_ppm(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 /* always respond 8 pages per minutes */
2936 /* a little hard ! */
2937 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2940 /*******************************************************************
2941 * fill a notify_info_data with username
2942 ********************************************************************/
2944 static void spoolss_notify_username(struct messaging_context *msg_ctx,
2946 struct spoolss_Notify *data,
2947 print_queue_struct *queue,
2948 struct spoolss_PrinterInfo2 *pinfo2,
2949 TALLOC_CTX *mem_ctx)
2951 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2954 /*******************************************************************
2955 * fill a notify_info_data with job status
2956 ********************************************************************/
2958 static void spoolss_notify_job_status(struct messaging_context *msg_ctx,
2960 struct spoolss_Notify *data,
2961 print_queue_struct *queue,
2962 struct spoolss_PrinterInfo2 *pinfo2,
2963 TALLOC_CTX *mem_ctx)
2965 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2968 /*******************************************************************
2969 * fill a notify_info_data with job name
2970 ********************************************************************/
2972 static void spoolss_notify_job_name(struct messaging_context *msg_ctx,
2974 struct spoolss_Notify *data,
2975 print_queue_struct *queue,
2976 struct spoolss_PrinterInfo2 *pinfo2,
2977 TALLOC_CTX *mem_ctx)
2979 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2982 /*******************************************************************
2983 * fill a notify_info_data with job status
2984 ********************************************************************/
2986 static void spoolss_notify_job_status_string(struct messaging_context *msg_ctx,
2988 struct spoolss_Notify *data,
2989 print_queue_struct *queue,
2990 struct spoolss_PrinterInfo2 *pinfo2,
2991 TALLOC_CTX *mem_ctx)
2994 * Now we're returning job status codes we just return a "" here. JRA.
2999 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3002 switch (queue->status) {
3007 p = ""; /* NT provides the paused string */
3016 #endif /* NO LONGER NEEDED. */
3018 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3021 /*******************************************************************
3022 * fill a notify_info_data with job time
3023 ********************************************************************/
3025 static void spoolss_notify_job_time(struct messaging_context *msg_ctx,
3027 struct spoolss_Notify *data,
3028 print_queue_struct *queue,
3029 struct spoolss_PrinterInfo2 *pinfo2,
3030 TALLOC_CTX *mem_ctx)
3032 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3035 /*******************************************************************
3036 * fill a notify_info_data with job size
3037 ********************************************************************/
3039 static void spoolss_notify_job_size(struct messaging_context *msg_ctx,
3041 struct spoolss_Notify *data,
3042 print_queue_struct *queue,
3043 struct spoolss_PrinterInfo2 *pinfo2,
3044 TALLOC_CTX *mem_ctx)
3046 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3049 /*******************************************************************
3050 * fill a notify_info_data with page info
3051 ********************************************************************/
3052 static void spoolss_notify_total_pages(struct messaging_context *msg_ctx,
3054 struct spoolss_Notify *data,
3055 print_queue_struct *queue,
3056 struct spoolss_PrinterInfo2 *pinfo2,
3057 TALLOC_CTX *mem_ctx)
3059 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3062 /*******************************************************************
3063 * fill a notify_info_data with pages printed info.
3064 ********************************************************************/
3065 static void spoolss_notify_pages_printed(struct messaging_context *msg_ctx,
3067 struct spoolss_Notify *data,
3068 print_queue_struct *queue,
3069 struct spoolss_PrinterInfo2 *pinfo2,
3070 TALLOC_CTX *mem_ctx)
3072 /* Add code when back-end tracks this */
3073 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3076 /*******************************************************************
3077 Fill a notify_info_data with job position.
3078 ********************************************************************/
3080 static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
3082 struct spoolss_Notify *data,
3083 print_queue_struct *queue,
3084 struct spoolss_PrinterInfo2 *pinfo2,
3085 TALLOC_CTX *mem_ctx)
3087 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3090 /*******************************************************************
3091 Fill a notify_info_data with submitted time.
3092 ********************************************************************/
3094 static void spoolss_notify_submitted_time(struct messaging_context *msg_ctx,
3096 struct spoolss_Notify *data,
3097 print_queue_struct *queue,
3098 struct spoolss_PrinterInfo2 *pinfo2,
3099 TALLOC_CTX *mem_ctx)
3101 data->data.string.string = NULL;
3102 data->data.string.size = 0;
3104 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3105 &data->data.string.string,
3106 &data->data.string.size);
3110 struct s_notify_info_data_table
3112 enum spoolss_NotifyType type;
3115 enum spoolss_NotifyTable variable_type;
3116 void (*fn) (struct messaging_context *msg_ctx,
3117 int snum, struct spoolss_Notify *data,
3118 print_queue_struct *queue,
3119 struct spoolss_PrinterInfo2 *pinfo2,
3120 TALLOC_CTX *mem_ctx);
3123 /* A table describing the various print notification constants and
3124 whether the notification data is a pointer to a variable sized
3125 buffer, a one value uint32_t or a two value uint32_t. */
3127 static const struct s_notify_info_data_table notify_info_data_table[] =
3129 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3130 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3131 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3132 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3133 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3134 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3135 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3136 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3137 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3138 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3139 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3140 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3141 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3142 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3143 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3144 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3145 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3146 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3147 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3148 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3149 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3150 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3151 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3152 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3153 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3154 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3155 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3156 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3157 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3158 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3159 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3160 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3161 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3162 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3163 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3164 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3165 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3166 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3167 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3168 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3169 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3170 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3171 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3172 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3173 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3174 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3175 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3176 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3177 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3180 /*******************************************************************
3181 Return the variable_type of info_data structure.
3182 ********************************************************************/
3184 static enum spoolss_NotifyTable variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3189 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3190 if ( (notify_info_data_table[i].type == type) &&
3191 (notify_info_data_table[i].field == field) ) {
3192 return notify_info_data_table[i].variable_type;
3196 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3198 return (enum spoolss_NotifyTable) 0;
3201 /****************************************************************************
3202 ****************************************************************************/
3204 static bool search_notify(enum spoolss_NotifyType type,
3210 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3211 if (notify_info_data_table[i].type == type &&
3212 notify_info_data_table[i].field == field &&
3213 notify_info_data_table[i].fn != NULL) {
3222 /****************************************************************************
3223 ****************************************************************************/
3225 static void construct_info_data(struct spoolss_Notify *info_data,
3226 enum spoolss_NotifyType type,
3227 uint16_t field, int id)
3229 info_data->type = type;
3230 info_data->field.field = field;
3231 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3232 info_data->job_id = id;
3235 /*******************************************************************
3237 * fill a notify_info struct with info asked
3239 ********************************************************************/
3241 static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
3242 struct printer_handle *print_hnd,
3243 struct spoolss_NotifyInfo *info,
3244 struct spoolss_PrinterInfo2 *pinfo2,
3246 const struct spoolss_NotifyOptionType *option_type,
3248 TALLOC_CTX *mem_ctx)
3251 enum spoolss_NotifyType type;
3254 struct spoolss_Notify *current_data;
3255 print_queue_struct *queue=NULL;
3257 type = option_type->type;
3259 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3260 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3261 option_type->count, lp_servicename(snum)));
3263 for(field_num=0; field_num < option_type->count; field_num++) {
3264 field = option_type->fields[field_num].field;
3266 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3268 if (!search_notify(type, field, &j) )
3271 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3272 struct spoolss_Notify,
3274 if (info->notifies == NULL) {
3275 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3279 current_data = &info->notifies[info->count];
3281 construct_info_data(current_data, type, field, id);
3283 DEBUG(10, ("construct_notify_printer_info: "
3284 "calling [%s] snum=%d printername=[%s])\n",
3285 notify_info_data_table[j].name, snum,
3286 pinfo2->printername));
3288 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3289 queue, pinfo2, mem_ctx);
3297 /*******************************************************************
3299 * fill a notify_info struct with info asked
3301 ********************************************************************/
3303 static bool construct_notify_jobs_info(struct messaging_context *msg_ctx,
3304 print_queue_struct *queue,
3305 struct spoolss_NotifyInfo *info,
3306 struct spoolss_PrinterInfo2 *pinfo2,
3308 const struct spoolss_NotifyOptionType *option_type,
3310 TALLOC_CTX *mem_ctx)
3313 enum spoolss_NotifyType type;
3315 struct spoolss_Notify *current_data;
3317 DEBUG(4,("construct_notify_jobs_info\n"));
3319 type = option_type->type;
3321 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3322 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3323 option_type->count));
3325 for(field_num=0; field_num<option_type->count; field_num++) {
3326 field = option_type->fields[field_num].field;
3328 if (!search_notify(type, field, &j) )
3331 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3332 struct spoolss_Notify,
3334 if (info->notifies == NULL) {
3335 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3339 current_data=&(info->notifies[info->count]);
3341 construct_info_data(current_data, type, field, id);
3342 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3343 queue, pinfo2, mem_ctx);
3351 * JFM: The enumeration is not that simple, it's even non obvious.
3353 * let's take an example: I want to monitor the PRINTER SERVER for
3354 * the printer's name and the number of jobs currently queued.
3355 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3356 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3358 * I have 3 printers on the back of my server.
3360 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3363 * 1 printer 1 name 1
3364 * 2 printer 1 cjob 1
3365 * 3 printer 2 name 2
3366 * 4 printer 2 cjob 2
3367 * 5 printer 3 name 3
3368 * 6 printer 3 name 3
3370 * that's the print server case, the printer case is even worse.
3373 /*******************************************************************
3375 * enumerate all printers on the printserver
3376 * fill a notify_info struct with info asked
3378 ********************************************************************/
3380 static WERROR printserver_notify_info(struct pipes_struct *p,
3381 struct policy_handle *hnd,
3382 struct spoolss_NotifyInfo *info,
3383 TALLOC_CTX *mem_ctx)
3386 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3387 int n_services=lp_numservices();
3389 struct spoolss_NotifyOption *option;
3390 struct spoolss_NotifyOptionType option_type;
3391 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3394 DEBUG(4,("printserver_notify_info\n"));
3399 option = Printer->notify.option;
3402 info->notifies = NULL;
3405 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3406 sending a ffpcn() request first */
3411 for (i=0; i<option->count; i++) {
3412 option_type = option->types[i];
3414 if (option_type.type != PRINTER_NOTIFY_TYPE)
3417 for (snum = 0; snum < n_services; snum++) {
3418 if (!lp_browseable(snum) ||
3419 !lp_snum_ok(snum) ||
3420 !lp_print_ok(snum)) {
3421 continue; /* skip */
3424 /* Maybe we should use the SYSTEM server_info here... */
3425 result = winreg_get_printer(mem_ctx,
3426 get_server_info_system(),
3428 Printer->servername,
3429 lp_servicename(snum),
3431 if (!W_ERROR_IS_OK(result)) {
3432 DEBUG(4, ("printserver_notify_info: "
3433 "Failed to get printer [%s]\n",
3434 lp_servicename(snum)));
3439 construct_notify_printer_info(p->msg_ctx,
3445 TALLOC_FREE(pinfo2);
3451 * Debugging information, don't delete.
3454 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3455 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3456 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3458 for (i=0; i<info->count; i++) {
3459 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3460 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3461 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3468 /*******************************************************************
3470 * fill a notify_info struct with info asked
3472 ********************************************************************/
3474 static WERROR printer_notify_info(struct pipes_struct *p,
3475 struct policy_handle *hnd,
3476 struct spoolss_NotifyInfo *info,
3477 TALLOC_CTX *mem_ctx)
3480 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3483 struct spoolss_NotifyOption *option;
3484 struct spoolss_NotifyOptionType option_type;
3486 print_queue_struct *queue=NULL;
3487 print_status_struct status;
3488 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3491 DEBUG(4,("printer_notify_info\n"));
3496 option = Printer->notify.option;
3500 info->notifies = NULL;
3503 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3504 sending a ffpcn() request first */
3509 get_printer_snum(p, hnd, &snum, NULL);
3511 /* Maybe we should use the SYSTEM server_info here... */
3512 result = winreg_get_printer(mem_ctx,
3513 get_server_info_system(),
3515 Printer->servername,
3516 lp_servicename(snum), &pinfo2);
3517 if (!W_ERROR_IS_OK(result)) {
3521 for (i=0; i<option->count; i++) {
3522 option_type = option->types[i];
3524 switch (option_type.type) {
3525 case PRINTER_NOTIFY_TYPE:
3526 if (construct_notify_printer_info(p->msg_ctx,
3535 case JOB_NOTIFY_TYPE:
3537 count = print_queue_status(p->msg_ctx, snum, &queue,
3540 for (j=0; j<count; j++) {
3541 construct_notify_jobs_info(p->msg_ctx,
3555 * Debugging information, don't delete.
3558 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3559 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3560 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3562 for (i=0; i<info->count; i++) {
3563 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3564 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3565 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3569 talloc_free(pinfo2);
3573 /****************************************************************
3574 _spoolss_RouterRefreshPrinterChangeNotify
3575 ****************************************************************/
3577 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3578 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3580 struct spoolss_NotifyInfo *info;
3582 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
3583 WERROR result = WERR_BADFID;
3585 /* we always have a spoolss_NotifyInfo struct */
3586 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3588 result = WERR_NOMEM;
3592 *r->out.info = info;
3595 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3596 "Invalid handle (%s:%u:%u).\n",
3597 OUR_HANDLE(r->in.handle)));
3601 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3604 * We are now using the change value, and
3605 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3606 * I don't have a global notification system, I'm sending back all the
3607 * informations even when _NOTHING_ has changed.
3610 /* We need to keep track of the change value to send back in
3611 RRPCN replies otherwise our updates are ignored. */
3613 Printer->notify.fnpcn = true;
3615 if (Printer->notify.client_connected) {
3616 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3617 "Saving change value in request [%x]\n",
3619 Printer->notify.change = r->in.change_low;
3622 /* just ignore the spoolss_NotifyOption */
3624 switch (Printer->printer_type) {
3626 result = printserver_notify_info(p, r->in.handle,
3630 case SPLHND_PRINTER:
3631 result = printer_notify_info(p, r->in.handle,
3636 Printer->notify.fnpcn = false;
3642 /********************************************************************
3643 * construct_printer_info_0
3644 * fill a printer_info_0 struct
3645 ********************************************************************/
3647 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3648 const struct auth_serversupplied_info *server_info,
3649 struct messaging_context *msg_ctx,
3650 struct spoolss_PrinterInfo2 *info2,
3651 struct spoolss_PrinterInfo0 *r,
3655 struct printer_session_counter *session_counter;
3656 struct timeval setuptime;
3657 print_status_struct status;
3659 r->printername = talloc_strdup(mem_ctx, info2->printername);
3660 W_ERROR_HAVE_NO_MEMORY(r->printername);
3662 r->servername = talloc_strdup(mem_ctx, info2->servername);
3663 W_ERROR_HAVE_NO_MEMORY(r->servername);
3665 count = print_queue_length(msg_ctx, snum, &status);
3667 /* check if we already have a counter for this printer */
3668 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3669 if (session_counter->snum == snum)
3673 /* it's the first time, add it to the list */
3674 if (session_counter == NULL) {
3675 session_counter = talloc_zero(counter_list, struct printer_session_counter);
3676 W_ERROR_HAVE_NO_MEMORY(session_counter);
3677 session_counter->snum = snum;
3678 session_counter->counter = 0;
3679 DLIST_ADD(counter_list, session_counter);
3683 session_counter->counter++;
3689 get_startup_time(&setuptime);
3690 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3693 * the global_counter should be stored in a TDB as it's common to all the clients
3694 * and should be zeroed on samba startup
3696 r->global_counter = session_counter->counter;
3698 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3699 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3700 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3701 r->free_build = SPOOLSS_RELEASE_BUILD;
3703 r->max_spooling = 0;
3704 r->session_counter = session_counter->counter;
3705 r->num_error_out_of_paper = 0x0;
3706 r->num_error_not_ready = 0x0; /* number of print failure */
3708 r->number_of_processors = 0x1;
3709 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3710 r->high_part_total_bytes = 0x0;
3712 /* ChangeID in milliseconds*/
3713 winreg_printer_get_changeid(mem_ctx, server_info, msg_ctx,
3714 info2->sharename, &r->change_id);
3716 r->last_error = WERR_OK;
3717 r->status = nt_printq_status(status.status);
3718 r->enumerate_network_printers = 0x0;
3719 r->c_setprinter = 0x0;
3720 r->processor_architecture = PROCESSOR_ARCHITECTURE_INTEL;
3721 r->processor_level = 0x6; /* 6 ???*/
3730 /********************************************************************
3731 * construct_printer_info1
3732 * fill a spoolss_PrinterInfo1 struct
3733 ********************************************************************/
3735 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3736 const struct spoolss_PrinterInfo2 *info2,
3738 struct spoolss_PrinterInfo1 *r,
3743 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3747 W_ERROR_HAVE_NO_MEMORY(r->description);
3749 if (info2->comment == NULL || info2->comment[0] == '\0') {
3750 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3752 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3754 W_ERROR_HAVE_NO_MEMORY(r->comment);
3756 r->name = talloc_strdup(mem_ctx, info2->printername);
3757 W_ERROR_HAVE_NO_MEMORY(r->name);
3762 /********************************************************************
3763 * construct_printer_info2
3764 * fill a spoolss_PrinterInfo2 struct
3765 ********************************************************************/
3767 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3768 struct messaging_context *msg_ctx,
3769 const struct spoolss_PrinterInfo2 *info2,
3770 struct spoolss_PrinterInfo2 *r,
3774 print_status_struct status;
3776 count = print_queue_length(msg_ctx, snum, &status);
3778 r->servername = talloc_strdup(mem_ctx, info2->servername);
3779 W_ERROR_HAVE_NO_MEMORY(r->servername);
3780 r->printername = talloc_strdup(mem_ctx, info2->printername);
3781 W_ERROR_HAVE_NO_MEMORY(r->printername);
3782 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3783 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3784 r->portname = talloc_strdup(mem_ctx, info2->portname);
3785 W_ERROR_HAVE_NO_MEMORY(r->portname);
3786 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3787 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3789 if (info2->comment[0] == '\0') {
3790 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3792 r->comment = talloc_strdup(mem_ctx, info2->comment);
3794 W_ERROR_HAVE_NO_MEMORY(r->comment);
3796 r->location = talloc_strdup(mem_ctx, info2->location);
3797 W_ERROR_HAVE_NO_MEMORY(r->location);
3798 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3799 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3800 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3801 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3802 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3803 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3804 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3805 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3807 r->attributes = info2->attributes;
3809 r->priority = info2->priority;
3810 r->defaultpriority = info2->defaultpriority;
3811 r->starttime = info2->starttime;
3812 r->untiltime = info2->untiltime;
3813 r->status = nt_printq_status(status.status);
3815 r->averageppm = info2->averageppm;
3817 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3819 DEBUG(8,("Returning NULL Devicemode!\n"));
3824 if (info2->secdesc != NULL) {
3825 /* don't use talloc_steal() here unless you do a deep steal of all
3826 the SEC_DESC members */
3828 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3834 /********************************************************************
3835 * construct_printer_info3
3836 * fill a spoolss_PrinterInfo3 struct
3837 ********************************************************************/
3839 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3840 const struct spoolss_PrinterInfo2 *info2,
3841 struct spoolss_PrinterInfo3 *r,
3844 /* These are the components of the SD we are returning. */
3846 if (info2->secdesc != NULL) {
3847 /* don't use talloc_steal() here unless you do a deep steal of all
3848 the SEC_DESC members */
3850 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3851 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3857 /********************************************************************
3858 * construct_printer_info4
3859 * fill a spoolss_PrinterInfo4 struct
3860 ********************************************************************/
3862 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3863 const struct spoolss_PrinterInfo2 *info2,
3864 struct spoolss_PrinterInfo4 *r,
3867 r->printername = talloc_strdup(mem_ctx, info2->printername);
3868 W_ERROR_HAVE_NO_MEMORY(r->printername);
3869 r->servername = talloc_strdup(mem_ctx, info2->servername);
3870 W_ERROR_HAVE_NO_MEMORY(r->servername);
3872 r->attributes = info2->attributes;
3877 /********************************************************************
3878 * construct_printer_info5
3879 * fill a spoolss_PrinterInfo5 struct
3880 ********************************************************************/
3882 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3883 const struct spoolss_PrinterInfo2 *info2,
3884 struct spoolss_PrinterInfo5 *r,
3887 r->printername = talloc_strdup(mem_ctx, info2->printername);
3888 W_ERROR_HAVE_NO_MEMORY(r->printername);
3889 r->portname = talloc_strdup(mem_ctx, info2->portname);
3890 W_ERROR_HAVE_NO_MEMORY(r->portname);
3892 r->attributes = info2->attributes;
3894 /* these two are not used by NT+ according to MSDN */
3895 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3896 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3901 /********************************************************************
3902 * construct_printer_info_6
3903 * fill a spoolss_PrinterInfo6 struct
3904 ********************************************************************/
3906 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3907 struct messaging_context *msg_ctx,
3908 const struct spoolss_PrinterInfo2 *info2,
3909 struct spoolss_PrinterInfo6 *r,
3913 print_status_struct status;
3915 count = print_queue_length(msg_ctx, snum, &status);
3917 r->status = nt_printq_status(status.status);
3922 /********************************************************************
3923 * construct_printer_info7
3924 * fill a spoolss_PrinterInfo7 struct
3925 ********************************************************************/
3927 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3928 struct messaging_context *msg_ctx,
3929 struct printer_handle *print_hnd,
3930 struct spoolss_PrinterInfo7 *r,
3933 struct auth_serversupplied_info *server_info;
3937 status = make_server_info_system(mem_ctx, &server_info);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 DEBUG(0, ("construct_printer_info7: "
3940 "Could not create system server_info\n"));
3944 if (is_printer_published(mem_ctx, server_info, msg_ctx,
3945 print_hnd->servername,
3946 lp_servicename(snum), &guid, NULL)) {
3947 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3948 r->action = DSPRINT_PUBLISH;
3950 r->guid = talloc_strdup(mem_ctx, "");
3951 r->action = DSPRINT_UNPUBLISH;
3953 W_ERROR_HAVE_NO_MEMORY(r->guid);
3955 TALLOC_FREE(server_info);
3959 /********************************************************************
3960 * construct_printer_info8
3961 * fill a spoolss_PrinterInfo8 struct
3962 ********************************************************************/
3964 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3965 const struct spoolss_PrinterInfo2 *info2,
3966 struct spoolss_DeviceModeInfo *r,
3969 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3971 DEBUG(8,("Returning NULL Devicemode!\n"));
3978 /********************************************************************
3979 ********************************************************************/
3981 static bool snum_is_shared_printer(int snum)
3983 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3986 /********************************************************************
3987 Spoolss_enumprinters.
3988 ********************************************************************/
3990 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3991 const struct auth_serversupplied_info *server_info,
3992 struct messaging_context *msg_ctx,
3995 union spoolss_PrinterInfo **info_p,
3999 int n_services = lp_numservices();
4000 union spoolss_PrinterInfo *info = NULL;
4002 WERROR result = WERR_OK;
4007 for (snum = 0; snum < n_services; snum++) {
4009 const char *printer;
4010 struct spoolss_PrinterInfo2 *info2;
4012 if (!snum_is_shared_printer(snum)) {
4016 printer = lp_const_servicename(snum);
4018 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4021 result = winreg_create_printer(mem_ctx,
4026 if (!W_ERROR_IS_OK(result)) {
4030 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4031 union spoolss_PrinterInfo,
4034 result = WERR_NOMEM;
4038 result = winreg_get_printer(mem_ctx, server_info, msg_ctx,
4039 NULL, printer, &info2);
4040 if (!W_ERROR_IS_OK(result)) {
4046 result = construct_printer_info0(info, server_info,
4048 &info[count].info0, snum);
4051 result = construct_printer_info1(info, info2, flags,
4052 &info[count].info1, snum);
4055 result = construct_printer_info2(info, msg_ctx, info2,
4056 &info[count].info2, snum);
4059 result = construct_printer_info4(info, info2,
4060 &info[count].info4, snum);
4063 result = construct_printer_info5(info, info2,
4064 &info[count].info5, snum);
4068 result = WERR_UNKNOWN_LEVEL;
4072 if (!W_ERROR_IS_OK(result)) {
4083 if (!W_ERROR_IS_OK(result)) {
4093 /********************************************************************
4094 * handle enumeration of printers at level 0
4095 ********************************************************************/
4097 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4098 const struct auth_serversupplied_info *server_info,
4099 struct messaging_context *msg_ctx,
4101 const char *servername,
4102 union spoolss_PrinterInfo **info,
4105 DEBUG(4,("enum_all_printers_info_0\n"));
4107 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4108 0, flags, info, count);
4112 /********************************************************************
4113 ********************************************************************/
4115 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4116 const struct auth_serversupplied_info *server_info,
4117 struct messaging_context *msg_ctx,
4119 union spoolss_PrinterInfo **info,
4122 DEBUG(4,("enum_all_printers_info_1\n"));
4124 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4125 1, flags, info, count);
4128 /********************************************************************
4129 enum_all_printers_info_1_local.
4130 *********************************************************************/
4132 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4133 const struct auth_serversupplied_info *server_info,
4134 struct messaging_context *msg_ctx,
4135 union spoolss_PrinterInfo **info,
4138 DEBUG(4,("enum_all_printers_info_1_local\n"));
4140 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4141 PRINTER_ENUM_ICON8, info, count);
4144 /********************************************************************
4145 enum_all_printers_info_1_name.
4146 *********************************************************************/
4148 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4149 const struct auth_serversupplied_info *server_info,
4150 struct messaging_context *msg_ctx,
4152 union spoolss_PrinterInfo **info,
4155 const char *s = name;
4157 DEBUG(4,("enum_all_printers_info_1_name\n"));
4159 if ((name[0] == '\\') && (name[1] == '\\')) {
4163 if (!is_myname_or_ipaddr(s)) {
4164 return WERR_INVALID_NAME;
4167 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4168 PRINTER_ENUM_ICON8, info, count);
4171 /********************************************************************
4172 enum_all_printers_info_1_network.
4173 *********************************************************************/
4175 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4176 const struct auth_serversupplied_info *server_info,
4177 struct messaging_context *msg_ctx,
4179 union spoolss_PrinterInfo **info,
4182 const char *s = name;
4184 DEBUG(4,("enum_all_printers_info_1_network\n"));
4186 /* If we respond to a enum_printers level 1 on our name with flags
4187 set to PRINTER_ENUM_REMOTE with a list of printers then these
4188 printers incorrectly appear in the APW browse list.
4189 Specifically the printers for the server appear at the workgroup
4190 level where all the other servers in the domain are
4191 listed. Windows responds to this call with a
4192 WERR_CAN_NOT_COMPLETE so we should do the same. */
4194 if (name[0] == '\\' && name[1] == '\\') {
4198 if (is_myname_or_ipaddr(s)) {
4199 return WERR_CAN_NOT_COMPLETE;
4202 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4203 PRINTER_ENUM_NAME, info, count);
4206 /********************************************************************
4207 * api_spoolss_enumprinters
4209 * called from api_spoolss_enumprinters (see this to understand)
4210 ********************************************************************/
4212 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4213 const struct auth_serversupplied_info *server_info,
4214 struct messaging_context *msg_ctx,
4215 union spoolss_PrinterInfo **info,
4218 DEBUG(4,("enum_all_printers_info_2\n"));
4220 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4224 /********************************************************************
4225 * handle enumeration of printers at level 1
4226 ********************************************************************/
4228 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4229 const struct auth_serversupplied_info *server_info,
4230 struct messaging_context *msg_ctx,
4233 union spoolss_PrinterInfo **info,
4236 /* Not all the flags are equals */
4238 if (flags & PRINTER_ENUM_LOCAL) {
4239 return enum_all_printers_info_1_local(mem_ctx, server_info,
4240 msg_ctx, info, count);
4243 if (flags & PRINTER_ENUM_NAME) {
4244 return enum_all_printers_info_1_name(mem_ctx, server_info,
4245 msg_ctx, name, info,
4249 if (flags & PRINTER_ENUM_NETWORK) {
4250 return enum_all_printers_info_1_network(mem_ctx, server_info,
4251 msg_ctx, name, info,
4255 return WERR_OK; /* NT4sp5 does that */
4258 /********************************************************************
4259 * handle enumeration of printers at level 2
4260 ********************************************************************/
4262 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4263 const struct auth_serversupplied_info *server_info,
4264 struct messaging_context *msg_ctx,
4266 const char *servername,
4267 union spoolss_PrinterInfo **info,
4270 if (flags & PRINTER_ENUM_LOCAL) {
4271 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4275 if (flags & PRINTER_ENUM_NAME) {
4276 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4277 return WERR_INVALID_NAME;
4280 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4284 if (flags & PRINTER_ENUM_REMOTE) {
4285 return WERR_UNKNOWN_LEVEL;
4291 /********************************************************************
4292 * handle enumeration of printers at level 4
4293 ********************************************************************/
4295 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4296 const struct auth_serversupplied_info *server_info,
4297 struct messaging_context *msg_ctx,
4299 const char *servername,
4300 union spoolss_PrinterInfo **info,
4303 DEBUG(4,("enum_all_printers_info_4\n"));
4305 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4306 4, flags, info, count);
4310 /********************************************************************
4311 * handle enumeration of printers at level 5
4312 ********************************************************************/
4314 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4315 const struct auth_serversupplied_info *server_info,
4316 struct messaging_context *msg_ctx,
4318 const char *servername,
4319 union spoolss_PrinterInfo **info,
4322 DEBUG(4,("enum_all_printers_info_5\n"));
4324 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4325 5, flags, info, count);
4328 /****************************************************************
4329 _spoolss_EnumPrinters
4330 ****************************************************************/
4332 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4333 struct spoolss_EnumPrinters *r)
4335 const struct auth_serversupplied_info *server_info = get_server_info_system();
4336 const char *name = NULL;
4339 /* that's an [in out] buffer */
4341 if (!r->in.buffer && (r->in.offered != 0)) {
4342 return WERR_INVALID_PARAM;
4345 DEBUG(4,("_spoolss_EnumPrinters\n"));
4349 *r->out.info = NULL;
4353 * flags==PRINTER_ENUM_NAME
4354 * if name=="" then enumerates all printers
4355 * if name!="" then enumerate the printer
4356 * flags==PRINTER_ENUM_REMOTE
4357 * name is NULL, enumerate printers
4358 * Level 2: name!="" enumerates printers, name can't be NULL
4359 * Level 3: doesn't exist
4360 * Level 4: does a local registry lookup
4361 * Level 5: same as Level 2
4365 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4366 W_ERROR_HAVE_NO_MEMORY(name);
4369 switch (r->in.level) {
4371 result = enumprinters_level0(p->mem_ctx, server_info,
4372 p->msg_ctx, r->in.flags, name,
4373 r->out.info, r->out.count);
4376 result = enumprinters_level1(p->mem_ctx, server_info,
4377 p->msg_ctx, r->in.flags, name,
4378 r->out.info, r->out.count);
4381 result = enumprinters_level2(p->mem_ctx, server_info,
4382 p->msg_ctx, r->in.flags, name,
4383 r->out.info, r->out.count);
4386 result = enumprinters_level4(p->mem_ctx, server_info,
4387 p->msg_ctx, r->in.flags, name,
4388 r->out.info, r->out.count);
4391 result = enumprinters_level5(p->mem_ctx, server_info,
4392 p->msg_ctx, r->in.flags, name,
4393 r->out.info, r->out.count);
4396 return WERR_UNKNOWN_LEVEL;
4399 if (!W_ERROR_IS_OK(result)) {
4403 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4404 spoolss_EnumPrinters,
4405 *r->out.info, r->in.level,
4407 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4408 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4410 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4413 /****************************************************************
4415 ****************************************************************/
4417 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4418 struct spoolss_GetPrinter *r)
4420 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
4421 struct spoolss_PrinterInfo2 *info2 = NULL;
4422 WERROR result = WERR_OK;
4423 const char *servername = NULL;
4426 /* that's an [in out] buffer */
4428 if (!r->in.buffer && (r->in.offered != 0)) {
4429 return WERR_INVALID_PARAM;
4434 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4438 if (Printer != NULL || Printer->servername != NULL) {
4439 servername = Printer->servername;
4442 result = winreg_get_printer(p->mem_ctx,
4443 get_server_info_system(),
4446 lp_const_servicename(snum),
4448 if (!W_ERROR_IS_OK(result)) {
4452 switch (r->in.level) {
4454 result = construct_printer_info0(p->mem_ctx,
4455 get_server_info_system(),
4458 &r->out.info->info0,
4462 result = construct_printer_info1(p->mem_ctx, info2,
4464 &r->out.info->info1, snum);
4467 result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
4468 &r->out.info->info2, snum);
4471 result = construct_printer_info3(p->mem_ctx, info2,
4472 &r->out.info->info3, snum);
4475 result = construct_printer_info4(p->mem_ctx, info2,
4476 &r->out.info->info4, snum);
4479 result = construct_printer_info5(p->mem_ctx, info2,
4480 &r->out.info->info5, snum);
4483 result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
4484 &r->out.info->info6, snum);
4487 result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
4489 &r->out.info->info7, snum);
4492 result = construct_printer_info8(p->mem_ctx, info2,
4493 &r->out.info->info8, snum);
4496 result = WERR_UNKNOWN_LEVEL;
4500 if (!W_ERROR_IS_OK(result)) {
4501 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4502 r->in.level, win_errstr(result)));
4503 TALLOC_FREE(r->out.info);
4507 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4508 r->out.info, r->in.level);
4509 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4511 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4514 /********************************************************************
4515 ********************************************************************/
4517 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4519 if (in && strlen(in)) { \
4520 out = talloc_strdup(mem_ctx, in); \
4522 out = talloc_strdup(mem_ctx, ""); \
4524 W_ERROR_HAVE_NO_MEMORY(out); \
4527 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4529 if (in && strlen(in)) { \
4530 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4532 out = talloc_strdup(mem_ctx, ""); \
4534 W_ERROR_HAVE_NO_MEMORY(out); \
4537 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4538 const char **string_array,
4539 const char ***presult,
4540 const char *cservername,
4544 int i, num_strings = 0;
4545 const char **array = NULL;
4547 if (string_array == NULL) {
4548 return WERR_INVALID_PARAMETER;;
4551 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4552 const char *str = NULL;
4554 if (cservername == NULL || arch == NULL) {
4555 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4557 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4560 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4567 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4568 &array, &num_strings);
4578 /********************************************************************
4579 * fill a spoolss_DriverInfo1 struct
4580 ********************************************************************/
4582 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4583 struct spoolss_DriverInfo1 *r,
4584 const struct spoolss_DriverInfo8 *driver,
4585 const char *servername)
4587 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4588 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4593 /********************************************************************
4594 * fill a spoolss_DriverInfo2 struct
4595 ********************************************************************/
4597 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4598 struct spoolss_DriverInfo2 *r,
4599 const struct spoolss_DriverInfo8 *driver,
4600 const char *servername)
4603 const char *cservername = canon_servername(servername);
4605 r->version = driver->version;
4607 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4608 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4609 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4610 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4612 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4613 driver->architecture,
4615 driver->driver_path,
4618 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4619 driver->architecture,
4624 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4625 driver->architecture,
4627 driver->config_file,
4633 /********************************************************************
4634 * fill a spoolss_DriverInfo3 struct
4635 ********************************************************************/
4637 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4638 struct spoolss_DriverInfo3 *r,
4639 const struct spoolss_DriverInfo8 *driver,
4640 const char *servername)
4642 const char *cservername = canon_servername(servername);
4644 r->version = driver->version;
4646 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4647 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4648 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4649 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4651 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4652 driver->architecture,
4654 driver->driver_path,
4657 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4658 driver->architecture,
4663 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4664 driver->architecture,
4666 driver->config_file,
4669 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4670 driver->architecture,
4675 FILL_DRIVER_STRING(mem_ctx,
4676 driver->monitor_name,
4679 FILL_DRIVER_STRING(mem_ctx,
4680 driver->default_datatype,
4681 r->default_datatype);
4683 return string_array_from_driver_info(mem_ctx,
4684 driver->dependent_files,
4685 &r->dependent_files,
4687 driver->architecture,
4691 /********************************************************************
4692 * fill a spoolss_DriverInfo4 struct
4693 ********************************************************************/
4695 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4696 struct spoolss_DriverInfo4 *r,
4697 const struct spoolss_DriverInfo8 *driver,
4698 const char *servername)
4700 const char *cservername = canon_servername(servername);
4703 r->version = driver->version;
4705 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4706 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4707 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4708 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4710 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4711 driver->architecture,
4713 driver->driver_path,
4716 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4717 driver->architecture,
4722 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4723 driver->architecture,
4725 driver->config_file,
4728 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4729 driver->architecture,
4734 result = string_array_from_driver_info(mem_ctx,
4735 driver->dependent_files,
4736 &r->dependent_files,
4738 driver->architecture,
4740 if (!W_ERROR_IS_OK(result)) {
4744 FILL_DRIVER_STRING(mem_ctx,
4745 driver->monitor_name,
4748 FILL_DRIVER_STRING(mem_ctx,
4749 driver->default_datatype,
4750 r->default_datatype);
4753 result = string_array_from_driver_info(mem_ctx,
4754 driver->previous_names,
4761 /********************************************************************
4762 * fill a spoolss_DriverInfo5 struct
4763 ********************************************************************/
4765 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4766 struct spoolss_DriverInfo5 *r,
4767 const struct spoolss_DriverInfo8 *driver,
4768 const char *servername)
4770 const char *cservername = canon_servername(servername);
4772 r->version = driver->version;
4774 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4775 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4776 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4777 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4779 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4780 driver->architecture,
4782 driver->driver_path,
4785 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4786 driver->architecture,
4791 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4792 driver->architecture,
4794 driver->config_file,
4797 r->driver_attributes = 0;
4798 r->config_version = 0;
4799 r->driver_version = 0;
4803 /********************************************************************
4804 * fill a spoolss_DriverInfo6 struct
4805 ********************************************************************/
4807 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4808 struct spoolss_DriverInfo6 *r,
4809 const struct spoolss_DriverInfo8 *driver,
4810 const char *servername)
4812 const char *cservername = canon_servername(servername);
4815 r->version = driver->version;
4817 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4818 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4819 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4820 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4822 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4823 driver->architecture,
4825 driver->driver_path,
4828 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4829 driver->architecture,
4834 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4835 driver->architecture,
4837 driver->config_file,
4840 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4841 driver->architecture,
4846 FILL_DRIVER_STRING(mem_ctx,
4847 driver->monitor_name,
4850 FILL_DRIVER_STRING(mem_ctx,
4851 driver->default_datatype,
4852 r->default_datatype);
4854 result = string_array_from_driver_info(mem_ctx,
4855 driver->dependent_files,
4856 &r->dependent_files,
4858 driver->architecture,
4860 if (!W_ERROR_IS_OK(result)) {
4864 result = string_array_from_driver_info(mem_ctx,
4865 driver->previous_names,
4868 if (!W_ERROR_IS_OK(result)) {
4872 r->driver_date = driver->driver_date;
4873 r->driver_version = driver->driver_version;
4875 FILL_DRIVER_STRING(mem_ctx,
4876 driver->manufacturer_name,
4877 r->manufacturer_name);
4878 FILL_DRIVER_STRING(mem_ctx,
4879 driver->manufacturer_url,
4880 r->manufacturer_url);
4881 FILL_DRIVER_STRING(mem_ctx,
4882 driver->hardware_id,
4884 FILL_DRIVER_STRING(mem_ctx,
4891 /********************************************************************
4892 * fill a spoolss_DriverInfo8 struct
4893 ********************************************************************/
4895 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4896 struct spoolss_DriverInfo8 *r,
4897 const struct spoolss_DriverInfo8 *driver,
4898 const char *servername)
4900 const char *cservername = canon_servername(servername);
4903 r->version = driver->version;
4905 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4906 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4907 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4908 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4910 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4911 driver->architecture,
4913 driver->driver_path,
4916 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4917 driver->architecture,
4922 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4923 driver->architecture,
4925 driver->config_file,
4928 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4929 driver->architecture,
4934 FILL_DRIVER_STRING(mem_ctx,
4935 driver->monitor_name,
4938 FILL_DRIVER_STRING(mem_ctx,
4939 driver->default_datatype,
4940 r->default_datatype);
4942 result = string_array_from_driver_info(mem_ctx,
4943 driver->dependent_files,
4944 &r->dependent_files,
4946 driver->architecture,
4948 if (!W_ERROR_IS_OK(result)) {
4952 result = string_array_from_driver_info(mem_ctx,
4953 driver->previous_names,
4956 if (!W_ERROR_IS_OK(result)) {
4960 r->driver_date = driver->driver_date;
4961 r->driver_version = driver->driver_version;
4963 FILL_DRIVER_STRING(mem_ctx,
4964 driver->manufacturer_name,
4965 r->manufacturer_name);
4966 FILL_DRIVER_STRING(mem_ctx,
4967 driver->manufacturer_url,
4968 r->manufacturer_url);
4969 FILL_DRIVER_STRING(mem_ctx,
4970 driver->hardware_id,
4972 FILL_DRIVER_STRING(mem_ctx,
4976 FILL_DRIVER_STRING(mem_ctx,
4977 driver->print_processor,
4978 r->print_processor);
4979 FILL_DRIVER_STRING(mem_ctx,
4980 driver->vendor_setup,
4983 result = string_array_from_driver_info(mem_ctx,
4984 driver->color_profiles,
4987 if (!W_ERROR_IS_OK(result)) {
4991 FILL_DRIVER_STRING(mem_ctx,
4995 r->printer_driver_attributes = driver->printer_driver_attributes;
4997 result = string_array_from_driver_info(mem_ctx,
4998 driver->core_driver_dependencies,
4999 &r->core_driver_dependencies,
5001 if (!W_ERROR_IS_OK(result)) {
5005 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
5006 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
5011 #if 0 /* disabled until marshalling issues are resolved - gd */
5012 /********************************************************************
5013 ********************************************************************/
5015 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
5016 struct spoolss_DriverFileInfo *r,
5017 const char *cservername,
5018 const char *file_name,
5019 enum spoolss_DriverFileType file_type,
5020 uint32_t file_version)
5022 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
5023 cservername, file_name);
5024 W_ERROR_HAVE_NO_MEMORY(r->file_name);
5025 r->file_type = file_type;
5026 r->file_version = file_version;
5031 /********************************************************************
5032 ********************************************************************/
5034 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
5035 const struct spoolss_DriverInfo8 *driver,
5036 const char *cservername,
5037 struct spoolss_DriverFileInfo **info_p,
5040 struct spoolss_DriverFileInfo *info = NULL;
5048 if (strlen(driver->driver_path)) {
5049 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5050 struct spoolss_DriverFileInfo,
5052 W_ERROR_HAVE_NO_MEMORY(info);
5053 result = fill_spoolss_DriverFileInfo(info,
5056 driver->driver_path,
5057 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
5059 W_ERROR_NOT_OK_RETURN(result);
5063 if (strlen(driver->config_file)) {
5064 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5065 struct spoolss_DriverFileInfo,
5067 W_ERROR_HAVE_NO_MEMORY(info);
5068 result = fill_spoolss_DriverFileInfo(info,
5071 driver->config_file,
5072 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
5074 W_ERROR_NOT_OK_RETURN(result);
5078 if (strlen(driver->data_file)) {
5079 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5080 struct spoolss_DriverFileInfo,
5082 W_ERROR_HAVE_NO_MEMORY(info);
5083 result = fill_spoolss_DriverFileInfo(info,
5087 SPOOLSS_DRIVER_FILE_TYPE_DATA,
5089 W_ERROR_NOT_OK_RETURN(result);
5093 if (strlen(driver->help_file)) {
5094 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5095 struct spoolss_DriverFileInfo,
5097 W_ERROR_HAVE_NO_MEMORY(info);
5098 result = fill_spoolss_DriverFileInfo(info,
5102 SPOOLSS_DRIVER_FILE_TYPE_HELP,
5104 W_ERROR_NOT_OK_RETURN(result);
5108 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
5109 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5110 struct spoolss_DriverFileInfo,
5112 W_ERROR_HAVE_NO_MEMORY(info);
5113 result = fill_spoolss_DriverFileInfo(info,
5116 driver->dependent_files[i],
5117 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
5119 W_ERROR_NOT_OK_RETURN(result);
5129 /********************************************************************
5130 * fill a spoolss_DriverInfo101 struct
5131 ********************************************************************/
5133 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
5134 struct spoolss_DriverInfo101 *r,
5135 const struct spoolss_DriverInfo8 *driver,
5136 const char *servername)
5138 const char *cservername = canon_servername(servername);
5141 r->version = driver->version;
5143 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5144 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5145 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5146 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5148 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5152 if (!W_ERROR_IS_OK(result)) {
5156 FILL_DRIVER_STRING(mem_ctx,
5157 driver->monitor_name,
5160 FILL_DRIVER_STRING(mem_ctx,
5161 driver->default_datatype,
5162 r->default_datatype);
5164 result = string_array_from_driver_info(mem_ctx,
5165 driver->previous_names,
5168 if (!W_ERROR_IS_OK(result)) {
5172 r->driver_date = driver->driver_date;
5173 r->driver_version = driver->driver_version;
5175 FILL_DRIVER_STRING(mem_ctx,
5176 driver->manufacturer_name,
5177 r->manufacturer_name);
5178 FILL_DRIVER_STRING(mem_ctx,
5179 driver->manufacturer_url,
5180 r->manufacturer_url);
5181 FILL_DRIVER_STRING(mem_ctx,
5182 driver->hardware_id,
5184 FILL_DRIVER_STRING(mem_ctx,
5191 /********************************************************************
5192 ********************************************************************/
5194 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5195 const struct auth_serversupplied_info *server_info,
5196 struct messaging_context *msg_ctx,
5198 union spoolss_DriverInfo *r,
5200 const char *servername,
5201 const char *architecture,
5204 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5205 struct spoolss_DriverInfo8 *driver;
5208 result = winreg_get_printer(mem_ctx,
5212 lp_const_servicename(snum),
5215 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5216 win_errstr(result)));
5218 if (!W_ERROR_IS_OK(result)) {
5219 return WERR_INVALID_PRINTER_NAME;
5222 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5224 pinfo2->drivername, version, &driver);
5226 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5227 win_errstr(result)));
5229 if (!W_ERROR_IS_OK(result)) {
5231 * Is this a W2k client ?
5235 talloc_free(pinfo2);
5236 return WERR_UNKNOWN_PRINTER_DRIVER;
5239 /* Yes - try again with a WinNT driver. */
5241 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5245 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5246 win_errstr(result)));
5247 if (!W_ERROR_IS_OK(result)) {
5248 talloc_free(pinfo2);
5249 return WERR_UNKNOWN_PRINTER_DRIVER;
5255 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5258 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5261 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5264 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5267 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5270 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5273 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5275 #if 0 /* disabled until marshalling issues are resolved - gd */
5277 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5281 result = WERR_UNKNOWN_LEVEL;
5285 talloc_free(pinfo2);
5286 talloc_free(driver);
5291 /****************************************************************
5292 _spoolss_GetPrinterDriver2
5293 ****************************************************************/
5295 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5296 struct spoolss_GetPrinterDriver2 *r)
5298 struct printer_handle *printer;
5303 /* that's an [in out] buffer */
5305 if (!r->in.buffer && (r->in.offered != 0)) {
5306 return WERR_INVALID_PARAM;
5309 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5311 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5312 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5313 return WERR_INVALID_PRINTER_NAME;
5317 *r->out.server_major_version = 0;
5318 *r->out.server_minor_version = 0;
5320 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5324 result = construct_printer_driver_info_level(p->mem_ctx,
5325 get_server_info_system(),
5327 r->in.level, r->out.info,
5328 snum, printer->servername,
5330 r->in.client_major_version);
5331 if (!W_ERROR_IS_OK(result)) {
5332 TALLOC_FREE(r->out.info);
5336 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5337 r->out.info, r->in.level);
5338 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5340 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5344 /****************************************************************
5345 _spoolss_StartPagePrinter
5346 ****************************************************************/
5348 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5349 struct spoolss_StartPagePrinter *r)
5351 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5354 DEBUG(3,("_spoolss_StartPagePrinter: "
5355 "Error in startpageprinter printer handle\n"));
5359 Printer->page_started = true;
5363 /****************************************************************
5364 _spoolss_EndPagePrinter
5365 ****************************************************************/
5367 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5368 struct spoolss_EndPagePrinter *r)
5372 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5375 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5376 OUR_HANDLE(r->in.handle)));
5380 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5383 Printer->page_started = false;
5384 print_job_endpage(p->msg_ctx, snum, Printer->jobid);
5389 /****************************************************************
5390 _spoolss_StartDocPrinter
5391 ****************************************************************/
5393 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5394 struct spoolss_StartDocPrinter *r)
5396 struct spoolss_DocumentInfo1 *info_1;
5398 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5402 DEBUG(2,("_spoolss_StartDocPrinter: "
5403 "Invalid handle (%s:%u:%u)\n",
5404 OUR_HANDLE(r->in.handle)));
5408 if (Printer->jobid) {
5409 DEBUG(2, ("_spoolss_StartDocPrinter: "
5410 "StartDocPrinter called twice! "
5411 "(existing jobid = %d)\n", Printer->jobid));
5412 return WERR_INVALID_HANDLE;
5415 if (r->in.level != 1) {
5416 return WERR_UNKNOWN_LEVEL;
5419 info_1 = r->in.info.info1;
5422 * a nice thing with NT is it doesn't listen to what you tell it.
5423 * when asked to send _only_ RAW datas, it tries to send datas
5426 * So I add checks like in NT Server ...
5429 if (info_1->datatype) {
5430 if (strcmp(info_1->datatype, "RAW") != 0) {
5432 return WERR_INVALID_DATATYPE;
5436 /* get the share number of the printer */
5437 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5441 werr = print_job_start(get_server_info_system(),
5445 info_1->document_name,
5446 info_1->output_file,
5450 /* An error occured in print_job_start() so return an appropriate
5453 if (!W_ERROR_IS_OK(werr)) {
5457 Printer->document_started = true;
5458 *r->out.job_id = Printer->jobid;
5463 /****************************************************************
5464 _spoolss_EndDocPrinter
5465 ****************************************************************/
5467 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5468 struct spoolss_EndDocPrinter *r)
5470 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5475 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5476 OUR_HANDLE(r->in.handle)));
5480 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5484 Printer->document_started = false;
5485 status = print_job_end(p->msg_ctx, snum, Printer->jobid, NORMAL_CLOSE);
5486 if (!NT_STATUS_IS_OK(status)) {
5487 DEBUG(2, ("_spoolss_EndDocPrinter: "
5488 "print_job_end failed [%s]\n",
5489 nt_errstr(status)));
5493 return ntstatus_to_werror(status);
5496 /****************************************************************
5497 _spoolss_WritePrinter
5498 ****************************************************************/
5500 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5501 struct spoolss_WritePrinter *r)
5503 ssize_t buffer_written;
5505 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5508 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5509 OUR_HANDLE(r->in.handle)));
5510 *r->out.num_written = r->in._data_size;
5514 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5517 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5518 buffer_written = print_job_write(server_event_context(),p->msg_ctx,
5519 snum, Printer->jobid,
5520 (const char *)r->in.data.data,
5521 (size_t)r->in._data_size);
5522 if (buffer_written == (ssize_t)-1) {
5523 *r->out.num_written = 0;
5524 if (errno == ENOSPC)
5525 return WERR_NO_SPOOL_SPACE;
5527 return WERR_ACCESS_DENIED;
5530 *r->out.num_written = r->in._data_size;
5535 /********************************************************************
5536 * api_spoolss_getprinter
5537 * called from the spoolss dispatcher
5539 ********************************************************************/
5541 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5542 struct pipes_struct *p)
5544 const struct auth_serversupplied_info *server_info = get_server_info_system();
5546 WERROR errcode = WERR_BADFUNC;
5547 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
5550 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5551 OUR_HANDLE(handle)));
5555 if (!get_printer_snum(p, handle, &snum, NULL))
5559 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5560 errcode = print_queue_pause(server_info, p->msg_ctx, snum);
5562 case SPOOLSS_PRINTER_CONTROL_RESUME:
5563 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5564 errcode = print_queue_resume(server_info, p->msg_ctx, snum);
5566 case SPOOLSS_PRINTER_CONTROL_PURGE:
5567 errcode = print_queue_purge(server_info, p->msg_ctx, snum);
5570 return WERR_UNKNOWN_LEVEL;
5577 /****************************************************************
5578 _spoolss_AbortPrinter
5579 * From MSDN: "Deletes printer's spool file if printer is configured
5581 ****************************************************************/
5583 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5584 struct spoolss_AbortPrinter *r)
5586 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5588 WERROR errcode = WERR_OK;
5591 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5592 OUR_HANDLE(r->in.handle)));
5596 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5599 if (!Printer->document_started) {
5600 return WERR_SPL_NO_STARTDOC;
5603 errcode = print_job_delete(get_server_info_system(),
5611 /********************************************************************
5612 * called by spoolss_api_setprinter
5613 * when updating a printer description
5614 ********************************************************************/
5616 static WERROR update_printer_sec(struct policy_handle *handle,
5617 struct pipes_struct *p,
5618 struct sec_desc_buf *secdesc_ctr)
5620 struct spoolss_security_descriptor *new_secdesc = NULL;
5621 struct spoolss_security_descriptor *old_secdesc = NULL;
5622 const char *printer;
5626 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
5628 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5629 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5630 OUR_HANDLE(handle)));
5632 result = WERR_BADFID;
5636 if (secdesc_ctr == NULL) {
5637 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5638 result = WERR_INVALID_PARAM;
5641 printer = lp_const_servicename(snum);
5643 /* Check the user has permissions to change the security
5644 descriptor. By experimentation with two NT machines, the user
5645 requires Full Access to the printer to change security
5648 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5649 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5650 result = WERR_ACCESS_DENIED;
5654 /* NT seems to like setting the security descriptor even though
5655 nothing may have actually changed. */
5656 result = winreg_get_printer_secdesc(p->mem_ctx,
5657 get_server_info_system(),
5661 if (!W_ERROR_IS_OK(result)) {
5662 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5663 result = WERR_BADFID;
5667 if (DEBUGLEVEL >= 10) {
5668 struct security_acl *the_acl;
5671 the_acl = old_secdesc->dacl;
5672 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5673 printer, the_acl->num_aces));
5675 for (i = 0; i < the_acl->num_aces; i++) {
5676 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5677 &the_acl->aces[i].trustee),
5678 the_acl->aces[i].access_mask));
5681 the_acl = secdesc_ctr->sd->dacl;
5684 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5685 printer, the_acl->num_aces));
5687 for (i = 0; i < the_acl->num_aces; i++) {
5688 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5689 &the_acl->aces[i].trustee),
5690 the_acl->aces[i].access_mask));
5693 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5697 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5698 if (new_secdesc == NULL) {
5699 result = WERR_NOMEM;
5703 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5708 result = winreg_set_printer_secdesc(p->mem_ctx,
5709 get_server_info_system(),
5718 /********************************************************************
5719 Canonicalize printer info from a client
5720 ********************************************************************/
5722 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5723 struct spoolss_SetPrinterInfo2 *info2,
5726 fstring printername;
5729 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5730 "portname=%s drivername=%s comment=%s location=%s\n",
5731 info2->servername, info2->printername, info2->sharename,
5732 info2->portname, info2->drivername, info2->comment,
5735 /* we force some elements to "correct" values */
5736 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5737 if (info2->servername == NULL) {
5740 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5741 if (info2->sharename == NULL) {
5745 /* check to see if we allow printername != sharename */
5746 if (lp_force_printername(snum)) {
5747 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5748 global_myname(), info2->sharename);
5750 /* make sure printername is in \\server\printername format */
5751 fstrcpy(printername, info2->printername);
5753 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5754 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5758 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5759 global_myname(), p);
5761 if (info2->printername == NULL) {
5765 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5766 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5771 /****************************************************************************
5772 ****************************************************************************/
5774 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5776 char *cmd = lp_addport_cmd();
5777 char *command = NULL;
5779 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5780 bool is_print_op = false;
5783 return WERR_ACCESS_DENIED;
5786 command = talloc_asprintf(ctx,
5787 "%s \"%s\" \"%s\"", cmd, portname, uri );
5793 is_print_op = user_has_privileges( token, &se_printop );
5795 DEBUG(10,("Running [%s]\n", command));
5797 /********* BEGIN SePrintOperatorPrivilege **********/
5802 ret = smbrun(command, NULL);
5807 /********* END SePrintOperatorPrivilege **********/
5809 DEBUGADD(10,("returned [%d]\n", ret));
5811 TALLOC_FREE(command);
5814 return WERR_ACCESS_DENIED;
5820 /****************************************************************************
5821 ****************************************************************************/
5823 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5824 struct spoolss_SetPrinterInfo2 *info2,
5825 const char *remote_machine,
5826 struct messaging_context *msg_ctx)
5828 char *cmd = lp_addprinter_cmd();
5830 char *command = NULL;
5834 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5835 bool is_print_op = false;
5837 if (!remote_machine) {
5841 command = talloc_asprintf(ctx,
5842 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5843 cmd, info2->printername, info2->sharename,
5844 info2->portname, info2->drivername,
5845 info2->location, info2->comment, remote_machine);
5851 is_print_op = user_has_privileges( token, &se_printop );
5853 DEBUG(10,("Running [%s]\n", command));
5855 /********* BEGIN SePrintOperatorPrivilege **********/
5860 if ( (ret = smbrun(command, &fd)) == 0 ) {
5861 /* Tell everyone we updated smb.conf. */
5862 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5868 /********* END SePrintOperatorPrivilege **********/
5870 DEBUGADD(10,("returned [%d]\n", ret));
5872 TALLOC_FREE(command);
5880 /* reload our services immediately */
5882 reload_services(msg_ctx, -1, false);
5886 /* Get lines and convert them back to dos-codepage */
5887 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5888 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5891 /* Set the portname to what the script says the portname should be. */
5892 /* but don't require anything to be return from the script exit a good error code */
5895 /* Set the portname to what the script says the portname should be. */
5896 info2->portname = talloc_strdup(ctx, qlines[0]);
5897 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5900 TALLOC_FREE(qlines);
5904 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5905 const struct auth_serversupplied_info *server_info,
5906 struct messaging_context *msg_ctx,
5908 struct spoolss_SetPrinterInfo2 *printer,
5909 struct spoolss_PrinterInfo2 *old_printer)
5911 bool force_update = (old_printer == NULL);
5912 const char *dnsdomname;
5913 const char *longname;
5914 const char *uncname;
5915 const char *spooling;
5917 WERROR result = WERR_OK;
5919 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5920 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5921 winreg_set_printer_dataex(mem_ctx,
5925 SPOOL_DSSPOOLER_KEY,
5926 SPOOL_REG_DRIVERNAME,
5931 if (!force_update) {
5932 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5933 printer->drivername));
5935 notify_printer_driver(server_event_context(), msg_ctx,
5936 snum, printer->drivername);
5940 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5941 push_reg_sz(mem_ctx, &buffer, printer->comment);
5942 winreg_set_printer_dataex(mem_ctx,
5946 SPOOL_DSSPOOLER_KEY,
5947 SPOOL_REG_DESCRIPTION,
5952 if (!force_update) {
5953 notify_printer_comment(server_event_context(), msg_ctx,
5954 snum, printer->comment);
5958 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5959 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5960 winreg_set_printer_dataex(mem_ctx,
5964 SPOOL_DSSPOOLER_KEY,
5965 SPOOL_REG_PRINTSHARENAME,
5970 if (!force_update) {
5971 notify_printer_sharename(server_event_context(),
5973 snum, printer->sharename);
5977 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5980 p = strrchr(printer->printername, '\\' );
5984 p = printer->printername;
5987 push_reg_sz(mem_ctx, &buffer, p);
5988 winreg_set_printer_dataex(mem_ctx,
5992 SPOOL_DSSPOOLER_KEY,
5993 SPOOL_REG_PRINTERNAME,
5998 if (!force_update) {
5999 notify_printer_printername(server_event_context(),
6004 if (force_update || !strequal(printer->portname, old_printer->portname)) {
6005 push_reg_sz(mem_ctx, &buffer, printer->portname);
6006 winreg_set_printer_dataex(mem_ctx,
6010 SPOOL_DSSPOOLER_KEY,
6016 if (!force_update) {
6017 notify_printer_port(server_event_context(),
6018 msg_ctx, snum, printer->portname);
6022 if (force_update || !strequal(printer->location, old_printer->location)) {
6023 push_reg_sz(mem_ctx, &buffer, printer->location);
6024 winreg_set_printer_dataex(mem_ctx,
6028 SPOOL_DSSPOOLER_KEY,
6034 if (!force_update) {
6035 notify_printer_location(server_event_context(),
6041 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
6042 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
6043 winreg_set_printer_dataex(mem_ctx,
6047 SPOOL_DSSPOOLER_KEY,
6048 SPOOL_REG_PRINTSEPARATORFILE,
6053 if (!force_update) {
6054 notify_printer_location(server_event_context(),
6060 if (force_update || printer->starttime != old_printer->starttime) {
6061 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6062 SIVAL(buffer.data, 0, printer->starttime);
6063 winreg_set_printer_dataex(mem_ctx,
6067 SPOOL_DSSPOOLER_KEY,
6068 SPOOL_REG_PRINTSTARTTIME,
6074 if (force_update || printer->untiltime != old_printer->untiltime) {
6075 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6076 SIVAL(buffer.data, 0, printer->untiltime);
6077 winreg_set_printer_dataex(mem_ctx,
6081 SPOOL_DSSPOOLER_KEY,
6082 SPOOL_REG_PRINTENDTIME,
6088 if (force_update || printer->priority != old_printer->priority) {
6089 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6090 SIVAL(buffer.data, 0, printer->priority);
6091 winreg_set_printer_dataex(mem_ctx,
6095 SPOOL_DSSPOOLER_KEY,
6102 if (force_update || printer->attributes != old_printer->attributes) {
6103 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6104 SIVAL(buffer.data, 0, (printer->attributes &
6105 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
6106 winreg_set_printer_dataex(mem_ctx,
6110 SPOOL_DSSPOOLER_KEY,
6111 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
6116 switch (printer->attributes & 0x3) {
6118 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
6121 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
6124 spooling = SPOOL_REGVAL_PRINTDIRECT;
6127 spooling = "unknown";
6129 push_reg_sz(mem_ctx, &buffer, spooling);
6130 winreg_set_printer_dataex(mem_ctx,
6134 SPOOL_DSSPOOLER_KEY,
6135 SPOOL_REG_PRINTSPOOLING,
6141 push_reg_sz(mem_ctx, &buffer, global_myname());
6142 winreg_set_printer_dataex(mem_ctx,
6146 SPOOL_DSSPOOLER_KEY,
6147 SPOOL_REG_SHORTSERVERNAME,
6152 dnsdomname = get_mydnsfullname();
6153 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
6154 longname = talloc_strdup(mem_ctx, dnsdomname);
6156 longname = talloc_strdup(mem_ctx, global_myname());
6158 if (longname == NULL) {
6159 result = WERR_NOMEM;
6163 push_reg_sz(mem_ctx, &buffer, longname);
6164 winreg_set_printer_dataex(mem_ctx,
6168 SPOOL_DSSPOOLER_KEY,
6169 SPOOL_REG_SERVERNAME,
6174 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
6175 global_myname(), printer->sharename);
6176 push_reg_sz(mem_ctx, &buffer, uncname);
6177 winreg_set_printer_dataex(mem_ctx,
6181 SPOOL_DSSPOOLER_KEY,
6191 /********************************************************************
6192 * Called by spoolss_api_setprinter
6193 * when updating a printer description.
6194 ********************************************************************/
6196 static WERROR update_printer(struct pipes_struct *p,
6197 struct policy_handle *handle,
6198 struct spoolss_SetPrinterInfoCtr *info_ctr,
6199 struct spoolss_DeviceMode *devmode)
6201 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
6202 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
6203 struct spoolss_PrinterInfo2 *old_printer;
6204 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6205 const char *servername = NULL;
6207 WERROR result = WERR_OK;
6208 TALLOC_CTX *tmp_ctx;
6210 DEBUG(8,("update_printer\n"));
6212 tmp_ctx = talloc_new(p->mem_ctx);
6213 if (tmp_ctx == NULL) {
6218 result = WERR_BADFID;
6222 if (!get_printer_snum(p, handle, &snum, NULL)) {
6223 result = WERR_BADFID;
6227 if (Printer != NULL || Printer->servername != NULL) {
6228 servername = Printer->servername;
6231 result = winreg_get_printer(tmp_ctx,
6232 get_server_info_system(),
6235 lp_const_servicename(snum),
6237 if (!W_ERROR_IS_OK(result)) {
6238 result = WERR_BADFID;
6242 /* Do sanity check on the requested changes for Samba */
6243 if (!check_printer_ok(tmp_ctx, printer, snum)) {
6244 result = WERR_INVALID_PARAM;
6248 /* FIXME!!! If the driver has changed we really should verify that
6249 it is installed before doing much else --jerry */
6251 /* Check calling user has permission to update printer description */
6252 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6253 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6254 result = WERR_ACCESS_DENIED;
6258 /* Call addprinter hook */
6259 /* Check changes to see if this is really needed */
6261 if (*lp_addprinter_cmd() &&
6262 (!strequal(printer->drivername, old_printer->drivername) ||
6263 !strequal(printer->comment, old_printer->comment) ||
6264 !strequal(printer->portname, old_printer->portname) ||
6265 !strequal(printer->location, old_printer->location)) )
6267 /* add_printer_hook() will call reload_services() */
6268 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6269 printer, p->client_id->addr,
6271 result = WERR_ACCESS_DENIED;
6276 update_dsspooler(tmp_ctx,
6277 get_server_info_system(),
6283 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6285 if (devmode == NULL) {
6286 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6288 result = winreg_update_printer(tmp_ctx,
6289 get_server_info_system(),
6298 talloc_free(tmp_ctx);
6303 /****************************************************************************
6304 ****************************************************************************/
6305 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6306 struct policy_handle *handle,
6307 struct spoolss_SetPrinterInfo7 *info7)
6310 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6313 struct printer_handle *Printer;
6315 if ( lp_security() != SEC_ADS ) {
6316 return WERR_UNKNOWN_LEVEL;
6319 Printer = find_printer_index_by_hnd(p, handle);
6321 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6326 if (!get_printer_snum(p, handle, &snum, NULL))
6329 result = winreg_get_printer(p->mem_ctx,
6330 get_server_info_system(),
6332 Printer->servername,
6333 lp_servicename(snum),
6335 if (!W_ERROR_IS_OK(result)) {
6339 nt_printer_publish(pinfo2,
6340 get_server_info_system(),
6345 TALLOC_FREE(pinfo2);
6348 return WERR_UNKNOWN_LEVEL;
6352 /********************************************************************
6353 ********************************************************************/
6355 static WERROR update_printer_devmode(struct pipes_struct *p,
6356 struct policy_handle *handle,
6357 struct spoolss_DeviceMode *devmode)
6360 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6361 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6363 DEBUG(8,("update_printer_devmode\n"));
6369 if (!get_printer_snum(p, handle, &snum, NULL)) {
6373 /* Check calling user has permission to update printer description */
6374 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6375 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6376 return WERR_ACCESS_DENIED;
6379 return winreg_update_printer(p->mem_ctx,
6380 get_server_info_system(),
6382 lp_const_servicename(snum),
6390 /****************************************************************
6392 ****************************************************************/
6394 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6395 struct spoolss_SetPrinter *r)
6399 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6402 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6403 OUR_HANDLE(r->in.handle)));
6407 /* check the level */
6408 switch (r->in.info_ctr->level) {
6410 return control_printer(r->in.handle, r->in.command, p);
6412 result = update_printer(p, r->in.handle,
6414 r->in.devmode_ctr->devmode);
6415 if (!W_ERROR_IS_OK(result))
6417 if (r->in.secdesc_ctr->sd)
6418 result = update_printer_sec(r->in.handle, p,
6422 return update_printer_sec(r->in.handle, p,
6425 return publish_or_unpublish_printer(p, r->in.handle,
6426 r->in.info_ctr->info.info7);
6428 return update_printer_devmode(p, r->in.handle,
6429 r->in.devmode_ctr->devmode);
6431 return WERR_UNKNOWN_LEVEL;
6435 /****************************************************************
6436 _spoolss_FindClosePrinterNotify
6437 ****************************************************************/
6439 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6440 struct spoolss_FindClosePrinterNotify *r)
6442 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6445 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6446 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6450 if (Printer->notify.client_connected == true) {
6453 if ( Printer->printer_type == SPLHND_SERVER)
6455 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6456 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6459 srv_spoolss_replycloseprinter(
6460 snum, &Printer->notify.client_hnd, p->msg_ctx);
6463 Printer->notify.flags=0;
6464 Printer->notify.options=0;
6465 Printer->notify.localmachine[0]='\0';
6466 Printer->notify.printerlocal=0;
6467 TALLOC_FREE(Printer->notify.option);
6468 Printer->notify.client_connected = false;
6473 /****************************************************************
6475 ****************************************************************/
6477 WERROR _spoolss_AddJob(struct pipes_struct *p,
6478 struct spoolss_AddJob *r)
6480 if (!r->in.buffer && (r->in.offered != 0)) {
6481 return WERR_INVALID_PARAM;
6484 /* this is what a NT server returns for AddJob. AddJob must fail on
6485 * non-local printers */
6487 if (r->in.level != 1) {
6488 return WERR_UNKNOWN_LEVEL;
6491 return WERR_INVALID_PARAM;
6494 /****************************************************************************
6496 ****************************************************************************/
6498 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6499 struct spoolss_JobInfo1 *r,
6500 const print_queue_struct *queue,
6501 int position, int snum,
6502 struct spoolss_PrinterInfo2 *pinfo2)
6506 t = gmtime(&queue->time);
6508 r->job_id = queue->job;
6510 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6511 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6512 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6513 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6514 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6515 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6516 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6517 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6518 r->data_type = talloc_strdup(mem_ctx, "RAW");
6519 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6520 r->text_status = talloc_strdup(mem_ctx, "");
6521 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6523 r->status = nt_printj_status(queue->status);
6524 r->priority = queue->priority;
6525 r->position = position;
6526 r->total_pages = queue->page_count;
6527 r->pages_printed = 0; /* ??? */
6529 init_systemtime(&r->submitted, t);
6534 /****************************************************************************
6536 ****************************************************************************/
6538 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6539 struct spoolss_JobInfo2 *r,
6540 const print_queue_struct *queue,
6541 int position, int snum,
6542 struct spoolss_PrinterInfo2 *pinfo2,
6543 struct spoolss_DeviceMode *devmode)
6547 t = gmtime(&queue->time);
6549 r->job_id = queue->job;
6551 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6552 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6553 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6554 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6555 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6556 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6557 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6558 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6559 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6560 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6561 r->data_type = talloc_strdup(mem_ctx, "RAW");
6562 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6563 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6564 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6565 r->parameters = talloc_strdup(mem_ctx, "");
6566 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6567 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6568 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6570 r->devmode = devmode;
6572 r->text_status = talloc_strdup(mem_ctx, "");
6573 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6577 r->status = nt_printj_status(queue->status);
6578 r->priority = queue->priority;
6579 r->position = position;
6582 r->total_pages = queue->page_count;
6583 r->size = queue->size;
6584 init_systemtime(&r->submitted, t);
6586 r->pages_printed = 0; /* ??? */
6591 /****************************************************************************
6593 ****************************************************************************/
6595 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6596 struct spoolss_JobInfo3 *r,
6597 const print_queue_struct *queue,
6598 const print_queue_struct *next_queue,
6599 int position, int snum,
6600 struct spoolss_PrinterInfo2 *pinfo2)
6602 r->job_id = queue->job;
6605 r->next_job_id = next_queue->job;
6612 /****************************************************************************
6613 Enumjobs at level 1.
6614 ****************************************************************************/
6616 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6617 const print_queue_struct *queue,
6618 uint32_t num_queues, int snum,
6619 struct spoolss_PrinterInfo2 *pinfo2,
6620 union spoolss_JobInfo **info_p,
6623 union spoolss_JobInfo *info;
6625 WERROR result = WERR_OK;
6627 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6628 W_ERROR_HAVE_NO_MEMORY(info);
6630 *count = num_queues;
6632 for (i=0; i<*count; i++) {
6633 result = fill_job_info1(info,
6639 if (!W_ERROR_IS_OK(result)) {
6645 if (!W_ERROR_IS_OK(result)) {
6656 /****************************************************************************
6657 Enumjobs at level 2.
6658 ****************************************************************************/
6660 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6661 const print_queue_struct *queue,
6662 uint32_t num_queues, int snum,
6663 struct spoolss_PrinterInfo2 *pinfo2,
6664 union spoolss_JobInfo **info_p,
6667 union spoolss_JobInfo *info;
6669 WERROR result = WERR_OK;
6671 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6672 W_ERROR_HAVE_NO_MEMORY(info);
6674 *count = num_queues;
6676 for (i=0; i<*count; i++) {
6677 struct spoolss_DeviceMode *devmode;
6679 result = spoolss_create_default_devmode(info,
6680 pinfo2->printername,
6682 if (!W_ERROR_IS_OK(result)) {
6683 DEBUG(3, ("Can't proceed w/o a devmode!"));
6687 result = fill_job_info2(info,
6694 if (!W_ERROR_IS_OK(result)) {
6700 if (!W_ERROR_IS_OK(result)) {
6711 /****************************************************************************
6712 Enumjobs at level 3.
6713 ****************************************************************************/
6715 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6716 const print_queue_struct *queue,
6717 uint32_t num_queues, int snum,
6718 struct spoolss_PrinterInfo2 *pinfo2,
6719 union spoolss_JobInfo **info_p,
6722 union spoolss_JobInfo *info;
6724 WERROR result = WERR_OK;
6726 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6727 W_ERROR_HAVE_NO_MEMORY(info);
6729 *count = num_queues;
6731 for (i=0; i<*count; i++) {
6732 const print_queue_struct *next_queue = NULL;
6735 next_queue = &queue[i+1];
6738 result = fill_job_info3(info,
6745 if (!W_ERROR_IS_OK(result)) {
6751 if (!W_ERROR_IS_OK(result)) {
6762 /****************************************************************
6764 ****************************************************************/
6766 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6767 struct spoolss_EnumJobs *r)
6770 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6772 print_status_struct prt_status;
6773 print_queue_struct *queue = NULL;
6776 /* that's an [in out] buffer */
6778 if (!r->in.buffer && (r->in.offered != 0)) {
6779 return WERR_INVALID_PARAM;
6782 DEBUG(4,("_spoolss_EnumJobs\n"));
6786 *r->out.info = NULL;
6788 /* lookup the printer snum and tdb entry */
6790 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6794 result = winreg_get_printer(p->mem_ctx,
6795 get_server_info_system(),
6798 lp_const_servicename(snum),
6800 if (!W_ERROR_IS_OK(result)) {
6804 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
6805 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6806 count, prt_status.status, prt_status.message));
6810 TALLOC_FREE(pinfo2);
6814 switch (r->in.level) {
6816 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6817 pinfo2, r->out.info, r->out.count);
6820 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6821 pinfo2, r->out.info, r->out.count);
6824 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6825 pinfo2, r->out.info, r->out.count);
6828 result = WERR_UNKNOWN_LEVEL;
6833 TALLOC_FREE(pinfo2);
6835 if (!W_ERROR_IS_OK(result)) {
6839 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6841 *r->out.info, r->in.level,
6843 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6844 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6846 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6849 /****************************************************************
6850 _spoolss_ScheduleJob
6851 ****************************************************************/
6853 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6854 struct spoolss_ScheduleJob *r)
6859 /****************************************************************
6860 ****************************************************************/
6862 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6863 struct messaging_context *msg_ctx,
6864 const char *printer_name,
6866 struct spoolss_SetJobInfo1 *r)
6870 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6874 if (strequal(old_doc_name, r->document_name)) {
6878 if (!print_job_set_name(server_event_context(), msg_ctx,
6879 printer_name, job_id, r->document_name)) {
6886 /****************************************************************
6888 ****************************************************************/
6890 WERROR _spoolss_SetJob(struct pipes_struct *p,
6891 struct spoolss_SetJob *r)
6893 const struct auth_serversupplied_info *server_info = get_server_info_system();
6895 WERROR errcode = WERR_BADFUNC;
6897 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6901 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6902 return WERR_INVALID_PRINTER_NAME;
6905 switch (r->in.command) {
6906 case SPOOLSS_JOB_CONTROL_CANCEL:
6907 case SPOOLSS_JOB_CONTROL_DELETE:
6908 errcode = print_job_delete(server_info, p->msg_ctx,
6909 snum, r->in.job_id);
6910 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6914 case SPOOLSS_JOB_CONTROL_PAUSE:
6915 if (print_job_pause(server_info, p->msg_ctx,
6916 snum, r->in.job_id, &errcode)) {
6920 case SPOOLSS_JOB_CONTROL_RESTART:
6921 case SPOOLSS_JOB_CONTROL_RESUME:
6922 if (print_job_resume(server_info, p->msg_ctx,
6923 snum, r->in.job_id, &errcode)) {
6931 return WERR_UNKNOWN_LEVEL;
6934 if (!W_ERROR_IS_OK(errcode)) {
6938 if (r->in.ctr == NULL) {
6942 switch (r->in.ctr->level) {
6944 errcode = spoolss_setjob_1(p->mem_ctx, p->msg_ctx,
6945 lp_const_servicename(snum),
6947 r->in.ctr->info.info1);
6953 return WERR_UNKNOWN_LEVEL;
6959 /****************************************************************************
6960 Enumerates all printer drivers by level and architecture.
6961 ****************************************************************************/
6963 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6964 const struct auth_serversupplied_info *server_info,
6965 struct messaging_context *msg_ctx,
6966 const char *servername,
6967 const char *architecture,
6969 union spoolss_DriverInfo **info_p,
6974 struct spoolss_DriverInfo8 *driver;
6975 union spoolss_DriverInfo *info = NULL;
6977 WERROR result = WERR_OK;
6978 uint32_t num_drivers;
6979 const char **drivers;
6984 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6985 result = winreg_get_driver_list(mem_ctx, server_info, msg_ctx,
6986 architecture, version,
6987 &num_drivers, &drivers);
6988 if (!W_ERROR_IS_OK(result)) {
6991 DEBUG(4, ("we have:[%d] drivers in environment"
6992 " [%s] and version [%d]\n",
6993 num_drivers, architecture, version));
6995 if (num_drivers != 0) {
6996 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6997 union spoolss_DriverInfo,
6998 count + num_drivers);
7000 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
7001 "failed to enlarge driver info buffer!\n"));
7002 result = WERR_NOMEM;
7007 for (i = 0; i < num_drivers; i++) {
7008 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
7010 result = winreg_get_driver(mem_ctx, server_info,
7012 architecture, drivers[i],
7014 if (!W_ERROR_IS_OK(result)) {
7020 result = fill_printer_driver_info1(info, &info[count+i].info1,
7021 driver, servername);
7024 result = fill_printer_driver_info2(info, &info[count+i].info2,
7025 driver, servername);
7028 result = fill_printer_driver_info3(info, &info[count+i].info3,
7029 driver, servername);
7032 result = fill_printer_driver_info4(info, &info[count+i].info4,
7033 driver, servername);
7036 result = fill_printer_driver_info5(info, &info[count+i].info5,
7037 driver, servername);
7040 result = fill_printer_driver_info6(info, &info[count+i].info6,
7041 driver, servername);
7044 result = fill_printer_driver_info8(info, &info[count+i].info8,
7045 driver, servername);
7048 result = WERR_UNKNOWN_LEVEL;
7052 TALLOC_FREE(driver);
7054 if (!W_ERROR_IS_OK(result)) {
7059 count += num_drivers;
7060 TALLOC_FREE(drivers);
7064 TALLOC_FREE(drivers);
7066 if (!W_ERROR_IS_OK(result)) {
7077 /****************************************************************************
7078 Enumerates all printer drivers by level.
7079 ****************************************************************************/
7081 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
7082 const struct auth_serversupplied_info *server_info,
7083 struct messaging_context *msg_ctx,
7084 const char *servername,
7085 const char *architecture,
7087 union spoolss_DriverInfo **info_p,
7091 WERROR result = WERR_OK;
7093 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
7095 for (a=0; archi_table[a].long_archi != NULL; a++) {
7097 union spoolss_DriverInfo *info = NULL;
7100 result = enumprinterdrivers_level_by_architecture(mem_ctx,
7104 archi_table[a].long_archi,
7108 if (!W_ERROR_IS_OK(result)) {
7112 for (i=0; i < count; i++) {
7113 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
7114 info[i], info_p, count_p);
7121 return enumprinterdrivers_level_by_architecture(mem_ctx,
7131 /****************************************************************
7132 _spoolss_EnumPrinterDrivers
7133 ****************************************************************/
7135 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
7136 struct spoolss_EnumPrinterDrivers *r)
7138 const char *cservername;
7141 /* that's an [in out] buffer */
7143 if (!r->in.buffer && (r->in.offered != 0)) {
7144 return WERR_INVALID_PARAM;
7147 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
7151 *r->out.info = NULL;
7153 cservername = canon_servername(r->in.server);
7155 if (!is_myname_or_ipaddr(cservername)) {
7156 return WERR_UNKNOWN_PRINTER_DRIVER;
7159 result = enumprinterdrivers_level(p->mem_ctx,
7160 get_server_info_system(),
7167 if (!W_ERROR_IS_OK(result)) {
7171 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7172 spoolss_EnumPrinterDrivers,
7173 *r->out.info, r->in.level,
7175 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7176 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7178 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7181 /****************************************************************
7183 ****************************************************************/
7185 WERROR _spoolss_EnumForms(struct pipes_struct *p,
7186 struct spoolss_EnumForms *r)
7192 *r->out.info = NULL;
7194 /* that's an [in out] buffer */
7196 if (!r->in.buffer && (r->in.offered != 0) ) {
7197 return WERR_INVALID_PARAM;
7200 DEBUG(4,("_spoolss_EnumForms\n"));
7201 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7202 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7204 switch (r->in.level) {
7206 result = winreg_printer_enumforms1(p->mem_ctx,
7207 get_server_info_system(),
7213 result = WERR_UNKNOWN_LEVEL;
7217 if (!W_ERROR_IS_OK(result)) {
7221 if (*r->out.count == 0) {
7222 return WERR_NO_MORE_ITEMS;
7225 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7227 *r->out.info, r->in.level,
7229 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7230 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7232 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7235 /****************************************************************
7237 ****************************************************************/
7239 WERROR _spoolss_GetForm(struct pipes_struct *p,
7240 struct spoolss_GetForm *r)
7244 /* that's an [in out] buffer */
7246 if (!r->in.buffer && (r->in.offered != 0)) {
7247 return WERR_INVALID_PARAM;
7250 DEBUG(4,("_spoolss_GetForm\n"));
7251 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7252 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7254 switch (r->in.level) {
7256 result = winreg_printer_getform1(p->mem_ctx,
7257 get_server_info_system(),
7260 &r->out.info->info1);
7263 result = WERR_UNKNOWN_LEVEL;
7267 if (!W_ERROR_IS_OK(result)) {
7268 TALLOC_FREE(r->out.info);
7272 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
7273 r->out.info, r->in.level);
7274 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7276 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7279 /****************************************************************************
7280 ****************************************************************************/
7282 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
7283 struct spoolss_PortInfo1 *r,
7286 r->port_name = talloc_strdup(mem_ctx, name);
7287 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7292 /****************************************************************************
7293 TODO: This probably needs distinguish between TCP/IP and Local ports
7295 ****************************************************************************/
7297 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7298 struct spoolss_PortInfo2 *r,
7301 r->port_name = talloc_strdup(mem_ctx, name);
7302 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7304 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7305 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7307 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7308 W_ERROR_HAVE_NO_MEMORY(r->description);
7310 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7317 /****************************************************************************
7318 wrapper around the enumer ports command
7319 ****************************************************************************/
7321 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7323 char *cmd = lp_enumports_cmd();
7324 char **qlines = NULL;
7325 char *command = NULL;
7333 /* if no hook then just fill in the default port */
7336 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7339 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7340 TALLOC_FREE(qlines);
7347 /* we have a valid enumport command */
7349 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7354 DEBUG(10,("Running [%s]\n", command));
7355 ret = smbrun(command, &fd);
7356 DEBUG(10,("Returned [%d]\n", ret));
7357 TALLOC_FREE(command);
7362 return WERR_ACCESS_DENIED;
7366 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7367 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7377 /****************************************************************************
7379 ****************************************************************************/
7381 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7382 union spoolss_PortInfo **info_p,
7385 union spoolss_PortInfo *info = NULL;
7387 WERROR result = WERR_OK;
7388 char **qlines = NULL;
7391 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7392 if (!W_ERROR_IS_OK(result)) {
7397 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7399 DEBUG(10,("Returning WERR_NOMEM\n"));
7400 result = WERR_NOMEM;
7404 for (i=0; i<numlines; i++) {
7405 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7406 result = fill_port_1(info, &info[i].info1, qlines[i]);
7407 if (!W_ERROR_IS_OK(result)) {
7412 TALLOC_FREE(qlines);
7415 if (!W_ERROR_IS_OK(result)) {
7417 TALLOC_FREE(qlines);
7429 /****************************************************************************
7431 ****************************************************************************/
7433 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7434 union spoolss_PortInfo **info_p,
7437 union spoolss_PortInfo *info = NULL;
7439 WERROR result = WERR_OK;
7440 char **qlines = NULL;
7443 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7444 if (!W_ERROR_IS_OK(result)) {
7449 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7451 DEBUG(10,("Returning WERR_NOMEM\n"));
7452 result = WERR_NOMEM;
7456 for (i=0; i<numlines; i++) {
7457 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7458 result = fill_port_2(info, &info[i].info2, qlines[i]);
7459 if (!W_ERROR_IS_OK(result)) {
7464 TALLOC_FREE(qlines);
7467 if (!W_ERROR_IS_OK(result)) {
7469 TALLOC_FREE(qlines);
7481 /****************************************************************
7483 ****************************************************************/
7485 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7486 struct spoolss_EnumPorts *r)
7490 /* that's an [in out] buffer */
7492 if (!r->in.buffer && (r->in.offered != 0)) {
7493 return WERR_INVALID_PARAM;
7496 DEBUG(4,("_spoolss_EnumPorts\n"));
7500 *r->out.info = NULL;
7502 switch (r->in.level) {
7504 result = enumports_level_1(p->mem_ctx, r->out.info,
7508 result = enumports_level_2(p->mem_ctx, r->out.info,
7512 return WERR_UNKNOWN_LEVEL;
7515 if (!W_ERROR_IS_OK(result)) {
7519 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7521 *r->out.info, r->in.level,
7523 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7524 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7526 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7529 /****************************************************************************
7530 ****************************************************************************/
7532 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7534 struct spoolss_SetPrinterInfoCtr *info_ctr,
7535 struct spoolss_DeviceMode *devmode,
7536 struct security_descriptor *secdesc,
7537 struct spoolss_UserLevelCtr *user_ctr,
7538 struct policy_handle *handle)
7540 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7541 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7543 WERROR err = WERR_OK;
7545 /* samba does not have a concept of local, non-shared printers yet, so
7546 * make sure we always setup sharename - gd */
7547 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7548 (info2->printername != NULL && info2->printername[0] != '\0')) {
7549 DEBUG(5, ("spoolss_addprinterex_level_2: "
7550 "no sharename has been set, setting printername %s as sharename\n",
7551 info2->printername));
7552 info2->sharename = info2->printername;
7555 /* check to see if the printer already exists */
7556 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7557 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7559 return WERR_PRINTER_ALREADY_EXISTS;
7562 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7563 if ((snum = print_queue_snum(info2->printername)) != -1) {
7564 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7565 info2->printername));
7566 return WERR_PRINTER_ALREADY_EXISTS;
7570 /* validate printer info struct */
7571 if (!info2->printername || strlen(info2->printername) == 0) {
7572 return WERR_INVALID_PRINTER_NAME;
7574 if (!info2->portname || strlen(info2->portname) == 0) {
7575 return WERR_UNKNOWN_PORT;
7577 if (!info2->drivername || strlen(info2->drivername) == 0) {
7578 return WERR_UNKNOWN_PRINTER_DRIVER;
7580 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7581 return WERR_UNKNOWN_PRINTPROCESSOR;
7584 /* FIXME!!! smbd should check to see if the driver is installed before
7585 trying to add a printer like this --jerry */
7587 if (*lp_addprinter_cmd() ) {
7588 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7589 info2, p->client_id->addr,
7591 return WERR_ACCESS_DENIED;
7594 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7595 "smb.conf parameter \"addprinter command\" is defined. This"
7596 "parameter must exist for this call to succeed\n",
7597 info2->sharename ));
7600 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7601 return WERR_ACCESS_DENIED;
7604 /* you must be a printer admin to add a new printer */
7605 if (!print_access_check(get_server_info_system(),
7608 PRINTER_ACCESS_ADMINISTER)) {
7609 return WERR_ACCESS_DENIED;
7613 * Do sanity check on the requested changes for Samba.
7616 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7617 return WERR_INVALID_PARAM;
7620 if (devmode == NULL) {
7621 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7624 update_dsspooler(p->mem_ctx,
7625 get_server_info_system(),
7631 err = winreg_update_printer(p->mem_ctx,
7632 get_server_info_system(),
7639 if (!W_ERROR_IS_OK(err)) {
7643 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7644 /* Handle open failed - remove addition. */
7645 ZERO_STRUCTP(handle);
7646 return WERR_ACCESS_DENIED;
7652 /****************************************************************
7653 _spoolss_AddPrinterEx
7654 ****************************************************************/
7656 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7657 struct spoolss_AddPrinterEx *r)
7659 switch (r->in.info_ctr->level) {
7661 /* we don't handle yet */
7662 /* but I know what to do ... */
7663 return WERR_UNKNOWN_LEVEL;
7665 return spoolss_addprinterex_level_2(p, r->in.server,
7667 r->in.devmode_ctr->devmode,
7668 r->in.secdesc_ctr->sd,
7669 r->in.userlevel_ctr,
7672 return WERR_UNKNOWN_LEVEL;
7676 /****************************************************************
7678 ****************************************************************/
7680 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7681 struct spoolss_AddPrinter *r)
7683 struct spoolss_AddPrinterEx a;
7684 struct spoolss_UserLevelCtr userlevel_ctr;
7686 ZERO_STRUCT(userlevel_ctr);
7688 userlevel_ctr.level = 1;
7690 a.in.server = r->in.server;
7691 a.in.info_ctr = r->in.info_ctr;
7692 a.in.devmode_ctr = r->in.devmode_ctr;
7693 a.in.secdesc_ctr = r->in.secdesc_ctr;
7694 a.in.userlevel_ctr = &userlevel_ctr;
7695 a.out.handle = r->out.handle;
7697 return _spoolss_AddPrinterEx(p, &a);
7700 /****************************************************************
7701 _spoolss_AddPrinterDriverEx
7702 ****************************************************************/
7704 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7705 struct spoolss_AddPrinterDriverEx *r)
7707 WERROR err = WERR_OK;
7708 const char *driver_name = NULL;
7713 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7714 fn = "_spoolss_AddPrinterDriver";
7716 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7717 fn = "_spoolss_AddPrinterDriverEx";
7720 return WERR_INVALID_PARAM;
7724 * we only support the semantics of AddPrinterDriver()
7725 * i.e. only copy files that are newer than existing ones
7728 if (r->in.flags == 0) {
7729 return WERR_INVALID_PARAM;
7732 if (r->in.flags != APD_COPY_NEW_FILES) {
7733 return WERR_ACCESS_DENIED;
7737 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7738 /* Clever hack from Martin Zielinski <mz@seh.de>
7739 * to allow downgrade from level 8 (Vista).
7741 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7742 r->in.info_ctr->level));
7743 return WERR_UNKNOWN_LEVEL;
7746 DEBUG(5,("Cleaning driver's information\n"));
7747 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7748 if (!W_ERROR_IS_OK(err))
7751 DEBUG(5,("Moving driver to final destination\n"));
7752 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7757 err = winreg_add_driver(p->mem_ctx,
7758 get_server_info_system(),
7763 if (!W_ERROR_IS_OK(err)) {
7768 * I think this is where he DrvUpgradePrinter() hook would be
7769 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7770 * server. Right now, we just need to send ourselves a message
7771 * to update each printer bound to this driver. --jerry
7774 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7775 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7783 /****************************************************************
7784 _spoolss_AddPrinterDriver
7785 ****************************************************************/
7787 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7788 struct spoolss_AddPrinterDriver *r)
7790 struct spoolss_AddPrinterDriverEx a;
7792 switch (r->in.info_ctr->level) {
7799 return WERR_UNKNOWN_LEVEL;
7802 a.in.servername = r->in.servername;
7803 a.in.info_ctr = r->in.info_ctr;
7804 a.in.flags = APD_COPY_NEW_FILES;
7806 return _spoolss_AddPrinterDriverEx(p, &a);
7809 /****************************************************************************
7810 ****************************************************************************/
7812 struct _spoolss_paths {
7818 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7820 static const struct _spoolss_paths spoolss_paths[]= {
7821 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7822 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7825 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7826 const char *servername,
7827 const char *environment,
7831 const char *pservername = NULL;
7832 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7833 const char *short_archi;
7837 /* environment may be empty */
7838 if (environment && strlen(environment)) {
7839 long_archi = environment;
7842 /* servername may be empty */
7843 if (servername && strlen(servername)) {
7844 pservername = canon_servername(servername);
7846 if (!is_myname_or_ipaddr(pservername)) {
7847 return WERR_INVALID_PARAM;
7851 if (!(short_archi = get_short_archi(long_archi))) {
7852 return WERR_INVALID_ENVIRONMENT;
7855 switch (component) {
7856 case SPOOLSS_PRTPROCS_PATH:
7857 case SPOOLSS_DRIVER_PATH:
7859 *path = talloc_asprintf(mem_ctx,
7862 spoolss_paths[component].share,
7865 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7866 SPOOLSS_DEFAULT_SERVER_PATH,
7867 spoolss_paths[component].dir,
7872 return WERR_INVALID_PARAM;
7882 /****************************************************************************
7883 ****************************************************************************/
7885 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7886 const char *servername,
7887 const char *environment,
7888 struct spoolss_DriverDirectoryInfo1 *r)
7893 werr = compose_spoolss_server_path(mem_ctx,
7896 SPOOLSS_DRIVER_PATH,
7898 if (!W_ERROR_IS_OK(werr)) {
7902 DEBUG(4,("printer driver directory: [%s]\n", path));
7904 r->directory_name = path;
7909 /****************************************************************
7910 _spoolss_GetPrinterDriverDirectory
7911 ****************************************************************/
7913 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7914 struct spoolss_GetPrinterDriverDirectory *r)
7918 /* that's an [in out] buffer */
7920 if (!r->in.buffer && (r->in.offered != 0)) {
7921 return WERR_INVALID_PARAM;
7924 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7929 /* r->in.level is ignored */
7931 werror = getprinterdriverdir_level_1(p->mem_ctx,
7934 &r->out.info->info1);
7935 if (!W_ERROR_IS_OK(werror)) {
7936 TALLOC_FREE(r->out.info);
7940 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7941 r->out.info, r->in.level);
7942 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7944 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7947 /****************************************************************
7948 _spoolss_EnumPrinterData
7949 ****************************************************************/
7951 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7952 struct spoolss_EnumPrinterData *r)
7955 struct spoolss_EnumPrinterDataEx r2;
7957 struct spoolss_PrinterEnumValues *info, *val = NULL;
7960 r2.in.handle = r->in.handle;
7961 r2.in.key_name = "PrinterDriverData";
7963 r2.out.count = &count;
7964 r2.out.info = &info;
7965 r2.out.needed = &needed;
7967 result = _spoolss_EnumPrinterDataEx(p, &r2);
7968 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7969 r2.in.offered = needed;
7970 result = _spoolss_EnumPrinterDataEx(p, &r2);
7972 if (!W_ERROR_IS_OK(result)) {
7977 * The NT machine wants to know the biggest size of value and data
7979 * cf: MSDN EnumPrinterData remark section
7982 if (!r->in.value_offered && !r->in.data_offered) {
7983 uint32_t biggest_valuesize = 0;
7984 uint32_t biggest_datasize = 0;
7987 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7989 for (i=0; i<count; i++) {
7991 name_length = strlen(info[i].value_name);
7992 if (strlen(info[i].value_name) > biggest_valuesize) {
7993 biggest_valuesize = name_length;
7996 if (info[i].data_length > biggest_datasize) {
7997 biggest_datasize = info[i].data_length;
8000 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8004 /* the value is an UNICODE string but real_value_size is the length
8005 in bytes including the trailing 0 */
8007 *r->out.value_needed = 2 * (1 + biggest_valuesize);
8008 *r->out.data_needed = biggest_datasize;
8010 DEBUG(6,("final values: [%d], [%d]\n",
8011 *r->out.value_needed, *r->out.data_needed));
8016 if (r->in.enum_index < count) {
8017 val = &info[r->in.enum_index];
8021 /* out_value should default to "" or else NT4 has
8022 problems unmarshalling the response */
8024 if (r->in.value_offered) {
8025 *r->out.value_needed = 1;
8026 r->out.value_name = talloc_strdup(r, "");
8027 if (!r->out.value_name) {
8031 r->out.value_name = NULL;
8032 *r->out.value_needed = 0;
8035 /* the data is counted in bytes */
8037 *r->out.data_needed = r->in.data_offered;
8039 result = WERR_NO_MORE_ITEMS;
8043 * - counted in bytes in the request
8044 * - counted in UNICODE chars in the max reply
8045 * - counted in bytes in the real size
8047 * take a pause *before* coding not *during* coding
8051 if (r->in.value_offered) {
8052 r->out.value_name = talloc_strdup(r, val->value_name);
8053 if (!r->out.value_name) {
8056 *r->out.value_needed = val->value_name_len;
8058 r->out.value_name = NULL;
8059 *r->out.value_needed = 0;
8064 *r->out.type = val->type;
8066 /* data - counted in bytes */
8069 * See the section "Dynamically Typed Query Parameters"
8073 if (r->out.data && val->data && val->data->data &&
8074 val->data_length && r->in.data_offered) {
8075 memcpy(r->out.data, val->data->data,
8076 MIN(val->data_length,r->in.data_offered));
8079 *r->out.data_needed = val->data_length;
8087 /****************************************************************
8088 _spoolss_SetPrinterData
8089 ****************************************************************/
8091 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
8092 struct spoolss_SetPrinterData *r)
8094 struct spoolss_SetPrinterDataEx r2;
8096 r2.in.handle = r->in.handle;
8097 r2.in.key_name = "PrinterDriverData";
8098 r2.in.value_name = r->in.value_name;
8099 r2.in.type = r->in.type;
8100 r2.in.data = r->in.data;
8101 r2.in.offered = r->in.offered;
8103 return _spoolss_SetPrinterDataEx(p, &r2);
8106 /****************************************************************
8107 _spoolss_ResetPrinter
8108 ****************************************************************/
8110 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
8111 struct spoolss_ResetPrinter *r)
8113 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8116 DEBUG(5,("_spoolss_ResetPrinter\n"));
8119 * All we do is to check to see if the handle and queue is valid.
8120 * This call really doesn't mean anything to us because we only
8121 * support RAW printing. --jerry
8125 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8126 OUR_HANDLE(r->in.handle)));
8130 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8134 /* blindly return success */
8138 /****************************************************************
8139 _spoolss_DeletePrinterData
8140 ****************************************************************/
8142 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
8143 struct spoolss_DeletePrinterData *r)
8145 struct spoolss_DeletePrinterDataEx r2;
8147 r2.in.handle = r->in.handle;
8148 r2.in.key_name = "PrinterDriverData";
8149 r2.in.value_name = r->in.value_name;
8151 return _spoolss_DeletePrinterDataEx(p, &r2);
8154 /****************************************************************
8156 ****************************************************************/
8158 WERROR _spoolss_AddForm(struct pipes_struct *p,
8159 struct spoolss_AddForm *r)
8161 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8163 WERROR status = WERR_OK;
8164 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8166 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8168 DEBUG(5,("_spoolss_AddForm\n"));
8171 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8172 OUR_HANDLE(r->in.handle)));
8176 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8177 and not a printer admin, then fail */
8179 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8180 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8181 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8182 p->server_info->info3->base.domain.string,
8184 p->server_info->ptok,
8185 lp_printer_admin(snum))) {
8186 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
8187 return WERR_ACCESS_DENIED;
8190 switch (form->flags) {
8191 case SPOOLSS_FORM_USER:
8192 case SPOOLSS_FORM_BUILTIN:
8193 case SPOOLSS_FORM_PRINTER:
8196 return WERR_INVALID_PARAM;
8199 status = winreg_printer_addform1(p->mem_ctx,
8200 get_server_info_system(),
8203 if (!W_ERROR_IS_OK(status)) {
8208 * ChangeID must always be set if this is a printer
8210 if (Printer->printer_type == SPLHND_PRINTER) {
8211 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8215 status = winreg_printer_update_changeid(p->mem_ctx,
8216 get_server_info_system(),
8218 lp_const_servicename(snum));
8219 if (!W_ERROR_IS_OK(status)) {
8227 /****************************************************************
8229 ****************************************************************/
8231 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
8232 struct spoolss_DeleteForm *r)
8234 const char *form_name = r->in.form_name;
8235 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8237 WERROR status = WERR_OK;
8238 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8240 DEBUG(5,("_spoolss_DeleteForm\n"));
8243 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8244 OUR_HANDLE(r->in.handle)));
8248 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8249 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8250 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8251 p->server_info->info3->base.domain.string,
8253 p->server_info->ptok,
8254 lp_printer_admin(snum))) {
8255 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8256 return WERR_ACCESS_DENIED;
8259 status = winreg_printer_deleteform1(p->mem_ctx,
8260 get_server_info_system(),
8263 if (!W_ERROR_IS_OK(status)) {
8268 * ChangeID must always be set if this is a printer
8270 if (Printer->printer_type == SPLHND_PRINTER) {
8271 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8275 status = winreg_printer_update_changeid(p->mem_ctx,
8276 get_server_info_system(),
8278 lp_const_servicename(snum));
8279 if (!W_ERROR_IS_OK(status)) {
8287 /****************************************************************
8289 ****************************************************************/
8291 WERROR _spoolss_SetForm(struct pipes_struct *p,
8292 struct spoolss_SetForm *r)
8294 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8295 const char *form_name = r->in.form_name;
8297 WERROR status = WERR_OK;
8298 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8300 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8302 DEBUG(5,("_spoolss_SetForm\n"));
8305 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8306 OUR_HANDLE(r->in.handle)));
8310 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8311 and not a printer admin, then fail */
8313 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8314 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8315 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8316 p->server_info->info3->base.domain.string,
8318 p->server_info->ptok,
8319 lp_printer_admin(snum))) {
8320 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8321 return WERR_ACCESS_DENIED;
8324 status = winreg_printer_setform1(p->mem_ctx,
8325 get_server_info_system(),
8329 if (!W_ERROR_IS_OK(status)) {
8334 * ChangeID must always be set if this is a printer
8336 if (Printer->printer_type == SPLHND_PRINTER) {
8337 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8341 status = winreg_printer_update_changeid(p->mem_ctx,
8342 get_server_info_system(),
8344 lp_const_servicename(snum));
8345 if (!W_ERROR_IS_OK(status)) {
8353 /****************************************************************************
8354 fill_print_processor1
8355 ****************************************************************************/
8357 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8358 struct spoolss_PrintProcessorInfo1 *r,
8359 const char *print_processor_name)
8361 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8362 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8367 /****************************************************************************
8368 enumprintprocessors level 1.
8369 ****************************************************************************/
8371 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8372 union spoolss_PrintProcessorInfo **info_p,
8375 union spoolss_PrintProcessorInfo *info;
8378 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8379 W_ERROR_HAVE_NO_MEMORY(info);
8383 result = fill_print_processor1(info, &info[0].info1, "winprint");
8384 if (!W_ERROR_IS_OK(result)) {
8389 if (!W_ERROR_IS_OK(result)) {
8400 /****************************************************************
8401 _spoolss_EnumPrintProcessors
8402 ****************************************************************/
8404 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8405 struct spoolss_EnumPrintProcessors *r)
8409 /* that's an [in out] buffer */
8411 if (!r->in.buffer && (r->in.offered != 0)) {
8412 return WERR_INVALID_PARAM;
8415 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8418 * Enumerate the print processors ...
8420 * Just reply with "winprint", to keep NT happy
8421 * and I can use my nice printer checker.
8426 *r->out.info = NULL;
8428 switch (r->in.level) {
8430 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8434 return WERR_UNKNOWN_LEVEL;
8437 if (!W_ERROR_IS_OK(result)) {
8441 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8442 spoolss_EnumPrintProcessors,
8443 *r->out.info, r->in.level,
8445 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8446 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8448 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8451 /****************************************************************************
8452 fill_printprocdatatype1
8453 ****************************************************************************/
8455 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8456 struct spoolss_PrintProcDataTypesInfo1 *r,
8457 const char *name_array)
8459 r->name_array = talloc_strdup(mem_ctx, name_array);
8460 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8465 /****************************************************************************
8466 enumprintprocdatatypes level 1.
8467 ****************************************************************************/
8469 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8470 union spoolss_PrintProcDataTypesInfo **info_p,
8474 union spoolss_PrintProcDataTypesInfo *info;
8476 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8477 W_ERROR_HAVE_NO_MEMORY(info);
8481 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8482 if (!W_ERROR_IS_OK(result)) {
8487 if (!W_ERROR_IS_OK(result)) {
8498 /****************************************************************
8499 _spoolss_EnumPrintProcDataTypes
8500 ****************************************************************/
8502 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8503 struct spoolss_EnumPrintProcDataTypes *r)
8507 /* that's an [in out] buffer */
8509 if (!r->in.buffer && (r->in.offered != 0)) {
8510 return WERR_INVALID_PARAM;
8513 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8517 *r->out.info = NULL;
8519 switch (r->in.level) {
8521 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8525 return WERR_UNKNOWN_LEVEL;
8528 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8529 spoolss_EnumPrintProcDataTypes,
8530 *r->out.info, r->in.level,
8532 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8533 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8535 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8538 /****************************************************************************
8540 ****************************************************************************/
8542 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8543 struct spoolss_MonitorInfo1 *r,
8544 const char *monitor_name)
8546 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8547 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8552 /****************************************************************************
8554 ****************************************************************************/
8556 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8557 struct spoolss_MonitorInfo2 *r,
8558 const char *monitor_name,
8559 const char *environment,
8560 const char *dll_name)
8562 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8563 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8564 r->environment = talloc_strdup(mem_ctx, environment);
8565 W_ERROR_HAVE_NO_MEMORY(r->environment);
8566 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8567 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8572 /****************************************************************************
8573 enumprintmonitors level 1.
8574 ****************************************************************************/
8576 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8577 union spoolss_MonitorInfo **info_p,
8580 union spoolss_MonitorInfo *info;
8581 WERROR result = WERR_OK;
8583 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8584 W_ERROR_HAVE_NO_MEMORY(info);
8588 result = fill_monitor_1(info, &info[0].info1,
8590 if (!W_ERROR_IS_OK(result)) {
8594 result = fill_monitor_1(info, &info[1].info1,
8596 if (!W_ERROR_IS_OK(result)) {
8601 if (!W_ERROR_IS_OK(result)) {
8612 /****************************************************************************
8613 enumprintmonitors level 2.
8614 ****************************************************************************/
8616 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8617 union spoolss_MonitorInfo **info_p,
8620 union spoolss_MonitorInfo *info;
8621 WERROR result = WERR_OK;
8623 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8624 W_ERROR_HAVE_NO_MEMORY(info);
8628 result = fill_monitor_2(info, &info[0].info2,
8630 "Windows NT X86", /* FIXME */
8632 if (!W_ERROR_IS_OK(result)) {
8636 result = fill_monitor_2(info, &info[1].info2,
8638 "Windows NT X86", /* FIXME */
8640 if (!W_ERROR_IS_OK(result)) {
8645 if (!W_ERROR_IS_OK(result)) {
8656 /****************************************************************
8657 _spoolss_EnumMonitors
8658 ****************************************************************/
8660 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8661 struct spoolss_EnumMonitors *r)
8665 /* that's an [in out] buffer */
8667 if (!r->in.buffer && (r->in.offered != 0)) {
8668 return WERR_INVALID_PARAM;
8671 DEBUG(5,("_spoolss_EnumMonitors\n"));
8674 * Enumerate the print monitors ...
8676 * Just reply with "Local Port", to keep NT happy
8677 * and I can use my nice printer checker.
8682 *r->out.info = NULL;
8684 switch (r->in.level) {
8686 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8690 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8694 return WERR_UNKNOWN_LEVEL;
8697 if (!W_ERROR_IS_OK(result)) {
8701 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8702 spoolss_EnumMonitors,
8703 *r->out.info, r->in.level,
8705 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8706 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8708 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8711 /****************************************************************************
8712 ****************************************************************************/
8714 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8715 const print_queue_struct *queue,
8716 int count, int snum,
8717 struct spoolss_PrinterInfo2 *pinfo2,
8719 struct spoolss_JobInfo1 *r)
8724 for (i=0; i<count; i++) {
8725 if (queue[i].job == (int)jobid) {
8731 if (found == false) {
8732 /* NT treats not found as bad param... yet another bad choice */
8733 return WERR_INVALID_PARAM;
8736 return fill_job_info1(mem_ctx,
8744 /****************************************************************************
8745 ****************************************************************************/
8747 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8748 const print_queue_struct *queue,
8749 int count, int snum,
8750 struct spoolss_PrinterInfo2 *pinfo2,
8752 struct spoolss_JobInfo2 *r)
8756 struct spoolss_DeviceMode *devmode;
8759 for (i=0; i<count; i++) {
8760 if (queue[i].job == (int)jobid) {
8766 if (found == false) {
8767 /* NT treats not found as bad param... yet another bad
8769 return WERR_INVALID_PARAM;
8773 * if the print job does not have a DEVMODE associated with it,
8774 * just use the one for the printer. A NULL devicemode is not
8775 * a failure condition
8778 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8780 result = spoolss_create_default_devmode(mem_ctx,
8781 pinfo2->printername,
8783 if (!W_ERROR_IS_OK(result)) {
8784 DEBUG(3, ("Can't proceed w/o a devmode!"));
8789 return fill_job_info2(mem_ctx,
8798 /****************************************************************
8800 ****************************************************************/
8802 WERROR _spoolss_GetJob(struct pipes_struct *p,
8803 struct spoolss_GetJob *r)
8805 WERROR result = WERR_OK;
8806 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8809 print_queue_struct *queue = NULL;
8810 print_status_struct prt_status;
8812 /* that's an [in out] buffer */
8814 if (!r->in.buffer && (r->in.offered != 0)) {
8815 return WERR_INVALID_PARAM;
8818 DEBUG(5,("_spoolss_GetJob\n"));
8822 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8826 result = winreg_get_printer(p->mem_ctx,
8827 get_server_info_system(),
8830 lp_const_servicename(snum),
8832 if (!W_ERROR_IS_OK(result)) {
8836 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
8838 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8839 count, prt_status.status, prt_status.message));
8841 switch (r->in.level) {
8843 result = getjob_level_1(p->mem_ctx,
8844 queue, count, snum, pinfo2,
8845 r->in.job_id, &r->out.info->info1);
8848 result = getjob_level_2(p->mem_ctx,
8849 queue, count, snum, pinfo2,
8850 r->in.job_id, &r->out.info->info2);
8853 result = WERR_UNKNOWN_LEVEL;
8858 TALLOC_FREE(pinfo2);
8860 if (!W_ERROR_IS_OK(result)) {
8861 TALLOC_FREE(r->out.info);
8865 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8867 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8869 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8872 /****************************************************************
8873 _spoolss_GetPrinterDataEx
8874 ****************************************************************/
8876 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8877 struct spoolss_GetPrinterDataEx *r)
8880 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8881 const char *printer;
8883 WERROR result = WERR_OK;
8885 enum winreg_Type val_type;
8890 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8892 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8893 r->in.key_name, r->in.value_name));
8895 /* in case of problem, return some default values */
8898 *r->out.type = REG_NONE;
8901 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8902 OUR_HANDLE(r->in.handle)));
8903 result = WERR_BADFID;
8907 /* Is the handle to a printer or to the server? */
8909 if (Printer->printer_type == SPLHND_SERVER) {
8911 union spoolss_PrinterData data;
8913 result = getprinterdata_printer_server(p->mem_ctx,
8917 if (!W_ERROR_IS_OK(result)) {
8921 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8922 *r->out.type, &data);
8923 if (!W_ERROR_IS_OK(result)) {
8927 *r->out.needed = blob.length;
8929 if (r->in.offered >= *r->out.needed) {
8930 memcpy(r->out.data, blob.data, blob.length);
8933 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8936 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8939 printer = lp_const_servicename(snum);
8941 /* check to see if the keyname is valid */
8942 if (!strlen(r->in.key_name)) {
8943 return WERR_INVALID_PARAM;
8946 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8947 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8948 strequal(r->in.value_name, "ChangeId")) {
8949 *r->out.type = REG_DWORD;
8951 if (r->in.offered >= *r->out.needed) {
8952 uint32_t changeid = 0;
8954 result = winreg_printer_get_changeid(p->mem_ctx,
8955 get_server_info_system(),
8959 if (!W_ERROR_IS_OK(result)) {
8963 SIVAL(r->out.data, 0, changeid);
8969 result = winreg_get_printer_dataex(p->mem_ctx,
8970 get_server_info_system(),
8978 if (!W_ERROR_IS_OK(result)) {
8982 *r->out.needed = val_size;
8983 *r->out.type = val_type;
8985 if (r->in.offered >= *r->out.needed) {
8986 memcpy(r->out.data, val_data, val_size);
8990 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8991 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8993 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8996 /****************************************************************
8997 _spoolss_SetPrinterDataEx
8998 ****************************************************************/
9000 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
9001 struct spoolss_SetPrinterDataEx *r)
9003 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
9005 WERROR result = WERR_OK;
9006 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9009 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9011 /* From MSDN documentation of SetPrinterDataEx: pass request to
9012 SetPrinterData if key is "PrinterDriverData" */
9015 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
9016 OUR_HANDLE(r->in.handle)));
9020 if (Printer->printer_type == SPLHND_SERVER) {
9021 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9022 "Not implemented for server handles yet\n"));
9023 return WERR_INVALID_PARAM;
9026 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9031 * Access check : NT returns "access denied" if you make a
9032 * SetPrinterData call without the necessary privildge.
9033 * we were originally returning OK if nothing changed
9034 * which made Win2k issue **a lot** of SetPrinterData
9035 * when connecting to a printer --jerry
9038 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9039 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9040 "change denied by handle access permissions\n"));
9041 return WERR_ACCESS_DENIED;
9044 result = winreg_get_printer(Printer,
9045 get_server_info_system(),
9047 Printer->servername,
9048 lp_servicename(snum),
9050 if (!W_ERROR_IS_OK(result)) {
9054 /* check for OID in valuename */
9056 oid_string = strchr(r->in.value_name, ',');
9062 /* save the registry data */
9064 result = winreg_set_printer_dataex(p->mem_ctx,
9065 get_server_info_system(),
9074 if (W_ERROR_IS_OK(result)) {
9075 /* save the OID if one was specified */
9077 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9078 r->in.key_name, SPOOL_OID_KEY);
9080 result = WERR_NOMEM;
9085 * I'm not checking the status here on purpose. Don't know
9086 * if this is right, but I'm returning the status from the
9087 * previous set_printer_dataex() call. I have no idea if
9088 * this is right. --jerry
9090 winreg_set_printer_dataex(p->mem_ctx,
9091 get_server_info_system(),
9097 (uint8_t *) oid_string,
9098 strlen(oid_string) + 1);
9101 result = winreg_printer_update_changeid(p->mem_ctx,
9102 get_server_info_system(),
9104 lp_const_servicename(snum));
9109 talloc_free(pinfo2);
9113 /****************************************************************
9114 _spoolss_DeletePrinterDataEx
9115 ****************************************************************/
9117 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
9118 struct spoolss_DeletePrinterDataEx *r)
9120 const char *printer;
9122 WERROR status = WERR_OK;
9123 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9125 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9128 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9129 "Invalid handle (%s:%u:%u).\n",
9130 OUR_HANDLE(r->in.handle)));
9134 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9135 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9136 "printer properties change denied by handle\n"));
9137 return WERR_ACCESS_DENIED;
9140 if (!r->in.value_name || !r->in.key_name) {
9144 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9147 printer = lp_const_servicename(snum);
9149 status = winreg_delete_printer_dataex(p->mem_ctx,
9150 get_server_info_system(),
9155 if (W_ERROR_IS_OK(status)) {
9156 status = winreg_printer_update_changeid(p->mem_ctx,
9157 get_server_info_system(),
9165 /****************************************************************
9166 _spoolss_EnumPrinterKey
9167 ****************************************************************/
9169 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
9170 struct spoolss_EnumPrinterKey *r)
9173 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9175 WERROR result = WERR_BADFILE;
9176 const char **array = NULL;
9179 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9182 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9183 OUR_HANDLE(r->in.handle)));
9187 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9191 result = winreg_enum_printer_key(p->mem_ctx,
9192 get_server_info_system(),
9194 lp_const_servicename(snum),
9198 if (!W_ERROR_IS_OK(result)) {
9202 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
9203 result = WERR_NOMEM;
9207 *r->out._ndr_size = r->in.offered / 2;
9208 *r->out.needed = blob.length;
9210 if (r->in.offered < *r->out.needed) {
9211 result = WERR_MORE_DATA;
9214 r->out.key_buffer->string_array = array;
9218 if (!W_ERROR_IS_OK(result)) {
9220 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9228 /****************************************************************
9229 _spoolss_DeletePrinterKey
9230 ****************************************************************/
9232 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
9233 struct spoolss_DeletePrinterKey *r)
9235 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9238 const char *printer;
9240 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9243 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9244 OUR_HANDLE(r->in.handle)));
9248 /* if keyname == NULL, return error */
9249 if ( !r->in.key_name )
9250 return WERR_INVALID_PARAM;
9252 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9256 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9257 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9258 "printer properties change denied by handle\n"));
9259 return WERR_ACCESS_DENIED;
9262 printer = lp_const_servicename(snum);
9264 /* delete the key and all subkeys */
9265 status = winreg_delete_printer_key(p->mem_ctx,
9266 get_server_info_system(),
9270 if (W_ERROR_IS_OK(status)) {
9271 status = winreg_printer_update_changeid(p->mem_ctx,
9272 get_server_info_system(),
9280 /****************************************************************
9281 _spoolss_EnumPrinterDataEx
9282 ****************************************************************/
9284 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
9285 struct spoolss_EnumPrinterDataEx *r)
9288 struct spoolss_PrinterEnumValues *info = NULL;
9289 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9293 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9297 *r->out.info = NULL;
9300 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9301 OUR_HANDLE(r->in.handle)));
9306 * first check for a keyname of NULL or "". Win2k seems to send
9307 * this a lot and we should send back WERR_INVALID_PARAM
9308 * no need to spend time looking up the printer in this case.
9312 if (!strlen(r->in.key_name)) {
9313 result = WERR_INVALID_PARAM;
9317 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9321 /* now look for a match on the key name */
9322 result = winreg_enum_printer_dataex(p->mem_ctx,
9323 get_server_info_system(),
9325 lp_const_servicename(snum),
9329 if (!W_ERROR_IS_OK(result)) {
9333 #if 0 /* FIXME - gd */
9334 /* housekeeping information in the reply */
9336 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9337 * the hand marshalled container size is a multiple
9338 * of 4 bytes for RPC alignment.
9342 needed += 4-(needed % 4);
9345 *r->out.count = count;
9346 *r->out.info = info;
9349 if (!W_ERROR_IS_OK(result)) {
9353 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9354 spoolss_EnumPrinterDataEx,
9357 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9358 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9360 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9363 /****************************************************************************
9364 ****************************************************************************/
9366 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9367 const char *servername,
9368 const char *environment,
9369 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9374 werr = compose_spoolss_server_path(mem_ctx,
9377 SPOOLSS_PRTPROCS_PATH,
9379 if (!W_ERROR_IS_OK(werr)) {
9383 DEBUG(4,("print processor directory: [%s]\n", path));
9385 r->directory_name = path;
9390 /****************************************************************
9391 _spoolss_GetPrintProcessorDirectory
9392 ****************************************************************/
9394 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9395 struct spoolss_GetPrintProcessorDirectory *r)
9399 /* that's an [in out] buffer */
9401 if (!r->in.buffer && (r->in.offered != 0)) {
9402 return WERR_INVALID_PARAM;
9405 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9410 /* r->in.level is ignored */
9412 /* We always should reply with a local print processor directory so that
9413 * users are not forced to have a [prnproc$] share on the Samba spoolss
9414 * server - Guenther */
9416 result = getprintprocessordirectory_level_1(p->mem_ctx,
9417 NULL, /* r->in.server */
9419 &r->out.info->info1);
9420 if (!W_ERROR_IS_OK(result)) {
9421 TALLOC_FREE(r->out.info);
9425 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9426 r->out.info, r->in.level);
9427 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9429 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9432 /*******************************************************************
9433 ********************************************************************/
9435 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9436 const char *dllname)
9438 enum ndr_err_code ndr_err;
9439 struct spoolss_MonitorUi ui;
9441 ui.dll_name = dllname;
9443 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9444 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9445 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9446 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9448 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9451 /*******************************************************************
9452 Streams the monitor UI DLL name in UNICODE
9453 *******************************************************************/
9455 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9456 NT_USER_TOKEN *token, DATA_BLOB *in,
9457 DATA_BLOB *out, uint32_t *needed)
9459 const char *dllname = "tcpmonui.dll";
9461 *needed = (strlen(dllname)+1) * 2;
9463 if (out->length < *needed) {
9464 return WERR_INSUFFICIENT_BUFFER;
9467 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9474 /*******************************************************************
9475 ********************************************************************/
9477 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9478 struct spoolss_PortData1 *port1,
9479 const DATA_BLOB *buf)
9481 enum ndr_err_code ndr_err;
9482 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9483 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9484 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9485 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9487 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9490 /*******************************************************************
9491 ********************************************************************/
9493 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9494 struct spoolss_PortData2 *port2,
9495 const DATA_BLOB *buf)
9497 enum ndr_err_code ndr_err;
9498 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9499 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9500 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9501 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9503 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9506 /*******************************************************************
9507 Create a new TCP/IP port
9508 *******************************************************************/
9510 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9511 NT_USER_TOKEN *token, DATA_BLOB *in,
9512 DATA_BLOB *out, uint32_t *needed)
9514 struct spoolss_PortData1 port1;
9515 struct spoolss_PortData2 port2;
9516 char *device_uri = NULL;
9519 const char *portname;
9520 const char *hostaddress;
9522 uint32_t port_number;
9525 /* peek for spoolss_PortData version */
9527 if (!in || (in->length < (128 + 4))) {
9528 return WERR_GENERAL_FAILURE;
9531 version = IVAL(in->data, 128);
9537 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9541 portname = port1.portname;
9542 hostaddress = port1.hostaddress;
9543 queue = port1.queue;
9544 protocol = port1.protocol;
9545 port_number = port1.port_number;
9551 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9555 portname = port2.portname;
9556 hostaddress = port2.hostaddress;
9557 queue = port2.queue;
9558 protocol = port2.protocol;
9559 port_number = port2.port_number;
9563 DEBUG(1,("xcvtcp_addport: "
9564 "unknown version of port_data: %d\n", version));
9565 return WERR_UNKNOWN_PORT;
9568 /* create the device URI and call the add_port_hook() */
9571 case PROTOCOL_RAWTCP_TYPE:
9572 device_uri = talloc_asprintf(mem_ctx,
9573 "socket://%s:%d/", hostaddress,
9577 case PROTOCOL_LPR_TYPE:
9578 device_uri = talloc_asprintf(mem_ctx,
9579 "lpr://%s/%s", hostaddress, queue );
9583 return WERR_UNKNOWN_PORT;
9590 return add_port_hook(mem_ctx, token, portname, device_uri);
9593 /*******************************************************************
9594 *******************************************************************/
9596 struct xcv_api_table xcvtcp_cmds[] = {
9597 { "MonitorUI", xcvtcp_monitorui },
9598 { "AddPort", xcvtcp_addport},
9602 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9603 NT_USER_TOKEN *token, const char *command,
9610 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9612 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9613 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9614 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9617 return WERR_BADFUNC;
9620 /*******************************************************************
9621 *******************************************************************/
9622 #if 0 /* don't support management using the "Local Port" monitor */
9624 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9625 NT_USER_TOKEN *token, DATA_BLOB *in,
9626 DATA_BLOB *out, uint32_t *needed)
9628 const char *dllname = "localui.dll";
9630 *needed = (strlen(dllname)+1) * 2;
9632 if (out->length < *needed) {
9633 return WERR_INSUFFICIENT_BUFFER;
9636 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9643 /*******************************************************************
9644 *******************************************************************/
9646 struct xcv_api_table xcvlocal_cmds[] = {
9647 { "MonitorUI", xcvlocal_monitorui },
9651 struct xcv_api_table xcvlocal_cmds[] = {
9658 /*******************************************************************
9659 *******************************************************************/
9661 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9662 NT_USER_TOKEN *token, const char *command,
9663 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9668 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9670 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9671 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9672 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9674 return WERR_BADFUNC;
9677 /****************************************************************
9679 ****************************************************************/
9681 WERROR _spoolss_XcvData(struct pipes_struct *p,
9682 struct spoolss_XcvData *r)
9684 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9685 DATA_BLOB out_data = data_blob_null;
9689 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9690 OUR_HANDLE(r->in.handle)));
9694 /* Has to be a handle to the TCP/IP port monitor */
9696 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9697 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9701 /* requires administrative access to the server */
9703 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9704 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9705 return WERR_ACCESS_DENIED;
9708 /* Allocate the outgoing buffer */
9710 if (r->in.out_data_size) {
9711 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9712 if (out_data.data == NULL) {
9717 switch ( Printer->printer_type ) {
9718 case SPLHND_PORTMON_TCP:
9719 werror = process_xcvtcp_command(p->mem_ctx,
9720 p->server_info->ptok,
9721 r->in.function_name,
9722 &r->in.in_data, &out_data,
9725 case SPLHND_PORTMON_LOCAL:
9726 werror = process_xcvlocal_command(p->mem_ctx,
9727 p->server_info->ptok,
9728 r->in.function_name,
9729 &r->in.in_data, &out_data,
9733 werror = WERR_INVALID_PRINT_MONITOR;
9736 if (!W_ERROR_IS_OK(werror)) {
9740 *r->out.status_code = 0;
9742 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9743 memcpy(r->out.out_data, out_data.data,
9744 MIN(r->in.out_data_size, out_data.length));
9750 /****************************************************************
9751 _spoolss_AddPrintProcessor
9752 ****************************************************************/
9754 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9755 struct spoolss_AddPrintProcessor *r)
9757 /* for now, just indicate success and ignore the add. We'll
9758 automatically set the winprint processor for printer
9759 entries later. Used to debug the LexMark Optra S 1855 PCL
9765 /****************************************************************
9767 ****************************************************************/
9769 WERROR _spoolss_AddPort(struct pipes_struct *p,
9770 struct spoolss_AddPort *r)
9772 /* do what w2k3 does */
9774 return WERR_NOT_SUPPORTED;
9777 /****************************************************************
9778 _spoolss_GetPrinterDriver
9779 ****************************************************************/
9781 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9782 struct spoolss_GetPrinterDriver *r)
9784 p->rng_fault_state = true;
9785 return WERR_NOT_SUPPORTED;
9788 /****************************************************************
9789 _spoolss_ReadPrinter
9790 ****************************************************************/
9792 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9793 struct spoolss_ReadPrinter *r)
9795 p->rng_fault_state = true;
9796 return WERR_NOT_SUPPORTED;
9799 /****************************************************************
9800 _spoolss_WaitForPrinterChange
9801 ****************************************************************/
9803 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9804 struct spoolss_WaitForPrinterChange *r)
9806 p->rng_fault_state = true;
9807 return WERR_NOT_SUPPORTED;
9810 /****************************************************************
9811 _spoolss_ConfigurePort
9812 ****************************************************************/
9814 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9815 struct spoolss_ConfigurePort *r)
9817 p->rng_fault_state = true;
9818 return WERR_NOT_SUPPORTED;
9821 /****************************************************************
9823 ****************************************************************/
9825 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9826 struct spoolss_DeletePort *r)
9828 p->rng_fault_state = true;
9829 return WERR_NOT_SUPPORTED;
9832 /****************************************************************
9833 _spoolss_CreatePrinterIC
9834 ****************************************************************/
9836 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9837 struct spoolss_CreatePrinterIC *r)
9839 p->rng_fault_state = true;
9840 return WERR_NOT_SUPPORTED;
9843 /****************************************************************
9844 _spoolss_PlayGDIScriptOnPrinterIC
9845 ****************************************************************/
9847 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9848 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9850 p->rng_fault_state = true;
9851 return WERR_NOT_SUPPORTED;
9854 /****************************************************************
9855 _spoolss_DeletePrinterIC
9856 ****************************************************************/
9858 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9859 struct spoolss_DeletePrinterIC *r)
9861 p->rng_fault_state = true;
9862 return WERR_NOT_SUPPORTED;
9865 /****************************************************************
9866 _spoolss_AddPrinterConnection
9867 ****************************************************************/
9869 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9870 struct spoolss_AddPrinterConnection *r)
9872 p->rng_fault_state = true;
9873 return WERR_NOT_SUPPORTED;
9876 /****************************************************************
9877 _spoolss_DeletePrinterConnection
9878 ****************************************************************/
9880 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9881 struct spoolss_DeletePrinterConnection *r)
9883 p->rng_fault_state = true;
9884 return WERR_NOT_SUPPORTED;
9887 /****************************************************************
9888 _spoolss_PrinterMessageBox
9889 ****************************************************************/
9891 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9892 struct spoolss_PrinterMessageBox *r)
9894 p->rng_fault_state = true;
9895 return WERR_NOT_SUPPORTED;
9898 /****************************************************************
9900 ****************************************************************/
9902 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9903 struct spoolss_AddMonitor *r)
9905 p->rng_fault_state = true;
9906 return WERR_NOT_SUPPORTED;
9909 /****************************************************************
9910 _spoolss_DeleteMonitor
9911 ****************************************************************/
9913 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9914 struct spoolss_DeleteMonitor *r)
9916 p->rng_fault_state = true;
9917 return WERR_NOT_SUPPORTED;
9920 /****************************************************************
9921 _spoolss_DeletePrintProcessor
9922 ****************************************************************/
9924 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9925 struct spoolss_DeletePrintProcessor *r)
9927 p->rng_fault_state = true;
9928 return WERR_NOT_SUPPORTED;
9931 /****************************************************************
9932 _spoolss_AddPrintProvidor
9933 ****************************************************************/
9935 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9936 struct spoolss_AddPrintProvidor *r)
9938 p->rng_fault_state = true;
9939 return WERR_NOT_SUPPORTED;
9942 /****************************************************************
9943 _spoolss_DeletePrintProvidor
9944 ****************************************************************/
9946 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9947 struct spoolss_DeletePrintProvidor *r)
9949 p->rng_fault_state = true;
9950 return WERR_NOT_SUPPORTED;
9953 /****************************************************************
9954 _spoolss_FindFirstPrinterChangeNotification
9955 ****************************************************************/
9957 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9958 struct spoolss_FindFirstPrinterChangeNotification *r)
9960 p->rng_fault_state = true;
9961 return WERR_NOT_SUPPORTED;
9964 /****************************************************************
9965 _spoolss_FindNextPrinterChangeNotification
9966 ****************************************************************/
9968 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9969 struct spoolss_FindNextPrinterChangeNotification *r)
9971 p->rng_fault_state = true;
9972 return WERR_NOT_SUPPORTED;
9975 /****************************************************************
9976 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9977 ****************************************************************/
9979 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9980 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9982 p->rng_fault_state = true;
9983 return WERR_NOT_SUPPORTED;
9986 /****************************************************************
9987 _spoolss_ReplyOpenPrinter
9988 ****************************************************************/
9990 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9991 struct spoolss_ReplyOpenPrinter *r)
9993 p->rng_fault_state = true;
9994 return WERR_NOT_SUPPORTED;
9997 /****************************************************************
9998 _spoolss_RouterReplyPrinter
9999 ****************************************************************/
10001 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
10002 struct spoolss_RouterReplyPrinter *r)
10004 p->rng_fault_state = true;
10005 return WERR_NOT_SUPPORTED;
10008 /****************************************************************
10009 _spoolss_ReplyClosePrinter
10010 ****************************************************************/
10012 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
10013 struct spoolss_ReplyClosePrinter *r)
10015 p->rng_fault_state = true;
10016 return WERR_NOT_SUPPORTED;
10019 /****************************************************************
10021 ****************************************************************/
10023 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
10024 struct spoolss_AddPortEx *r)
10026 p->rng_fault_state = true;
10027 return WERR_NOT_SUPPORTED;
10030 /****************************************************************
10031 _spoolss_RouterFindFirstPrinterChangeNotification
10032 ****************************************************************/
10034 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
10035 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10037 p->rng_fault_state = true;
10038 return WERR_NOT_SUPPORTED;
10041 /****************************************************************
10042 _spoolss_SpoolerInit
10043 ****************************************************************/
10045 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
10046 struct spoolss_SpoolerInit *r)
10048 p->rng_fault_state = true;
10049 return WERR_NOT_SUPPORTED;
10052 /****************************************************************
10053 _spoolss_ResetPrinterEx
10054 ****************************************************************/
10056 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
10057 struct spoolss_ResetPrinterEx *r)
10059 p->rng_fault_state = true;
10060 return WERR_NOT_SUPPORTED;
10063 /****************************************************************
10064 _spoolss_RouterReplyPrinterEx
10065 ****************************************************************/
10067 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
10068 struct spoolss_RouterReplyPrinterEx *r)
10070 p->rng_fault_state = true;
10071 return WERR_NOT_SUPPORTED;
10074 /****************************************************************
10076 ****************************************************************/
10078 WERROR _spoolss_44(struct pipes_struct *p,
10079 struct spoolss_44 *r)
10081 p->rng_fault_state = true;
10082 return WERR_NOT_SUPPORTED;
10085 /****************************************************************
10087 ****************************************************************/
10089 WERROR _spoolss_47(struct pipes_struct *p,
10090 struct spoolss_47 *r)
10092 p->rng_fault_state = true;
10093 return WERR_NOT_SUPPORTED;
10096 /****************************************************************
10098 ****************************************************************/
10100 WERROR _spoolss_4a(struct pipes_struct *p,
10101 struct spoolss_4a *r)
10103 p->rng_fault_state = true;
10104 return WERR_NOT_SUPPORTED;
10107 /****************************************************************
10109 ****************************************************************/
10111 WERROR _spoolss_4b(struct pipes_struct *p,
10112 struct spoolss_4b *r)
10114 p->rng_fault_state = true;
10115 return WERR_NOT_SUPPORTED;
10118 /****************************************************************
10120 ****************************************************************/
10122 WERROR _spoolss_4c(struct pipes_struct *p,
10123 struct spoolss_4c *r)
10125 p->rng_fault_state = true;
10126 return WERR_NOT_SUPPORTED;
10129 /****************************************************************
10131 ****************************************************************/
10133 WERROR _spoolss_53(struct pipes_struct *p,
10134 struct spoolss_53 *r)
10136 p->rng_fault_state = true;
10137 return WERR_NOT_SUPPORTED;
10140 /****************************************************************
10142 ****************************************************************/
10144 WERROR _spoolss_55(struct pipes_struct *p,
10145 struct spoolss_55 *r)
10147 p->rng_fault_state = true;
10148 return WERR_NOT_SUPPORTED;
10151 /****************************************************************
10153 ****************************************************************/
10155 WERROR _spoolss_56(struct pipes_struct *p,
10156 struct spoolss_56 *r)
10158 p->rng_fault_state = true;
10159 return WERR_NOT_SUPPORTED;
10162 /****************************************************************
10164 ****************************************************************/
10166 WERROR _spoolss_57(struct pipes_struct *p,
10167 struct spoolss_57 *r)
10169 p->rng_fault_state = true;
10170 return WERR_NOT_SUPPORTED;
10173 /****************************************************************
10175 ****************************************************************/
10177 WERROR _spoolss_5a(struct pipes_struct *p,
10178 struct spoolss_5a *r)
10180 p->rng_fault_state = true;
10181 return WERR_NOT_SUPPORTED;
10184 /****************************************************************
10186 ****************************************************************/
10188 WERROR _spoolss_5b(struct pipes_struct *p,
10189 struct spoolss_5b *r)
10191 p->rng_fault_state = true;
10192 return WERR_NOT_SUPPORTED;
10195 /****************************************************************
10197 ****************************************************************/
10199 WERROR _spoolss_5c(struct pipes_struct *p,
10200 struct spoolss_5c *r)
10202 p->rng_fault_state = true;
10203 return WERR_NOT_SUPPORTED;
10206 /****************************************************************
10208 ****************************************************************/
10210 WERROR _spoolss_5d(struct pipes_struct *p,
10211 struct spoolss_5d *r)
10213 p->rng_fault_state = true;
10214 return WERR_NOT_SUPPORTED;
10217 /****************************************************************
10219 ****************************************************************/
10221 WERROR _spoolss_5e(struct pipes_struct *p,
10222 struct spoolss_5e *r)
10224 p->rng_fault_state = true;
10225 return WERR_NOT_SUPPORTED;
10228 /****************************************************************
10230 ****************************************************************/
10232 WERROR _spoolss_5f(struct pipes_struct *p,
10233 struct spoolss_5f *r)
10235 p->rng_fault_state = true;
10236 return WERR_NOT_SUPPORTED;
10239 /****************************************************************
10241 ****************************************************************/
10243 WERROR _spoolss_60(struct pipes_struct *p,
10244 struct spoolss_60 *r)
10246 p->rng_fault_state = true;
10247 return WERR_NOT_SUPPORTED;
10250 /****************************************************************
10252 ****************************************************************/
10254 WERROR _spoolss_61(struct pipes_struct *p,
10255 struct spoolss_61 *r)
10257 p->rng_fault_state = true;
10258 return WERR_NOT_SUPPORTED;
10261 /****************************************************************
10263 ****************************************************************/
10265 WERROR _spoolss_62(struct pipes_struct *p,
10266 struct spoolss_62 *r)
10268 p->rng_fault_state = true;
10269 return WERR_NOT_SUPPORTED;
10272 /****************************************************************
10274 ****************************************************************/
10276 WERROR _spoolss_63(struct pipes_struct *p,
10277 struct spoolss_63 *r)
10279 p->rng_fault_state = true;
10280 return WERR_NOT_SUPPORTED;
10283 /****************************************************************
10285 ****************************************************************/
10287 WERROR _spoolss_64(struct pipes_struct *p,
10288 struct spoolss_64 *r)
10290 p->rng_fault_state = true;
10291 return WERR_NOT_SUPPORTED;
10294 /****************************************************************
10296 ****************************************************************/
10298 WERROR _spoolss_65(struct pipes_struct *p,
10299 struct spoolss_65 *r)
10301 p->rng_fault_state = true;
10302 return WERR_NOT_SUPPORTED;
10305 /****************************************************************
10306 _spoolss_GetCorePrinterDrivers
10307 ****************************************************************/
10309 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
10310 struct spoolss_GetCorePrinterDrivers *r)
10312 p->rng_fault_state = true;
10313 return WERR_NOT_SUPPORTED;
10316 /****************************************************************
10318 ****************************************************************/
10320 WERROR _spoolss_67(struct pipes_struct *p,
10321 struct spoolss_67 *r)
10323 p->rng_fault_state = true;
10324 return WERR_NOT_SUPPORTED;
10327 /****************************************************************
10328 _spoolss_GetPrinterDriverPackagePath
10329 ****************************************************************/
10331 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10332 struct spoolss_GetPrinterDriverPackagePath *r)
10334 p->rng_fault_state = true;
10335 return WERR_NOT_SUPPORTED;
10338 /****************************************************************
10340 ****************************************************************/
10342 WERROR _spoolss_69(struct pipes_struct *p,
10343 struct spoolss_69 *r)
10345 p->rng_fault_state = true;
10346 return WERR_NOT_SUPPORTED;
10349 /****************************************************************
10351 ****************************************************************/
10353 WERROR _spoolss_6a(struct pipes_struct *p,
10354 struct spoolss_6a *r)
10356 p->rng_fault_state = true;
10357 return WERR_NOT_SUPPORTED;
10360 /****************************************************************
10362 ****************************************************************/
10364 WERROR _spoolss_6b(struct pipes_struct *p,
10365 struct spoolss_6b *r)
10367 p->rng_fault_state = true;
10368 return WERR_NOT_SUPPORTED;
10371 /****************************************************************
10373 ****************************************************************/
10375 WERROR _spoolss_6c(struct pipes_struct *p,
10376 struct spoolss_6c *r)
10378 p->rng_fault_state = true;
10379 return WERR_NOT_SUPPORTED;
10382 /****************************************************************
10384 ****************************************************************/
10386 WERROR _spoolss_6d(struct pipes_struct *p,
10387 struct spoolss_6d *r)
10389 p->rng_fault_state = true;
10390 return WERR_NOT_SUPPORTED;