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 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
117 static uint32_t smb_connections = 0;
120 /* Map generic permissions to printer object specific permissions */
122 const struct standard_mapping printer_std_mapping = {
129 /* Map generic permissions to print server object specific permissions */
131 const struct standard_mapping printserver_std_mapping = {
138 /* API table for Xcv Monitor functions */
140 struct xcv_api_table {
142 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
145 static void prune_printername_cache(void);
147 /********************************************************************
148 * Canonicalize servername.
149 ********************************************************************/
151 static const char *canon_servername(const char *servername)
153 const char *pservername = servername;
154 while (*pservername == '\\') {
160 /* translate between internal status numbers and NT status numbers */
161 static int nt_printj_status(int v)
167 return JOB_STATUS_PAUSED;
169 return JOB_STATUS_SPOOLING;
171 return JOB_STATUS_PRINTING;
173 return JOB_STATUS_ERROR;
175 return JOB_STATUS_DELETING;
177 return JOB_STATUS_OFFLINE;
179 return JOB_STATUS_PAPEROUT;
181 return JOB_STATUS_PRINTED;
183 return JOB_STATUS_DELETED;
185 return JOB_STATUS_BLOCKED_DEVQ;
186 case LPQ_USER_INTERVENTION:
187 return JOB_STATUS_USER_INTERVENTION;
192 static int nt_printq_status(int v)
196 return PRINTER_STATUS_PAUSED;
205 /***************************************************************************
206 Disconnect from the client
207 ****************************************************************************/
209 static void srv_spoolss_replycloseprinter(
210 int snum, struct policy_handle *handle,
211 struct messaging_context *msg_ctx)
217 * Tell the specific printing tdb we no longer want messages for this printer
218 * by deregistering our PID.
221 if (!print_notify_deregister_pid(snum))
222 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
224 /* weird if the test succeeds !!! */
225 if (smb_connections==0) {
226 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
230 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
233 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
234 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
235 win_errstr(result)));
237 /* if it's the last connection, deconnect the IPC$ share */
238 if (smb_connections==1) {
240 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
242 * The above call shuts down the pipe also.
244 notify_cli_pipe = NULL;
246 if (msg_ctx != NULL) {
247 messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
251 * Tell the serverid.tdb we're no longer
252 * interested in printer notify messages.
255 serverid_register_msg_flags(
256 messaging_server_id(msg_ctx),
257 false, FLAG_MSG_PRINT_NOTIFY);
264 /****************************************************************************
265 Functions to free a printer entry datastruct.
266 ****************************************************************************/
268 static int printer_entry_destructor(struct printer_handle *Printer)
270 if (Printer->notify.client_connected == true) {
273 if ( Printer->printer_type == SPLHND_SERVER) {
275 srv_spoolss_replycloseprinter(
276 snum, &Printer->notify.client_hnd,
277 Printer->notify.msg_ctx);
278 } else if (Printer->printer_type == SPLHND_PRINTER) {
279 snum = print_queue_snum(Printer->sharename);
281 srv_spoolss_replycloseprinter(
282 snum, &Printer->notify.client_hnd,
283 Printer->notify.msg_ctx);
287 Printer->notify.flags=0;
288 Printer->notify.options=0;
289 Printer->notify.localmachine[0]='\0';
290 Printer->notify.printerlocal=0;
291 TALLOC_FREE(Printer->notify.option);
292 Printer->notify.client_connected = false;
294 TALLOC_FREE(Printer->devmode);
296 /* Remove from the internal list. */
297 DLIST_REMOVE(printers_list, Printer);
301 /****************************************************************************
302 find printer index by handle
303 ****************************************************************************/
305 static struct printer_handle *find_printer_index_by_hnd(struct pipes_struct *p,
306 struct policy_handle *hnd)
308 struct printer_handle *find_printer = NULL;
310 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
311 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
318 /****************************************************************************
319 Close printer index by handle.
320 ****************************************************************************/
322 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
324 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
327 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
332 close_policy_hnd(p, hnd);
337 /****************************************************************************
338 Delete a printer given a handle.
339 ****************************************************************************/
341 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
342 const char *sharename,
343 struct messaging_context *msg_ctx)
345 char *cmd = lp_deleteprinter_cmd();
346 char *command = NULL;
348 SE_PRIV se_printop = SE_PRINT_OPERATOR;
349 bool is_print_op = false;
351 /* can't fail if we don't try */
356 command = talloc_asprintf(ctx,
363 is_print_op = user_has_privileges( token, &se_printop );
365 DEBUG(10,("Running [%s]\n", command));
367 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
372 if ( (ret = smbrun(command, NULL)) == 0 ) {
373 /* Tell everyone we updated smb.conf. */
374 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
380 /********** END SePrintOperatorPrivlege BLOCK **********/
382 DEBUGADD(10,("returned [%d]\n", ret));
384 TALLOC_FREE(command);
387 return WERR_BADFID; /* What to return here? */
389 /* go ahead and re-read the services immediately */
391 reload_services(msg_ctx, -1, false);
394 if ( lp_servicenumber( sharename ) > 0 )
395 return WERR_ACCESS_DENIED;
400 /****************************************************************************
401 Delete a printer given a handle.
402 ****************************************************************************/
404 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
406 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
410 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
416 * It turns out that Windows allows delete printer on a handle
417 * opened by an admin user, then used on a pipe handle created
418 * by an anonymous user..... but they're working on security.... riiight !
422 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
423 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
424 return WERR_ACCESS_DENIED;
427 /* this does not need a become root since the access check has been
428 done on the handle already */
430 result = winreg_delete_printer_key(p->mem_ctx,
431 get_server_info_system(),
435 if (!W_ERROR_IS_OK(result)) {
436 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
440 result = delete_printer_hook(p->mem_ctx, p->server_info->ptok,
441 Printer->sharename, p->msg_ctx);
442 if (!W_ERROR_IS_OK(result)) {
445 prune_printername_cache();
449 /****************************************************************************
450 Return the snum of a printer corresponding to an handle.
451 ****************************************************************************/
453 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
454 int *number, struct share_params **params)
456 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
459 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
464 switch (Printer->printer_type) {
466 DEBUG(4,("short name:%s\n", Printer->sharename));
467 *number = print_queue_snum(Printer->sharename);
468 return (*number != -1);
476 /****************************************************************************
477 Set printer handle type.
478 Check if it's \\server or \\server\printer
479 ****************************************************************************/
481 static bool set_printer_hnd_printertype(struct printer_handle *Printer, const char *handlename)
483 DEBUG(3,("Setting printer type=%s\n", handlename));
485 /* it's a print server */
486 if (handlename && *handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
487 DEBUGADD(4,("Printer is a print server\n"));
488 Printer->printer_type = SPLHND_SERVER;
490 /* it's a printer (set_printer_hnd_name() will handle port monitors */
492 DEBUGADD(4,("Printer is a printer\n"));
493 Printer->printer_type = SPLHND_PRINTER;
499 static void prune_printername_cache_fn(const char *key, const char *value,
500 time_t timeout, void *private_data)
505 static void prune_printername_cache(void)
507 gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
510 /****************************************************************************
511 Set printer handle name.. Accept names like \\server, \\server\printer,
512 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
513 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
514 XcvDataPort() interface.
515 ****************************************************************************/
517 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
518 const struct auth_serversupplied_info *server_info,
519 struct messaging_context *msg_ctx,
520 struct printer_handle *Printer,
521 const char *handlename)
524 int n_services=lp_numservices();
526 const char *printername;
527 const char *servername = NULL;
530 struct spoolss_PrinterInfo2 *info2 = NULL;
534 * Hopefully nobody names his printers like this. Maybe \ or ,
535 * are illegal in printer names even?
537 const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
541 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
542 (unsigned long)strlen(handlename)));
544 aprinter = CONST_DISCARD(char *, handlename);
545 if ( *handlename == '\\' ) {
546 servername = canon_servername(handlename);
547 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
551 if (!is_myname_or_ipaddr(servername)) {
555 fstrcpy(Printer->servername, servername);
558 if (Printer->printer_type == SPLHND_SERVER) {
562 if (Printer->printer_type != SPLHND_PRINTER) {
566 DEBUGADD(5, ("searching for [%s]\n", aprinter));
568 /* check for the Port Monitor Interface */
569 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
570 Printer->printer_type = SPLHND_PORTMON_TCP;
571 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
574 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
575 Printer->printer_type = SPLHND_PORTMON_LOCAL;
576 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
581 * With hundreds of printers, the "for" loop iterating all
582 * shares can be quite expensive, as it is done on every
583 * OpenPrinter. The loop maps "aprinter" to "sname", the
584 * result of which we cache in gencache.
587 cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
589 if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
591 found = (strcmp(tmp, printer_not_found) != 0);
593 DEBUG(4, ("Printer %s not found\n", aprinter));
601 /* Search all sharenames first as this is easier than pulling
602 the printer_info_2 off of disk. Don't use find_service() since
603 that calls out to map_username() */
605 /* do another loop to look for printernames */
606 for (snum = 0; !found && snum < n_services; snum++) {
607 const char *printer = lp_const_servicename(snum);
609 /* no point going on if this is not a printer */
610 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
614 /* ignore [printers] share */
615 if (strequal(printer, "printers")) {
619 fstrcpy(sname, printer);
620 if (strequal(aprinter, printer)) {
625 /* no point looking up the printer object if
626 we aren't allowing printername != sharename */
627 if (lp_force_printername(snum)) {
631 result = winreg_get_printer(mem_ctx,
637 if ( !W_ERROR_IS_OK(result) ) {
638 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
639 sname, win_errstr(result)));
643 printername = strrchr(info2->printername, '\\');
644 if (printername == NULL) {
645 printername = info2->printername;
650 if (strequal(printername, aprinter)) {
655 DEBUGADD(10, ("printername: %s\n", printername));
661 if (cache_key != NULL) {
662 gencache_set(cache_key, printer_not_found,
664 TALLOC_FREE(cache_key);
666 DEBUGADD(4,("Printer not found\n"));
670 if (cache_key != NULL) {
671 gencache_set(cache_key, sname, time(NULL)+300);
672 TALLOC_FREE(cache_key);
675 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
677 fstrcpy(Printer->sharename, sname);
682 /****************************************************************************
683 Find first available printer slot. creates a printer handle for you.
684 ****************************************************************************/
686 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
687 const char *name, uint32_t access_granted)
689 struct printer_handle *new_printer;
691 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
693 new_printer = talloc_zero(p->mem_ctx, struct printer_handle);
694 if (new_printer == NULL) {
697 talloc_set_destructor(new_printer, printer_entry_destructor);
699 /* This also steals the printer_handle on the policy_handle */
700 if (!create_policy_hnd(p, hnd, new_printer)) {
701 TALLOC_FREE(new_printer);
705 /* Add to the internal list. */
706 DLIST_ADD(printers_list, new_printer);
708 new_printer->notify.option=NULL;
710 if (!set_printer_hnd_printertype(new_printer, name)) {
711 close_printer_handle(p, hnd);
715 if (!set_printer_hnd_name(p->mem_ctx,
716 get_server_info_system(),
718 new_printer, name)) {
719 close_printer_handle(p, hnd);
723 new_printer->access_granted = access_granted;
725 DEBUG(5, ("%d printer handles active\n",
726 (int)num_pipe_handles(p)));
731 /***************************************************************************
732 check to see if the client motify handle is monitoring the notification
733 given by (notify_type, notify_field).
734 **************************************************************************/
736 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
737 uint16_t notify_field)
742 static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type,
743 uint16_t notify_field)
745 struct spoolss_NotifyOption *option = p->notify.option;
749 * Flags should always be zero when the change notify
750 * is registered by the client's spooler. A user Win32 app
751 * might use the flags though instead of the NOTIFY_OPTION_INFO
760 return is_monitoring_event_flags(
761 p->notify.flags, notify_type, notify_field);
763 for (i = 0; i < option->count; i++) {
765 /* Check match for notify_type */
767 if (option->types[i].type != notify_type)
770 /* Check match for field */
772 for (j = 0; j < option->types[i].count; j++) {
773 if (option->types[i].fields[j].field == notify_field) {
779 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
780 p->servername, p->sharename, notify_type, notify_field));
785 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
786 _data->data.integer[0] = _integer; \
787 _data->data.integer[1] = 0;
790 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
791 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
792 if (!_data->data.string.string) {\
793 _data->data.string.size = 0; \
795 _data->data.string.size = strlen_m_term(_p) * 2;
797 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
798 _data->data.devmode.devmode = _devmode;
800 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
801 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
802 if (!_data->data.sd.sd) { \
803 _data->data.sd.sd_size = 0; \
805 _data->data.sd.sd_size = \
806 ndr_size_security_descriptor(_data->data.sd.sd, 0);
808 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
813 struct spoolss_Time st;
817 if (!init_systemtime(&st, t)) {
821 p = talloc_array(mem_ctx, char, len);
827 * Systemtime must be linearized as a set of UINT16's.
828 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
831 SSVAL(p, 0, st.year);
832 SSVAL(p, 2, st.month);
833 SSVAL(p, 4, st.day_of_week);
835 SSVAL(p, 8, st.hour);
836 SSVAL(p, 10, st.minute);
837 SSVAL(p, 12, st.second);
838 SSVAL(p, 14, st.millisecond);
844 /* Convert a notification message to a struct spoolss_Notify */
846 static void notify_one_value(struct spoolss_notify_msg *msg,
847 struct spoolss_Notify *data,
850 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
853 static void notify_string(struct spoolss_notify_msg *msg,
854 struct spoolss_Notify *data,
857 /* The length of the message includes the trailing \0 */
859 data->data.string.size = msg->len * 2;
860 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
861 if (!data->data.string.string) {
862 data->data.string.size = 0;
867 static void notify_system_time(struct spoolss_notify_msg *msg,
868 struct spoolss_Notify *data,
871 data->data.string.string = NULL;
872 data->data.string.size = 0;
874 if (msg->len != sizeof(time_t)) {
875 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
880 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
881 &data->data.string.string,
882 &data->data.string.size);
885 struct notify2_message_table {
887 void (*fn)(struct spoolss_notify_msg *msg,
888 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
891 static struct notify2_message_table printer_notify_table[] = {
892 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
893 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
894 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
895 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
896 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
897 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
898 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
899 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
900 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
901 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
902 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
903 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
904 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
905 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
906 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
907 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
908 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
909 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
910 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
913 static struct notify2_message_table job_notify_table[] = {
914 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
915 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
916 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
917 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
918 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
919 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
920 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
921 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
922 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
923 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
924 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
925 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
926 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
927 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
928 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
929 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
930 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
931 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
932 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
933 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
934 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
935 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
936 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
937 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
941 /***********************************************************************
942 Allocate talloc context for container object
943 **********************************************************************/
945 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
950 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
955 /***********************************************************************
956 release all allocated memory and zero out structure
957 **********************************************************************/
959 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
965 talloc_destroy(ctr->ctx);
972 /***********************************************************************
973 **********************************************************************/
975 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
983 /***********************************************************************
984 **********************************************************************/
986 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
988 if ( !ctr || !ctr->msg_groups )
991 if ( idx >= ctr->num_groups )
994 return &ctr->msg_groups[idx];
998 /***********************************************************************
999 How many groups of change messages do we have ?
1000 **********************************************************************/
1002 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
1007 return ctr->num_groups;
1010 /***********************************************************************
1011 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
1012 **********************************************************************/
1014 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
1016 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
1017 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
1018 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
1024 /* loop over all groups looking for a matching printer name */
1026 for ( i=0; i<ctr->num_groups; i++ ) {
1027 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
1031 /* add a new group? */
1033 if ( i == ctr->num_groups ) {
1036 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
1037 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
1040 ctr->msg_groups = groups;
1042 /* clear the new entry and set the printer name */
1044 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
1045 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
1048 /* add the change messages; 'i' is the correct index now regardless */
1050 msg_grp = &ctr->msg_groups[i];
1052 msg_grp->num_msgs++;
1054 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
1055 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
1058 msg_grp->msgs = msg_list;
1060 new_slot = msg_grp->num_msgs-1;
1061 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
1063 /* need to allocate own copy of data */
1065 if ( msg->len != 0 )
1066 msg_grp->msgs[new_slot].notify.data = (char *)
1067 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
1069 return ctr->num_groups;
1072 static void construct_info_data(struct spoolss_Notify *info_data,
1073 enum spoolss_NotifyType type,
1074 uint16_t field, int id);
1076 /***********************************************************************
1077 Send a change notication message on all handles which have a call
1079 **********************************************************************/
1081 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1083 struct printer_handle *p;
1084 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
1085 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
1086 SPOOLSS_NOTIFY_MSG *messages;
1087 int sending_msg_count;
1090 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1094 messages = msg_group->msgs;
1097 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
1101 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1103 /* loop over all printers */
1105 for (p = printers_list; p; p = p->next) {
1106 struct spoolss_Notify *notifies;
1111 /* Is there notification on this handle? */
1113 if ( !p->notify.client_connected )
1116 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1118 /* For this printer? Print servers always receive
1121 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1122 ( !strequal(msg_group->printername, p->sharename) ) )
1125 DEBUG(10,("Our printer\n"));
1127 /* allocate the max entries possible */
1129 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1134 /* build the array of change notifications */
1136 sending_msg_count = 0;
1138 for ( i=0; i<msg_group->num_msgs; i++ ) {
1139 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1141 /* Are we monitoring this event? */
1143 if (!is_monitoring_event(p, msg->type, msg->field))
1146 sending_msg_count++;
1149 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1150 msg->type, msg->field, p->sharename));
1153 * if the is a printer notification handle and not a job notification
1154 * type, then set the id to 0. Other wise just use what was specified
1157 * When registering change notification on a print server handle
1158 * we always need to send back the id (snum) matching the printer
1159 * for which the change took place. For change notify registered
1160 * on a printer handle, this does not matter and the id should be 0.
1165 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1171 /* Convert unix jobid to smb jobid */
1173 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1174 id = sysjob_to_jobid(msg->id);
1177 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1182 construct_info_data(¬ifies[count],
1183 (enum spoolss_NotifyType) msg->type,
1188 case PRINTER_NOTIFY_TYPE:
1189 if ( printer_notify_table[msg->field].fn )
1190 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1193 case JOB_NOTIFY_TYPE:
1194 if ( job_notify_table[msg->field].fn )
1195 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1199 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1206 if ( sending_msg_count ) {
1209 union spoolss_ReplyPrinterInfo info;
1210 struct spoolss_NotifyInfo info0;
1211 uint32_t reply_result;
1213 info0.version = 0x2;
1214 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1215 info0.count = count;
1216 info0.notifies = notifies;
1218 info.info0 = &info0;
1220 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1221 &p->notify.client_hnd,
1222 p->notify.change, /* color */
1225 0, /* reply_type, must be 0 */
1228 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1229 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1230 notify_cli_pipe->srv_name_slash,
1233 switch (reply_result) {
1236 case PRINTER_NOTIFY_INFO_DISCARDED:
1237 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1238 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1247 DEBUG(8,("send_notify2_changes: Exit...\n"));
1251 /***********************************************************************
1252 **********************************************************************/
1254 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1257 uint32_t tv_sec, tv_usec;
1260 /* Unpack message */
1262 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1265 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1267 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1270 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1271 &msg->notify.value[0], &msg->notify.value[1]);
1273 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1274 &msg->len, &msg->notify.data);
1276 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1277 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1279 tv->tv_sec = tv_sec;
1280 tv->tv_usec = tv_usec;
1283 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1284 msg->notify.value[1]));
1286 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1291 /********************************************************************
1292 Receive a notify2 message list
1293 ********************************************************************/
1295 static void receive_notify2_message_list(struct messaging_context *msg,
1298 struct server_id server_id,
1301 size_t msg_count, i;
1302 char *buf = (char *)data->data;
1305 SPOOLSS_NOTIFY_MSG notify;
1306 SPOOLSS_NOTIFY_MSG_CTR messages;
1309 if (data->length < 4) {
1310 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1314 msg_count = IVAL(buf, 0);
1317 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1319 if (msg_count == 0) {
1320 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1324 /* initialize the container */
1326 ZERO_STRUCT( messages );
1327 notify_msg_ctr_init( &messages );
1330 * build message groups for each printer identified
1331 * in a change_notify msg. Remember that a PCN message
1332 * includes the handle returned for the srv_spoolss_replyopenprinter()
1333 * call. Therefore messages are grouped according to printer handle.
1336 for ( i=0; i<msg_count; i++ ) {
1337 struct timeval msg_tv;
1339 if (msg_ptr + 4 - buf > data->length) {
1340 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1344 msg_len = IVAL(msg_ptr,0);
1347 if (msg_ptr + msg_len - buf > data->length) {
1348 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1352 /* unpack messages */
1354 ZERO_STRUCT( notify );
1355 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1358 /* add to correct list in container */
1360 notify_msg_ctr_addmsg( &messages, ¬ify );
1362 /* free memory that might have been allocated by notify2_unpack_msg() */
1364 if ( notify.len != 0 )
1365 SAFE_FREE( notify.notify.data );
1368 /* process each group of messages */
1370 num_groups = notify_msg_ctr_numgroups( &messages );
1371 for ( i=0; i<num_groups; i++ )
1372 send_notify2_changes( &messages, i );
1377 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1378 (uint32_t)msg_count ));
1380 notify_msg_ctr_destroy( &messages );
1385 /********************************************************************
1386 Send a message to ourself about new driver being installed
1387 so we can upgrade the information for each printer bound to this
1389 ********************************************************************/
1391 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1392 struct messaging_context *msg_ctx)
1394 int len = strlen(drivername);
1399 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1402 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1403 MSG_PRINTER_DRVUPGRADE,
1404 (uint8_t *)drivername, len+1);
1409 /**********************************************************************
1410 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1411 over all printers, upgrading ones as necessary
1412 **********************************************************************/
1414 void do_drv_upgrade_printer(struct messaging_context *msg,
1417 struct server_id server_id,
1420 TALLOC_CTX *tmp_ctx;
1421 struct auth_serversupplied_info *server_info = NULL;
1422 struct spoolss_PrinterInfo2 *pinfo2;
1425 const char *drivername;
1427 int n_services = lp_numservices();
1430 tmp_ctx = talloc_new(NULL);
1431 if (!tmp_ctx) return;
1433 status = make_server_info_system(tmp_ctx, &server_info);
1434 if (!NT_STATUS_IS_OK(status)) {
1435 DEBUG(0, ("do_drv_upgrade_printer: "
1436 "Could not create system server_info\n"));
1440 len = MIN(data->length,sizeof(drivername)-1);
1441 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1443 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1447 DEBUG(10, ("do_drv_upgrade_printer: "
1448 "Got message for new driver [%s]\n", drivername));
1450 /* Iterate the printer list */
1452 for (snum = 0; snum < n_services; snum++) {
1453 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1457 result = winreg_get_printer(tmp_ctx, server_info, msg,
1459 lp_const_servicename(snum),
1462 if (!W_ERROR_IS_OK(result)) {
1466 if (!pinfo2->drivername) {
1470 if (strcmp(drivername, pinfo2->drivername) != 0) {
1474 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1476 /* all we care about currently is the change_id */
1477 result = winreg_printer_update_changeid(tmp_ctx,
1480 pinfo2->printername);
1482 if (!W_ERROR_IS_OK(result)) {
1483 DEBUG(3, ("do_drv_upgrade_printer: "
1484 "Failed to update changeid [%s]\n",
1485 win_errstr(result)));
1491 talloc_free(tmp_ctx);
1494 /********************************************************************
1495 Update the cache for all printq's with a registered client
1497 ********************************************************************/
1499 void update_monitored_printq_cache(struct messaging_context *msg_ctx)
1501 struct printer_handle *printer = printers_list;
1504 /* loop through all printers and update the cache where
1505 client_connected == true */
1508 if ( (printer->printer_type == SPLHND_PRINTER)
1509 && printer->notify.client_connected )
1511 snum = print_queue_snum(printer->sharename);
1512 print_queue_status(msg_ctx, snum, NULL, NULL );
1515 printer = printer->next;
1521 /****************************************************************
1522 _spoolss_OpenPrinter
1523 ****************************************************************/
1525 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1526 struct spoolss_OpenPrinter *r)
1528 struct spoolss_OpenPrinterEx e;
1531 ZERO_STRUCT(e.in.userlevel);
1533 e.in.printername = r->in.printername;
1534 e.in.datatype = r->in.datatype;
1535 e.in.devmode_ctr = r->in.devmode_ctr;
1536 e.in.access_mask = r->in.access_mask;
1539 e.out.handle = r->out.handle;
1541 werr = _spoolss_OpenPrinterEx(p, &e);
1543 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1544 /* OpenPrinterEx returns this for a bad
1545 * printer name. We must return WERR_INVALID_PRINTER_NAME
1548 werr = WERR_INVALID_PRINTER_NAME;
1554 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1555 struct spoolss_DeviceMode *orig,
1556 struct spoolss_DeviceMode **dest)
1558 struct spoolss_DeviceMode *dm;
1560 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1565 /* copy all values, then duplicate strings and structs */
1568 dm->devicename = talloc_strdup(dm, orig->devicename);
1569 if (!dm->devicename) {
1572 dm->formname = talloc_strdup(dm, orig->formname);
1573 if (!dm->formname) {
1576 if (orig->driverextra_data.data) {
1577 dm->driverextra_data.data =
1578 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1579 orig->driverextra_data.length);
1580 if (!dm->driverextra_data.data) {
1589 /****************************************************************
1590 _spoolss_OpenPrinterEx
1591 ****************************************************************/
1593 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1594 struct spoolss_OpenPrinterEx *r)
1597 struct printer_handle *Printer=NULL;
1599 if (!r->in.printername) {
1600 return WERR_INVALID_PARAM;
1603 /* some sanity check because you can open a printer or a print server */
1604 /* aka: \\server\printer or \\server */
1606 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1608 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1609 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1610 "for printer %s\n", r->in.printername));
1611 ZERO_STRUCTP(r->out.handle);
1612 return WERR_INVALID_PARAM;
1615 Printer = find_printer_index_by_hnd(p, r->out.handle);
1617 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1618 "handle we created for printer %s\n", r->in.printername));
1619 close_printer_handle(p, r->out.handle);
1620 ZERO_STRUCTP(r->out.handle);
1621 return WERR_INVALID_PARAM;
1625 * First case: the user is opening the print server:
1627 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1628 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1630 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1631 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1632 * or if the user is listed in the smb.conf printer admin parameter.
1634 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1635 * client view printer folder, but does not show the MSAPW.
1637 * Note: this test needs code to check access rights here too. Jeremy
1638 * could you look at this?
1640 * Second case: the user is opening a printer:
1641 * NT doesn't let us connect to a printer if the connecting user
1642 * doesn't have print permission.
1644 * Third case: user is opening a Port Monitor
1645 * access checks same as opening a handle to the print server.
1648 switch (Printer->printer_type )
1651 case SPLHND_PORTMON_TCP:
1652 case SPLHND_PORTMON_LOCAL:
1653 /* Printserver handles use global struct... */
1657 /* Map standard access rights to object specific access rights */
1659 se_map_standard(&r->in.access_mask,
1660 &printserver_std_mapping);
1662 /* Deny any object specific bits that don't apply to print
1663 servers (i.e printer and job specific bits) */
1665 r->in.access_mask &= SEC_MASK_SPECIFIC;
1667 if (r->in.access_mask &
1668 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1669 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1670 close_printer_handle(p, r->out.handle);
1671 ZERO_STRUCTP(r->out.handle);
1672 return WERR_ACCESS_DENIED;
1675 /* Allow admin access */
1677 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1679 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1681 if (!lp_ms_add_printer_wizard()) {
1682 close_printer_handle(p, r->out.handle);
1683 ZERO_STRUCTP(r->out.handle);
1684 return WERR_ACCESS_DENIED;
1687 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1688 and not a printer admin, then fail */
1690 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1691 !user_has_privileges(p->server_info->ptok,
1693 !token_contains_name_in_list(
1694 uidtoname(p->server_info->utok.uid),
1695 p->server_info->info3->base.domain.string,
1697 p->server_info->ptok,
1698 lp_printer_admin(snum))) {
1699 close_printer_handle(p, r->out.handle);
1700 ZERO_STRUCTP(r->out.handle);
1701 return WERR_ACCESS_DENIED;
1704 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1708 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1711 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1712 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1714 /* We fall through to return WERR_OK */
1717 case SPLHND_PRINTER:
1718 /* NT doesn't let us connect to a printer if the connecting user
1719 doesn't have print permission. */
1721 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1722 close_printer_handle(p, r->out.handle);
1723 ZERO_STRUCTP(r->out.handle);
1727 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1728 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1731 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1733 /* map an empty access mask to the minimum access mask */
1734 if (r->in.access_mask == 0x0)
1735 r->in.access_mask = PRINTER_ACCESS_USE;
1738 * If we are not serving the printer driver for this printer,
1739 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1740 * will keep NT clients happy --jerry
1743 if (lp_use_client_driver(snum)
1744 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1746 r->in.access_mask = PRINTER_ACCESS_USE;
1749 /* check smb.conf parameters and the the sec_desc */
1751 if (!allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
1752 p->client_id->name, p->client_id->addr)) {
1753 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1754 ZERO_STRUCTP(r->out.handle);
1755 return WERR_ACCESS_DENIED;
1758 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1759 p->server_info->ptok, snum) ||
1760 !print_access_check(get_server_info_system(),
1763 r->in.access_mask)) {
1764 DEBUG(3, ("access DENIED for printer open\n"));
1765 close_printer_handle(p, r->out.handle);
1766 ZERO_STRUCTP(r->out.handle);
1767 return WERR_ACCESS_DENIED;
1770 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1771 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1772 close_printer_handle(p, r->out.handle);
1773 ZERO_STRUCTP(r->out.handle);
1774 return WERR_ACCESS_DENIED;
1777 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1778 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1780 r->in.access_mask = PRINTER_ACCESS_USE;
1782 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1783 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1785 winreg_create_printer(p->mem_ctx,
1786 get_server_info_system(),
1788 Printer->servername,
1789 lp_const_servicename(snum));
1794 /* sanity check to prevent programmer error */
1795 ZERO_STRUCTP(r->out.handle);
1799 Printer->access_granted = r->in.access_mask;
1802 * If the client sent a devmode in the OpenPrinter() call, then
1803 * save it here in case we get a job submission on this handle
1806 if ((Printer->printer_type != SPLHND_SERVER) &&
1807 r->in.devmode_ctr.devmode) {
1808 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1812 #if 0 /* JERRY -- I'm doubtful this is really effective */
1813 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1814 optimization in Windows 2000 clients --jerry */
1816 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1817 && (RA_WIN2K == get_remote_arch()) )
1819 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1820 sys_usleep( 500000 );
1827 /****************************************************************
1828 _spoolss_ClosePrinter
1829 ****************************************************************/
1831 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1832 struct spoolss_ClosePrinter *r)
1834 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1836 if (Printer && Printer->document_started) {
1837 struct spoolss_EndDocPrinter e;
1839 e.in.handle = r->in.handle;
1841 _spoolss_EndDocPrinter(p, &e);
1844 if (!close_printer_handle(p, r->in.handle))
1847 /* clear the returned printer handle. Observed behavior
1848 from Win2k server. Don't think this really matters.
1849 Previous code just copied the value of the closed
1852 ZERO_STRUCTP(r->out.handle);
1857 /****************************************************************
1858 _spoolss_DeletePrinter
1859 ****************************************************************/
1861 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1862 struct spoolss_DeletePrinter *r)
1864 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1868 if (Printer && Printer->document_started) {
1869 struct spoolss_EndDocPrinter e;
1871 e.in.handle = r->in.handle;
1873 _spoolss_EndDocPrinter(p, &e);
1876 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1877 winreg_delete_printer_key(p->mem_ctx,
1878 get_server_info_system(),
1880 lp_const_servicename(snum),
1884 result = delete_printer_handle(p, r->in.handle);
1889 /*******************************************************************
1890 * static function to lookup the version id corresponding to an
1891 * long architecture string
1892 ******************************************************************/
1894 static const struct print_architecture_table_node archi_table[]= {
1896 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1897 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1898 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1899 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1900 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1901 {"Windows IA64", SPL_ARCH_IA64, 3 },
1902 {"Windows x64", SPL_ARCH_X64, 3 },
1906 static int get_version_id(const char *arch)
1910 for (i=0; archi_table[i].long_archi != NULL; i++)
1912 if (strcmp(arch, archi_table[i].long_archi) == 0)
1913 return (archi_table[i].version);
1919 /****************************************************************
1920 _spoolss_DeletePrinterDriver
1921 ****************************************************************/
1923 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1924 struct spoolss_DeletePrinterDriver *r)
1927 struct spoolss_DriverInfo8 *info = NULL;
1928 struct spoolss_DriverInfo8 *info_win2k = NULL;
1931 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1933 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1934 and not a printer admin, then fail */
1936 if ( (p->server_info->utok.uid != sec_initial_uid())
1937 && !user_has_privileges(p->server_info->ptok, &se_printop )
1938 && !token_contains_name_in_list(
1939 uidtoname(p->server_info->utok.uid),
1940 p->server_info->info3->base.domain.string,
1942 p->server_info->ptok,
1943 lp_printer_admin(-1)) )
1945 return WERR_ACCESS_DENIED;
1948 /* check that we have a valid driver name first */
1950 if ((version = get_version_id(r->in.architecture)) == -1)
1951 return WERR_INVALID_ENVIRONMENT;
1953 status = winreg_get_driver(p->mem_ctx,
1954 get_server_info_system(),
1956 r->in.architecture, r->in.driver,
1958 if (!W_ERROR_IS_OK(status)) {
1959 /* try for Win2k driver if "Windows NT x86" */
1961 if ( version == 2 ) {
1964 status = winreg_get_driver(p->mem_ctx,
1965 get_server_info_system(),
1970 if (!W_ERROR_IS_OK(status)) {
1971 status = WERR_UNKNOWN_PRINTER_DRIVER;
1975 /* otherwise it was a failure */
1977 status = WERR_UNKNOWN_PRINTER_DRIVER;
1983 if (printer_driver_in_use(p->mem_ctx,
1984 get_server_info_system(),
1987 status = WERR_PRINTER_DRIVER_IN_USE;
1992 status = winreg_get_driver(p->mem_ctx,
1993 get_server_info_system(),
1996 r->in.driver, 3, &info_win2k);
1997 if (W_ERROR_IS_OK(status)) {
1998 /* if we get to here, we now have 2 driver info structures to remove */
1999 /* remove the Win2k driver first*/
2001 status = winreg_del_driver(p->mem_ctx,
2002 get_server_info_system(),
2005 talloc_free(info_win2k);
2007 /* this should not have failed---if it did, report to client */
2008 if (!W_ERROR_IS_OK(status)) {
2014 status = winreg_del_driver(p->mem_ctx,
2015 get_server_info_system(),
2025 /****************************************************************
2026 _spoolss_DeletePrinterDriverEx
2027 ****************************************************************/
2029 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
2030 struct spoolss_DeletePrinterDriverEx *r)
2032 struct spoolss_DriverInfo8 *info = NULL;
2033 struct spoolss_DriverInfo8 *info_win2k = NULL;
2037 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2039 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2040 and not a printer admin, then fail */
2042 if ( (p->server_info->utok.uid != sec_initial_uid())
2043 && !user_has_privileges(p->server_info->ptok, &se_printop )
2044 && !token_contains_name_in_list(
2045 uidtoname(p->server_info->utok.uid),
2046 p->server_info->info3->base.domain.string,
2048 p->server_info->ptok, lp_printer_admin(-1)) )
2050 return WERR_ACCESS_DENIED;
2053 /* check that we have a valid driver name first */
2054 if ((version = get_version_id(r->in.architecture)) == -1) {
2055 /* this is what NT returns */
2056 return WERR_INVALID_ENVIRONMENT;
2059 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2060 version = r->in.version;
2062 status = winreg_get_driver(p->mem_ctx,
2063 get_server_info_system(),
2069 if (!W_ERROR_IS_OK(status)) {
2070 status = WERR_UNKNOWN_PRINTER_DRIVER;
2073 * if the client asked for a specific version,
2074 * or this is something other than Windows NT x86,
2078 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2081 /* try for Win2k driver if "Windows NT x86" */
2084 status = winreg_get_driver(info,
2085 get_server_info_system(),
2090 if (!W_ERROR_IS_OK(status)) {
2091 status = WERR_UNKNOWN_PRINTER_DRIVER;
2096 if (printer_driver_in_use(info,
2097 get_server_info_system(),
2100 status = WERR_PRINTER_DRIVER_IN_USE;
2105 * we have a couple of cases to consider.
2106 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2107 * then the delete should fail if **any** files overlap with
2109 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2110 * non-overlapping files
2111 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2112 * is set, the do not delete any files
2113 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2116 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2118 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2121 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2122 printer_driver_files_in_use(info,
2123 get_server_info_system(),
2126 /* no idea of the correct error here */
2127 status = WERR_ACCESS_DENIED;
2132 /* also check for W32X86/3 if necessary; maybe we already have? */
2134 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2135 status = winreg_get_driver(info,
2136 get_server_info_system(),
2139 r->in.driver, 3, &info_win2k);
2140 if (W_ERROR_IS_OK(status)) {
2143 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
2144 printer_driver_files_in_use(info,
2145 get_server_info_system(),
2148 /* no idea of the correct error here */
2149 talloc_free(info_win2k);
2150 status = WERR_ACCESS_DENIED;
2154 /* if we get to here, we now have 2 driver info structures to remove */
2155 /* remove the Win2k driver first*/
2157 status = winreg_del_driver(info,
2158 get_server_info_system(),
2163 /* this should not have failed---if it did, report to client */
2165 if (!W_ERROR_IS_OK(status)) {
2170 * now delete any associated files if delete_files is
2171 * true. Even if this part failes, we return succes
2172 * because the driver doesn not exist any more
2175 delete_driver_files(get_server_info_system(),
2181 status = winreg_del_driver(info,
2182 get_server_info_system(),
2186 if (!W_ERROR_IS_OK(status)) {
2191 * now delete any associated files if delete_files is
2192 * true. Even if this part failes, we return succes
2193 * because the driver doesn not exist any more
2196 delete_driver_files(get_server_info_system(), info);
2205 /********************************************************************
2206 GetPrinterData on a printer server Handle.
2207 ********************************************************************/
2209 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2211 enum winreg_Type *type,
2212 union spoolss_PrinterData *data)
2214 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2216 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2222 if (!StrCaseCmp(value, "BeepEnabled")) {
2228 if (!StrCaseCmp(value, "EventLog")) {
2230 /* formally was 0x1b */
2235 if (!StrCaseCmp(value, "NetPopup")) {
2241 if (!StrCaseCmp(value, "MajorVersion")) {
2244 /* Windows NT 4.0 seems to not allow uploading of drivers
2245 to a server that reports 0x3 as the MajorVersion.
2246 need to investigate more how Win2k gets around this .
2249 if (RA_WINNT == get_remote_arch()) {
2258 if (!StrCaseCmp(value, "MinorVersion")) {
2265 * uint32_t size = 0x114
2266 * uint32_t major = 5
2267 * uint32_t minor = [0|1]
2268 * uint32_t build = [2195|2600]
2269 * extra unicode string = e.g. "Service Pack 3"
2271 if (!StrCaseCmp(value, "OSVersion")) {
2273 enum ndr_err_code ndr_err;
2274 struct spoolss_OSVersion os;
2276 os.major = 5; /* Windows 2000 == 5.0 */
2278 os.build = 2195; /* build */
2279 os.extra_string = ""; /* leave extra string empty */
2281 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2282 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2283 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2284 return WERR_GENERAL_FAILURE;
2288 data->binary = blob;
2294 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2297 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2298 W_ERROR_HAVE_NO_MEMORY(data->string);
2303 if (!StrCaseCmp(value, "Architecture")) {
2305 data->string = talloc_strdup(mem_ctx,
2306 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2307 W_ERROR_HAVE_NO_MEMORY(data->string);
2312 if (!StrCaseCmp(value, "DsPresent")) {
2315 /* only show the publish check box if we are a
2316 member of a AD domain */
2318 if (lp_security() == SEC_ADS) {
2326 if (!StrCaseCmp(value, "DNSMachineName")) {
2327 const char *hostname = get_mydnsfullname();
2330 return WERR_BADFILE;
2334 data->string = talloc_strdup(mem_ctx, hostname);
2335 W_ERROR_HAVE_NO_MEMORY(data->string);
2342 return WERR_INVALID_PARAM;
2345 /****************************************************************
2346 _spoolss_GetPrinterData
2347 ****************************************************************/
2349 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2350 struct spoolss_GetPrinterData *r)
2352 struct spoolss_GetPrinterDataEx r2;
2354 r2.in.handle = r->in.handle;
2355 r2.in.key_name = "PrinterDriverData";
2356 r2.in.value_name = r->in.value_name;
2357 r2.in.offered = r->in.offered;
2358 r2.out.type = r->out.type;
2359 r2.out.data = r->out.data;
2360 r2.out.needed = r->out.needed;
2362 return _spoolss_GetPrinterDataEx(p, &r2);
2365 /*********************************************************
2366 Connect to the client machine.
2367 **********************************************************/
2369 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2370 struct sockaddr_storage *client_ss, const char *remote_machine)
2373 struct cli_state *the_cli;
2374 struct sockaddr_storage rm_addr;
2375 char addr[INET6_ADDRSTRLEN];
2377 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2378 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2380 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2381 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2384 print_sockaddr(addr, sizeof(addr), &rm_addr);
2386 rm_addr = *client_ss;
2387 print_sockaddr(addr, sizeof(addr), &rm_addr);
2388 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2392 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2393 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2398 /* setup the connection */
2399 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2400 &rm_addr, 0, "IPC$", "IPC",
2404 0, lp_client_signing(), NULL );
2406 if ( !NT_STATUS_IS_OK( ret ) ) {
2407 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2412 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2413 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2414 cli_shutdown(the_cli);
2419 * Ok - we have an anonymous connection to the IPC$ share.
2420 * Now start the NT Domain stuff :-).
2423 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2424 if (!NT_STATUS_IS_OK(ret)) {
2425 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2426 remote_machine, nt_errstr(ret)));
2427 cli_shutdown(the_cli);
2434 /***************************************************************************
2435 Connect to the client.
2436 ****************************************************************************/
2438 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2439 uint32_t localprinter,
2440 enum winreg_Type type,
2441 struct policy_handle *handle,
2442 struct sockaddr_storage *client_ss,
2443 struct messaging_context *msg_ctx)
2449 * If it's the first connection, contact the client
2450 * and connect to the IPC$ share anonymously
2452 if (smb_connections==0) {
2453 fstring unix_printer;
2455 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2457 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2460 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2461 receive_notify2_message_list);
2462 /* Tell the connections db we're now interested in printer
2463 * notify messages. */
2464 serverid_register_msg_flags(messaging_server_id(msg_ctx),
2465 true, FLAG_MSG_PRINT_NOTIFY);
2469 * Tell the specific printing tdb we want messages for this printer
2470 * by registering our PID.
2473 if (!print_notify_register_pid(snum))
2474 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2478 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2486 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2487 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2488 win_errstr(result)));
2490 return (W_ERROR_IS_OK(result));
2493 /****************************************************************
2494 ****************************************************************/
2496 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2497 const struct spoolss_NotifyOption *r)
2499 struct spoolss_NotifyOption *option;
2506 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2513 if (!option->count) {
2517 option->types = talloc_zero_array(option,
2518 struct spoolss_NotifyOptionType, option->count);
2519 if (!option->types) {
2520 talloc_free(option);
2524 for (i=0; i < option->count; i++) {
2525 option->types[i] = r->types[i];
2527 if (option->types[i].count) {
2528 option->types[i].fields = talloc_zero_array(option,
2529 union spoolss_Field, option->types[i].count);
2530 if (!option->types[i].fields) {
2531 talloc_free(option);
2534 for (k=0; k<option->types[i].count; k++) {
2535 option->types[i].fields[k] =
2536 r->types[i].fields[k];
2544 /****************************************************************
2545 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2547 * before replying OK: status=0 a rpc call is made to the workstation
2548 * asking ReplyOpenPrinter
2550 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2551 * called from api_spoolss_rffpcnex
2552 ****************************************************************/
2554 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2555 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2558 struct spoolss_NotifyOption *option = r->in.notify_options;
2559 struct sockaddr_storage client_ss;
2561 /* store the notify value in the printer struct */
2563 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
2566 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2567 "Invalid handle (%s:%u:%u).\n",
2568 OUR_HANDLE(r->in.handle)));
2572 Printer->notify.flags = r->in.flags;
2573 Printer->notify.options = r->in.options;
2574 Printer->notify.printerlocal = r->in.printer_local;
2575 Printer->notify.msg_ctx = p->msg_ctx;
2577 TALLOC_FREE(Printer->notify.option);
2578 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2580 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2582 /* Connect to the client machine and send a ReplyOpenPrinter */
2584 if ( Printer->printer_type == SPLHND_SERVER)
2586 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2587 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2590 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2591 "client_address is %s\n", p->client_id->addr));
2593 if (!interpret_string_addr(&client_ss, p->client_id->addr,
2595 return WERR_SERVER_UNAVAILABLE;
2598 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2599 Printer->notify.printerlocal, REG_SZ,
2600 &Printer->notify.client_hnd,
2601 &client_ss, p->msg_ctx))
2602 return WERR_SERVER_UNAVAILABLE;
2604 Printer->notify.client_connected = true;
2609 /*******************************************************************
2610 * fill a notify_info_data with the servername
2611 ********************************************************************/
2613 static void spoolss_notify_server_name(struct messaging_context *msg_ctx,
2615 struct spoolss_Notify *data,
2616 print_queue_struct *queue,
2617 struct spoolss_PrinterInfo2 *pinfo2,
2618 TALLOC_CTX *mem_ctx)
2620 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2623 /*******************************************************************
2624 * fill a notify_info_data with the printername (not including the servername).
2625 ********************************************************************/
2627 static void spoolss_notify_printer_name(struct messaging_context *msg_ctx,
2629 struct spoolss_Notify *data,
2630 print_queue_struct *queue,
2631 struct spoolss_PrinterInfo2 *pinfo2,
2632 TALLOC_CTX *mem_ctx)
2634 /* the notify name should not contain the \\server\ part */
2635 const char *p = strrchr(pinfo2->printername, '\\');
2638 p = pinfo2->printername;
2643 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2646 /*******************************************************************
2647 * fill a notify_info_data with the servicename
2648 ********************************************************************/
2650 static void spoolss_notify_share_name(struct messaging_context *msg_ctx,
2652 struct spoolss_Notify *data,
2653 print_queue_struct *queue,
2654 struct spoolss_PrinterInfo2 *pinfo2,
2655 TALLOC_CTX *mem_ctx)
2657 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2660 /*******************************************************************
2661 * fill a notify_info_data with the port name
2662 ********************************************************************/
2664 static void spoolss_notify_port_name(struct messaging_context *msg_ctx,
2666 struct spoolss_Notify *data,
2667 print_queue_struct *queue,
2668 struct spoolss_PrinterInfo2 *pinfo2,
2669 TALLOC_CTX *mem_ctx)
2671 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2674 /*******************************************************************
2675 * fill a notify_info_data with the printername
2676 * but it doesn't exist, have to see what to do
2677 ********************************************************************/
2679 static void spoolss_notify_driver_name(struct messaging_context *msg_ctx,
2681 struct spoolss_Notify *data,
2682 print_queue_struct *queue,
2683 struct spoolss_PrinterInfo2 *pinfo2,
2684 TALLOC_CTX *mem_ctx)
2686 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2689 /*******************************************************************
2690 * fill a notify_info_data with the comment
2691 ********************************************************************/
2693 static void spoolss_notify_comment(struct messaging_context *msg_ctx,
2695 struct spoolss_Notify *data,
2696 print_queue_struct *queue,
2697 struct spoolss_PrinterInfo2 *pinfo2,
2698 TALLOC_CTX *mem_ctx)
2702 if (*pinfo2->comment == '\0') {
2703 p = lp_comment(snum);
2705 p = pinfo2->comment;
2708 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2711 /*******************************************************************
2712 * fill a notify_info_data with the comment
2713 * location = "Room 1, floor 2, building 3"
2714 ********************************************************************/
2716 static void spoolss_notify_location(struct messaging_context *msg_ctx,
2718 struct spoolss_Notify *data,
2719 print_queue_struct *queue,
2720 struct spoolss_PrinterInfo2 *pinfo2,
2721 TALLOC_CTX *mem_ctx)
2723 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2726 /*******************************************************************
2727 * fill a notify_info_data with the device mode
2728 * jfm:xxxx don't to it for know but that's a real problem !!!
2729 ********************************************************************/
2731 static void spoolss_notify_devmode(struct messaging_context *msg_ctx,
2733 struct spoolss_Notify *data,
2734 print_queue_struct *queue,
2735 struct spoolss_PrinterInfo2 *pinfo2,
2736 TALLOC_CTX *mem_ctx)
2738 /* for a dummy implementation we have to zero the fields */
2739 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2742 /*******************************************************************
2743 * fill a notify_info_data with the separator file name
2744 ********************************************************************/
2746 static void spoolss_notify_sepfile(struct messaging_context *msg_ctx,
2748 struct spoolss_Notify *data,
2749 print_queue_struct *queue,
2750 struct spoolss_PrinterInfo2 *pinfo2,
2751 TALLOC_CTX *mem_ctx)
2753 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2756 /*******************************************************************
2757 * fill a notify_info_data with the print processor
2758 * jfm:xxxx return always winprint to indicate we don't do anything to it
2759 ********************************************************************/
2761 static void spoolss_notify_print_processor(struct messaging_context *msg_ctx,
2763 struct spoolss_Notify *data,
2764 print_queue_struct *queue,
2765 struct spoolss_PrinterInfo2 *pinfo2,
2766 TALLOC_CTX *mem_ctx)
2768 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2771 /*******************************************************************
2772 * fill a notify_info_data with the print processor options
2773 * jfm:xxxx send an empty string
2774 ********************************************************************/
2776 static void spoolss_notify_parameters(struct messaging_context *msg_ctx,
2778 struct spoolss_Notify *data,
2779 print_queue_struct *queue,
2780 struct spoolss_PrinterInfo2 *pinfo2,
2781 TALLOC_CTX *mem_ctx)
2783 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2786 /*******************************************************************
2787 * fill a notify_info_data with the data type
2788 * jfm:xxxx always send RAW as data type
2789 ********************************************************************/
2791 static void spoolss_notify_datatype(struct messaging_context *msg_ctx,
2793 struct spoolss_Notify *data,
2794 print_queue_struct *queue,
2795 struct spoolss_PrinterInfo2 *pinfo2,
2796 TALLOC_CTX *mem_ctx)
2798 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2801 /*******************************************************************
2802 * fill a notify_info_data with the security descriptor
2803 * jfm:xxxx send an null pointer to say no security desc
2804 * have to implement security before !
2805 ********************************************************************/
2807 static void spoolss_notify_security_desc(struct messaging_context *msg_ctx,
2809 struct spoolss_Notify *data,
2810 print_queue_struct *queue,
2811 struct spoolss_PrinterInfo2 *pinfo2,
2812 TALLOC_CTX *mem_ctx)
2814 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2817 /*******************************************************************
2818 * fill a notify_info_data with the attributes
2819 * jfm:xxxx a samba printer is always shared
2820 ********************************************************************/
2822 static void spoolss_notify_attributes(struct messaging_context *msg_ctx,
2824 struct spoolss_Notify *data,
2825 print_queue_struct *queue,
2826 struct spoolss_PrinterInfo2 *pinfo2,
2827 TALLOC_CTX *mem_ctx)
2829 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2832 /*******************************************************************
2833 * fill a notify_info_data with the priority
2834 ********************************************************************/
2836 static void spoolss_notify_priority(struct messaging_context *msg_ctx,
2838 struct spoolss_Notify *data,
2839 print_queue_struct *queue,
2840 struct spoolss_PrinterInfo2 *pinfo2,
2841 TALLOC_CTX *mem_ctx)
2843 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2846 /*******************************************************************
2847 * fill a notify_info_data with the default priority
2848 ********************************************************************/
2850 static void spoolss_notify_default_priority(struct messaging_context *msg_ctx,
2852 struct spoolss_Notify *data,
2853 print_queue_struct *queue,
2854 struct spoolss_PrinterInfo2 *pinfo2,
2855 TALLOC_CTX *mem_ctx)
2857 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2860 /*******************************************************************
2861 * fill a notify_info_data with the start time
2862 ********************************************************************/
2864 static void spoolss_notify_start_time(struct messaging_context *msg_ctx,
2866 struct spoolss_Notify *data,
2867 print_queue_struct *queue,
2868 struct spoolss_PrinterInfo2 *pinfo2,
2869 TALLOC_CTX *mem_ctx)
2871 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2874 /*******************************************************************
2875 * fill a notify_info_data with the until time
2876 ********************************************************************/
2878 static void spoolss_notify_until_time(struct messaging_context *msg_ctx,
2880 struct spoolss_Notify *data,
2881 print_queue_struct *queue,
2882 struct spoolss_PrinterInfo2 *pinfo2,
2883 TALLOC_CTX *mem_ctx)
2885 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2888 /*******************************************************************
2889 * fill a notify_info_data with the status
2890 ********************************************************************/
2892 static void spoolss_notify_status(struct messaging_context *msg_ctx,
2894 struct spoolss_Notify *data,
2895 print_queue_struct *queue,
2896 struct spoolss_PrinterInfo2 *pinfo2,
2897 TALLOC_CTX *mem_ctx)
2899 print_status_struct status;
2901 print_queue_length(msg_ctx, snum, &status);
2902 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2905 /*******************************************************************
2906 * fill a notify_info_data with the number of jobs queued
2907 ********************************************************************/
2909 static void spoolss_notify_cjobs(struct messaging_context *msg_ctx,
2911 struct spoolss_Notify *data,
2912 print_queue_struct *queue,
2913 struct spoolss_PrinterInfo2 *pinfo2,
2914 TALLOC_CTX *mem_ctx)
2916 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(
2917 data, print_queue_length(msg_ctx, snum, NULL));
2920 /*******************************************************************
2921 * fill a notify_info_data with the average ppm
2922 ********************************************************************/
2924 static void spoolss_notify_average_ppm(struct messaging_context *msg_ctx,
2926 struct spoolss_Notify *data,
2927 print_queue_struct *queue,
2928 struct spoolss_PrinterInfo2 *pinfo2,
2929 TALLOC_CTX *mem_ctx)
2931 /* always respond 8 pages per minutes */
2932 /* a little hard ! */
2933 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2936 /*******************************************************************
2937 * fill a notify_info_data with username
2938 ********************************************************************/
2940 static void spoolss_notify_username(struct messaging_context *msg_ctx,
2942 struct spoolss_Notify *data,
2943 print_queue_struct *queue,
2944 struct spoolss_PrinterInfo2 *pinfo2,
2945 TALLOC_CTX *mem_ctx)
2947 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2950 /*******************************************************************
2951 * fill a notify_info_data with job status
2952 ********************************************************************/
2954 static void spoolss_notify_job_status(struct messaging_context *msg_ctx,
2956 struct spoolss_Notify *data,
2957 print_queue_struct *queue,
2958 struct spoolss_PrinterInfo2 *pinfo2,
2959 TALLOC_CTX *mem_ctx)
2961 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2964 /*******************************************************************
2965 * fill a notify_info_data with job name
2966 ********************************************************************/
2968 static void spoolss_notify_job_name(struct messaging_context *msg_ctx,
2970 struct spoolss_Notify *data,
2971 print_queue_struct *queue,
2972 struct spoolss_PrinterInfo2 *pinfo2,
2973 TALLOC_CTX *mem_ctx)
2975 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2978 /*******************************************************************
2979 * fill a notify_info_data with job status
2980 ********************************************************************/
2982 static void spoolss_notify_job_status_string(struct messaging_context *msg_ctx,
2984 struct spoolss_Notify *data,
2985 print_queue_struct *queue,
2986 struct spoolss_PrinterInfo2 *pinfo2,
2987 TALLOC_CTX *mem_ctx)
2990 * Now we're returning job status codes we just return a "" here. JRA.
2995 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2998 switch (queue->status) {
3003 p = ""; /* NT provides the paused string */
3012 #endif /* NO LONGER NEEDED. */
3014 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3017 /*******************************************************************
3018 * fill a notify_info_data with job time
3019 ********************************************************************/
3021 static void spoolss_notify_job_time(struct messaging_context *msg_ctx,
3023 struct spoolss_Notify *data,
3024 print_queue_struct *queue,
3025 struct spoolss_PrinterInfo2 *pinfo2,
3026 TALLOC_CTX *mem_ctx)
3028 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3031 /*******************************************************************
3032 * fill a notify_info_data with job size
3033 ********************************************************************/
3035 static void spoolss_notify_job_size(struct messaging_context *msg_ctx,
3037 struct spoolss_Notify *data,
3038 print_queue_struct *queue,
3039 struct spoolss_PrinterInfo2 *pinfo2,
3040 TALLOC_CTX *mem_ctx)
3042 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3045 /*******************************************************************
3046 * fill a notify_info_data with page info
3047 ********************************************************************/
3048 static void spoolss_notify_total_pages(struct messaging_context *msg_ctx,
3050 struct spoolss_Notify *data,
3051 print_queue_struct *queue,
3052 struct spoolss_PrinterInfo2 *pinfo2,
3053 TALLOC_CTX *mem_ctx)
3055 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3058 /*******************************************************************
3059 * fill a notify_info_data with pages printed info.
3060 ********************************************************************/
3061 static void spoolss_notify_pages_printed(struct messaging_context *msg_ctx,
3063 struct spoolss_Notify *data,
3064 print_queue_struct *queue,
3065 struct spoolss_PrinterInfo2 *pinfo2,
3066 TALLOC_CTX *mem_ctx)
3068 /* Add code when back-end tracks this */
3069 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3072 /*******************************************************************
3073 Fill a notify_info_data with job position.
3074 ********************************************************************/
3076 static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
3078 struct spoolss_Notify *data,
3079 print_queue_struct *queue,
3080 struct spoolss_PrinterInfo2 *pinfo2,
3081 TALLOC_CTX *mem_ctx)
3083 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3086 /*******************************************************************
3087 Fill a notify_info_data with submitted time.
3088 ********************************************************************/
3090 static void spoolss_notify_submitted_time(struct messaging_context *msg_ctx,
3092 struct spoolss_Notify *data,
3093 print_queue_struct *queue,
3094 struct spoolss_PrinterInfo2 *pinfo2,
3095 TALLOC_CTX *mem_ctx)
3097 data->data.string.string = NULL;
3098 data->data.string.size = 0;
3100 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3101 &data->data.string.string,
3102 &data->data.string.size);
3106 struct s_notify_info_data_table
3108 enum spoolss_NotifyType type;
3111 enum spoolss_NotifyTable variable_type;
3112 void (*fn) (struct messaging_context *msg_ctx,
3113 int snum, struct spoolss_Notify *data,
3114 print_queue_struct *queue,
3115 struct spoolss_PrinterInfo2 *pinfo2,
3116 TALLOC_CTX *mem_ctx);
3119 /* A table describing the various print notification constants and
3120 whether the notification data is a pointer to a variable sized
3121 buffer, a one value uint32_t or a two value uint32_t. */
3123 static const struct s_notify_info_data_table notify_info_data_table[] =
3125 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3126 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3127 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3128 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3129 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3130 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3131 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3132 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3133 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3134 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3135 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3136 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3137 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3138 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3139 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3140 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3141 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3142 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3143 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3144 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3145 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3146 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3147 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3148 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3149 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3150 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3151 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3152 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3153 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3154 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3155 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3156 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3157 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3158 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3159 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3160 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3161 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3162 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3163 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3164 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3165 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3166 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3167 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3168 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3169 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3170 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3171 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3172 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3173 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3176 /*******************************************************************
3177 Return the variable_type of info_data structure.
3178 ********************************************************************/
3180 static enum spoolss_NotifyTable variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3185 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3186 if ( (notify_info_data_table[i].type == type) &&
3187 (notify_info_data_table[i].field == field) ) {
3188 return notify_info_data_table[i].variable_type;
3192 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3194 return (enum spoolss_NotifyTable) 0;
3197 /****************************************************************************
3198 ****************************************************************************/
3200 static bool search_notify(enum spoolss_NotifyType type,
3206 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3207 if (notify_info_data_table[i].type == type &&
3208 notify_info_data_table[i].field == field &&
3209 notify_info_data_table[i].fn != NULL) {
3218 /****************************************************************************
3219 ****************************************************************************/
3221 static void construct_info_data(struct spoolss_Notify *info_data,
3222 enum spoolss_NotifyType type,
3223 uint16_t field, int id)
3225 info_data->type = type;
3226 info_data->field.field = field;
3227 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3228 info_data->job_id = id;
3231 /*******************************************************************
3233 * fill a notify_info struct with info asked
3235 ********************************************************************/
3237 static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
3238 struct printer_handle *print_hnd,
3239 struct spoolss_NotifyInfo *info,
3240 struct spoolss_PrinterInfo2 *pinfo2,
3242 const struct spoolss_NotifyOptionType *option_type,
3244 TALLOC_CTX *mem_ctx)
3247 enum spoolss_NotifyType type;
3250 struct spoolss_Notify *current_data;
3251 print_queue_struct *queue=NULL;
3253 type = option_type->type;
3255 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3256 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3257 option_type->count, lp_servicename(snum)));
3259 for(field_num=0; field_num < option_type->count; field_num++) {
3260 field = option_type->fields[field_num].field;
3262 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3264 if (!search_notify(type, field, &j) )
3267 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3268 struct spoolss_Notify,
3270 if (info->notifies == NULL) {
3271 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3275 current_data = &info->notifies[info->count];
3277 construct_info_data(current_data, type, field, id);
3279 DEBUG(10, ("construct_notify_printer_info: "
3280 "calling [%s] snum=%d printername=[%s])\n",
3281 notify_info_data_table[j].name, snum,
3282 pinfo2->printername));
3284 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3285 queue, pinfo2, mem_ctx);
3293 /*******************************************************************
3295 * fill a notify_info struct with info asked
3297 ********************************************************************/
3299 static bool construct_notify_jobs_info(struct messaging_context *msg_ctx,
3300 print_queue_struct *queue,
3301 struct spoolss_NotifyInfo *info,
3302 struct spoolss_PrinterInfo2 *pinfo2,
3304 const struct spoolss_NotifyOptionType *option_type,
3306 TALLOC_CTX *mem_ctx)
3309 enum spoolss_NotifyType type;
3311 struct spoolss_Notify *current_data;
3313 DEBUG(4,("construct_notify_jobs_info\n"));
3315 type = option_type->type;
3317 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3318 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3319 option_type->count));
3321 for(field_num=0; field_num<option_type->count; field_num++) {
3322 field = option_type->fields[field_num].field;
3324 if (!search_notify(type, field, &j) )
3327 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3328 struct spoolss_Notify,
3330 if (info->notifies == NULL) {
3331 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3335 current_data=&(info->notifies[info->count]);
3337 construct_info_data(current_data, type, field, id);
3338 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3339 queue, pinfo2, mem_ctx);
3347 * JFM: The enumeration is not that simple, it's even non obvious.
3349 * let's take an example: I want to monitor the PRINTER SERVER for
3350 * the printer's name and the number of jobs currently queued.
3351 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3352 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3354 * I have 3 printers on the back of my server.
3356 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3359 * 1 printer 1 name 1
3360 * 2 printer 1 cjob 1
3361 * 3 printer 2 name 2
3362 * 4 printer 2 cjob 2
3363 * 5 printer 3 name 3
3364 * 6 printer 3 name 3
3366 * that's the print server case, the printer case is even worse.
3369 /*******************************************************************
3371 * enumerate all printers on the printserver
3372 * fill a notify_info struct with info asked
3374 ********************************************************************/
3376 static WERROR printserver_notify_info(struct pipes_struct *p,
3377 struct policy_handle *hnd,
3378 struct spoolss_NotifyInfo *info,
3379 TALLOC_CTX *mem_ctx)
3382 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3383 int n_services=lp_numservices();
3385 struct spoolss_NotifyOption *option;
3386 struct spoolss_NotifyOptionType option_type;
3387 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3390 DEBUG(4,("printserver_notify_info\n"));
3395 option = Printer->notify.option;
3398 info->notifies = NULL;
3401 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3402 sending a ffpcn() request first */
3407 for (i=0; i<option->count; i++) {
3408 option_type = option->types[i];
3410 if (option_type.type != PRINTER_NOTIFY_TYPE)
3413 for (snum = 0; snum < n_services; snum++) {
3414 if (!lp_browseable(snum) ||
3415 !lp_snum_ok(snum) ||
3416 !lp_print_ok(snum)) {
3417 continue; /* skip */
3420 /* Maybe we should use the SYSTEM server_info here... */
3421 result = winreg_get_printer(mem_ctx,
3422 get_server_info_system(),
3424 Printer->servername,
3425 lp_servicename(snum),
3427 if (!W_ERROR_IS_OK(result)) {
3428 DEBUG(4, ("printserver_notify_info: "
3429 "Failed to get printer [%s]\n",
3430 lp_servicename(snum)));
3435 construct_notify_printer_info(p->msg_ctx,
3441 TALLOC_FREE(pinfo2);
3447 * Debugging information, don't delete.
3450 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3451 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3452 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3454 for (i=0; i<info->count; i++) {
3455 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3456 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3457 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3464 /*******************************************************************
3466 * fill a notify_info struct with info asked
3468 ********************************************************************/
3470 static WERROR printer_notify_info(struct pipes_struct *p,
3471 struct policy_handle *hnd,
3472 struct spoolss_NotifyInfo *info,
3473 TALLOC_CTX *mem_ctx)
3476 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3479 struct spoolss_NotifyOption *option;
3480 struct spoolss_NotifyOptionType option_type;
3482 print_queue_struct *queue=NULL;
3483 print_status_struct status;
3484 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3487 DEBUG(4,("printer_notify_info\n"));
3492 option = Printer->notify.option;
3496 info->notifies = NULL;
3499 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3500 sending a ffpcn() request first */
3505 get_printer_snum(p, hnd, &snum, NULL);
3507 /* Maybe we should use the SYSTEM server_info here... */
3508 result = winreg_get_printer(mem_ctx,
3509 get_server_info_system(),
3511 Printer->servername,
3512 lp_servicename(snum), &pinfo2);
3513 if (!W_ERROR_IS_OK(result)) {
3517 for (i=0; i<option->count; i++) {
3518 option_type = option->types[i];
3520 switch (option_type.type) {
3521 case PRINTER_NOTIFY_TYPE:
3522 if (construct_notify_printer_info(p->msg_ctx,
3531 case JOB_NOTIFY_TYPE:
3533 count = print_queue_status(p->msg_ctx, snum, &queue,
3536 for (j=0; j<count; j++) {
3537 construct_notify_jobs_info(p->msg_ctx,
3551 * Debugging information, don't delete.
3554 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3555 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3556 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3558 for (i=0; i<info->count; i++) {
3559 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3560 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3561 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3565 talloc_free(pinfo2);
3569 /****************************************************************
3570 _spoolss_RouterRefreshPrinterChangeNotify
3571 ****************************************************************/
3573 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3574 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3576 struct spoolss_NotifyInfo *info;
3578 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
3579 WERROR result = WERR_BADFID;
3581 /* we always have a spoolss_NotifyInfo struct */
3582 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3584 result = WERR_NOMEM;
3588 *r->out.info = info;
3591 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3592 "Invalid handle (%s:%u:%u).\n",
3593 OUR_HANDLE(r->in.handle)));
3597 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3600 * We are now using the change value, and
3601 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3602 * I don't have a global notification system, I'm sending back all the
3603 * informations even when _NOTHING_ has changed.
3606 /* We need to keep track of the change value to send back in
3607 RRPCN replies otherwise our updates are ignored. */
3609 Printer->notify.fnpcn = true;
3611 if (Printer->notify.client_connected) {
3612 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3613 "Saving change value in request [%x]\n",
3615 Printer->notify.change = r->in.change_low;
3618 /* just ignore the spoolss_NotifyOption */
3620 switch (Printer->printer_type) {
3622 result = printserver_notify_info(p, r->in.handle,
3626 case SPLHND_PRINTER:
3627 result = printer_notify_info(p, r->in.handle,
3632 Printer->notify.fnpcn = false;
3638 /********************************************************************
3639 * construct_printer_info_0
3640 * fill a printer_info_0 struct
3641 ********************************************************************/
3643 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3644 const struct auth_serversupplied_info *server_info,
3645 struct messaging_context *msg_ctx,
3646 struct spoolss_PrinterInfo2 *info2,
3647 struct spoolss_PrinterInfo0 *r,
3651 struct printer_session_counter *session_counter;
3652 struct timeval setuptime;
3653 print_status_struct status;
3655 r->printername = talloc_strdup(mem_ctx, info2->printername);
3656 W_ERROR_HAVE_NO_MEMORY(r->printername);
3658 r->servername = talloc_strdup(mem_ctx, info2->servername);
3659 W_ERROR_HAVE_NO_MEMORY(r->servername);
3661 count = print_queue_length(msg_ctx, snum, &status);
3663 /* check if we already have a counter for this printer */
3664 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3665 if (session_counter->snum == snum)
3669 /* it's the first time, add it to the list */
3670 if (session_counter == NULL) {
3671 session_counter = talloc_zero(counter_list, struct printer_session_counter);
3672 W_ERROR_HAVE_NO_MEMORY(session_counter);
3673 session_counter->snum = snum;
3674 session_counter->counter = 0;
3675 DLIST_ADD(counter_list, session_counter);
3679 session_counter->counter++;
3685 get_startup_time(&setuptime);
3686 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3689 * the global_counter should be stored in a TDB as it's common to all the clients
3690 * and should be zeroed on samba startup
3692 r->global_counter = session_counter->counter;
3694 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3695 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3696 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3697 r->free_build = SPOOLSS_RELEASE_BUILD;
3699 r->max_spooling = 0;
3700 r->session_counter = session_counter->counter;
3701 r->num_error_out_of_paper = 0x0;
3702 r->num_error_not_ready = 0x0; /* number of print failure */
3704 r->number_of_processors = 0x1;
3705 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3706 r->high_part_total_bytes = 0x0;
3708 /* ChangeID in milliseconds*/
3709 winreg_printer_get_changeid(mem_ctx, server_info, msg_ctx,
3710 info2->sharename, &r->change_id);
3712 r->last_error = WERR_OK;
3713 r->status = nt_printq_status(status.status);
3714 r->enumerate_network_printers = 0x0;
3715 r->c_setprinter = 0x0;
3716 r->processor_architecture = PROCESSOR_ARCHITECTURE_INTEL;
3717 r->processor_level = 0x6; /* 6 ???*/
3726 /********************************************************************
3727 * construct_printer_info1
3728 * fill a spoolss_PrinterInfo1 struct
3729 ********************************************************************/
3731 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3732 const struct spoolss_PrinterInfo2 *info2,
3734 struct spoolss_PrinterInfo1 *r,
3739 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3743 W_ERROR_HAVE_NO_MEMORY(r->description);
3745 if (info2->comment == NULL || info2->comment[0] == '\0') {
3746 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3748 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3750 W_ERROR_HAVE_NO_MEMORY(r->comment);
3752 r->name = talloc_strdup(mem_ctx, info2->printername);
3753 W_ERROR_HAVE_NO_MEMORY(r->name);
3758 /********************************************************************
3759 * construct_printer_info2
3760 * fill a spoolss_PrinterInfo2 struct
3761 ********************************************************************/
3763 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3764 struct messaging_context *msg_ctx,
3765 const struct spoolss_PrinterInfo2 *info2,
3766 struct spoolss_PrinterInfo2 *r,
3770 print_status_struct status;
3772 count = print_queue_length(msg_ctx, snum, &status);
3774 r->servername = talloc_strdup(mem_ctx, info2->servername);
3775 W_ERROR_HAVE_NO_MEMORY(r->servername);
3776 r->printername = talloc_strdup(mem_ctx, info2->printername);
3777 W_ERROR_HAVE_NO_MEMORY(r->printername);
3778 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3779 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3780 r->portname = talloc_strdup(mem_ctx, info2->portname);
3781 W_ERROR_HAVE_NO_MEMORY(r->portname);
3782 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3783 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3785 if (info2->comment[0] == '\0') {
3786 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3788 r->comment = talloc_strdup(mem_ctx, info2->comment);
3790 W_ERROR_HAVE_NO_MEMORY(r->comment);
3792 r->location = talloc_strdup(mem_ctx, info2->location);
3793 W_ERROR_HAVE_NO_MEMORY(r->location);
3794 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3795 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3796 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3797 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3798 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3799 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3800 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3801 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3803 r->attributes = info2->attributes;
3805 r->priority = info2->priority;
3806 r->defaultpriority = info2->defaultpriority;
3807 r->starttime = info2->starttime;
3808 r->untiltime = info2->untiltime;
3809 r->status = nt_printq_status(status.status);
3811 r->averageppm = info2->averageppm;
3813 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3815 DEBUG(8,("Returning NULL Devicemode!\n"));
3820 if (info2->secdesc != NULL) {
3821 /* don't use talloc_steal() here unless you do a deep steal of all
3822 the SEC_DESC members */
3824 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3830 /********************************************************************
3831 * construct_printer_info3
3832 * fill a spoolss_PrinterInfo3 struct
3833 ********************************************************************/
3835 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3836 const struct spoolss_PrinterInfo2 *info2,
3837 struct spoolss_PrinterInfo3 *r,
3840 /* These are the components of the SD we are returning. */
3842 if (info2->secdesc != NULL) {
3843 /* don't use talloc_steal() here unless you do a deep steal of all
3844 the SEC_DESC members */
3846 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3847 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3853 /********************************************************************
3854 * construct_printer_info4
3855 * fill a spoolss_PrinterInfo4 struct
3856 ********************************************************************/
3858 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3859 const struct spoolss_PrinterInfo2 *info2,
3860 struct spoolss_PrinterInfo4 *r,
3863 r->printername = talloc_strdup(mem_ctx, info2->printername);
3864 W_ERROR_HAVE_NO_MEMORY(r->printername);
3865 r->servername = talloc_strdup(mem_ctx, info2->servername);
3866 W_ERROR_HAVE_NO_MEMORY(r->servername);
3868 r->attributes = info2->attributes;
3873 /********************************************************************
3874 * construct_printer_info5
3875 * fill a spoolss_PrinterInfo5 struct
3876 ********************************************************************/
3878 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3879 const struct spoolss_PrinterInfo2 *info2,
3880 struct spoolss_PrinterInfo5 *r,
3883 r->printername = talloc_strdup(mem_ctx, info2->printername);
3884 W_ERROR_HAVE_NO_MEMORY(r->printername);
3885 r->portname = talloc_strdup(mem_ctx, info2->portname);
3886 W_ERROR_HAVE_NO_MEMORY(r->portname);
3888 r->attributes = info2->attributes;
3890 /* these two are not used by NT+ according to MSDN */
3891 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3892 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3897 /********************************************************************
3898 * construct_printer_info_6
3899 * fill a spoolss_PrinterInfo6 struct
3900 ********************************************************************/
3902 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3903 struct messaging_context *msg_ctx,
3904 const struct spoolss_PrinterInfo2 *info2,
3905 struct spoolss_PrinterInfo6 *r,
3909 print_status_struct status;
3911 count = print_queue_length(msg_ctx, snum, &status);
3913 r->status = nt_printq_status(status.status);
3918 /********************************************************************
3919 * construct_printer_info7
3920 * fill a spoolss_PrinterInfo7 struct
3921 ********************************************************************/
3923 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3924 struct messaging_context *msg_ctx,
3925 struct printer_handle *print_hnd,
3926 struct spoolss_PrinterInfo7 *r,
3929 struct auth_serversupplied_info *server_info;
3933 status = make_server_info_system(mem_ctx, &server_info);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 DEBUG(0, ("construct_printer_info7: "
3936 "Could not create system server_info\n"));
3940 if (is_printer_published(mem_ctx, server_info, msg_ctx,
3941 print_hnd->servername,
3942 lp_servicename(snum), &guid, NULL)) {
3943 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3944 r->action = DSPRINT_PUBLISH;
3946 r->guid = talloc_strdup(mem_ctx, "");
3947 r->action = DSPRINT_UNPUBLISH;
3949 W_ERROR_HAVE_NO_MEMORY(r->guid);
3951 TALLOC_FREE(server_info);
3955 /********************************************************************
3956 * construct_printer_info8
3957 * fill a spoolss_PrinterInfo8 struct
3958 ********************************************************************/
3960 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3961 const struct spoolss_PrinterInfo2 *info2,
3962 struct spoolss_DeviceModeInfo *r,
3965 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3967 DEBUG(8,("Returning NULL Devicemode!\n"));
3974 /********************************************************************
3975 ********************************************************************/
3977 static bool snum_is_shared_printer(int snum)
3979 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3982 /********************************************************************
3983 Spoolss_enumprinters.
3984 ********************************************************************/
3986 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3987 const struct auth_serversupplied_info *server_info,
3988 struct messaging_context *msg_ctx,
3991 union spoolss_PrinterInfo **info_p,
3995 int n_services = lp_numservices();
3996 union spoolss_PrinterInfo *info = NULL;
3998 WERROR result = WERR_OK;
4003 for (snum = 0; snum < n_services; snum++) {
4005 const char *printer;
4006 struct spoolss_PrinterInfo2 *info2;
4008 if (!snum_is_shared_printer(snum)) {
4012 printer = lp_const_servicename(snum);
4014 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4017 result = winreg_create_printer(mem_ctx,
4022 if (!W_ERROR_IS_OK(result)) {
4026 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4027 union spoolss_PrinterInfo,
4030 result = WERR_NOMEM;
4034 result = winreg_get_printer(mem_ctx, server_info, msg_ctx,
4035 NULL, printer, &info2);
4036 if (!W_ERROR_IS_OK(result)) {
4042 result = construct_printer_info0(info, server_info,
4044 &info[count].info0, snum);
4047 result = construct_printer_info1(info, info2, flags,
4048 &info[count].info1, snum);
4051 result = construct_printer_info2(info, msg_ctx, info2,
4052 &info[count].info2, snum);
4055 result = construct_printer_info4(info, info2,
4056 &info[count].info4, snum);
4059 result = construct_printer_info5(info, info2,
4060 &info[count].info5, snum);
4064 result = WERR_UNKNOWN_LEVEL;
4068 if (!W_ERROR_IS_OK(result)) {
4079 if (!W_ERROR_IS_OK(result)) {
4089 /********************************************************************
4090 * handle enumeration of printers at level 0
4091 ********************************************************************/
4093 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4094 const struct auth_serversupplied_info *server_info,
4095 struct messaging_context *msg_ctx,
4097 const char *servername,
4098 union spoolss_PrinterInfo **info,
4101 DEBUG(4,("enum_all_printers_info_0\n"));
4103 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4104 0, flags, info, count);
4108 /********************************************************************
4109 ********************************************************************/
4111 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4112 const struct auth_serversupplied_info *server_info,
4113 struct messaging_context *msg_ctx,
4115 union spoolss_PrinterInfo **info,
4118 DEBUG(4,("enum_all_printers_info_1\n"));
4120 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4121 1, flags, info, count);
4124 /********************************************************************
4125 enum_all_printers_info_1_local.
4126 *********************************************************************/
4128 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4129 const struct auth_serversupplied_info *server_info,
4130 struct messaging_context *msg_ctx,
4131 union spoolss_PrinterInfo **info,
4134 DEBUG(4,("enum_all_printers_info_1_local\n"));
4136 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4137 PRINTER_ENUM_ICON8, info, count);
4140 /********************************************************************
4141 enum_all_printers_info_1_name.
4142 *********************************************************************/
4144 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4145 const struct auth_serversupplied_info *server_info,
4146 struct messaging_context *msg_ctx,
4148 union spoolss_PrinterInfo **info,
4151 const char *s = name;
4153 DEBUG(4,("enum_all_printers_info_1_name\n"));
4155 if ((name[0] == '\\') && (name[1] == '\\')) {
4159 if (!is_myname_or_ipaddr(s)) {
4160 return WERR_INVALID_NAME;
4163 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4164 PRINTER_ENUM_ICON8, info, count);
4167 /********************************************************************
4168 enum_all_printers_info_1_network.
4169 *********************************************************************/
4171 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4172 const struct auth_serversupplied_info *server_info,
4173 struct messaging_context *msg_ctx,
4175 union spoolss_PrinterInfo **info,
4178 const char *s = name;
4180 DEBUG(4,("enum_all_printers_info_1_network\n"));
4182 /* If we respond to a enum_printers level 1 on our name with flags
4183 set to PRINTER_ENUM_REMOTE with a list of printers then these
4184 printers incorrectly appear in the APW browse list.
4185 Specifically the printers for the server appear at the workgroup
4186 level where all the other servers in the domain are
4187 listed. Windows responds to this call with a
4188 WERR_CAN_NOT_COMPLETE so we should do the same. */
4190 if (name[0] == '\\' && name[1] == '\\') {
4194 if (is_myname_or_ipaddr(s)) {
4195 return WERR_CAN_NOT_COMPLETE;
4198 return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
4199 PRINTER_ENUM_NAME, info, count);
4202 /********************************************************************
4203 * api_spoolss_enumprinters
4205 * called from api_spoolss_enumprinters (see this to understand)
4206 ********************************************************************/
4208 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4209 const struct auth_serversupplied_info *server_info,
4210 struct messaging_context *msg_ctx,
4211 union spoolss_PrinterInfo **info,
4214 DEBUG(4,("enum_all_printers_info_2\n"));
4216 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4220 /********************************************************************
4221 * handle enumeration of printers at level 1
4222 ********************************************************************/
4224 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4225 const struct auth_serversupplied_info *server_info,
4226 struct messaging_context *msg_ctx,
4229 union spoolss_PrinterInfo **info,
4232 /* Not all the flags are equals */
4234 if (flags & PRINTER_ENUM_LOCAL) {
4235 return enum_all_printers_info_1_local(mem_ctx, server_info,
4236 msg_ctx, info, count);
4239 if (flags & PRINTER_ENUM_NAME) {
4240 return enum_all_printers_info_1_name(mem_ctx, server_info,
4241 msg_ctx, name, info,
4245 if (flags & PRINTER_ENUM_NETWORK) {
4246 return enum_all_printers_info_1_network(mem_ctx, server_info,
4247 msg_ctx, name, info,
4251 return WERR_OK; /* NT4sp5 does that */
4254 /********************************************************************
4255 * handle enumeration of printers at level 2
4256 ********************************************************************/
4258 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4259 const struct auth_serversupplied_info *server_info,
4260 struct messaging_context *msg_ctx,
4262 const char *servername,
4263 union spoolss_PrinterInfo **info,
4266 if (flags & PRINTER_ENUM_LOCAL) {
4267 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4271 if (flags & PRINTER_ENUM_NAME) {
4272 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4273 return WERR_INVALID_NAME;
4276 return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
4280 if (flags & PRINTER_ENUM_REMOTE) {
4281 return WERR_UNKNOWN_LEVEL;
4287 /********************************************************************
4288 * handle enumeration of printers at level 4
4289 ********************************************************************/
4291 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4292 const struct auth_serversupplied_info *server_info,
4293 struct messaging_context *msg_ctx,
4295 const char *servername,
4296 union spoolss_PrinterInfo **info,
4299 DEBUG(4,("enum_all_printers_info_4\n"));
4301 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4302 4, flags, info, count);
4306 /********************************************************************
4307 * handle enumeration of printers at level 5
4308 ********************************************************************/
4310 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4311 const struct auth_serversupplied_info *server_info,
4312 struct messaging_context *msg_ctx,
4314 const char *servername,
4315 union spoolss_PrinterInfo **info,
4318 DEBUG(4,("enum_all_printers_info_5\n"));
4320 return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
4321 5, flags, info, count);
4324 /****************************************************************
4325 _spoolss_EnumPrinters
4326 ****************************************************************/
4328 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4329 struct spoolss_EnumPrinters *r)
4331 const struct auth_serversupplied_info *server_info = get_server_info_system();
4332 const char *name = NULL;
4335 /* that's an [in out] buffer */
4337 if (!r->in.buffer && (r->in.offered != 0)) {
4338 return WERR_INVALID_PARAM;
4341 DEBUG(4,("_spoolss_EnumPrinters\n"));
4345 *r->out.info = NULL;
4349 * flags==PRINTER_ENUM_NAME
4350 * if name=="" then enumerates all printers
4351 * if name!="" then enumerate the printer
4352 * flags==PRINTER_ENUM_REMOTE
4353 * name is NULL, enumerate printers
4354 * Level 2: name!="" enumerates printers, name can't be NULL
4355 * Level 3: doesn't exist
4356 * Level 4: does a local registry lookup
4357 * Level 5: same as Level 2
4361 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4362 W_ERROR_HAVE_NO_MEMORY(name);
4365 switch (r->in.level) {
4367 result = enumprinters_level0(p->mem_ctx, server_info,
4368 p->msg_ctx, r->in.flags, name,
4369 r->out.info, r->out.count);
4372 result = enumprinters_level1(p->mem_ctx, server_info,
4373 p->msg_ctx, r->in.flags, name,
4374 r->out.info, r->out.count);
4377 result = enumprinters_level2(p->mem_ctx, server_info,
4378 p->msg_ctx, r->in.flags, name,
4379 r->out.info, r->out.count);
4382 result = enumprinters_level4(p->mem_ctx, server_info,
4383 p->msg_ctx, r->in.flags, name,
4384 r->out.info, r->out.count);
4387 result = enumprinters_level5(p->mem_ctx, server_info,
4388 p->msg_ctx, r->in.flags, name,
4389 r->out.info, r->out.count);
4392 return WERR_UNKNOWN_LEVEL;
4395 if (!W_ERROR_IS_OK(result)) {
4399 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4400 spoolss_EnumPrinters,
4401 *r->out.info, r->in.level,
4403 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4404 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4406 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4409 /****************************************************************
4411 ****************************************************************/
4413 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4414 struct spoolss_GetPrinter *r)
4416 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
4417 struct spoolss_PrinterInfo2 *info2 = NULL;
4418 WERROR result = WERR_OK;
4419 const char *servername = NULL;
4422 /* that's an [in out] buffer */
4424 if (!r->in.buffer && (r->in.offered != 0)) {
4425 return WERR_INVALID_PARAM;
4430 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4434 if (Printer != NULL || Printer->servername != NULL) {
4435 servername = Printer->servername;
4438 result = winreg_get_printer(p->mem_ctx,
4439 get_server_info_system(),
4442 lp_const_servicename(snum),
4444 if (!W_ERROR_IS_OK(result)) {
4448 switch (r->in.level) {
4450 result = construct_printer_info0(p->mem_ctx,
4451 get_server_info_system(),
4454 &r->out.info->info0,
4458 result = construct_printer_info1(p->mem_ctx, info2,
4460 &r->out.info->info1, snum);
4463 result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
4464 &r->out.info->info2, snum);
4467 result = construct_printer_info3(p->mem_ctx, info2,
4468 &r->out.info->info3, snum);
4471 result = construct_printer_info4(p->mem_ctx, info2,
4472 &r->out.info->info4, snum);
4475 result = construct_printer_info5(p->mem_ctx, info2,
4476 &r->out.info->info5, snum);
4479 result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
4480 &r->out.info->info6, snum);
4483 result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
4485 &r->out.info->info7, snum);
4488 result = construct_printer_info8(p->mem_ctx, info2,
4489 &r->out.info->info8, snum);
4492 result = WERR_UNKNOWN_LEVEL;
4496 if (!W_ERROR_IS_OK(result)) {
4497 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4498 r->in.level, win_errstr(result)));
4499 TALLOC_FREE(r->out.info);
4503 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4504 r->out.info, r->in.level);
4505 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4507 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4510 /********************************************************************
4511 ********************************************************************/
4513 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4515 if (in && strlen(in)) { \
4516 out = talloc_strdup(mem_ctx, in); \
4518 out = talloc_strdup(mem_ctx, ""); \
4520 W_ERROR_HAVE_NO_MEMORY(out); \
4523 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4525 if (in && strlen(in)) { \
4526 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4528 out = talloc_strdup(mem_ctx, ""); \
4530 W_ERROR_HAVE_NO_MEMORY(out); \
4533 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4534 const char **string_array,
4535 const char ***presult,
4536 const char *cservername,
4540 int i, num_strings = 0;
4541 const char **array = NULL;
4543 if (string_array == NULL) {
4544 return WERR_INVALID_PARAMETER;;
4547 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4548 const char *str = NULL;
4550 if (cservername == NULL || arch == NULL) {
4551 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4553 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4556 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4563 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4564 &array, &num_strings);
4574 /********************************************************************
4575 * fill a spoolss_DriverInfo1 struct
4576 ********************************************************************/
4578 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4579 struct spoolss_DriverInfo1 *r,
4580 const struct spoolss_DriverInfo8 *driver,
4581 const char *servername)
4583 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4584 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4589 /********************************************************************
4590 * fill a spoolss_DriverInfo2 struct
4591 ********************************************************************/
4593 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4594 struct spoolss_DriverInfo2 *r,
4595 const struct spoolss_DriverInfo8 *driver,
4596 const char *servername)
4599 const char *cservername = canon_servername(servername);
4601 r->version = driver->version;
4603 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4604 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4605 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4606 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4608 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4609 driver->architecture,
4611 driver->driver_path,
4614 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4615 driver->architecture,
4620 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4621 driver->architecture,
4623 driver->config_file,
4629 /********************************************************************
4630 * fill a spoolss_DriverInfo3 struct
4631 ********************************************************************/
4633 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4634 struct spoolss_DriverInfo3 *r,
4635 const struct spoolss_DriverInfo8 *driver,
4636 const char *servername)
4638 const char *cservername = canon_servername(servername);
4640 r->version = driver->version;
4642 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4643 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4644 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4645 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4647 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4648 driver->architecture,
4650 driver->driver_path,
4653 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4654 driver->architecture,
4659 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4660 driver->architecture,
4662 driver->config_file,
4665 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4666 driver->architecture,
4671 FILL_DRIVER_STRING(mem_ctx,
4672 driver->monitor_name,
4675 FILL_DRIVER_STRING(mem_ctx,
4676 driver->default_datatype,
4677 r->default_datatype);
4679 return string_array_from_driver_info(mem_ctx,
4680 driver->dependent_files,
4681 &r->dependent_files,
4683 driver->architecture,
4687 /********************************************************************
4688 * fill a spoolss_DriverInfo4 struct
4689 ********************************************************************/
4691 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4692 struct spoolss_DriverInfo4 *r,
4693 const struct spoolss_DriverInfo8 *driver,
4694 const char *servername)
4696 const char *cservername = canon_servername(servername);
4699 r->version = driver->version;
4701 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4702 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4703 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4704 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4706 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4707 driver->architecture,
4709 driver->driver_path,
4712 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4713 driver->architecture,
4718 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4719 driver->architecture,
4721 driver->config_file,
4724 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4725 driver->architecture,
4730 result = string_array_from_driver_info(mem_ctx,
4731 driver->dependent_files,
4732 &r->dependent_files,
4734 driver->architecture,
4736 if (!W_ERROR_IS_OK(result)) {
4740 FILL_DRIVER_STRING(mem_ctx,
4741 driver->monitor_name,
4744 FILL_DRIVER_STRING(mem_ctx,
4745 driver->default_datatype,
4746 r->default_datatype);
4749 result = string_array_from_driver_info(mem_ctx,
4750 driver->previous_names,
4757 /********************************************************************
4758 * fill a spoolss_DriverInfo5 struct
4759 ********************************************************************/
4761 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4762 struct spoolss_DriverInfo5 *r,
4763 const struct spoolss_DriverInfo8 *driver,
4764 const char *servername)
4766 const char *cservername = canon_servername(servername);
4768 r->version = driver->version;
4770 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4771 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4772 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4773 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4775 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4776 driver->architecture,
4778 driver->driver_path,
4781 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4782 driver->architecture,
4787 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4788 driver->architecture,
4790 driver->config_file,
4793 r->driver_attributes = 0;
4794 r->config_version = 0;
4795 r->driver_version = 0;
4799 /********************************************************************
4800 * fill a spoolss_DriverInfo6 struct
4801 ********************************************************************/
4803 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4804 struct spoolss_DriverInfo6 *r,
4805 const struct spoolss_DriverInfo8 *driver,
4806 const char *servername)
4808 const char *cservername = canon_servername(servername);
4811 r->version = driver->version;
4813 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4814 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4815 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4816 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4818 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4819 driver->architecture,
4821 driver->driver_path,
4824 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4825 driver->architecture,
4830 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4831 driver->architecture,
4833 driver->config_file,
4836 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4837 driver->architecture,
4842 FILL_DRIVER_STRING(mem_ctx,
4843 driver->monitor_name,
4846 FILL_DRIVER_STRING(mem_ctx,
4847 driver->default_datatype,
4848 r->default_datatype);
4850 result = string_array_from_driver_info(mem_ctx,
4851 driver->dependent_files,
4852 &r->dependent_files,
4854 driver->architecture,
4856 if (!W_ERROR_IS_OK(result)) {
4860 result = string_array_from_driver_info(mem_ctx,
4861 driver->previous_names,
4864 if (!W_ERROR_IS_OK(result)) {
4868 r->driver_date = driver->driver_date;
4869 r->driver_version = driver->driver_version;
4871 FILL_DRIVER_STRING(mem_ctx,
4872 driver->manufacturer_name,
4873 r->manufacturer_name);
4874 FILL_DRIVER_STRING(mem_ctx,
4875 driver->manufacturer_url,
4876 r->manufacturer_url);
4877 FILL_DRIVER_STRING(mem_ctx,
4878 driver->hardware_id,
4880 FILL_DRIVER_STRING(mem_ctx,
4887 /********************************************************************
4888 * fill a spoolss_DriverInfo8 struct
4889 ********************************************************************/
4891 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4892 struct spoolss_DriverInfo8 *r,
4893 const struct spoolss_DriverInfo8 *driver,
4894 const char *servername)
4896 const char *cservername = canon_servername(servername);
4899 r->version = driver->version;
4901 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4902 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4903 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4904 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4906 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4907 driver->architecture,
4909 driver->driver_path,
4912 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4913 driver->architecture,
4918 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4919 driver->architecture,
4921 driver->config_file,
4924 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4925 driver->architecture,
4930 FILL_DRIVER_STRING(mem_ctx,
4931 driver->monitor_name,
4934 FILL_DRIVER_STRING(mem_ctx,
4935 driver->default_datatype,
4936 r->default_datatype);
4938 result = string_array_from_driver_info(mem_ctx,
4939 driver->dependent_files,
4940 &r->dependent_files,
4942 driver->architecture,
4944 if (!W_ERROR_IS_OK(result)) {
4948 result = string_array_from_driver_info(mem_ctx,
4949 driver->previous_names,
4952 if (!W_ERROR_IS_OK(result)) {
4956 r->driver_date = driver->driver_date;
4957 r->driver_version = driver->driver_version;
4959 FILL_DRIVER_STRING(mem_ctx,
4960 driver->manufacturer_name,
4961 r->manufacturer_name);
4962 FILL_DRIVER_STRING(mem_ctx,
4963 driver->manufacturer_url,
4964 r->manufacturer_url);
4965 FILL_DRIVER_STRING(mem_ctx,
4966 driver->hardware_id,
4968 FILL_DRIVER_STRING(mem_ctx,
4972 FILL_DRIVER_STRING(mem_ctx,
4973 driver->print_processor,
4974 r->print_processor);
4975 FILL_DRIVER_STRING(mem_ctx,
4976 driver->vendor_setup,
4979 result = string_array_from_driver_info(mem_ctx,
4980 driver->color_profiles,
4983 if (!W_ERROR_IS_OK(result)) {
4987 FILL_DRIVER_STRING(mem_ctx,
4991 r->printer_driver_attributes = driver->printer_driver_attributes;
4993 result = string_array_from_driver_info(mem_ctx,
4994 driver->core_driver_dependencies,
4995 &r->core_driver_dependencies,
4997 if (!W_ERROR_IS_OK(result)) {
5001 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
5002 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
5007 #if 0 /* disabled until marshalling issues are resolved - gd */
5008 /********************************************************************
5009 ********************************************************************/
5011 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
5012 struct spoolss_DriverFileInfo *r,
5013 const char *cservername,
5014 const char *file_name,
5015 enum spoolss_DriverFileType file_type,
5016 uint32_t file_version)
5018 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
5019 cservername, file_name);
5020 W_ERROR_HAVE_NO_MEMORY(r->file_name);
5021 r->file_type = file_type;
5022 r->file_version = file_version;
5027 /********************************************************************
5028 ********************************************************************/
5030 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
5031 const struct spoolss_DriverInfo8 *driver,
5032 const char *cservername,
5033 struct spoolss_DriverFileInfo **info_p,
5036 struct spoolss_DriverFileInfo *info = NULL;
5044 if (strlen(driver->driver_path)) {
5045 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5046 struct spoolss_DriverFileInfo,
5048 W_ERROR_HAVE_NO_MEMORY(info);
5049 result = fill_spoolss_DriverFileInfo(info,
5052 driver->driver_path,
5053 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
5055 W_ERROR_NOT_OK_RETURN(result);
5059 if (strlen(driver->config_file)) {
5060 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5061 struct spoolss_DriverFileInfo,
5063 W_ERROR_HAVE_NO_MEMORY(info);
5064 result = fill_spoolss_DriverFileInfo(info,
5067 driver->config_file,
5068 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
5070 W_ERROR_NOT_OK_RETURN(result);
5074 if (strlen(driver->data_file)) {
5075 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5076 struct spoolss_DriverFileInfo,
5078 W_ERROR_HAVE_NO_MEMORY(info);
5079 result = fill_spoolss_DriverFileInfo(info,
5083 SPOOLSS_DRIVER_FILE_TYPE_DATA,
5085 W_ERROR_NOT_OK_RETURN(result);
5089 if (strlen(driver->help_file)) {
5090 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5091 struct spoolss_DriverFileInfo,
5093 W_ERROR_HAVE_NO_MEMORY(info);
5094 result = fill_spoolss_DriverFileInfo(info,
5098 SPOOLSS_DRIVER_FILE_TYPE_HELP,
5100 W_ERROR_NOT_OK_RETURN(result);
5104 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
5105 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5106 struct spoolss_DriverFileInfo,
5108 W_ERROR_HAVE_NO_MEMORY(info);
5109 result = fill_spoolss_DriverFileInfo(info,
5112 driver->dependent_files[i],
5113 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
5115 W_ERROR_NOT_OK_RETURN(result);
5125 /********************************************************************
5126 * fill a spoolss_DriverInfo101 struct
5127 ********************************************************************/
5129 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
5130 struct spoolss_DriverInfo101 *r,
5131 const struct spoolss_DriverInfo8 *driver,
5132 const char *servername)
5134 const char *cservername = canon_servername(servername);
5137 r->version = driver->version;
5139 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5140 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5141 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5142 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5144 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5148 if (!W_ERROR_IS_OK(result)) {
5152 FILL_DRIVER_STRING(mem_ctx,
5153 driver->monitor_name,
5156 FILL_DRIVER_STRING(mem_ctx,
5157 driver->default_datatype,
5158 r->default_datatype);
5160 result = string_array_from_driver_info(mem_ctx,
5161 driver->previous_names,
5164 if (!W_ERROR_IS_OK(result)) {
5168 r->driver_date = driver->driver_date;
5169 r->driver_version = driver->driver_version;
5171 FILL_DRIVER_STRING(mem_ctx,
5172 driver->manufacturer_name,
5173 r->manufacturer_name);
5174 FILL_DRIVER_STRING(mem_ctx,
5175 driver->manufacturer_url,
5176 r->manufacturer_url);
5177 FILL_DRIVER_STRING(mem_ctx,
5178 driver->hardware_id,
5180 FILL_DRIVER_STRING(mem_ctx,
5187 /********************************************************************
5188 ********************************************************************/
5190 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5191 const struct auth_serversupplied_info *server_info,
5192 struct messaging_context *msg_ctx,
5194 union spoolss_DriverInfo *r,
5196 const char *servername,
5197 const char *architecture,
5200 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5201 struct spoolss_DriverInfo8 *driver;
5204 result = winreg_get_printer(mem_ctx,
5208 lp_const_servicename(snum),
5211 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5212 win_errstr(result)));
5214 if (!W_ERROR_IS_OK(result)) {
5215 return WERR_INVALID_PRINTER_NAME;
5218 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5220 pinfo2->drivername, version, &driver);
5222 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5223 win_errstr(result)));
5225 if (!W_ERROR_IS_OK(result)) {
5227 * Is this a W2k client ?
5231 talloc_free(pinfo2);
5232 return WERR_UNKNOWN_PRINTER_DRIVER;
5235 /* Yes - try again with a WinNT driver. */
5237 result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
5241 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5242 win_errstr(result)));
5243 if (!W_ERROR_IS_OK(result)) {
5244 talloc_free(pinfo2);
5245 return WERR_UNKNOWN_PRINTER_DRIVER;
5251 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5254 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5257 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5260 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5263 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5266 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5269 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5271 #if 0 /* disabled until marshalling issues are resolved - gd */
5273 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5277 result = WERR_UNKNOWN_LEVEL;
5281 talloc_free(pinfo2);
5282 talloc_free(driver);
5287 /****************************************************************
5288 _spoolss_GetPrinterDriver2
5289 ****************************************************************/
5291 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5292 struct spoolss_GetPrinterDriver2 *r)
5294 struct printer_handle *printer;
5299 /* that's an [in out] buffer */
5301 if (!r->in.buffer && (r->in.offered != 0)) {
5302 return WERR_INVALID_PARAM;
5305 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5307 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5308 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5309 return WERR_INVALID_PRINTER_NAME;
5313 *r->out.server_major_version = 0;
5314 *r->out.server_minor_version = 0;
5316 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5320 result = construct_printer_driver_info_level(p->mem_ctx,
5321 get_server_info_system(),
5323 r->in.level, r->out.info,
5324 snum, printer->servername,
5326 r->in.client_major_version);
5327 if (!W_ERROR_IS_OK(result)) {
5328 TALLOC_FREE(r->out.info);
5332 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5333 r->out.info, r->in.level);
5334 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5336 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5340 /****************************************************************
5341 _spoolss_StartPagePrinter
5342 ****************************************************************/
5344 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5345 struct spoolss_StartPagePrinter *r)
5347 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5350 DEBUG(3,("_spoolss_StartPagePrinter: "
5351 "Error in startpageprinter printer handle\n"));
5355 Printer->page_started = true;
5359 /****************************************************************
5360 _spoolss_EndPagePrinter
5361 ****************************************************************/
5363 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5364 struct spoolss_EndPagePrinter *r)
5368 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5371 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5372 OUR_HANDLE(r->in.handle)));
5376 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5379 Printer->page_started = false;
5380 print_job_endpage(p->msg_ctx, snum, Printer->jobid);
5385 /****************************************************************
5386 _spoolss_StartDocPrinter
5387 ****************************************************************/
5389 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5390 struct spoolss_StartDocPrinter *r)
5392 struct spoolss_DocumentInfo1 *info_1;
5394 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5398 DEBUG(2,("_spoolss_StartDocPrinter: "
5399 "Invalid handle (%s:%u:%u)\n",
5400 OUR_HANDLE(r->in.handle)));
5404 if (Printer->jobid) {
5405 DEBUG(2, ("_spoolss_StartDocPrinter: "
5406 "StartDocPrinter called twice! "
5407 "(existing jobid = %d)\n", Printer->jobid));
5408 return WERR_INVALID_HANDLE;
5411 if (r->in.level != 1) {
5412 return WERR_UNKNOWN_LEVEL;
5415 info_1 = r->in.info.info1;
5418 * a nice thing with NT is it doesn't listen to what you tell it.
5419 * when asked to send _only_ RAW datas, it tries to send datas
5422 * So I add checks like in NT Server ...
5425 if (info_1->datatype) {
5426 if (strcmp(info_1->datatype, "RAW") != 0) {
5428 return WERR_INVALID_DATATYPE;
5432 /* get the share number of the printer */
5433 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5437 werr = print_job_start(get_server_info_system(),
5441 info_1->document_name,
5442 info_1->output_file,
5446 /* An error occured in print_job_start() so return an appropriate
5449 if (!W_ERROR_IS_OK(werr)) {
5453 Printer->document_started = true;
5454 *r->out.job_id = Printer->jobid;
5459 /****************************************************************
5460 _spoolss_EndDocPrinter
5461 ****************************************************************/
5463 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5464 struct spoolss_EndDocPrinter *r)
5466 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5471 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5472 OUR_HANDLE(r->in.handle)));
5476 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5480 Printer->document_started = false;
5481 status = print_job_end(p->msg_ctx, snum, Printer->jobid, NORMAL_CLOSE);
5482 if (!NT_STATUS_IS_OK(status)) {
5483 DEBUG(2, ("_spoolss_EndDocPrinter: "
5484 "print_job_end failed [%s]\n",
5485 nt_errstr(status)));
5489 return ntstatus_to_werror(status);
5492 /****************************************************************
5493 _spoolss_WritePrinter
5494 ****************************************************************/
5496 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5497 struct spoolss_WritePrinter *r)
5499 ssize_t buffer_written;
5501 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5504 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5505 OUR_HANDLE(r->in.handle)));
5506 *r->out.num_written = r->in._data_size;
5510 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5513 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5514 buffer_written = print_job_write(server_event_context(),p->msg_ctx,
5515 snum, Printer->jobid,
5516 (const char *)r->in.data.data,
5517 (size_t)r->in._data_size);
5518 if (buffer_written == (ssize_t)-1) {
5519 *r->out.num_written = 0;
5520 if (errno == ENOSPC)
5521 return WERR_NO_SPOOL_SPACE;
5523 return WERR_ACCESS_DENIED;
5526 *r->out.num_written = r->in._data_size;
5531 /********************************************************************
5532 * api_spoolss_getprinter
5533 * called from the spoolss dispatcher
5535 ********************************************************************/
5537 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5538 struct pipes_struct *p)
5540 const struct auth_serversupplied_info *server_info = get_server_info_system();
5542 WERROR errcode = WERR_BADFUNC;
5543 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
5546 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5547 OUR_HANDLE(handle)));
5551 if (!get_printer_snum(p, handle, &snum, NULL))
5555 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5556 errcode = print_queue_pause(server_info, p->msg_ctx, snum);
5558 case SPOOLSS_PRINTER_CONTROL_RESUME:
5559 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5560 errcode = print_queue_resume(server_info, p->msg_ctx, snum);
5562 case SPOOLSS_PRINTER_CONTROL_PURGE:
5563 errcode = print_queue_purge(server_info, p->msg_ctx, snum);
5566 return WERR_UNKNOWN_LEVEL;
5573 /****************************************************************
5574 _spoolss_AbortPrinter
5575 * From MSDN: "Deletes printer's spool file if printer is configured
5577 ****************************************************************/
5579 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5580 struct spoolss_AbortPrinter *r)
5582 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5584 WERROR errcode = WERR_OK;
5587 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5588 OUR_HANDLE(r->in.handle)));
5592 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5595 if (!Printer->document_started) {
5596 return WERR_SPL_NO_STARTDOC;
5599 errcode = print_job_delete(get_server_info_system(),
5607 /********************************************************************
5608 * called by spoolss_api_setprinter
5609 * when updating a printer description
5610 ********************************************************************/
5612 static WERROR update_printer_sec(struct policy_handle *handle,
5613 struct pipes_struct *p,
5614 struct sec_desc_buf *secdesc_ctr)
5616 struct spoolss_security_descriptor *new_secdesc = NULL;
5617 struct spoolss_security_descriptor *old_secdesc = NULL;
5618 const char *printer;
5622 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
5624 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5625 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5626 OUR_HANDLE(handle)));
5628 result = WERR_BADFID;
5632 if (secdesc_ctr == NULL) {
5633 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5634 result = WERR_INVALID_PARAM;
5637 printer = lp_const_servicename(snum);
5639 /* Check the user has permissions to change the security
5640 descriptor. By experimentation with two NT machines, the user
5641 requires Full Access to the printer to change security
5644 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5645 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5646 result = WERR_ACCESS_DENIED;
5650 /* NT seems to like setting the security descriptor even though
5651 nothing may have actually changed. */
5652 result = winreg_get_printer_secdesc(p->mem_ctx,
5653 get_server_info_system(),
5657 if (!W_ERROR_IS_OK(result)) {
5658 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5659 result = WERR_BADFID;
5663 if (DEBUGLEVEL >= 10) {
5664 struct security_acl *the_acl;
5667 the_acl = old_secdesc->dacl;
5668 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5669 printer, the_acl->num_aces));
5671 for (i = 0; i < the_acl->num_aces; i++) {
5672 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5673 &the_acl->aces[i].trustee),
5674 the_acl->aces[i].access_mask));
5677 the_acl = secdesc_ctr->sd->dacl;
5680 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5681 printer, the_acl->num_aces));
5683 for (i = 0; i < the_acl->num_aces; i++) {
5684 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5685 &the_acl->aces[i].trustee),
5686 the_acl->aces[i].access_mask));
5689 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5693 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5694 if (new_secdesc == NULL) {
5695 result = WERR_NOMEM;
5699 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5704 result = winreg_set_printer_secdesc(p->mem_ctx,
5705 get_server_info_system(),
5714 /********************************************************************
5715 Canonicalize printer info from a client
5716 ********************************************************************/
5718 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5719 struct spoolss_SetPrinterInfo2 *info2,
5722 fstring printername;
5725 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5726 "portname=%s drivername=%s comment=%s location=%s\n",
5727 info2->servername, info2->printername, info2->sharename,
5728 info2->portname, info2->drivername, info2->comment,
5731 /* we force some elements to "correct" values */
5732 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5733 if (info2->servername == NULL) {
5736 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5737 if (info2->sharename == NULL) {
5741 /* check to see if we allow printername != sharename */
5742 if (lp_force_printername(snum)) {
5743 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5744 global_myname(), info2->sharename);
5746 /* make sure printername is in \\server\printername format */
5747 fstrcpy(printername, info2->printername);
5749 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5750 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5754 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5755 global_myname(), p);
5757 if (info2->printername == NULL) {
5761 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5762 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5767 /****************************************************************************
5768 ****************************************************************************/
5770 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5772 char *cmd = lp_addport_cmd();
5773 char *command = NULL;
5775 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5776 bool is_print_op = false;
5779 return WERR_ACCESS_DENIED;
5782 command = talloc_asprintf(ctx,
5783 "%s \"%s\" \"%s\"", cmd, portname, uri );
5789 is_print_op = user_has_privileges( token, &se_printop );
5791 DEBUG(10,("Running [%s]\n", command));
5793 /********* BEGIN SePrintOperatorPrivilege **********/
5798 ret = smbrun(command, NULL);
5803 /********* END SePrintOperatorPrivilege **********/
5805 DEBUGADD(10,("returned [%d]\n", ret));
5807 TALLOC_FREE(command);
5810 return WERR_ACCESS_DENIED;
5816 /****************************************************************************
5817 ****************************************************************************/
5819 static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5820 struct spoolss_SetPrinterInfo2 *info2,
5821 const char *remote_machine,
5822 struct messaging_context *msg_ctx)
5824 char *cmd = lp_addprinter_cmd();
5826 char *command = NULL;
5830 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5831 bool is_print_op = false;
5833 if (!remote_machine) {
5837 command = talloc_asprintf(ctx,
5838 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5839 cmd, info2->printername, info2->sharename,
5840 info2->portname, info2->drivername,
5841 info2->location, info2->comment, remote_machine);
5847 is_print_op = user_has_privileges( token, &se_printop );
5849 DEBUG(10,("Running [%s]\n", command));
5851 /********* BEGIN SePrintOperatorPrivilege **********/
5856 if ( (ret = smbrun(command, &fd)) == 0 ) {
5857 /* Tell everyone we updated smb.conf. */
5858 message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5864 /********* END SePrintOperatorPrivilege **********/
5866 DEBUGADD(10,("returned [%d]\n", ret));
5868 TALLOC_FREE(command);
5876 /* reload our services immediately */
5878 reload_services(msg_ctx, -1, false);
5882 /* Get lines and convert them back to dos-codepage */
5883 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5884 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5887 /* Set the portname to what the script says the portname should be. */
5888 /* but don't require anything to be return from the script exit a good error code */
5891 /* Set the portname to what the script says the portname should be. */
5892 info2->portname = talloc_strdup(ctx, qlines[0]);
5893 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5896 TALLOC_FREE(qlines);
5900 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5901 const struct auth_serversupplied_info *server_info,
5902 struct messaging_context *msg_ctx,
5904 struct spoolss_SetPrinterInfo2 *printer,
5905 struct spoolss_PrinterInfo2 *old_printer)
5907 bool force_update = (old_printer == NULL);
5908 const char *dnsdomname;
5909 const char *longname;
5910 const char *uncname;
5911 const char *spooling;
5913 WERROR result = WERR_OK;
5915 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5916 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5917 winreg_set_printer_dataex(mem_ctx,
5921 SPOOL_DSSPOOLER_KEY,
5922 SPOOL_REG_DRIVERNAME,
5927 if (!force_update) {
5928 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5929 printer->drivername));
5931 notify_printer_driver(server_event_context(), msg_ctx,
5932 snum, printer->drivername);
5936 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5937 push_reg_sz(mem_ctx, &buffer, printer->comment);
5938 winreg_set_printer_dataex(mem_ctx,
5942 SPOOL_DSSPOOLER_KEY,
5943 SPOOL_REG_DESCRIPTION,
5948 if (!force_update) {
5949 notify_printer_comment(server_event_context(), msg_ctx,
5950 snum, printer->comment);
5954 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5955 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5956 winreg_set_printer_dataex(mem_ctx,
5960 SPOOL_DSSPOOLER_KEY,
5961 SPOOL_REG_PRINTSHARENAME,
5966 if (!force_update) {
5967 notify_printer_sharename(server_event_context(),
5969 snum, printer->sharename);
5973 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5976 p = strrchr(printer->printername, '\\' );
5980 p = printer->printername;
5983 push_reg_sz(mem_ctx, &buffer, p);
5984 winreg_set_printer_dataex(mem_ctx,
5988 SPOOL_DSSPOOLER_KEY,
5989 SPOOL_REG_PRINTERNAME,
5994 if (!force_update) {
5995 notify_printer_printername(server_event_context(),
6000 if (force_update || !strequal(printer->portname, old_printer->portname)) {
6001 push_reg_sz(mem_ctx, &buffer, printer->portname);
6002 winreg_set_printer_dataex(mem_ctx,
6006 SPOOL_DSSPOOLER_KEY,
6012 if (!force_update) {
6013 notify_printer_port(server_event_context(),
6014 msg_ctx, snum, printer->portname);
6018 if (force_update || !strequal(printer->location, old_printer->location)) {
6019 push_reg_sz(mem_ctx, &buffer, printer->location);
6020 winreg_set_printer_dataex(mem_ctx,
6024 SPOOL_DSSPOOLER_KEY,
6030 if (!force_update) {
6031 notify_printer_location(server_event_context(),
6037 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
6038 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
6039 winreg_set_printer_dataex(mem_ctx,
6043 SPOOL_DSSPOOLER_KEY,
6044 SPOOL_REG_PRINTSEPARATORFILE,
6049 if (!force_update) {
6050 notify_printer_location(server_event_context(),
6056 if (force_update || printer->starttime != old_printer->starttime) {
6057 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6058 SIVAL(buffer.data, 0, printer->starttime);
6059 winreg_set_printer_dataex(mem_ctx,
6063 SPOOL_DSSPOOLER_KEY,
6064 SPOOL_REG_PRINTSTARTTIME,
6070 if (force_update || printer->untiltime != old_printer->untiltime) {
6071 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6072 SIVAL(buffer.data, 0, printer->untiltime);
6073 winreg_set_printer_dataex(mem_ctx,
6077 SPOOL_DSSPOOLER_KEY,
6078 SPOOL_REG_PRINTENDTIME,
6084 if (force_update || printer->priority != old_printer->priority) {
6085 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6086 SIVAL(buffer.data, 0, printer->priority);
6087 winreg_set_printer_dataex(mem_ctx,
6091 SPOOL_DSSPOOLER_KEY,
6098 if (force_update || printer->attributes != old_printer->attributes) {
6099 buffer = data_blob_talloc(mem_ctx, NULL, 4);
6100 SIVAL(buffer.data, 0, (printer->attributes &
6101 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
6102 winreg_set_printer_dataex(mem_ctx,
6106 SPOOL_DSSPOOLER_KEY,
6107 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
6112 switch (printer->attributes & 0x3) {
6114 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
6117 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
6120 spooling = SPOOL_REGVAL_PRINTDIRECT;
6123 spooling = "unknown";
6125 push_reg_sz(mem_ctx, &buffer, spooling);
6126 winreg_set_printer_dataex(mem_ctx,
6130 SPOOL_DSSPOOLER_KEY,
6131 SPOOL_REG_PRINTSPOOLING,
6137 push_reg_sz(mem_ctx, &buffer, global_myname());
6138 winreg_set_printer_dataex(mem_ctx,
6142 SPOOL_DSSPOOLER_KEY,
6143 SPOOL_REG_SHORTSERVERNAME,
6148 dnsdomname = get_mydnsfullname();
6149 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
6150 longname = talloc_strdup(mem_ctx, dnsdomname);
6152 longname = talloc_strdup(mem_ctx, global_myname());
6154 if (longname == NULL) {
6155 result = WERR_NOMEM;
6159 push_reg_sz(mem_ctx, &buffer, longname);
6160 winreg_set_printer_dataex(mem_ctx,
6164 SPOOL_DSSPOOLER_KEY,
6165 SPOOL_REG_SERVERNAME,
6170 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
6171 global_myname(), printer->sharename);
6172 push_reg_sz(mem_ctx, &buffer, uncname);
6173 winreg_set_printer_dataex(mem_ctx,
6177 SPOOL_DSSPOOLER_KEY,
6187 /********************************************************************
6188 * Called by spoolss_api_setprinter
6189 * when updating a printer description.
6190 ********************************************************************/
6192 static WERROR update_printer(struct pipes_struct *p,
6193 struct policy_handle *handle,
6194 struct spoolss_SetPrinterInfoCtr *info_ctr,
6195 struct spoolss_DeviceMode *devmode)
6197 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
6198 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
6199 struct spoolss_PrinterInfo2 *old_printer;
6200 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6201 const char *servername = NULL;
6203 WERROR result = WERR_OK;
6204 TALLOC_CTX *tmp_ctx;
6206 DEBUG(8,("update_printer\n"));
6208 tmp_ctx = talloc_new(p->mem_ctx);
6209 if (tmp_ctx == NULL) {
6214 result = WERR_BADFID;
6218 if (!get_printer_snum(p, handle, &snum, NULL)) {
6219 result = WERR_BADFID;
6223 if (Printer != NULL || Printer->servername != NULL) {
6224 servername = Printer->servername;
6227 result = winreg_get_printer(tmp_ctx,
6228 get_server_info_system(),
6231 lp_const_servicename(snum),
6233 if (!W_ERROR_IS_OK(result)) {
6234 result = WERR_BADFID;
6238 /* Do sanity check on the requested changes for Samba */
6239 if (!check_printer_ok(tmp_ctx, printer, snum)) {
6240 result = WERR_INVALID_PARAM;
6244 /* FIXME!!! If the driver has changed we really should verify that
6245 it is installed before doing much else --jerry */
6247 /* Check calling user has permission to update printer description */
6248 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6249 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6250 result = WERR_ACCESS_DENIED;
6254 /* Call addprinter hook */
6255 /* Check changes to see if this is really needed */
6257 if (*lp_addprinter_cmd() &&
6258 (!strequal(printer->drivername, old_printer->drivername) ||
6259 !strequal(printer->comment, old_printer->comment) ||
6260 !strequal(printer->portname, old_printer->portname) ||
6261 !strequal(printer->location, old_printer->location)) )
6263 /* add_printer_hook() will call reload_services() */
6264 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
6265 printer, p->client_id->addr,
6267 result = WERR_ACCESS_DENIED;
6272 update_dsspooler(tmp_ctx,
6273 get_server_info_system(),
6279 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
6281 if (devmode == NULL) {
6282 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
6284 result = winreg_update_printer(tmp_ctx,
6285 get_server_info_system(),
6294 talloc_free(tmp_ctx);
6299 /****************************************************************************
6300 ****************************************************************************/
6301 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6302 struct policy_handle *handle,
6303 struct spoolss_SetPrinterInfo7 *info7)
6306 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6309 struct printer_handle *Printer;
6311 if ( lp_security() != SEC_ADS ) {
6312 return WERR_UNKNOWN_LEVEL;
6315 Printer = find_printer_index_by_hnd(p, handle);
6317 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6322 if (!get_printer_snum(p, handle, &snum, NULL))
6325 result = winreg_get_printer(p->mem_ctx,
6326 get_server_info_system(),
6328 Printer->servername,
6329 lp_servicename(snum),
6331 if (!W_ERROR_IS_OK(result)) {
6335 nt_printer_publish(pinfo2,
6336 get_server_info_system(),
6341 TALLOC_FREE(pinfo2);
6344 return WERR_UNKNOWN_LEVEL;
6348 /********************************************************************
6349 ********************************************************************/
6351 static WERROR update_printer_devmode(struct pipes_struct *p,
6352 struct policy_handle *handle,
6353 struct spoolss_DeviceMode *devmode)
6356 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6357 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6359 DEBUG(8,("update_printer_devmode\n"));
6365 if (!get_printer_snum(p, handle, &snum, NULL)) {
6369 /* Check calling user has permission to update printer description */
6370 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6371 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6372 return WERR_ACCESS_DENIED;
6375 return winreg_update_printer(p->mem_ctx,
6376 get_server_info_system(),
6378 lp_const_servicename(snum),
6386 /****************************************************************
6388 ****************************************************************/
6390 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6391 struct spoolss_SetPrinter *r)
6395 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6398 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6399 OUR_HANDLE(r->in.handle)));
6403 /* check the level */
6404 switch (r->in.info_ctr->level) {
6406 return control_printer(r->in.handle, r->in.command, p);
6408 result = update_printer(p, r->in.handle,
6410 r->in.devmode_ctr->devmode);
6411 if (!W_ERROR_IS_OK(result))
6413 if (r->in.secdesc_ctr->sd)
6414 result = update_printer_sec(r->in.handle, p,
6418 return update_printer_sec(r->in.handle, p,
6421 return publish_or_unpublish_printer(p, r->in.handle,
6422 r->in.info_ctr->info.info7);
6424 return update_printer_devmode(p, r->in.handle,
6425 r->in.devmode_ctr->devmode);
6427 return WERR_UNKNOWN_LEVEL;
6431 /****************************************************************
6432 _spoolss_FindClosePrinterNotify
6433 ****************************************************************/
6435 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6436 struct spoolss_FindClosePrinterNotify *r)
6438 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6441 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6442 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6446 if (Printer->notify.client_connected == true) {
6449 if ( Printer->printer_type == SPLHND_SERVER)
6451 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6452 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6455 srv_spoolss_replycloseprinter(
6456 snum, &Printer->notify.client_hnd, p->msg_ctx);
6459 Printer->notify.flags=0;
6460 Printer->notify.options=0;
6461 Printer->notify.localmachine[0]='\0';
6462 Printer->notify.printerlocal=0;
6463 TALLOC_FREE(Printer->notify.option);
6464 Printer->notify.client_connected = false;
6469 /****************************************************************
6471 ****************************************************************/
6473 WERROR _spoolss_AddJob(struct pipes_struct *p,
6474 struct spoolss_AddJob *r)
6476 if (!r->in.buffer && (r->in.offered != 0)) {
6477 return WERR_INVALID_PARAM;
6480 /* this is what a NT server returns for AddJob. AddJob must fail on
6481 * non-local printers */
6483 if (r->in.level != 1) {
6484 return WERR_UNKNOWN_LEVEL;
6487 return WERR_INVALID_PARAM;
6490 /****************************************************************************
6492 ****************************************************************************/
6494 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6495 struct spoolss_JobInfo1 *r,
6496 const print_queue_struct *queue,
6497 int position, int snum,
6498 struct spoolss_PrinterInfo2 *pinfo2)
6502 t = gmtime(&queue->time);
6504 r->job_id = queue->job;
6506 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6507 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6508 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6509 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6510 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6511 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6512 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6513 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6514 r->data_type = talloc_strdup(mem_ctx, "RAW");
6515 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6516 r->text_status = talloc_strdup(mem_ctx, "");
6517 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6519 r->status = nt_printj_status(queue->status);
6520 r->priority = queue->priority;
6521 r->position = position;
6522 r->total_pages = queue->page_count;
6523 r->pages_printed = 0; /* ??? */
6525 init_systemtime(&r->submitted, t);
6530 /****************************************************************************
6532 ****************************************************************************/
6534 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6535 struct spoolss_JobInfo2 *r,
6536 const print_queue_struct *queue,
6537 int position, int snum,
6538 struct spoolss_PrinterInfo2 *pinfo2,
6539 struct spoolss_DeviceMode *devmode)
6543 t = gmtime(&queue->time);
6545 r->job_id = queue->job;
6547 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6548 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6549 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6550 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6551 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6552 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6553 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6554 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6555 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6556 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6557 r->data_type = talloc_strdup(mem_ctx, "RAW");
6558 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6559 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6560 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6561 r->parameters = talloc_strdup(mem_ctx, "");
6562 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6563 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6564 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6566 r->devmode = devmode;
6568 r->text_status = talloc_strdup(mem_ctx, "");
6569 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6573 r->status = nt_printj_status(queue->status);
6574 r->priority = queue->priority;
6575 r->position = position;
6578 r->total_pages = queue->page_count;
6579 r->size = queue->size;
6580 init_systemtime(&r->submitted, t);
6582 r->pages_printed = 0; /* ??? */
6587 /****************************************************************************
6589 ****************************************************************************/
6591 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6592 struct spoolss_JobInfo3 *r,
6593 const print_queue_struct *queue,
6594 const print_queue_struct *next_queue,
6595 int position, int snum,
6596 struct spoolss_PrinterInfo2 *pinfo2)
6598 r->job_id = queue->job;
6601 r->next_job_id = next_queue->job;
6608 /****************************************************************************
6609 Enumjobs at level 1.
6610 ****************************************************************************/
6612 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6613 const print_queue_struct *queue,
6614 uint32_t num_queues, int snum,
6615 struct spoolss_PrinterInfo2 *pinfo2,
6616 union spoolss_JobInfo **info_p,
6619 union spoolss_JobInfo *info;
6621 WERROR result = WERR_OK;
6623 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6624 W_ERROR_HAVE_NO_MEMORY(info);
6626 *count = num_queues;
6628 for (i=0; i<*count; i++) {
6629 result = fill_job_info1(info,
6635 if (!W_ERROR_IS_OK(result)) {
6641 if (!W_ERROR_IS_OK(result)) {
6652 /****************************************************************************
6653 Enumjobs at level 2.
6654 ****************************************************************************/
6656 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6657 const print_queue_struct *queue,
6658 uint32_t num_queues, int snum,
6659 struct spoolss_PrinterInfo2 *pinfo2,
6660 union spoolss_JobInfo **info_p,
6663 union spoolss_JobInfo *info;
6665 WERROR result = WERR_OK;
6667 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6668 W_ERROR_HAVE_NO_MEMORY(info);
6670 *count = num_queues;
6672 for (i=0; i<*count; i++) {
6673 struct spoolss_DeviceMode *devmode;
6675 result = spoolss_create_default_devmode(info,
6676 pinfo2->printername,
6678 if (!W_ERROR_IS_OK(result)) {
6679 DEBUG(3, ("Can't proceed w/o a devmode!"));
6683 result = fill_job_info2(info,
6690 if (!W_ERROR_IS_OK(result)) {
6696 if (!W_ERROR_IS_OK(result)) {
6707 /****************************************************************************
6708 Enumjobs at level 3.
6709 ****************************************************************************/
6711 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6712 const print_queue_struct *queue,
6713 uint32_t num_queues, int snum,
6714 struct spoolss_PrinterInfo2 *pinfo2,
6715 union spoolss_JobInfo **info_p,
6718 union spoolss_JobInfo *info;
6720 WERROR result = WERR_OK;
6722 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6723 W_ERROR_HAVE_NO_MEMORY(info);
6725 *count = num_queues;
6727 for (i=0; i<*count; i++) {
6728 const print_queue_struct *next_queue = NULL;
6731 next_queue = &queue[i+1];
6734 result = fill_job_info3(info,
6741 if (!W_ERROR_IS_OK(result)) {
6747 if (!W_ERROR_IS_OK(result)) {
6758 /****************************************************************
6760 ****************************************************************/
6762 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6763 struct spoolss_EnumJobs *r)
6766 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6768 print_status_struct prt_status;
6769 print_queue_struct *queue = NULL;
6772 /* that's an [in out] buffer */
6774 if (!r->in.buffer && (r->in.offered != 0)) {
6775 return WERR_INVALID_PARAM;
6778 DEBUG(4,("_spoolss_EnumJobs\n"));
6782 *r->out.info = NULL;
6784 /* lookup the printer snum and tdb entry */
6786 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6790 result = winreg_get_printer(p->mem_ctx,
6791 get_server_info_system(),
6794 lp_const_servicename(snum),
6796 if (!W_ERROR_IS_OK(result)) {
6800 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
6801 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6802 count, prt_status.status, prt_status.message));
6806 TALLOC_FREE(pinfo2);
6810 switch (r->in.level) {
6812 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6813 pinfo2, r->out.info, r->out.count);
6816 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6817 pinfo2, r->out.info, r->out.count);
6820 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6821 pinfo2, r->out.info, r->out.count);
6824 result = WERR_UNKNOWN_LEVEL;
6829 TALLOC_FREE(pinfo2);
6831 if (!W_ERROR_IS_OK(result)) {
6835 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6837 *r->out.info, r->in.level,
6839 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6840 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6842 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6845 /****************************************************************
6846 _spoolss_ScheduleJob
6847 ****************************************************************/
6849 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6850 struct spoolss_ScheduleJob *r)
6855 /****************************************************************
6856 ****************************************************************/
6858 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6859 struct messaging_context *msg_ctx,
6860 const char *printer_name,
6862 struct spoolss_SetJobInfo1 *r)
6866 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6870 if (strequal(old_doc_name, r->document_name)) {
6874 if (!print_job_set_name(server_event_context(), msg_ctx,
6875 printer_name, job_id, r->document_name)) {
6882 /****************************************************************
6884 ****************************************************************/
6886 WERROR _spoolss_SetJob(struct pipes_struct *p,
6887 struct spoolss_SetJob *r)
6889 const struct auth_serversupplied_info *server_info = get_server_info_system();
6891 WERROR errcode = WERR_BADFUNC;
6893 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6897 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6898 return WERR_INVALID_PRINTER_NAME;
6901 switch (r->in.command) {
6902 case SPOOLSS_JOB_CONTROL_CANCEL:
6903 case SPOOLSS_JOB_CONTROL_DELETE:
6904 errcode = print_job_delete(server_info, p->msg_ctx,
6905 snum, r->in.job_id);
6906 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6910 case SPOOLSS_JOB_CONTROL_PAUSE:
6911 if (print_job_pause(server_info, p->msg_ctx,
6912 snum, r->in.job_id, &errcode)) {
6916 case SPOOLSS_JOB_CONTROL_RESTART:
6917 case SPOOLSS_JOB_CONTROL_RESUME:
6918 if (print_job_resume(server_info, p->msg_ctx,
6919 snum, r->in.job_id, &errcode)) {
6927 return WERR_UNKNOWN_LEVEL;
6930 if (!W_ERROR_IS_OK(errcode)) {
6934 if (r->in.ctr == NULL) {
6938 switch (r->in.ctr->level) {
6940 errcode = spoolss_setjob_1(p->mem_ctx, p->msg_ctx,
6941 lp_const_servicename(snum),
6943 r->in.ctr->info.info1);
6949 return WERR_UNKNOWN_LEVEL;
6955 /****************************************************************************
6956 Enumerates all printer drivers by level and architecture.
6957 ****************************************************************************/
6959 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6960 const struct auth_serversupplied_info *server_info,
6961 struct messaging_context *msg_ctx,
6962 const char *servername,
6963 const char *architecture,
6965 union spoolss_DriverInfo **info_p,
6970 struct spoolss_DriverInfo8 *driver;
6971 union spoolss_DriverInfo *info = NULL;
6973 WERROR result = WERR_OK;
6974 uint32_t num_drivers;
6975 const char **drivers;
6980 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6981 result = winreg_get_driver_list(mem_ctx, server_info, msg_ctx,
6982 architecture, version,
6983 &num_drivers, &drivers);
6984 if (!W_ERROR_IS_OK(result)) {
6987 DEBUG(4, ("we have:[%d] drivers in environment"
6988 " [%s] and version [%d]\n",
6989 num_drivers, architecture, version));
6991 if (num_drivers != 0) {
6992 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6993 union spoolss_DriverInfo,
6994 count + num_drivers);
6996 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6997 "failed to enlarge driver info buffer!\n"));
6998 result = WERR_NOMEM;
7003 for (i = 0; i < num_drivers; i++) {
7004 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
7006 result = winreg_get_driver(mem_ctx, server_info,
7008 architecture, drivers[i],
7010 if (!W_ERROR_IS_OK(result)) {
7016 result = fill_printer_driver_info1(info, &info[count+i].info1,
7017 driver, servername);
7020 result = fill_printer_driver_info2(info, &info[count+i].info2,
7021 driver, servername);
7024 result = fill_printer_driver_info3(info, &info[count+i].info3,
7025 driver, servername);
7028 result = fill_printer_driver_info4(info, &info[count+i].info4,
7029 driver, servername);
7032 result = fill_printer_driver_info5(info, &info[count+i].info5,
7033 driver, servername);
7036 result = fill_printer_driver_info6(info, &info[count+i].info6,
7037 driver, servername);
7040 result = fill_printer_driver_info8(info, &info[count+i].info8,
7041 driver, servername);
7044 result = WERR_UNKNOWN_LEVEL;
7048 TALLOC_FREE(driver);
7050 if (!W_ERROR_IS_OK(result)) {
7055 count += num_drivers;
7056 TALLOC_FREE(drivers);
7060 TALLOC_FREE(drivers);
7062 if (!W_ERROR_IS_OK(result)) {
7073 /****************************************************************************
7074 Enumerates all printer drivers by level.
7075 ****************************************************************************/
7077 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
7078 const struct auth_serversupplied_info *server_info,
7079 struct messaging_context *msg_ctx,
7080 const char *servername,
7081 const char *architecture,
7083 union spoolss_DriverInfo **info_p,
7087 WERROR result = WERR_OK;
7089 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
7091 for (a=0; archi_table[a].long_archi != NULL; a++) {
7093 union spoolss_DriverInfo *info = NULL;
7096 result = enumprinterdrivers_level_by_architecture(mem_ctx,
7100 archi_table[a].long_archi,
7104 if (!W_ERROR_IS_OK(result)) {
7108 for (i=0; i < count; i++) {
7109 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
7110 info[i], info_p, count_p);
7117 return enumprinterdrivers_level_by_architecture(mem_ctx,
7127 /****************************************************************
7128 _spoolss_EnumPrinterDrivers
7129 ****************************************************************/
7131 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
7132 struct spoolss_EnumPrinterDrivers *r)
7134 const char *cservername;
7137 /* that's an [in out] buffer */
7139 if (!r->in.buffer && (r->in.offered != 0)) {
7140 return WERR_INVALID_PARAM;
7143 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
7147 *r->out.info = NULL;
7149 cservername = canon_servername(r->in.server);
7151 if (!is_myname_or_ipaddr(cservername)) {
7152 return WERR_UNKNOWN_PRINTER_DRIVER;
7155 result = enumprinterdrivers_level(p->mem_ctx,
7156 get_server_info_system(),
7163 if (!W_ERROR_IS_OK(result)) {
7167 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7168 spoolss_EnumPrinterDrivers,
7169 *r->out.info, r->in.level,
7171 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7172 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7174 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7177 /****************************************************************
7179 ****************************************************************/
7181 WERROR _spoolss_EnumForms(struct pipes_struct *p,
7182 struct spoolss_EnumForms *r)
7188 *r->out.info = NULL;
7190 /* that's an [in out] buffer */
7192 if (!r->in.buffer && (r->in.offered != 0) ) {
7193 return WERR_INVALID_PARAM;
7196 DEBUG(4,("_spoolss_EnumForms\n"));
7197 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7198 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7200 switch (r->in.level) {
7202 result = winreg_printer_enumforms1(p->mem_ctx,
7203 get_server_info_system(),
7209 result = WERR_UNKNOWN_LEVEL;
7213 if (!W_ERROR_IS_OK(result)) {
7217 if (*r->out.count == 0) {
7218 return WERR_NO_MORE_ITEMS;
7221 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7223 *r->out.info, r->in.level,
7225 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7226 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7228 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7231 /****************************************************************
7233 ****************************************************************/
7235 WERROR _spoolss_GetForm(struct pipes_struct *p,
7236 struct spoolss_GetForm *r)
7240 /* that's an [in out] buffer */
7242 if (!r->in.buffer && (r->in.offered != 0)) {
7243 return WERR_INVALID_PARAM;
7246 DEBUG(4,("_spoolss_GetForm\n"));
7247 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7248 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7250 switch (r->in.level) {
7252 result = winreg_printer_getform1(p->mem_ctx,
7253 get_server_info_system(),
7256 &r->out.info->info1);
7259 result = WERR_UNKNOWN_LEVEL;
7263 if (!W_ERROR_IS_OK(result)) {
7264 TALLOC_FREE(r->out.info);
7268 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
7269 r->out.info, r->in.level);
7270 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7272 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7275 /****************************************************************************
7276 ****************************************************************************/
7278 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
7279 struct spoolss_PortInfo1 *r,
7282 r->port_name = talloc_strdup(mem_ctx, name);
7283 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7288 /****************************************************************************
7289 TODO: This probably needs distinguish between TCP/IP and Local ports
7291 ****************************************************************************/
7293 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
7294 struct spoolss_PortInfo2 *r,
7297 r->port_name = talloc_strdup(mem_ctx, name);
7298 W_ERROR_HAVE_NO_MEMORY(r->port_name);
7300 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
7301 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
7303 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
7304 W_ERROR_HAVE_NO_MEMORY(r->description);
7306 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
7313 /****************************************************************************
7314 wrapper around the enumer ports command
7315 ****************************************************************************/
7317 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
7319 char *cmd = lp_enumports_cmd();
7320 char **qlines = NULL;
7321 char *command = NULL;
7329 /* if no hook then just fill in the default port */
7332 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7335 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7336 TALLOC_FREE(qlines);
7343 /* we have a valid enumport command */
7345 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7350 DEBUG(10,("Running [%s]\n", command));
7351 ret = smbrun(command, &fd);
7352 DEBUG(10,("Returned [%d]\n", ret));
7353 TALLOC_FREE(command);
7358 return WERR_ACCESS_DENIED;
7362 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7363 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7373 /****************************************************************************
7375 ****************************************************************************/
7377 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7378 union spoolss_PortInfo **info_p,
7381 union spoolss_PortInfo *info = NULL;
7383 WERROR result = WERR_OK;
7384 char **qlines = NULL;
7387 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7388 if (!W_ERROR_IS_OK(result)) {
7393 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7395 DEBUG(10,("Returning WERR_NOMEM\n"));
7396 result = WERR_NOMEM;
7400 for (i=0; i<numlines; i++) {
7401 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7402 result = fill_port_1(info, &info[i].info1, qlines[i]);
7403 if (!W_ERROR_IS_OK(result)) {
7408 TALLOC_FREE(qlines);
7411 if (!W_ERROR_IS_OK(result)) {
7413 TALLOC_FREE(qlines);
7425 /****************************************************************************
7427 ****************************************************************************/
7429 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7430 union spoolss_PortInfo **info_p,
7433 union spoolss_PortInfo *info = NULL;
7435 WERROR result = WERR_OK;
7436 char **qlines = NULL;
7439 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7440 if (!W_ERROR_IS_OK(result)) {
7445 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7447 DEBUG(10,("Returning WERR_NOMEM\n"));
7448 result = WERR_NOMEM;
7452 for (i=0; i<numlines; i++) {
7453 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7454 result = fill_port_2(info, &info[i].info2, qlines[i]);
7455 if (!W_ERROR_IS_OK(result)) {
7460 TALLOC_FREE(qlines);
7463 if (!W_ERROR_IS_OK(result)) {
7465 TALLOC_FREE(qlines);
7477 /****************************************************************
7479 ****************************************************************/
7481 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7482 struct spoolss_EnumPorts *r)
7486 /* that's an [in out] buffer */
7488 if (!r->in.buffer && (r->in.offered != 0)) {
7489 return WERR_INVALID_PARAM;
7492 DEBUG(4,("_spoolss_EnumPorts\n"));
7496 *r->out.info = NULL;
7498 switch (r->in.level) {
7500 result = enumports_level_1(p->mem_ctx, r->out.info,
7504 result = enumports_level_2(p->mem_ctx, r->out.info,
7508 return WERR_UNKNOWN_LEVEL;
7511 if (!W_ERROR_IS_OK(result)) {
7515 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7517 *r->out.info, r->in.level,
7519 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7520 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7522 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7525 /****************************************************************************
7526 ****************************************************************************/
7528 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7530 struct spoolss_SetPrinterInfoCtr *info_ctr,
7531 struct spoolss_DeviceMode *devmode,
7532 struct security_descriptor *secdesc,
7533 struct spoolss_UserLevelCtr *user_ctr,
7534 struct policy_handle *handle)
7536 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7537 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7539 WERROR err = WERR_OK;
7541 /* samba does not have a concept of local, non-shared printers yet, so
7542 * make sure we always setup sharename - gd */
7543 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7544 (info2->printername != NULL && info2->printername[0] != '\0')) {
7545 DEBUG(5, ("spoolss_addprinterex_level_2: "
7546 "no sharename has been set, setting printername %s as sharename\n",
7547 info2->printername));
7548 info2->sharename = info2->printername;
7551 /* check to see if the printer already exists */
7552 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7553 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7555 return WERR_PRINTER_ALREADY_EXISTS;
7558 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7559 if ((snum = print_queue_snum(info2->printername)) != -1) {
7560 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7561 info2->printername));
7562 return WERR_PRINTER_ALREADY_EXISTS;
7566 /* validate printer info struct */
7567 if (!info2->printername || strlen(info2->printername) == 0) {
7568 return WERR_INVALID_PRINTER_NAME;
7570 if (!info2->portname || strlen(info2->portname) == 0) {
7571 return WERR_UNKNOWN_PORT;
7573 if (!info2->drivername || strlen(info2->drivername) == 0) {
7574 return WERR_UNKNOWN_PRINTER_DRIVER;
7576 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7577 return WERR_UNKNOWN_PRINTPROCESSOR;
7580 /* FIXME!!! smbd should check to see if the driver is installed before
7581 trying to add a printer like this --jerry */
7583 if (*lp_addprinter_cmd() ) {
7584 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7585 info2, p->client_id->addr,
7587 return WERR_ACCESS_DENIED;
7590 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7591 "smb.conf parameter \"addprinter command\" is defined. This"
7592 "parameter must exist for this call to succeed\n",
7593 info2->sharename ));
7596 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7597 return WERR_ACCESS_DENIED;
7600 /* you must be a printer admin to add a new printer */
7601 if (!print_access_check(get_server_info_system(),
7604 PRINTER_ACCESS_ADMINISTER)) {
7605 return WERR_ACCESS_DENIED;
7609 * Do sanity check on the requested changes for Samba.
7612 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7613 return WERR_INVALID_PARAM;
7616 if (devmode == NULL) {
7617 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7620 update_dsspooler(p->mem_ctx,
7621 get_server_info_system(),
7627 err = winreg_update_printer(p->mem_ctx,
7628 get_server_info_system(),
7635 if (!W_ERROR_IS_OK(err)) {
7639 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7640 /* Handle open failed - remove addition. */
7641 ZERO_STRUCTP(handle);
7642 return WERR_ACCESS_DENIED;
7648 /****************************************************************
7649 _spoolss_AddPrinterEx
7650 ****************************************************************/
7652 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7653 struct spoolss_AddPrinterEx *r)
7655 switch (r->in.info_ctr->level) {
7657 /* we don't handle yet */
7658 /* but I know what to do ... */
7659 return WERR_UNKNOWN_LEVEL;
7661 return spoolss_addprinterex_level_2(p, r->in.server,
7663 r->in.devmode_ctr->devmode,
7664 r->in.secdesc_ctr->sd,
7665 r->in.userlevel_ctr,
7668 return WERR_UNKNOWN_LEVEL;
7672 /****************************************************************
7674 ****************************************************************/
7676 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7677 struct spoolss_AddPrinter *r)
7679 struct spoolss_AddPrinterEx a;
7680 struct spoolss_UserLevelCtr userlevel_ctr;
7682 ZERO_STRUCT(userlevel_ctr);
7684 userlevel_ctr.level = 1;
7686 a.in.server = r->in.server;
7687 a.in.info_ctr = r->in.info_ctr;
7688 a.in.devmode_ctr = r->in.devmode_ctr;
7689 a.in.secdesc_ctr = r->in.secdesc_ctr;
7690 a.in.userlevel_ctr = &userlevel_ctr;
7691 a.out.handle = r->out.handle;
7693 return _spoolss_AddPrinterEx(p, &a);
7696 /****************************************************************
7697 _spoolss_AddPrinterDriverEx
7698 ****************************************************************/
7700 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7701 struct spoolss_AddPrinterDriverEx *r)
7703 WERROR err = WERR_OK;
7704 const char *driver_name = NULL;
7709 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7710 fn = "_spoolss_AddPrinterDriver";
7712 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7713 fn = "_spoolss_AddPrinterDriverEx";
7716 return WERR_INVALID_PARAM;
7720 * we only support the semantics of AddPrinterDriver()
7721 * i.e. only copy files that are newer than existing ones
7724 if (r->in.flags == 0) {
7725 return WERR_INVALID_PARAM;
7728 if (r->in.flags != APD_COPY_NEW_FILES) {
7729 return WERR_ACCESS_DENIED;
7733 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7734 /* Clever hack from Martin Zielinski <mz@seh.de>
7735 * to allow downgrade from level 8 (Vista).
7737 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7738 r->in.info_ctr->level));
7739 return WERR_UNKNOWN_LEVEL;
7742 DEBUG(5,("Cleaning driver's information\n"));
7743 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7744 if (!W_ERROR_IS_OK(err))
7747 DEBUG(5,("Moving driver to final destination\n"));
7748 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7753 err = winreg_add_driver(p->mem_ctx,
7754 get_server_info_system(),
7759 if (!W_ERROR_IS_OK(err)) {
7764 * I think this is where he DrvUpgradePrinter() hook would be
7765 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7766 * server. Right now, we just need to send ourselves a message
7767 * to update each printer bound to this driver. --jerry
7770 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
7771 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7779 /****************************************************************
7780 _spoolss_AddPrinterDriver
7781 ****************************************************************/
7783 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7784 struct spoolss_AddPrinterDriver *r)
7786 struct spoolss_AddPrinterDriverEx a;
7788 switch (r->in.info_ctr->level) {
7795 return WERR_UNKNOWN_LEVEL;
7798 a.in.servername = r->in.servername;
7799 a.in.info_ctr = r->in.info_ctr;
7800 a.in.flags = APD_COPY_NEW_FILES;
7802 return _spoolss_AddPrinterDriverEx(p, &a);
7805 /****************************************************************************
7806 ****************************************************************************/
7808 struct _spoolss_paths {
7814 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7816 static const struct _spoolss_paths spoolss_paths[]= {
7817 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7818 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7821 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7822 const char *servername,
7823 const char *environment,
7827 const char *pservername = NULL;
7828 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7829 const char *short_archi;
7833 /* environment may be empty */
7834 if (environment && strlen(environment)) {
7835 long_archi = environment;
7838 /* servername may be empty */
7839 if (servername && strlen(servername)) {
7840 pservername = canon_servername(servername);
7842 if (!is_myname_or_ipaddr(pservername)) {
7843 return WERR_INVALID_PARAM;
7847 if (!(short_archi = get_short_archi(long_archi))) {
7848 return WERR_INVALID_ENVIRONMENT;
7851 switch (component) {
7852 case SPOOLSS_PRTPROCS_PATH:
7853 case SPOOLSS_DRIVER_PATH:
7855 *path = talloc_asprintf(mem_ctx,
7858 spoolss_paths[component].share,
7861 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7862 SPOOLSS_DEFAULT_SERVER_PATH,
7863 spoolss_paths[component].dir,
7868 return WERR_INVALID_PARAM;
7878 /****************************************************************************
7879 ****************************************************************************/
7881 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7882 const char *servername,
7883 const char *environment,
7884 struct spoolss_DriverDirectoryInfo1 *r)
7889 werr = compose_spoolss_server_path(mem_ctx,
7892 SPOOLSS_DRIVER_PATH,
7894 if (!W_ERROR_IS_OK(werr)) {
7898 DEBUG(4,("printer driver directory: [%s]\n", path));
7900 r->directory_name = path;
7905 /****************************************************************
7906 _spoolss_GetPrinterDriverDirectory
7907 ****************************************************************/
7909 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7910 struct spoolss_GetPrinterDriverDirectory *r)
7914 /* that's an [in out] buffer */
7916 if (!r->in.buffer && (r->in.offered != 0)) {
7917 return WERR_INVALID_PARAM;
7920 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7925 /* r->in.level is ignored */
7927 werror = getprinterdriverdir_level_1(p->mem_ctx,
7930 &r->out.info->info1);
7931 if (!W_ERROR_IS_OK(werror)) {
7932 TALLOC_FREE(r->out.info);
7936 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7937 r->out.info, r->in.level);
7938 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7940 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7943 /****************************************************************
7944 _spoolss_EnumPrinterData
7945 ****************************************************************/
7947 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7948 struct spoolss_EnumPrinterData *r)
7951 struct spoolss_EnumPrinterDataEx r2;
7953 struct spoolss_PrinterEnumValues *info, *val = NULL;
7956 r2.in.handle = r->in.handle;
7957 r2.in.key_name = "PrinterDriverData";
7959 r2.out.count = &count;
7960 r2.out.info = &info;
7961 r2.out.needed = &needed;
7963 result = _spoolss_EnumPrinterDataEx(p, &r2);
7964 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7965 r2.in.offered = needed;
7966 result = _spoolss_EnumPrinterDataEx(p, &r2);
7968 if (!W_ERROR_IS_OK(result)) {
7973 * The NT machine wants to know the biggest size of value and data
7975 * cf: MSDN EnumPrinterData remark section
7978 if (!r->in.value_offered && !r->in.data_offered) {
7979 uint32_t biggest_valuesize = 0;
7980 uint32_t biggest_datasize = 0;
7983 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7985 for (i=0; i<count; i++) {
7987 name_length = strlen(info[i].value_name);
7988 if (strlen(info[i].value_name) > biggest_valuesize) {
7989 biggest_valuesize = name_length;
7992 if (info[i].data_length > biggest_datasize) {
7993 biggest_datasize = info[i].data_length;
7996 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8000 /* the value is an UNICODE string but real_value_size is the length
8001 in bytes including the trailing 0 */
8003 *r->out.value_needed = 2 * (1 + biggest_valuesize);
8004 *r->out.data_needed = biggest_datasize;
8006 DEBUG(6,("final values: [%d], [%d]\n",
8007 *r->out.value_needed, *r->out.data_needed));
8012 if (r->in.enum_index < count) {
8013 val = &info[r->in.enum_index];
8017 /* out_value should default to "" or else NT4 has
8018 problems unmarshalling the response */
8020 if (r->in.value_offered) {
8021 *r->out.value_needed = 1;
8022 r->out.value_name = talloc_strdup(r, "");
8023 if (!r->out.value_name) {
8027 r->out.value_name = NULL;
8028 *r->out.value_needed = 0;
8031 /* the data is counted in bytes */
8033 *r->out.data_needed = r->in.data_offered;
8035 result = WERR_NO_MORE_ITEMS;
8039 * - counted in bytes in the request
8040 * - counted in UNICODE chars in the max reply
8041 * - counted in bytes in the real size
8043 * take a pause *before* coding not *during* coding
8047 if (r->in.value_offered) {
8048 r->out.value_name = talloc_strdup(r, val->value_name);
8049 if (!r->out.value_name) {
8052 *r->out.value_needed = val->value_name_len;
8054 r->out.value_name = NULL;
8055 *r->out.value_needed = 0;
8060 *r->out.type = val->type;
8062 /* data - counted in bytes */
8065 * See the section "Dynamically Typed Query Parameters"
8069 if (r->out.data && val->data && val->data->data &&
8070 val->data_length && r->in.data_offered) {
8071 memcpy(r->out.data, val->data->data,
8072 MIN(val->data_length,r->in.data_offered));
8075 *r->out.data_needed = val->data_length;
8083 /****************************************************************
8084 _spoolss_SetPrinterData
8085 ****************************************************************/
8087 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
8088 struct spoolss_SetPrinterData *r)
8090 struct spoolss_SetPrinterDataEx r2;
8092 r2.in.handle = r->in.handle;
8093 r2.in.key_name = "PrinterDriverData";
8094 r2.in.value_name = r->in.value_name;
8095 r2.in.type = r->in.type;
8096 r2.in.data = r->in.data;
8097 r2.in.offered = r->in.offered;
8099 return _spoolss_SetPrinterDataEx(p, &r2);
8102 /****************************************************************
8103 _spoolss_ResetPrinter
8104 ****************************************************************/
8106 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
8107 struct spoolss_ResetPrinter *r)
8109 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8112 DEBUG(5,("_spoolss_ResetPrinter\n"));
8115 * All we do is to check to see if the handle and queue is valid.
8116 * This call really doesn't mean anything to us because we only
8117 * support RAW printing. --jerry
8121 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8122 OUR_HANDLE(r->in.handle)));
8126 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8130 /* blindly return success */
8134 /****************************************************************
8135 _spoolss_DeletePrinterData
8136 ****************************************************************/
8138 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
8139 struct spoolss_DeletePrinterData *r)
8141 struct spoolss_DeletePrinterDataEx r2;
8143 r2.in.handle = r->in.handle;
8144 r2.in.key_name = "PrinterDriverData";
8145 r2.in.value_name = r->in.value_name;
8147 return _spoolss_DeletePrinterDataEx(p, &r2);
8150 /****************************************************************
8152 ****************************************************************/
8154 WERROR _spoolss_AddForm(struct pipes_struct *p,
8155 struct spoolss_AddForm *r)
8157 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8159 WERROR status = WERR_OK;
8160 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8162 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8164 DEBUG(5,("_spoolss_AddForm\n"));
8167 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8168 OUR_HANDLE(r->in.handle)));
8172 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8173 and not a printer admin, then fail */
8175 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8176 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8177 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8178 p->server_info->info3->base.domain.string,
8180 p->server_info->ptok,
8181 lp_printer_admin(snum))) {
8182 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
8183 return WERR_ACCESS_DENIED;
8186 switch (form->flags) {
8187 case SPOOLSS_FORM_USER:
8188 case SPOOLSS_FORM_BUILTIN:
8189 case SPOOLSS_FORM_PRINTER:
8192 return WERR_INVALID_PARAM;
8195 status = winreg_printer_addform1(p->mem_ctx,
8196 get_server_info_system(),
8199 if (!W_ERROR_IS_OK(status)) {
8204 * ChangeID must always be set if this is a printer
8206 if (Printer->printer_type == SPLHND_PRINTER) {
8207 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8211 status = winreg_printer_update_changeid(p->mem_ctx,
8212 get_server_info_system(),
8214 lp_const_servicename(snum));
8215 if (!W_ERROR_IS_OK(status)) {
8223 /****************************************************************
8225 ****************************************************************/
8227 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
8228 struct spoolss_DeleteForm *r)
8230 const char *form_name = r->in.form_name;
8231 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8233 WERROR status = WERR_OK;
8234 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8236 DEBUG(5,("_spoolss_DeleteForm\n"));
8239 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8240 OUR_HANDLE(r->in.handle)));
8244 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8245 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8246 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8247 p->server_info->info3->base.domain.string,
8249 p->server_info->ptok,
8250 lp_printer_admin(snum))) {
8251 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8252 return WERR_ACCESS_DENIED;
8255 status = winreg_printer_deleteform1(p->mem_ctx,
8256 get_server_info_system(),
8259 if (!W_ERROR_IS_OK(status)) {
8264 * ChangeID must always be set if this is a printer
8266 if (Printer->printer_type == SPLHND_PRINTER) {
8267 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8271 status = winreg_printer_update_changeid(p->mem_ctx,
8272 get_server_info_system(),
8274 lp_const_servicename(snum));
8275 if (!W_ERROR_IS_OK(status)) {
8283 /****************************************************************
8285 ****************************************************************/
8287 WERROR _spoolss_SetForm(struct pipes_struct *p,
8288 struct spoolss_SetForm *r)
8290 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8291 const char *form_name = r->in.form_name;
8293 WERROR status = WERR_OK;
8294 SE_PRIV se_printop = SE_PRINT_OPERATOR;
8296 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8298 DEBUG(5,("_spoolss_SetForm\n"));
8301 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8302 OUR_HANDLE(r->in.handle)));
8306 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8307 and not a printer admin, then fail */
8309 if ((p->server_info->utok.uid != sec_initial_uid()) &&
8310 !user_has_privileges(p->server_info->ptok, &se_printop) &&
8311 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8312 p->server_info->info3->base.domain.string,
8314 p->server_info->ptok,
8315 lp_printer_admin(snum))) {
8316 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8317 return WERR_ACCESS_DENIED;
8320 status = winreg_printer_setform1(p->mem_ctx,
8321 get_server_info_system(),
8325 if (!W_ERROR_IS_OK(status)) {
8330 * ChangeID must always be set if this is a printer
8332 if (Printer->printer_type == SPLHND_PRINTER) {
8333 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8337 status = winreg_printer_update_changeid(p->mem_ctx,
8338 get_server_info_system(),
8340 lp_const_servicename(snum));
8341 if (!W_ERROR_IS_OK(status)) {
8349 /****************************************************************************
8350 fill_print_processor1
8351 ****************************************************************************/
8353 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8354 struct spoolss_PrintProcessorInfo1 *r,
8355 const char *print_processor_name)
8357 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8358 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8363 /****************************************************************************
8364 enumprintprocessors level 1.
8365 ****************************************************************************/
8367 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8368 union spoolss_PrintProcessorInfo **info_p,
8371 union spoolss_PrintProcessorInfo *info;
8374 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8375 W_ERROR_HAVE_NO_MEMORY(info);
8379 result = fill_print_processor1(info, &info[0].info1, "winprint");
8380 if (!W_ERROR_IS_OK(result)) {
8385 if (!W_ERROR_IS_OK(result)) {
8396 /****************************************************************
8397 _spoolss_EnumPrintProcessors
8398 ****************************************************************/
8400 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8401 struct spoolss_EnumPrintProcessors *r)
8405 /* that's an [in out] buffer */
8407 if (!r->in.buffer && (r->in.offered != 0)) {
8408 return WERR_INVALID_PARAM;
8411 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8414 * Enumerate the print processors ...
8416 * Just reply with "winprint", to keep NT happy
8417 * and I can use my nice printer checker.
8422 *r->out.info = NULL;
8424 switch (r->in.level) {
8426 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8430 return WERR_UNKNOWN_LEVEL;
8433 if (!W_ERROR_IS_OK(result)) {
8437 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8438 spoolss_EnumPrintProcessors,
8439 *r->out.info, r->in.level,
8441 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8442 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8444 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8447 /****************************************************************************
8448 fill_printprocdatatype1
8449 ****************************************************************************/
8451 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8452 struct spoolss_PrintProcDataTypesInfo1 *r,
8453 const char *name_array)
8455 r->name_array = talloc_strdup(mem_ctx, name_array);
8456 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8461 /****************************************************************************
8462 enumprintprocdatatypes level 1.
8463 ****************************************************************************/
8465 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8466 union spoolss_PrintProcDataTypesInfo **info_p,
8470 union spoolss_PrintProcDataTypesInfo *info;
8472 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8473 W_ERROR_HAVE_NO_MEMORY(info);
8477 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8478 if (!W_ERROR_IS_OK(result)) {
8483 if (!W_ERROR_IS_OK(result)) {
8494 /****************************************************************
8495 _spoolss_EnumPrintProcDataTypes
8496 ****************************************************************/
8498 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8499 struct spoolss_EnumPrintProcDataTypes *r)
8503 /* that's an [in out] buffer */
8505 if (!r->in.buffer && (r->in.offered != 0)) {
8506 return WERR_INVALID_PARAM;
8509 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8513 *r->out.info = NULL;
8515 switch (r->in.level) {
8517 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8521 return WERR_UNKNOWN_LEVEL;
8524 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8525 spoolss_EnumPrintProcDataTypes,
8526 *r->out.info, r->in.level,
8528 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8529 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8531 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8534 /****************************************************************************
8536 ****************************************************************************/
8538 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8539 struct spoolss_MonitorInfo1 *r,
8540 const char *monitor_name)
8542 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8543 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8548 /****************************************************************************
8550 ****************************************************************************/
8552 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8553 struct spoolss_MonitorInfo2 *r,
8554 const char *monitor_name,
8555 const char *environment,
8556 const char *dll_name)
8558 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8559 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8560 r->environment = talloc_strdup(mem_ctx, environment);
8561 W_ERROR_HAVE_NO_MEMORY(r->environment);
8562 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8563 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8568 /****************************************************************************
8569 enumprintmonitors level 1.
8570 ****************************************************************************/
8572 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8573 union spoolss_MonitorInfo **info_p,
8576 union spoolss_MonitorInfo *info;
8577 WERROR result = WERR_OK;
8579 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8580 W_ERROR_HAVE_NO_MEMORY(info);
8584 result = fill_monitor_1(info, &info[0].info1,
8586 if (!W_ERROR_IS_OK(result)) {
8590 result = fill_monitor_1(info, &info[1].info1,
8592 if (!W_ERROR_IS_OK(result)) {
8597 if (!W_ERROR_IS_OK(result)) {
8608 /****************************************************************************
8609 enumprintmonitors level 2.
8610 ****************************************************************************/
8612 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8613 union spoolss_MonitorInfo **info_p,
8616 union spoolss_MonitorInfo *info;
8617 WERROR result = WERR_OK;
8619 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8620 W_ERROR_HAVE_NO_MEMORY(info);
8624 result = fill_monitor_2(info, &info[0].info2,
8626 "Windows NT X86", /* FIXME */
8628 if (!W_ERROR_IS_OK(result)) {
8632 result = fill_monitor_2(info, &info[1].info2,
8634 "Windows NT X86", /* FIXME */
8636 if (!W_ERROR_IS_OK(result)) {
8641 if (!W_ERROR_IS_OK(result)) {
8652 /****************************************************************
8653 _spoolss_EnumMonitors
8654 ****************************************************************/
8656 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8657 struct spoolss_EnumMonitors *r)
8661 /* that's an [in out] buffer */
8663 if (!r->in.buffer && (r->in.offered != 0)) {
8664 return WERR_INVALID_PARAM;
8667 DEBUG(5,("_spoolss_EnumMonitors\n"));
8670 * Enumerate the print monitors ...
8672 * Just reply with "Local Port", to keep NT happy
8673 * and I can use my nice printer checker.
8678 *r->out.info = NULL;
8680 switch (r->in.level) {
8682 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8686 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8690 return WERR_UNKNOWN_LEVEL;
8693 if (!W_ERROR_IS_OK(result)) {
8697 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8698 spoolss_EnumMonitors,
8699 *r->out.info, r->in.level,
8701 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8702 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8704 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8707 /****************************************************************************
8708 ****************************************************************************/
8710 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8711 const print_queue_struct *queue,
8712 int count, int snum,
8713 struct spoolss_PrinterInfo2 *pinfo2,
8715 struct spoolss_JobInfo1 *r)
8720 for (i=0; i<count; i++) {
8721 if (queue[i].job == (int)jobid) {
8727 if (found == false) {
8728 /* NT treats not found as bad param... yet another bad choice */
8729 return WERR_INVALID_PARAM;
8732 return fill_job_info1(mem_ctx,
8740 /****************************************************************************
8741 ****************************************************************************/
8743 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8744 const print_queue_struct *queue,
8745 int count, int snum,
8746 struct spoolss_PrinterInfo2 *pinfo2,
8748 struct spoolss_JobInfo2 *r)
8752 struct spoolss_DeviceMode *devmode;
8755 for (i=0; i<count; i++) {
8756 if (queue[i].job == (int)jobid) {
8762 if (found == false) {
8763 /* NT treats not found as bad param... yet another bad
8765 return WERR_INVALID_PARAM;
8769 * if the print job does not have a DEVMODE associated with it,
8770 * just use the one for the printer. A NULL devicemode is not
8771 * a failure condition
8774 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8776 result = spoolss_create_default_devmode(mem_ctx,
8777 pinfo2->printername,
8779 if (!W_ERROR_IS_OK(result)) {
8780 DEBUG(3, ("Can't proceed w/o a devmode!"));
8785 return fill_job_info2(mem_ctx,
8794 /****************************************************************
8796 ****************************************************************/
8798 WERROR _spoolss_GetJob(struct pipes_struct *p,
8799 struct spoolss_GetJob *r)
8801 WERROR result = WERR_OK;
8802 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8805 print_queue_struct *queue = NULL;
8806 print_status_struct prt_status;
8808 /* that's an [in out] buffer */
8810 if (!r->in.buffer && (r->in.offered != 0)) {
8811 return WERR_INVALID_PARAM;
8814 DEBUG(5,("_spoolss_GetJob\n"));
8818 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8822 result = winreg_get_printer(p->mem_ctx,
8823 get_server_info_system(),
8826 lp_const_servicename(snum),
8828 if (!W_ERROR_IS_OK(result)) {
8832 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
8834 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8835 count, prt_status.status, prt_status.message));
8837 switch (r->in.level) {
8839 result = getjob_level_1(p->mem_ctx,
8840 queue, count, snum, pinfo2,
8841 r->in.job_id, &r->out.info->info1);
8844 result = getjob_level_2(p->mem_ctx,
8845 queue, count, snum, pinfo2,
8846 r->in.job_id, &r->out.info->info2);
8849 result = WERR_UNKNOWN_LEVEL;
8854 TALLOC_FREE(pinfo2);
8856 if (!W_ERROR_IS_OK(result)) {
8857 TALLOC_FREE(r->out.info);
8861 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8863 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8865 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8868 /****************************************************************
8869 _spoolss_GetPrinterDataEx
8870 ****************************************************************/
8872 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8873 struct spoolss_GetPrinterDataEx *r)
8876 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
8877 const char *printer;
8879 WERROR result = WERR_OK;
8881 enum winreg_Type val_type;
8886 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8888 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8889 r->in.key_name, r->in.value_name));
8891 /* in case of problem, return some default values */
8894 *r->out.type = REG_NONE;
8897 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8898 OUR_HANDLE(r->in.handle)));
8899 result = WERR_BADFID;
8903 /* Is the handle to a printer or to the server? */
8905 if (Printer->printer_type == SPLHND_SERVER) {
8907 union spoolss_PrinterData data;
8909 result = getprinterdata_printer_server(p->mem_ctx,
8913 if (!W_ERROR_IS_OK(result)) {
8917 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8918 *r->out.type, &data);
8919 if (!W_ERROR_IS_OK(result)) {
8923 *r->out.needed = blob.length;
8925 if (r->in.offered >= *r->out.needed) {
8926 memcpy(r->out.data, blob.data, blob.length);
8929 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8932 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8935 printer = lp_const_servicename(snum);
8937 /* check to see if the keyname is valid */
8938 if (!strlen(r->in.key_name)) {
8939 return WERR_INVALID_PARAM;
8942 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8943 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8944 strequal(r->in.value_name, "ChangeId")) {
8945 *r->out.type = REG_DWORD;
8947 if (r->in.offered >= *r->out.needed) {
8948 uint32_t changeid = 0;
8950 result = winreg_printer_get_changeid(p->mem_ctx,
8951 get_server_info_system(),
8955 if (!W_ERROR_IS_OK(result)) {
8959 SIVAL(r->out.data, 0, changeid);
8965 result = winreg_get_printer_dataex(p->mem_ctx,
8966 get_server_info_system(),
8974 if (!W_ERROR_IS_OK(result)) {
8978 *r->out.needed = val_size;
8979 *r->out.type = val_type;
8981 if (r->in.offered >= *r->out.needed) {
8982 memcpy(r->out.data, val_data, val_size);
8986 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8987 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8989 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8992 /****************************************************************
8993 _spoolss_SetPrinterDataEx
8994 ****************************************************************/
8996 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8997 struct spoolss_SetPrinterDataEx *r)
8999 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
9001 WERROR result = WERR_OK;
9002 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9005 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9007 /* From MSDN documentation of SetPrinterDataEx: pass request to
9008 SetPrinterData if key is "PrinterDriverData" */
9011 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
9012 OUR_HANDLE(r->in.handle)));
9016 if (Printer->printer_type == SPLHND_SERVER) {
9017 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9018 "Not implemented for server handles yet\n"));
9019 return WERR_INVALID_PARAM;
9022 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9027 * Access check : NT returns "access denied" if you make a
9028 * SetPrinterData call without the necessary privildge.
9029 * we were originally returning OK if nothing changed
9030 * which made Win2k issue **a lot** of SetPrinterData
9031 * when connecting to a printer --jerry
9034 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9035 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9036 "change denied by handle access permissions\n"));
9037 return WERR_ACCESS_DENIED;
9040 result = winreg_get_printer(Printer,
9041 get_server_info_system(),
9043 Printer->servername,
9044 lp_servicename(snum),
9046 if (!W_ERROR_IS_OK(result)) {
9050 /* check for OID in valuename */
9052 oid_string = strchr(r->in.value_name, ',');
9058 /* save the registry data */
9060 result = winreg_set_printer_dataex(p->mem_ctx,
9061 get_server_info_system(),
9070 if (W_ERROR_IS_OK(result)) {
9071 /* save the OID if one was specified */
9073 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9074 r->in.key_name, SPOOL_OID_KEY);
9076 result = WERR_NOMEM;
9081 * I'm not checking the status here on purpose. Don't know
9082 * if this is right, but I'm returning the status from the
9083 * previous set_printer_dataex() call. I have no idea if
9084 * this is right. --jerry
9086 winreg_set_printer_dataex(p->mem_ctx,
9087 get_server_info_system(),
9093 (uint8_t *) oid_string,
9094 strlen(oid_string) + 1);
9097 result = winreg_printer_update_changeid(p->mem_ctx,
9098 get_server_info_system(),
9100 lp_const_servicename(snum));
9105 talloc_free(pinfo2);
9109 /****************************************************************
9110 _spoolss_DeletePrinterDataEx
9111 ****************************************************************/
9113 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
9114 struct spoolss_DeletePrinterDataEx *r)
9116 const char *printer;
9118 WERROR status = WERR_OK;
9119 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9121 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9124 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9125 "Invalid handle (%s:%u:%u).\n",
9126 OUR_HANDLE(r->in.handle)));
9130 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9131 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9132 "printer properties change denied by handle\n"));
9133 return WERR_ACCESS_DENIED;
9136 if (!r->in.value_name || !r->in.key_name) {
9140 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9143 printer = lp_const_servicename(snum);
9145 status = winreg_delete_printer_dataex(p->mem_ctx,
9146 get_server_info_system(),
9151 if (W_ERROR_IS_OK(status)) {
9152 status = winreg_printer_update_changeid(p->mem_ctx,
9153 get_server_info_system(),
9161 /****************************************************************
9162 _spoolss_EnumPrinterKey
9163 ****************************************************************/
9165 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
9166 struct spoolss_EnumPrinterKey *r)
9169 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9171 WERROR result = WERR_BADFILE;
9172 const char **array = NULL;
9175 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
9178 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
9179 OUR_HANDLE(r->in.handle)));
9183 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9187 result = winreg_enum_printer_key(p->mem_ctx,
9188 get_server_info_system(),
9190 lp_const_servicename(snum),
9194 if (!W_ERROR_IS_OK(result)) {
9198 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
9199 result = WERR_NOMEM;
9203 *r->out._ndr_size = r->in.offered / 2;
9204 *r->out.needed = blob.length;
9206 if (r->in.offered < *r->out.needed) {
9207 result = WERR_MORE_DATA;
9210 r->out.key_buffer->string_array = array;
9214 if (!W_ERROR_IS_OK(result)) {
9216 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9224 /****************************************************************
9225 _spoolss_DeletePrinterKey
9226 ****************************************************************/
9228 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
9229 struct spoolss_DeletePrinterKey *r)
9231 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9234 const char *printer;
9236 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9239 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9240 OUR_HANDLE(r->in.handle)));
9244 /* if keyname == NULL, return error */
9245 if ( !r->in.key_name )
9246 return WERR_INVALID_PARAM;
9248 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9252 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9253 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9254 "printer properties change denied by handle\n"));
9255 return WERR_ACCESS_DENIED;
9258 printer = lp_const_servicename(snum);
9260 /* delete the key and all subkeys */
9261 status = winreg_delete_printer_key(p->mem_ctx,
9262 get_server_info_system(),
9266 if (W_ERROR_IS_OK(status)) {
9267 status = winreg_printer_update_changeid(p->mem_ctx,
9268 get_server_info_system(),
9276 /****************************************************************
9277 _spoolss_EnumPrinterDataEx
9278 ****************************************************************/
9280 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
9281 struct spoolss_EnumPrinterDataEx *r)
9284 struct spoolss_PrinterEnumValues *info = NULL;
9285 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9289 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9293 *r->out.info = NULL;
9296 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9297 OUR_HANDLE(r->in.handle)));
9302 * first check for a keyname of NULL or "". Win2k seems to send
9303 * this a lot and we should send back WERR_INVALID_PARAM
9304 * no need to spend time looking up the printer in this case.
9308 if (!strlen(r->in.key_name)) {
9309 result = WERR_INVALID_PARAM;
9313 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9317 /* now look for a match on the key name */
9318 result = winreg_enum_printer_dataex(p->mem_ctx,
9319 get_server_info_system(),
9321 lp_const_servicename(snum),
9325 if (!W_ERROR_IS_OK(result)) {
9329 #if 0 /* FIXME - gd */
9330 /* housekeeping information in the reply */
9332 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9333 * the hand marshalled container size is a multiple
9334 * of 4 bytes for RPC alignment.
9338 needed += 4-(needed % 4);
9341 *r->out.count = count;
9342 *r->out.info = info;
9345 if (!W_ERROR_IS_OK(result)) {
9349 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9350 spoolss_EnumPrinterDataEx,
9353 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9354 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9356 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9359 /****************************************************************************
9360 ****************************************************************************/
9362 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9363 const char *servername,
9364 const char *environment,
9365 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9370 werr = compose_spoolss_server_path(mem_ctx,
9373 SPOOLSS_PRTPROCS_PATH,
9375 if (!W_ERROR_IS_OK(werr)) {
9379 DEBUG(4,("print processor directory: [%s]\n", path));
9381 r->directory_name = path;
9386 /****************************************************************
9387 _spoolss_GetPrintProcessorDirectory
9388 ****************************************************************/
9390 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9391 struct spoolss_GetPrintProcessorDirectory *r)
9395 /* that's an [in out] buffer */
9397 if (!r->in.buffer && (r->in.offered != 0)) {
9398 return WERR_INVALID_PARAM;
9401 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9406 /* r->in.level is ignored */
9408 /* We always should reply with a local print processor directory so that
9409 * users are not forced to have a [prnproc$] share on the Samba spoolss
9410 * server - Guenther */
9412 result = getprintprocessordirectory_level_1(p->mem_ctx,
9413 NULL, /* r->in.server */
9415 &r->out.info->info1);
9416 if (!W_ERROR_IS_OK(result)) {
9417 TALLOC_FREE(r->out.info);
9421 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9422 r->out.info, r->in.level);
9423 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9425 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9428 /*******************************************************************
9429 ********************************************************************/
9431 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9432 const char *dllname)
9434 enum ndr_err_code ndr_err;
9435 struct spoolss_MonitorUi ui;
9437 ui.dll_name = dllname;
9439 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9440 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9441 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9442 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9444 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9447 /*******************************************************************
9448 Streams the monitor UI DLL name in UNICODE
9449 *******************************************************************/
9451 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9452 NT_USER_TOKEN *token, DATA_BLOB *in,
9453 DATA_BLOB *out, uint32_t *needed)
9455 const char *dllname = "tcpmonui.dll";
9457 *needed = (strlen(dllname)+1) * 2;
9459 if (out->length < *needed) {
9460 return WERR_INSUFFICIENT_BUFFER;
9463 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9470 /*******************************************************************
9471 ********************************************************************/
9473 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9474 struct spoolss_PortData1 *port1,
9475 const DATA_BLOB *buf)
9477 enum ndr_err_code ndr_err;
9478 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9479 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9480 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9481 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9483 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9486 /*******************************************************************
9487 ********************************************************************/
9489 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9490 struct spoolss_PortData2 *port2,
9491 const DATA_BLOB *buf)
9493 enum ndr_err_code ndr_err;
9494 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9495 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9496 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9497 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9499 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9502 /*******************************************************************
9503 Create a new TCP/IP port
9504 *******************************************************************/
9506 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9507 NT_USER_TOKEN *token, DATA_BLOB *in,
9508 DATA_BLOB *out, uint32_t *needed)
9510 struct spoolss_PortData1 port1;
9511 struct spoolss_PortData2 port2;
9512 char *device_uri = NULL;
9515 const char *portname;
9516 const char *hostaddress;
9518 uint32_t port_number;
9521 /* peek for spoolss_PortData version */
9523 if (!in || (in->length < (128 + 4))) {
9524 return WERR_GENERAL_FAILURE;
9527 version = IVAL(in->data, 128);
9533 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9537 portname = port1.portname;
9538 hostaddress = port1.hostaddress;
9539 queue = port1.queue;
9540 protocol = port1.protocol;
9541 port_number = port1.port_number;
9547 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9551 portname = port2.portname;
9552 hostaddress = port2.hostaddress;
9553 queue = port2.queue;
9554 protocol = port2.protocol;
9555 port_number = port2.port_number;
9559 DEBUG(1,("xcvtcp_addport: "
9560 "unknown version of port_data: %d\n", version));
9561 return WERR_UNKNOWN_PORT;
9564 /* create the device URI and call the add_port_hook() */
9567 case PROTOCOL_RAWTCP_TYPE:
9568 device_uri = talloc_asprintf(mem_ctx,
9569 "socket://%s:%d/", hostaddress,
9573 case PROTOCOL_LPR_TYPE:
9574 device_uri = talloc_asprintf(mem_ctx,
9575 "lpr://%s/%s", hostaddress, queue );
9579 return WERR_UNKNOWN_PORT;
9586 return add_port_hook(mem_ctx, token, portname, device_uri);
9589 /*******************************************************************
9590 *******************************************************************/
9592 struct xcv_api_table xcvtcp_cmds[] = {
9593 { "MonitorUI", xcvtcp_monitorui },
9594 { "AddPort", xcvtcp_addport},
9598 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9599 NT_USER_TOKEN *token, const char *command,
9606 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9608 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9609 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9610 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9613 return WERR_BADFUNC;
9616 /*******************************************************************
9617 *******************************************************************/
9618 #if 0 /* don't support management using the "Local Port" monitor */
9620 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9621 NT_USER_TOKEN *token, DATA_BLOB *in,
9622 DATA_BLOB *out, uint32_t *needed)
9624 const char *dllname = "localui.dll";
9626 *needed = (strlen(dllname)+1) * 2;
9628 if (out->length < *needed) {
9629 return WERR_INSUFFICIENT_BUFFER;
9632 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9639 /*******************************************************************
9640 *******************************************************************/
9642 struct xcv_api_table xcvlocal_cmds[] = {
9643 { "MonitorUI", xcvlocal_monitorui },
9647 struct xcv_api_table xcvlocal_cmds[] = {
9654 /*******************************************************************
9655 *******************************************************************/
9657 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9658 NT_USER_TOKEN *token, const char *command,
9659 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9664 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9666 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9667 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9668 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9670 return WERR_BADFUNC;
9673 /****************************************************************
9675 ****************************************************************/
9677 WERROR _spoolss_XcvData(struct pipes_struct *p,
9678 struct spoolss_XcvData *r)
9680 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9681 DATA_BLOB out_data = data_blob_null;
9685 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9686 OUR_HANDLE(r->in.handle)));
9690 /* Has to be a handle to the TCP/IP port monitor */
9692 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9693 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9697 /* requires administrative access to the server */
9699 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9700 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9701 return WERR_ACCESS_DENIED;
9704 /* Allocate the outgoing buffer */
9706 if (r->in.out_data_size) {
9707 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9708 if (out_data.data == NULL) {
9713 switch ( Printer->printer_type ) {
9714 case SPLHND_PORTMON_TCP:
9715 werror = process_xcvtcp_command(p->mem_ctx,
9716 p->server_info->ptok,
9717 r->in.function_name,
9718 &r->in.in_data, &out_data,
9721 case SPLHND_PORTMON_LOCAL:
9722 werror = process_xcvlocal_command(p->mem_ctx,
9723 p->server_info->ptok,
9724 r->in.function_name,
9725 &r->in.in_data, &out_data,
9729 werror = WERR_INVALID_PRINT_MONITOR;
9732 if (!W_ERROR_IS_OK(werror)) {
9736 *r->out.status_code = 0;
9738 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9739 memcpy(r->out.out_data, out_data.data,
9740 MIN(r->in.out_data_size, out_data.length));
9746 /****************************************************************
9747 _spoolss_AddPrintProcessor
9748 ****************************************************************/
9750 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9751 struct spoolss_AddPrintProcessor *r)
9753 /* for now, just indicate success and ignore the add. We'll
9754 automatically set the winprint processor for printer
9755 entries later. Used to debug the LexMark Optra S 1855 PCL
9761 /****************************************************************
9763 ****************************************************************/
9765 WERROR _spoolss_AddPort(struct pipes_struct *p,
9766 struct spoolss_AddPort *r)
9768 /* do what w2k3 does */
9770 return WERR_NOT_SUPPORTED;
9773 /****************************************************************
9774 _spoolss_GetPrinterDriver
9775 ****************************************************************/
9777 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9778 struct spoolss_GetPrinterDriver *r)
9780 p->rng_fault_state = true;
9781 return WERR_NOT_SUPPORTED;
9784 /****************************************************************
9785 _spoolss_ReadPrinter
9786 ****************************************************************/
9788 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9789 struct spoolss_ReadPrinter *r)
9791 p->rng_fault_state = true;
9792 return WERR_NOT_SUPPORTED;
9795 /****************************************************************
9796 _spoolss_WaitForPrinterChange
9797 ****************************************************************/
9799 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9800 struct spoolss_WaitForPrinterChange *r)
9802 p->rng_fault_state = true;
9803 return WERR_NOT_SUPPORTED;
9806 /****************************************************************
9807 _spoolss_ConfigurePort
9808 ****************************************************************/
9810 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9811 struct spoolss_ConfigurePort *r)
9813 p->rng_fault_state = true;
9814 return WERR_NOT_SUPPORTED;
9817 /****************************************************************
9819 ****************************************************************/
9821 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9822 struct spoolss_DeletePort *r)
9824 p->rng_fault_state = true;
9825 return WERR_NOT_SUPPORTED;
9828 /****************************************************************
9829 _spoolss_CreatePrinterIC
9830 ****************************************************************/
9832 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9833 struct spoolss_CreatePrinterIC *r)
9835 p->rng_fault_state = true;
9836 return WERR_NOT_SUPPORTED;
9839 /****************************************************************
9840 _spoolss_PlayGDIScriptOnPrinterIC
9841 ****************************************************************/
9843 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9844 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9846 p->rng_fault_state = true;
9847 return WERR_NOT_SUPPORTED;
9850 /****************************************************************
9851 _spoolss_DeletePrinterIC
9852 ****************************************************************/
9854 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9855 struct spoolss_DeletePrinterIC *r)
9857 p->rng_fault_state = true;
9858 return WERR_NOT_SUPPORTED;
9861 /****************************************************************
9862 _spoolss_AddPrinterConnection
9863 ****************************************************************/
9865 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9866 struct spoolss_AddPrinterConnection *r)
9868 p->rng_fault_state = true;
9869 return WERR_NOT_SUPPORTED;
9872 /****************************************************************
9873 _spoolss_DeletePrinterConnection
9874 ****************************************************************/
9876 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9877 struct spoolss_DeletePrinterConnection *r)
9879 p->rng_fault_state = true;
9880 return WERR_NOT_SUPPORTED;
9883 /****************************************************************
9884 _spoolss_PrinterMessageBox
9885 ****************************************************************/
9887 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9888 struct spoolss_PrinterMessageBox *r)
9890 p->rng_fault_state = true;
9891 return WERR_NOT_SUPPORTED;
9894 /****************************************************************
9896 ****************************************************************/
9898 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9899 struct spoolss_AddMonitor *r)
9901 p->rng_fault_state = true;
9902 return WERR_NOT_SUPPORTED;
9905 /****************************************************************
9906 _spoolss_DeleteMonitor
9907 ****************************************************************/
9909 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9910 struct spoolss_DeleteMonitor *r)
9912 p->rng_fault_state = true;
9913 return WERR_NOT_SUPPORTED;
9916 /****************************************************************
9917 _spoolss_DeletePrintProcessor
9918 ****************************************************************/
9920 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9921 struct spoolss_DeletePrintProcessor *r)
9923 p->rng_fault_state = true;
9924 return WERR_NOT_SUPPORTED;
9927 /****************************************************************
9928 _spoolss_AddPrintProvidor
9929 ****************************************************************/
9931 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9932 struct spoolss_AddPrintProvidor *r)
9934 p->rng_fault_state = true;
9935 return WERR_NOT_SUPPORTED;
9938 /****************************************************************
9939 _spoolss_DeletePrintProvidor
9940 ****************************************************************/
9942 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9943 struct spoolss_DeletePrintProvidor *r)
9945 p->rng_fault_state = true;
9946 return WERR_NOT_SUPPORTED;
9949 /****************************************************************
9950 _spoolss_FindFirstPrinterChangeNotification
9951 ****************************************************************/
9953 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9954 struct spoolss_FindFirstPrinterChangeNotification *r)
9956 p->rng_fault_state = true;
9957 return WERR_NOT_SUPPORTED;
9960 /****************************************************************
9961 _spoolss_FindNextPrinterChangeNotification
9962 ****************************************************************/
9964 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9965 struct spoolss_FindNextPrinterChangeNotification *r)
9967 p->rng_fault_state = true;
9968 return WERR_NOT_SUPPORTED;
9971 /****************************************************************
9972 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9973 ****************************************************************/
9975 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9976 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9978 p->rng_fault_state = true;
9979 return WERR_NOT_SUPPORTED;
9982 /****************************************************************
9983 _spoolss_ReplyOpenPrinter
9984 ****************************************************************/
9986 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9987 struct spoolss_ReplyOpenPrinter *r)
9989 p->rng_fault_state = true;
9990 return WERR_NOT_SUPPORTED;
9993 /****************************************************************
9994 _spoolss_RouterReplyPrinter
9995 ****************************************************************/
9997 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9998 struct spoolss_RouterReplyPrinter *r)
10000 p->rng_fault_state = true;
10001 return WERR_NOT_SUPPORTED;
10004 /****************************************************************
10005 _spoolss_ReplyClosePrinter
10006 ****************************************************************/
10008 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
10009 struct spoolss_ReplyClosePrinter *r)
10011 p->rng_fault_state = true;
10012 return WERR_NOT_SUPPORTED;
10015 /****************************************************************
10017 ****************************************************************/
10019 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
10020 struct spoolss_AddPortEx *r)
10022 p->rng_fault_state = true;
10023 return WERR_NOT_SUPPORTED;
10026 /****************************************************************
10027 _spoolss_RouterFindFirstPrinterChangeNotification
10028 ****************************************************************/
10030 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
10031 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10033 p->rng_fault_state = true;
10034 return WERR_NOT_SUPPORTED;
10037 /****************************************************************
10038 _spoolss_SpoolerInit
10039 ****************************************************************/
10041 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
10042 struct spoolss_SpoolerInit *r)
10044 p->rng_fault_state = true;
10045 return WERR_NOT_SUPPORTED;
10048 /****************************************************************
10049 _spoolss_ResetPrinterEx
10050 ****************************************************************/
10052 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
10053 struct spoolss_ResetPrinterEx *r)
10055 p->rng_fault_state = true;
10056 return WERR_NOT_SUPPORTED;
10059 /****************************************************************
10060 _spoolss_RouterReplyPrinterEx
10061 ****************************************************************/
10063 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
10064 struct spoolss_RouterReplyPrinterEx *r)
10066 p->rng_fault_state = true;
10067 return WERR_NOT_SUPPORTED;
10070 /****************************************************************
10072 ****************************************************************/
10074 WERROR _spoolss_44(struct pipes_struct *p,
10075 struct spoolss_44 *r)
10077 p->rng_fault_state = true;
10078 return WERR_NOT_SUPPORTED;
10081 /****************************************************************
10083 ****************************************************************/
10085 WERROR _spoolss_47(struct pipes_struct *p,
10086 struct spoolss_47 *r)
10088 p->rng_fault_state = true;
10089 return WERR_NOT_SUPPORTED;
10092 /****************************************************************
10094 ****************************************************************/
10096 WERROR _spoolss_4a(struct pipes_struct *p,
10097 struct spoolss_4a *r)
10099 p->rng_fault_state = true;
10100 return WERR_NOT_SUPPORTED;
10103 /****************************************************************
10105 ****************************************************************/
10107 WERROR _spoolss_4b(struct pipes_struct *p,
10108 struct spoolss_4b *r)
10110 p->rng_fault_state = true;
10111 return WERR_NOT_SUPPORTED;
10114 /****************************************************************
10116 ****************************************************************/
10118 WERROR _spoolss_4c(struct pipes_struct *p,
10119 struct spoolss_4c *r)
10121 p->rng_fault_state = true;
10122 return WERR_NOT_SUPPORTED;
10125 /****************************************************************
10127 ****************************************************************/
10129 WERROR _spoolss_53(struct pipes_struct *p,
10130 struct spoolss_53 *r)
10132 p->rng_fault_state = true;
10133 return WERR_NOT_SUPPORTED;
10136 /****************************************************************
10138 ****************************************************************/
10140 WERROR _spoolss_55(struct pipes_struct *p,
10141 struct spoolss_55 *r)
10143 p->rng_fault_state = true;
10144 return WERR_NOT_SUPPORTED;
10147 /****************************************************************
10149 ****************************************************************/
10151 WERROR _spoolss_56(struct pipes_struct *p,
10152 struct spoolss_56 *r)
10154 p->rng_fault_state = true;
10155 return WERR_NOT_SUPPORTED;
10158 /****************************************************************
10160 ****************************************************************/
10162 WERROR _spoolss_57(struct pipes_struct *p,
10163 struct spoolss_57 *r)
10165 p->rng_fault_state = true;
10166 return WERR_NOT_SUPPORTED;
10169 /****************************************************************
10171 ****************************************************************/
10173 WERROR _spoolss_5a(struct pipes_struct *p,
10174 struct spoolss_5a *r)
10176 p->rng_fault_state = true;
10177 return WERR_NOT_SUPPORTED;
10180 /****************************************************************
10182 ****************************************************************/
10184 WERROR _spoolss_5b(struct pipes_struct *p,
10185 struct spoolss_5b *r)
10187 p->rng_fault_state = true;
10188 return WERR_NOT_SUPPORTED;
10191 /****************************************************************
10193 ****************************************************************/
10195 WERROR _spoolss_5c(struct pipes_struct *p,
10196 struct spoolss_5c *r)
10198 p->rng_fault_state = true;
10199 return WERR_NOT_SUPPORTED;
10202 /****************************************************************
10204 ****************************************************************/
10206 WERROR _spoolss_5d(struct pipes_struct *p,
10207 struct spoolss_5d *r)
10209 p->rng_fault_state = true;
10210 return WERR_NOT_SUPPORTED;
10213 /****************************************************************
10215 ****************************************************************/
10217 WERROR _spoolss_5e(struct pipes_struct *p,
10218 struct spoolss_5e *r)
10220 p->rng_fault_state = true;
10221 return WERR_NOT_SUPPORTED;
10224 /****************************************************************
10226 ****************************************************************/
10228 WERROR _spoolss_5f(struct pipes_struct *p,
10229 struct spoolss_5f *r)
10231 p->rng_fault_state = true;
10232 return WERR_NOT_SUPPORTED;
10235 /****************************************************************
10237 ****************************************************************/
10239 WERROR _spoolss_60(struct pipes_struct *p,
10240 struct spoolss_60 *r)
10242 p->rng_fault_state = true;
10243 return WERR_NOT_SUPPORTED;
10246 /****************************************************************
10248 ****************************************************************/
10250 WERROR _spoolss_61(struct pipes_struct *p,
10251 struct spoolss_61 *r)
10253 p->rng_fault_state = true;
10254 return WERR_NOT_SUPPORTED;
10257 /****************************************************************
10259 ****************************************************************/
10261 WERROR _spoolss_62(struct pipes_struct *p,
10262 struct spoolss_62 *r)
10264 p->rng_fault_state = true;
10265 return WERR_NOT_SUPPORTED;
10268 /****************************************************************
10270 ****************************************************************/
10272 WERROR _spoolss_63(struct pipes_struct *p,
10273 struct spoolss_63 *r)
10275 p->rng_fault_state = true;
10276 return WERR_NOT_SUPPORTED;
10279 /****************************************************************
10281 ****************************************************************/
10283 WERROR _spoolss_64(struct pipes_struct *p,
10284 struct spoolss_64 *r)
10286 p->rng_fault_state = true;
10287 return WERR_NOT_SUPPORTED;
10290 /****************************************************************
10292 ****************************************************************/
10294 WERROR _spoolss_65(struct pipes_struct *p,
10295 struct spoolss_65 *r)
10297 p->rng_fault_state = true;
10298 return WERR_NOT_SUPPORTED;
10301 /****************************************************************
10302 _spoolss_GetCorePrinterDrivers
10303 ****************************************************************/
10305 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
10306 struct spoolss_GetCorePrinterDrivers *r)
10308 p->rng_fault_state = true;
10309 return WERR_NOT_SUPPORTED;
10312 /****************************************************************
10314 ****************************************************************/
10316 WERROR _spoolss_67(struct pipes_struct *p,
10317 struct spoolss_67 *r)
10319 p->rng_fault_state = true;
10320 return WERR_NOT_SUPPORTED;
10323 /****************************************************************
10324 _spoolss_GetPrinterDriverPackagePath
10325 ****************************************************************/
10327 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
10328 struct spoolss_GetPrinterDriverPackagePath *r)
10330 p->rng_fault_state = true;
10331 return WERR_NOT_SUPPORTED;
10334 /****************************************************************
10336 ****************************************************************/
10338 WERROR _spoolss_69(struct pipes_struct *p,
10339 struct spoolss_69 *r)
10341 p->rng_fault_state = true;
10342 return WERR_NOT_SUPPORTED;
10345 /****************************************************************
10347 ****************************************************************/
10349 WERROR _spoolss_6a(struct pipes_struct *p,
10350 struct spoolss_6a *r)
10352 p->rng_fault_state = true;
10353 return WERR_NOT_SUPPORTED;
10356 /****************************************************************
10358 ****************************************************************/
10360 WERROR _spoolss_6b(struct pipes_struct *p,
10361 struct spoolss_6b *r)
10363 p->rng_fault_state = true;
10364 return WERR_NOT_SUPPORTED;
10367 /****************************************************************
10369 ****************************************************************/
10371 WERROR _spoolss_6c(struct pipes_struct *p,
10372 struct spoolss_6c *r)
10374 p->rng_fault_state = true;
10375 return WERR_NOT_SUPPORTED;
10378 /****************************************************************
10380 ****************************************************************/
10382 WERROR _spoolss_6d(struct pipes_struct *p,
10383 struct spoolss_6d *r)
10385 p->rng_fault_state = true;
10386 return WERR_NOT_SUPPORTED;