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.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern userdom_struct current_user_info;
33 #define DBGC_CLASS DBGC_RPC_SRV
35 #ifndef MAX_OPEN_PRINTER_EXS
36 #define MAX_OPEN_PRINTER_EXS 50
39 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
40 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
43 const char *long_archi;
44 const char *short_archi;
48 static Printer_entry *printers_list;
50 typedef struct _counter_printer_0 {
51 struct _counter_printer_0 *next;
52 struct _counter_printer_0 *prev;
58 static counter_printer_0 *counter_list;
60 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
61 static uint32 smb_connections=0;
64 /* in printing/nt_printing.c */
66 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
68 /* API table for Xcv Monitor functions */
70 struct xcv_api_table {
72 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
75 /********************************************************************
76 * Canonicalize servername.
77 ********************************************************************/
79 static const char *canon_servername(const char *servername)
81 const char *pservername = servername;
82 while (*pservername == '\\') {
88 /* translate between internal status numbers and NT status numbers */
89 static int nt_printj_status(int v)
95 return JOB_STATUS_PAUSED;
97 return JOB_STATUS_SPOOLING;
99 return JOB_STATUS_PRINTING;
101 return JOB_STATUS_ERROR;
103 return JOB_STATUS_DELETING;
105 return JOB_STATUS_OFFLINE;
107 return JOB_STATUS_PAPEROUT;
109 return JOB_STATUS_PRINTED;
111 return JOB_STATUS_DELETED;
113 return JOB_STATUS_BLOCKED_DEVQ;
114 case LPQ_USER_INTERVENTION:
115 return JOB_STATUS_USER_INTERVENTION;
120 static int nt_printq_status(int v)
124 return PRINTER_STATUS_PAUSED;
133 /***************************************************************************
134 Disconnect from the client
135 ****************************************************************************/
137 static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
143 * Tell the specific printing tdb we no longer want messages for this printer
144 * by deregistering our PID.
147 if (!print_notify_deregister_pid(snum))
148 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
150 /* weird if the test succeds !!! */
151 if (smb_connections==0) {
152 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
156 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
159 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
160 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
161 win_errstr(result)));
163 /* if it's the last connection, deconnect the IPC$ share */
164 if (smb_connections==1) {
166 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
167 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
169 messaging_deregister(smbd_messaging_context(),
170 MSG_PRINTER_NOTIFY2, NULL);
172 /* Tell the connections db we're no longer interested in
173 * printer notify messages. */
175 register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
181 /****************************************************************************
182 Functions to free a printer entry datastruct.
183 ****************************************************************************/
185 static int printer_entry_destructor(Printer_entry *Printer)
187 if (Printer->notify.client_connected==True) {
190 if ( Printer->printer_type == SPLHND_SERVER) {
192 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
193 } else if (Printer->printer_type == SPLHND_PRINTER) {
194 snum = print_queue_snum(Printer->sharename);
196 srv_spoolss_replycloseprinter(snum,
197 &Printer->notify.client_hnd);
201 Printer->notify.flags=0;
202 Printer->notify.options=0;
203 Printer->notify.localmachine[0]='\0';
204 Printer->notify.printerlocal=0;
205 TALLOC_FREE(Printer->notify.option);
206 Printer->notify.client_connected=False;
208 free_nt_devicemode( &Printer->nt_devmode );
209 free_a_printer( &Printer->printer_info, 2 );
211 /* Remove from the internal list. */
212 DLIST_REMOVE(printers_list, Printer);
216 /****************************************************************************
217 find printer index by handle
218 ****************************************************************************/
220 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
222 Printer_entry *find_printer = NULL;
224 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
225 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
232 /****************************************************************************
233 Close printer index by handle.
234 ****************************************************************************/
236 static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
238 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
241 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
245 close_policy_hnd(p, hnd);
250 /****************************************************************************
251 Delete a printer given a handle.
252 ****************************************************************************/
254 WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
256 char *cmd = lp_deleteprinter_cmd();
257 char *command = NULL;
259 SE_PRIV se_printop = SE_PRINT_OPERATOR;
260 bool is_print_op = False;
262 /* can't fail if we don't try */
267 command = talloc_asprintf(ctx,
274 is_print_op = user_has_privileges( token, &se_printop );
276 DEBUG(10,("Running [%s]\n", command));
278 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
283 if ( (ret = smbrun(command, NULL)) == 0 ) {
284 /* Tell everyone we updated smb.conf. */
285 message_send_all(smbd_messaging_context(),
286 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
292 /********** END SePrintOperatorPrivlege BLOCK **********/
294 DEBUGADD(10,("returned [%d]\n", ret));
296 TALLOC_FREE(command);
299 return WERR_BADFID; /* What to return here? */
301 /* go ahead and re-read the services immediately */
302 reload_services( False );
304 if ( lp_servicenumber( sharename ) < 0 )
305 return WERR_ACCESS_DENIED;
310 /****************************************************************************
311 Delete a printer given a handle.
312 ****************************************************************************/
314 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
316 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
319 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
324 * It turns out that Windows allows delete printer on a handle
325 * opened by an admin user, then used on a pipe handle created
326 * by an anonymous user..... but they're working on security.... riiight !
330 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
331 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
332 return WERR_ACCESS_DENIED;
335 /* this does not need a become root since the access check has been
336 done on the handle already */
338 if (del_a_printer( Printer->sharename ) != 0) {
339 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
343 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
344 Printer->sharename );
347 /****************************************************************************
348 Return the snum of a printer corresponding to an handle.
349 ****************************************************************************/
351 static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
352 struct share_params **params)
354 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
357 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
361 switch (Printer->printer_type) {
363 DEBUG(4,("short name:%s\n", Printer->sharename));
364 *number = print_queue_snum(Printer->sharename);
365 return (*number != -1);
373 /****************************************************************************
374 Set printer handle type.
375 Check if it's \\server or \\server\printer
376 ****************************************************************************/
378 static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
380 DEBUG(3,("Setting printer type=%s\n", handlename));
382 if ( strlen(handlename) < 3 ) {
383 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
387 /* it's a print server */
388 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
389 DEBUGADD(4,("Printer is a print server\n"));
390 Printer->printer_type = SPLHND_SERVER;
392 /* it's a printer (set_printer_hnd_name() will handle port monitors */
394 DEBUGADD(4,("Printer is a printer\n"));
395 Printer->printer_type = SPLHND_PRINTER;
401 /****************************************************************************
402 Set printer handle name.. Accept names like \\server, \\server\printer,
403 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
404 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
405 XcvDataPort() interface.
406 ****************************************************************************/
408 static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
411 int n_services=lp_numservices();
412 char *aprinter, *printername;
413 const char *servername;
416 NT_PRINTER_INFO_LEVEL *printer = NULL;
419 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
421 aprinter = handlename;
422 if ( *handlename == '\\' ) {
423 servername = canon_servername(handlename);
424 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
432 /* save the servername to fill in replies on this handle */
434 if ( !is_myname_or_ipaddr( servername ) )
437 fstrcpy( Printer->servername, servername );
439 if ( Printer->printer_type == SPLHND_SERVER )
442 if ( Printer->printer_type != SPLHND_PRINTER )
445 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
447 /* check for the Port Monitor Interface */
449 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
450 Printer->printer_type = SPLHND_PORTMON_TCP;
451 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
454 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
455 Printer->printer_type = SPLHND_PORTMON_LOCAL;
456 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
460 /* Search all sharenames first as this is easier than pulling
461 the printer_info_2 off of disk. Don't use find_service() since
462 that calls out to map_username() */
464 /* do another loop to look for printernames */
466 for (snum=0; !found && snum<n_services; snum++) {
468 /* no point going on if this is not a printer */
470 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
473 fstrcpy(sname, lp_servicename(snum));
474 if ( strequal( aprinter, sname ) ) {
479 /* no point looking up the printer object if
480 we aren't allowing printername != sharename */
482 if ( lp_force_printername(snum) )
485 fstrcpy(sname, lp_servicename(snum));
489 /* This call doesn't fill in the location or comment from
490 * a CUPS server for efficiency with large numbers of printers.
494 result = get_a_printer_search( NULL, &printer, 2, sname );
495 if ( !W_ERROR_IS_OK(result) ) {
496 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
497 sname, win_errstr(result)));
501 /* printername is always returned as \\server\printername */
502 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
503 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
504 printer->info_2->printername));
505 free_a_printer( &printer, 2);
511 if ( strequal(printername, aprinter) ) {
512 free_a_printer( &printer, 2);
517 DEBUGADD(10, ("printername: %s\n", printername));
519 free_a_printer( &printer, 2);
522 free_a_printer( &printer, 2);
525 DEBUGADD(4,("Printer not found\n"));
529 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
531 fstrcpy(Printer->sharename, sname);
536 /****************************************************************************
537 Find first available printer slot. creates a printer handle for you.
538 ****************************************************************************/
540 static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
542 Printer_entry *new_printer;
544 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
546 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
547 if (new_printer == NULL) {
550 talloc_set_destructor(new_printer, printer_entry_destructor);
552 if (!create_policy_hnd(p, hnd, new_printer)) {
553 TALLOC_FREE(new_printer);
557 /* Add to the internal list. */
558 DLIST_ADD(printers_list, new_printer);
560 new_printer->notify.option=NULL;
562 if (!set_printer_hnd_printertype(new_printer, name)) {
563 close_printer_handle(p, hnd);
567 if (!set_printer_hnd_name(new_printer, name)) {
568 close_printer_handle(p, hnd);
572 new_printer->access_granted = access_granted;
574 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
579 /***************************************************************************
580 check to see if the client motify handle is monitoring the notification
581 given by (notify_type, notify_field).
582 **************************************************************************/
584 static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type,
590 static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
593 struct spoolss_NotifyOption *option = p->notify.option;
597 * Flags should always be zero when the change notify
598 * is registered by the client's spooler. A user Win32 app
599 * might use the flags though instead of the NOTIFY_OPTION_INFO
608 return is_monitoring_event_flags(
609 p->notify.flags, notify_type, notify_field);
611 for (i = 0; i < option->count; i++) {
613 /* Check match for notify_type */
615 if (option->types[i].type != notify_type)
618 /* Check match for field */
620 for (j = 0; j < option->types[i].count; j++) {
621 if (option->types[i].fields[j] == notify_field) {
627 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
628 p->servername, p->sharename, notify_type, notify_field));
633 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
634 _data->data.integer[0] = _integer; \
635 _data->data.integer[1] = 0;
638 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
639 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
640 if (!_data->data.string.string) {\
641 _data->data.string.size = 0; \
643 _data->data.string.size = strlen_m_term(_p) * 2;
645 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
646 _data->data.devmode.devmode = _devmode;
648 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
649 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
650 if (!_data->data.sd.sd) { \
651 _data->data.sd.sd_size = 0; \
653 _data->data.sd.sd_size = _size;
655 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
660 struct spoolss_Time st;
664 if (!init_systemtime(&st, t)) {
668 p = talloc_array(mem_ctx, char, len);
674 * Systemtime must be linearized as a set of UINT16's.
675 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
678 SSVAL(p, 0, st.year);
679 SSVAL(p, 2, st.month);
680 SSVAL(p, 4, st.day_of_week);
682 SSVAL(p, 8, st.hour);
683 SSVAL(p, 10, st.minute);
684 SSVAL(p, 12, st.second);
685 SSVAL(p, 14, st.millisecond);
691 /* Convert a notification message to a struct spoolss_Notify */
693 static void notify_one_value(struct spoolss_notify_msg *msg,
694 struct spoolss_Notify *data,
697 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
700 static void notify_string(struct spoolss_notify_msg *msg,
701 struct spoolss_Notify *data,
704 /* The length of the message includes the trailing \0 */
706 data->data.string.size = msg->len * 2;
707 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
708 if (!data->data.string.string) {
709 data->data.string.size = 0;
714 static void notify_system_time(struct spoolss_notify_msg *msg,
715 struct spoolss_Notify *data,
718 data->data.string.string = NULL;
719 data->data.string.size = 0;
721 if (msg->len != sizeof(time_t)) {
722 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
727 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
728 &data->data.string.string,
729 &data->data.string.size);
732 struct notify2_message_table {
734 void (*fn)(struct spoolss_notify_msg *msg,
735 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
738 static struct notify2_message_table printer_notify_table[] = {
739 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
740 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
741 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
742 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
743 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
744 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
745 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
746 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
747 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
748 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
749 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
750 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
751 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
752 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
753 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
754 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
755 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
756 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
757 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
760 static struct notify2_message_table job_notify_table[] = {
761 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
762 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
763 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
764 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
765 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
766 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
767 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
768 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
769 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
770 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
771 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
772 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
773 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
774 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
775 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
776 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
777 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
778 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
779 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
780 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
781 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
782 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
783 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
784 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
788 /***********************************************************************
789 Allocate talloc context for container object
790 **********************************************************************/
792 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
797 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
802 /***********************************************************************
803 release all allocated memory and zero out structure
804 **********************************************************************/
806 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
812 talloc_destroy(ctr->ctx);
819 /***********************************************************************
820 **********************************************************************/
822 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
830 /***********************************************************************
831 **********************************************************************/
833 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
835 if ( !ctr || !ctr->msg_groups )
838 if ( idx >= ctr->num_groups )
841 return &ctr->msg_groups[idx];
845 /***********************************************************************
846 How many groups of change messages do we have ?
847 **********************************************************************/
849 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
854 return ctr->num_groups;
857 /***********************************************************************
858 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
859 **********************************************************************/
861 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
863 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
864 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
865 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
871 /* loop over all groups looking for a matching printer name */
873 for ( i=0; i<ctr->num_groups; i++ ) {
874 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
878 /* add a new group? */
880 if ( i == ctr->num_groups ) {
883 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
884 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
887 ctr->msg_groups = groups;
889 /* clear the new entry and set the printer name */
891 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
892 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
895 /* add the change messages; 'i' is the correct index now regardless */
897 msg_grp = &ctr->msg_groups[i];
901 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
902 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
905 msg_grp->msgs = msg_list;
907 new_slot = msg_grp->num_msgs-1;
908 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
910 /* need to allocate own copy of data */
913 msg_grp->msgs[new_slot].notify.data = (char *)
914 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
916 return ctr->num_groups;
919 /***********************************************************************
920 Send a change notication message on all handles which have a call
922 **********************************************************************/
924 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
927 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
928 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
929 SPOOLSS_NOTIFY_MSG *messages;
930 int sending_msg_count;
933 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
937 messages = msg_group->msgs;
940 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
944 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
946 /* loop over all printers */
948 for (p = printers_list; p; p = p->next) {
949 struct spoolss_Notify *notifies;
954 /* Is there notification on this handle? */
956 if ( !p->notify.client_connected )
959 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
961 /* For this printer? Print servers always receive
964 if ( ( p->printer_type == SPLHND_PRINTER ) &&
965 ( !strequal(msg_group->printername, p->sharename) ) )
968 DEBUG(10,("Our printer\n"));
970 /* allocate the max entries possible */
972 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
977 /* build the array of change notifications */
979 sending_msg_count = 0;
981 for ( i=0; i<msg_group->num_msgs; i++ ) {
982 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
984 /* Are we monitoring this event? */
986 if (!is_monitoring_event(p, msg->type, msg->field))
992 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
993 msg->type, msg->field, p->sharename));
996 * if the is a printer notification handle and not a job notification
997 * type, then set the id to 0. Other wise just use what was specified
1000 * When registering change notification on a print server handle
1001 * we always need to send back the id (snum) matching the printer
1002 * for which the change took place. For change notify registered
1003 * on a printer handle, this does not matter and the id should be 0.
1008 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1014 /* Convert unix jobid to smb jobid */
1016 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1017 id = sysjob_to_jobid(msg->id);
1020 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1025 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1028 case PRINTER_NOTIFY_TYPE:
1029 if ( printer_notify_table[msg->field].fn )
1030 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1033 case JOB_NOTIFY_TYPE:
1034 if ( job_notify_table[msg->field].fn )
1035 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1039 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1046 if ( sending_msg_count ) {
1049 union spoolss_ReplyPrinterInfo info;
1050 struct spoolss_NotifyInfo info0;
1051 uint32_t reply_result;
1053 info0.version = 0x2;
1054 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1055 info0.count = count;
1056 info0.notifies = notifies;
1058 info.info0 = &info0;
1060 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1061 &p->notify.client_hnd,
1062 p->notify.change, /* color */
1065 0, /* reply_type, must be 0 */
1068 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1069 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1070 notify_cli_pipe->srv_name_slash,
1073 switch (reply_result) {
1076 case PRINTER_NOTIFY_INFO_DISCARDED:
1077 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1078 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1087 DEBUG(8,("send_notify2_changes: Exit...\n"));
1091 /***********************************************************************
1092 **********************************************************************/
1094 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1097 uint32 tv_sec, tv_usec;
1100 /* Unpack message */
1102 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
1105 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
1107 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1110 tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
1111 &msg->notify.value[0], &msg->notify.value[1]);
1113 tdb_unpack((uint8 *)buf + offset, len - offset, "B",
1114 &msg->len, &msg->notify.data);
1116 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1117 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1119 tv->tv_sec = tv_sec;
1120 tv->tv_usec = tv_usec;
1123 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1124 msg->notify.value[1]));
1126 dump_data(3, (uint8 *)msg->notify.data, msg->len);
1131 /********************************************************************
1132 Receive a notify2 message list
1133 ********************************************************************/
1135 static void receive_notify2_message_list(struct messaging_context *msg,
1138 struct server_id server_id,
1141 size_t msg_count, i;
1142 char *buf = (char *)data->data;
1145 SPOOLSS_NOTIFY_MSG notify;
1146 SPOOLSS_NOTIFY_MSG_CTR messages;
1149 if (data->length < 4) {
1150 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1154 msg_count = IVAL(buf, 0);
1157 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1159 if (msg_count == 0) {
1160 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1164 /* initialize the container */
1166 ZERO_STRUCT( messages );
1167 notify_msg_ctr_init( &messages );
1170 * build message groups for each printer identified
1171 * in a change_notify msg. Remember that a PCN message
1172 * includes the handle returned for the srv_spoolss_replyopenprinter()
1173 * call. Therefore messages are grouped according to printer handle.
1176 for ( i=0; i<msg_count; i++ ) {
1177 struct timeval msg_tv;
1179 if (msg_ptr + 4 - buf > data->length) {
1180 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1184 msg_len = IVAL(msg_ptr,0);
1187 if (msg_ptr + msg_len - buf > data->length) {
1188 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1192 /* unpack messages */
1194 ZERO_STRUCT( notify );
1195 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1198 /* add to correct list in container */
1200 notify_msg_ctr_addmsg( &messages, ¬ify );
1202 /* free memory that might have been allocated by notify2_unpack_msg() */
1204 if ( notify.len != 0 )
1205 SAFE_FREE( notify.notify.data );
1208 /* process each group of messages */
1210 num_groups = notify_msg_ctr_numgroups( &messages );
1211 for ( i=0; i<num_groups; i++ )
1212 send_notify2_changes( &messages, i );
1217 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1219 notify_msg_ctr_destroy( &messages );
1224 /********************************************************************
1225 Send a message to ourself about new driver being installed
1226 so we can upgrade the information for each printer bound to this
1228 ********************************************************************/
1230 static bool srv_spoolss_drv_upgrade_printer(char* drivername)
1232 int len = strlen(drivername);
1237 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1240 messaging_send_buf(smbd_messaging_context(), procid_self(),
1241 MSG_PRINTER_DRVUPGRADE,
1242 (uint8 *)drivername, len+1);
1247 /**********************************************************************
1248 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1249 over all printers, upgrading ones as necessary
1250 **********************************************************************/
1252 void do_drv_upgrade_printer(struct messaging_context *msg,
1255 struct server_id server_id,
1260 int n_services = lp_numservices();
1263 len = MIN(data->length,sizeof(drivername)-1);
1264 strncpy(drivername, (const char *)data->data, len);
1266 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1268 /* Iterate the printer list */
1270 for (snum=0; snum<n_services; snum++)
1272 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1275 NT_PRINTER_INFO_LEVEL *printer = NULL;
1277 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1278 if (!W_ERROR_IS_OK(result))
1281 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1283 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1285 /* all we care about currently is the change_id */
1287 result = mod_a_printer(printer, 2);
1288 if (!W_ERROR_IS_OK(result)) {
1289 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1290 win_errstr(result)));
1294 free_a_printer(&printer, 2);
1301 /********************************************************************
1302 Update the cache for all printq's with a registered client
1304 ********************************************************************/
1306 void update_monitored_printq_cache( void )
1308 Printer_entry *printer = printers_list;
1311 /* loop through all printers and update the cache where
1312 client_connected == True */
1315 if ( (printer->printer_type == SPLHND_PRINTER)
1316 && printer->notify.client_connected )
1318 snum = print_queue_snum(printer->sharename);
1319 print_queue_status( snum, NULL, NULL );
1322 printer = printer->next;
1327 /********************************************************************
1328 Send a message to ourself about new driver being installed
1329 so we can upgrade the information for each printer bound to this
1331 ********************************************************************/
1333 static bool srv_spoolss_reset_printerdata(char* drivername)
1335 int len = strlen(drivername);
1340 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1343 messaging_send_buf(smbd_messaging_context(), procid_self(),
1344 MSG_PRINTERDATA_INIT_RESET,
1345 (uint8 *)drivername, len+1);
1350 /**********************************************************************
1351 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1352 over all printers, resetting printer data as neessary
1353 **********************************************************************/
1355 void reset_all_printerdata(struct messaging_context *msg,
1358 struct server_id server_id,
1363 int n_services = lp_numservices();
1366 len = MIN( data->length, sizeof(drivername)-1 );
1367 strncpy( drivername, (const char *)data->data, len );
1369 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1371 /* Iterate the printer list */
1373 for ( snum=0; snum<n_services; snum++ )
1375 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1378 NT_PRINTER_INFO_LEVEL *printer = NULL;
1380 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1381 if ( !W_ERROR_IS_OK(result) )
1385 * if the printer is bound to the driver,
1386 * then reset to the new driver initdata
1389 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1391 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1393 if ( !set_driver_init(printer, 2) ) {
1394 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1395 printer->info_2->printername, printer->info_2->drivername));
1398 result = mod_a_printer( printer, 2 );
1399 if ( !W_ERROR_IS_OK(result) ) {
1400 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1401 get_dos_error_msg(result)));
1405 free_a_printer( &printer, 2 );
1414 /****************************************************************
1415 _spoolss_OpenPrinter
1416 ****************************************************************/
1418 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1419 struct spoolss_OpenPrinter *r)
1421 struct spoolss_OpenPrinterEx e;
1424 ZERO_STRUCT(e.in.userlevel);
1426 e.in.printername = r->in.printername;
1427 e.in.datatype = r->in.datatype;
1428 e.in.devmode_ctr = r->in.devmode_ctr;
1429 e.in.access_mask = r->in.access_mask;
1432 e.out.handle = r->out.handle;
1434 werr = _spoolss_OpenPrinterEx(p, &e);
1436 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1437 /* OpenPrinterEx returns this for a bad
1438 * printer name. We must return WERR_INVALID_PRINTER_NAME
1441 werr = WERR_INVALID_PRINTER_NAME;
1447 /********************************************************************
1448 FIXME: temporary convert_devicemode_new function
1449 ********************************************************************/
1451 static bool convert_devicemode_new(const char *printername,
1452 struct spoolss_DeviceMode *devmode,
1453 NT_DEVICEMODE **pp_nt_devmode)
1455 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1458 * Ensure nt_devmode is a valid pointer
1459 * as we will be overwriting it.
1462 if (nt_devmode == NULL) {
1463 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1464 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1468 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1469 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1471 nt_devmode->specversion = devmode->specversion;
1472 nt_devmode->driverversion = devmode->driverversion;
1473 nt_devmode->size = devmode->size;
1474 nt_devmode->fields = devmode->fields;
1475 nt_devmode->orientation = devmode->orientation;
1476 nt_devmode->papersize = devmode->papersize;
1477 nt_devmode->paperlength = devmode->paperlength;
1478 nt_devmode->paperwidth = devmode->paperwidth;
1479 nt_devmode->scale = devmode->scale;
1480 nt_devmode->copies = devmode->copies;
1481 nt_devmode->defaultsource = devmode->defaultsource;
1482 nt_devmode->printquality = devmode->printquality;
1483 nt_devmode->color = devmode->color;
1484 nt_devmode->duplex = devmode->duplex;
1485 nt_devmode->yresolution = devmode->yresolution;
1486 nt_devmode->ttoption = devmode->ttoption;
1487 nt_devmode->collate = devmode->collate;
1489 nt_devmode->logpixels = devmode->logpixels;
1490 nt_devmode->bitsperpel = devmode->bitsperpel;
1491 nt_devmode->pelswidth = devmode->pelswidth;
1492 nt_devmode->pelsheight = devmode->pelsheight;
1493 nt_devmode->displayflags = devmode->displayflags;
1494 nt_devmode->displayfrequency = devmode->displayfrequency;
1495 nt_devmode->icmmethod = devmode->icmmethod;
1496 nt_devmode->icmintent = devmode->icmintent;
1497 nt_devmode->mediatype = devmode->mediatype;
1498 nt_devmode->dithertype = devmode->dithertype;
1499 nt_devmode->reserved1 = devmode->reserved1;
1500 nt_devmode->reserved2 = devmode->reserved2;
1501 nt_devmode->panningwidth = devmode->panningwidth;
1502 nt_devmode->panningheight = devmode->panningheight;
1505 * Only change private and driverextra if the incoming devmode
1506 * has a new one. JRA.
1509 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1510 SAFE_FREE(nt_devmode->nt_dev_private);
1511 nt_devmode->driverextra = devmode->__driverextra_length;
1512 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1514 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1517 *pp_nt_devmode = nt_devmode;
1522 /****************************************************************
1523 _spoolss_OpenPrinterEx
1524 ****************************************************************/
1526 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1527 struct spoolss_OpenPrinterEx *r)
1529 POLICY_HND *handle = r->out.handle;
1530 char *name = CONST_DISCARD(char *, r->in.printername);
1532 Printer_entry *Printer=NULL;
1535 return WERR_INVALID_PARAM;
1538 /* some sanity check because you can open a printer or a print server */
1539 /* aka: \\server\printer or \\server */
1541 DEBUGADD(3,("checking name: %s\n",name));
1543 if (!open_printer_hnd(p, handle, name, 0)) {
1544 ZERO_STRUCTP(r->out.handle);
1545 return WERR_INVALID_PARAM;
1548 Printer=find_printer_index_by_hnd(p, handle);
1550 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1551 "handle we created for printer %s\n", name ));
1552 close_printer_handle(p,handle);
1553 ZERO_STRUCTP(r->out.handle);
1554 return WERR_INVALID_PARAM;
1558 * First case: the user is opening the print server:
1560 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1561 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1563 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1564 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1565 * or if the user is listed in the smb.conf printer admin parameter.
1567 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1568 * client view printer folder, but does not show the MSAPW.
1570 * Note: this test needs code to check access rights here too. Jeremy
1571 * could you look at this?
1573 * Second case: the user is opening a printer:
1574 * NT doesn't let us connect to a printer if the connecting user
1575 * doesn't have print permission.
1577 * Third case: user is opening a Port Monitor
1578 * access checks same as opening a handle to the print server.
1581 switch (Printer->printer_type )
1584 case SPLHND_PORTMON_TCP:
1585 case SPLHND_PORTMON_LOCAL:
1586 /* Printserver handles use global struct... */
1590 /* Map standard access rights to object specific access rights */
1592 se_map_standard(&r->in.access_mask,
1593 &printserver_std_mapping);
1595 /* Deny any object specific bits that don't apply to print
1596 servers (i.e printer and job specific bits) */
1598 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1600 if (r->in.access_mask &
1601 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1602 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1603 close_printer_handle(p, handle);
1604 ZERO_STRUCTP(r->out.handle);
1605 return WERR_ACCESS_DENIED;
1608 /* Allow admin access */
1610 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1612 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1614 if (!lp_ms_add_printer_wizard()) {
1615 close_printer_handle(p, handle);
1616 ZERO_STRUCTP(r->out.handle);
1617 return WERR_ACCESS_DENIED;
1620 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1621 and not a printer admin, then fail */
1623 if ((p->server_info->utok.uid != 0) &&
1624 !user_has_privileges(p->server_info->ptok,
1626 !token_contains_name_in_list(
1627 uidtoname(p->server_info->utok.uid),
1629 p->server_info->ptok,
1630 lp_printer_admin(snum))) {
1631 close_printer_handle(p, handle);
1632 ZERO_STRUCTP(r->out.handle);
1633 return WERR_ACCESS_DENIED;
1636 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1640 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1643 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1644 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1646 /* We fall through to return WERR_OK */
1649 case SPLHND_PRINTER:
1650 /* NT doesn't let us connect to a printer if the connecting user
1651 doesn't have print permission. */
1653 if (!get_printer_snum(p, handle, &snum, NULL)) {
1654 close_printer_handle(p, handle);
1655 ZERO_STRUCTP(r->out.handle);
1659 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1661 /* map an empty access mask to the minimum access mask */
1662 if (r->in.access_mask == 0x0)
1663 r->in.access_mask = PRINTER_ACCESS_USE;
1666 * If we are not serving the printer driver for this printer,
1667 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1668 * will keep NT clients happy --jerry
1671 if (lp_use_client_driver(snum)
1672 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1674 r->in.access_mask = PRINTER_ACCESS_USE;
1677 /* check smb.conf parameters and the the sec_desc */
1679 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1680 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1681 ZERO_STRUCTP(r->out.handle);
1682 return WERR_ACCESS_DENIED;
1685 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1686 p->server_info->ptok, snum) ||
1687 !print_access_check(p->server_info, snum,
1688 r->in.access_mask)) {
1689 DEBUG(3, ("access DENIED for printer open\n"));
1690 close_printer_handle(p, handle);
1691 ZERO_STRUCTP(r->out.handle);
1692 return WERR_ACCESS_DENIED;
1695 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1696 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1697 close_printer_handle(p, handle);
1698 ZERO_STRUCTP(r->out.handle);
1699 return WERR_ACCESS_DENIED;
1702 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1703 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1705 r->in.access_mask = PRINTER_ACCESS_USE;
1707 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1708 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1713 /* sanity check to prevent programmer error */
1714 ZERO_STRUCTP(r->out.handle);
1718 Printer->access_granted = r->in.access_mask;
1721 * If the client sent a devmode in the OpenPrinter() call, then
1722 * save it here in case we get a job submission on this handle
1725 if ( (Printer->printer_type != SPLHND_SERVER)
1726 && r->in.devmode_ctr.devmode )
1728 convert_devicemode_new(Printer->sharename,
1729 r->in.devmode_ctr.devmode,
1730 &Printer->nt_devmode);
1733 #if 0 /* JERRY -- I'm doubtful this is really effective */
1734 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1735 optimization in Windows 2000 clients --jerry */
1737 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1738 && (RA_WIN2K == get_remote_arch()) )
1740 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1741 sys_usleep( 500000 );
1748 /****************************************************************************
1749 ****************************************************************************/
1751 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1752 NT_PRINTER_INFO_LEVEL_2 *d)
1754 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1760 d->attributes = r->attributes;
1761 d->priority = r->priority;
1762 d->default_priority = r->defaultpriority;
1763 d->starttime = r->starttime;
1764 d->untiltime = r->untiltime;
1765 d->status = r->status;
1766 d->cjobs = r->cjobs;
1768 fstrcpy(d->servername, r->servername);
1769 fstrcpy(d->printername, r->printername);
1770 fstrcpy(d->sharename, r->sharename);
1771 fstrcpy(d->portname, r->portname);
1772 fstrcpy(d->drivername, r->drivername);
1773 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1774 fstrcpy(d->location, r->location);
1775 fstrcpy(d->sepfile, r->sepfile);
1776 fstrcpy(d->printprocessor, r->printprocessor);
1777 fstrcpy(d->datatype, r->datatype);
1778 fstrcpy(d->parameters, r->parameters);
1783 /****************************************************************************
1784 ****************************************************************************/
1786 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
1787 NT_PRINTER_INFO_LEVEL *printer)
1791 switch (info_ctr->level) {
1793 /* allocate memory if needed. Messy because
1794 convert_printer_info is used to update an existing
1795 printer or build a new one */
1797 if (!printer->info_2) {
1798 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1799 if (!printer->info_2) {
1800 DEBUG(0,("convert_printer_info_new: "
1801 "talloc() failed!\n"));
1806 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1808 printer->info_2->setuptime = time(NULL);
1815 /*******************************************************************
1816 ********************************************************************/
1818 static bool string_array_to_fstring_array(const char **sarray, fstring **farray)
1827 *farray = SMB_MALLOC_ARRAY(fstring, 1);
1832 for (i=0; sarray[i] != NULL; i++) {
1833 *farray = SMB_REALLOC_ARRAY(*farray, fstring, i+2);
1837 fstrcpy((*farray)[i], sarray[i]);
1840 fstrcpy((*farray)[i], "");
1845 /*******************************************************************
1846 ********************************************************************/
1848 static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3 *r,
1849 NT_PRINTER_DRIVER_INFO_LEVEL_3 **p)
1851 NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
1853 DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
1856 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
1865 d->cversion = r->version;
1867 fstrcpy(d->name, r->driver_name);
1868 fstrcpy(d->environment, r->architecture);
1869 fstrcpy(d->driverpath, r->driver_path);
1870 fstrcpy(d->datafile, r->data_file);
1871 fstrcpy(d->configfile, r->config_file);
1872 fstrcpy(d->helpfile, r->help_file);
1873 fstrcpy(d->monitorname, r->monitor_name);
1874 fstrcpy(d->defaultdatatype, r->default_datatype);
1876 DEBUGADD(8,( "version: %d\n", d->cversion));
1877 DEBUGADD(8,( "name: %s\n", d->name));
1878 DEBUGADD(8,( "environment: %s\n", d->environment));
1879 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1880 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1881 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1882 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1883 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1884 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1886 if (r->dependent_files) {
1887 if (!string_array_to_fstring_array(r->dependent_files->string,
1888 &d->dependentfiles)) {
1897 /*******************************************************************
1898 ********************************************************************/
1900 static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6 *r,
1901 NT_PRINTER_DRIVER_INFO_LEVEL_6 **p)
1903 NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
1905 DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
1908 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
1917 d->version = r->version;
1919 fstrcpy(d->name, r->driver_name);
1920 fstrcpy(d->environment, r->architecture);
1921 fstrcpy(d->driverpath, r->driver_path);
1922 fstrcpy(d->datafile, r->data_file);
1923 fstrcpy(d->configfile, r->config_file);
1924 fstrcpy(d->helpfile, r->help_file);
1925 fstrcpy(d->monitorname, r->monitor_name);
1926 fstrcpy(d->defaultdatatype, r->default_datatype);
1928 DEBUGADD(8,( "version: %d\n", d->version));
1929 DEBUGADD(8,( "name: %s\n", d->name));
1930 DEBUGADD(8,( "environment: %s\n", d->environment));
1931 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1932 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1933 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1934 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1935 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1936 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1938 if (r->dependent_files) {
1939 if (!string_array_to_fstring_array(r->dependent_files->string,
1940 &d->dependentfiles)) {
1945 if (r->previous_names) {
1946 if (!string_array_to_fstring_array(r->previous_names->string,
1947 &d->previousnames)) {
1959 /********************************************************************
1960 ********************************************************************/
1962 static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r,
1963 NT_PRINTER_DRIVER_INFO_LEVEL *printer,
1968 printer->info_3 = NULL;
1969 if (!driver_info3_to_nt_driver_info3(r->info.info3, &printer->info_3)) {
1974 printer->info_6 = NULL;
1975 if (!driver_info6_to_nt_driver_info6(r->info.info6, &printer->info_6)) {
1986 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1987 NT_DEVICEMODE **pp_nt_devmode)
1989 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1992 * Ensure nt_devmode is a valid pointer
1993 * as we will be overwriting it.
1996 if (nt_devmode == NULL) {
1997 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1998 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
2002 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
2003 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
2005 nt_devmode->specversion=devmode->specversion;
2006 nt_devmode->driverversion=devmode->driverversion;
2007 nt_devmode->size=devmode->size;
2008 nt_devmode->fields=devmode->fields;
2009 nt_devmode->orientation=devmode->orientation;
2010 nt_devmode->papersize=devmode->papersize;
2011 nt_devmode->paperlength=devmode->paperlength;
2012 nt_devmode->paperwidth=devmode->paperwidth;
2013 nt_devmode->scale=devmode->scale;
2014 nt_devmode->copies=devmode->copies;
2015 nt_devmode->defaultsource=devmode->defaultsource;
2016 nt_devmode->printquality=devmode->printquality;
2017 nt_devmode->color=devmode->color;
2018 nt_devmode->duplex=devmode->duplex;
2019 nt_devmode->yresolution=devmode->yresolution;
2020 nt_devmode->ttoption=devmode->ttoption;
2021 nt_devmode->collate=devmode->collate;
2023 nt_devmode->logpixels=devmode->logpixels;
2024 nt_devmode->bitsperpel=devmode->bitsperpel;
2025 nt_devmode->pelswidth=devmode->pelswidth;
2026 nt_devmode->pelsheight=devmode->pelsheight;
2027 nt_devmode->displayflags=devmode->displayflags;
2028 nt_devmode->displayfrequency=devmode->displayfrequency;
2029 nt_devmode->icmmethod=devmode->icmmethod;
2030 nt_devmode->icmintent=devmode->icmintent;
2031 nt_devmode->mediatype=devmode->mediatype;
2032 nt_devmode->dithertype=devmode->dithertype;
2033 nt_devmode->reserved1=devmode->reserved1;
2034 nt_devmode->reserved2=devmode->reserved2;
2035 nt_devmode->panningwidth=devmode->panningwidth;
2036 nt_devmode->panningheight=devmode->panningheight;
2039 * Only change private and driverextra if the incoming devmode
2040 * has a new one. JRA.
2043 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
2044 SAFE_FREE(nt_devmode->nt_dev_private);
2045 nt_devmode->driverextra=devmode->driverextra;
2046 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
2048 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
2051 *pp_nt_devmode = nt_devmode;
2056 /********************************************************************
2057 * _spoolss_enddocprinter_internal.
2058 ********************************************************************/
2060 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
2062 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2066 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
2070 if (!get_printer_snum(p, handle, &snum, NULL))
2073 Printer->document_started=False;
2074 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
2075 /* error codes unhandled so far ... */
2080 /****************************************************************
2081 _spoolss_ClosePrinter
2082 ****************************************************************/
2084 WERROR _spoolss_ClosePrinter(pipes_struct *p,
2085 struct spoolss_ClosePrinter *r)
2087 POLICY_HND *handle = r->in.handle;
2089 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2091 if (Printer && Printer->document_started)
2092 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2094 if (!close_printer_handle(p, handle))
2097 /* clear the returned printer handle. Observed behavior
2098 from Win2k server. Don't think this really matters.
2099 Previous code just copied the value of the closed
2102 ZERO_STRUCTP(r->out.handle);
2107 /****************************************************************
2108 _spoolss_DeletePrinter
2109 ****************************************************************/
2111 WERROR _spoolss_DeletePrinter(pipes_struct *p,
2112 struct spoolss_DeletePrinter *r)
2114 POLICY_HND *handle = r->in.handle;
2115 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2118 if (Printer && Printer->document_started)
2119 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2121 result = delete_printer_handle(p, handle);
2123 update_c_setprinter(False);
2128 /*******************************************************************
2129 * static function to lookup the version id corresponding to an
2130 * long architecture string
2131 ******************************************************************/
2133 static int get_version_id (char * arch)
2136 struct table_node archi_table[]= {
2138 {"Windows 4.0", "WIN40", 0 },
2139 {"Windows NT x86", "W32X86", 2 },
2140 {"Windows NT R4000", "W32MIPS", 2 },
2141 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
2142 {"Windows NT PowerPC", "W32PPC", 2 },
2143 {"Windows IA64", "IA64", 3 },
2144 {"Windows x64", "x64", 3 },
2148 for (i=0; archi_table[i].long_archi != NULL; i++)
2150 if (strcmp(arch, archi_table[i].long_archi) == 0)
2151 return (archi_table[i].version);
2157 /****************************************************************
2158 _spoolss_DeletePrinterDriver
2159 ****************************************************************/
2161 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
2162 struct spoolss_DeletePrinterDriver *r)
2166 NT_PRINTER_DRIVER_INFO_LEVEL info;
2167 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2170 WERROR status_win2k = WERR_ACCESS_DENIED;
2171 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2173 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2174 and not a printer admin, then fail */
2176 if ( (p->server_info->utok.uid != 0)
2177 && !user_has_privileges(p->server_info->ptok, &se_printop )
2178 && !token_contains_name_in_list(
2179 uidtoname(p->server_info->utok.uid), NULL,
2180 NULL, p->server_info->ptok,
2181 lp_printer_admin(-1)) )
2183 return WERR_ACCESS_DENIED;
2186 driver = CONST_DISCARD(char *, r->in.driver);
2187 arch = CONST_DISCARD(char *, r->in.architecture);
2189 /* check that we have a valid driver name first */
2191 if ((version=get_version_id(arch)) == -1)
2192 return WERR_INVALID_ENVIRONMENT;
2195 ZERO_STRUCT(info_win2k);
2197 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2199 /* try for Win2k driver if "Windows NT x86" */
2201 if ( version == 2 ) {
2203 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2204 status = WERR_UNKNOWN_PRINTER_DRIVER;
2208 /* otherwise it was a failure */
2210 status = WERR_UNKNOWN_PRINTER_DRIVER;
2216 if (printer_driver_in_use(info.info_3)) {
2217 status = WERR_PRINTER_DRIVER_IN_USE;
2223 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2225 /* if we get to here, we now have 2 driver info structures to remove */
2226 /* remove the Win2k driver first*/
2228 status_win2k = delete_printer_driver(
2229 p, info_win2k.info_3, 3, False );
2230 free_a_printer_driver( info_win2k, 3 );
2232 /* this should not have failed---if it did, report to client */
2233 if ( !W_ERROR_IS_OK(status_win2k) )
2235 status = status_win2k;
2241 status = delete_printer_driver(p, info.info_3, version, False);
2243 /* if at least one of the deletes succeeded return OK */
2245 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2249 free_a_printer_driver( info, 3 );
2254 /****************************************************************
2255 _spoolss_DeletePrinterDriverEx
2256 ****************************************************************/
2258 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2259 struct spoolss_DeletePrinterDriverEx *r)
2263 NT_PRINTER_DRIVER_INFO_LEVEL info;
2264 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2266 uint32_t flags = r->in.delete_flags;
2269 WERROR status_win2k = WERR_ACCESS_DENIED;
2270 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2272 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2273 and not a printer admin, then fail */
2275 if ( (p->server_info->utok.uid != 0)
2276 && !user_has_privileges(p->server_info->ptok, &se_printop )
2277 && !token_contains_name_in_list(
2278 uidtoname(p->server_info->utok.uid), NULL, NULL,
2279 p->server_info->ptok, lp_printer_admin(-1)) )
2281 return WERR_ACCESS_DENIED;
2284 driver = CONST_DISCARD(char *, r->in.driver);
2285 arch = CONST_DISCARD(char *, r->in.architecture);
2287 /* check that we have a valid driver name first */
2288 if ((version=get_version_id(arch)) == -1) {
2289 /* this is what NT returns */
2290 return WERR_INVALID_ENVIRONMENT;
2293 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2294 version = r->in.version;
2297 ZERO_STRUCT(info_win2k);
2299 status = get_a_printer_driver(&info, 3, driver, arch, version);
2301 if ( !W_ERROR_IS_OK(status) )
2304 * if the client asked for a specific version,
2305 * or this is something other than Windows NT x86,
2309 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2312 /* try for Win2k driver if "Windows NT x86" */
2315 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2316 status = WERR_UNKNOWN_PRINTER_DRIVER;
2321 if ( printer_driver_in_use(info.info_3) ) {
2322 status = WERR_PRINTER_DRIVER_IN_USE;
2327 * we have a couple of cases to consider.
2328 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2329 * then the delete should fail if **any** files overlap with
2331 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2332 * non-overlapping files
2333 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2334 * is set, the do not delete any files
2335 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2338 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2340 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2342 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2343 /* no idea of the correct error here */
2344 status = WERR_ACCESS_DENIED;
2349 /* also check for W32X86/3 if necessary; maybe we already have? */
2351 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2352 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2355 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2356 /* no idea of the correct error here */
2357 free_a_printer_driver( info_win2k, 3 );
2358 status = WERR_ACCESS_DENIED;
2362 /* if we get to here, we now have 2 driver info structures to remove */
2363 /* remove the Win2k driver first*/
2365 status_win2k = delete_printer_driver(
2366 p, info_win2k.info_3, 3, delete_files);
2367 free_a_printer_driver( info_win2k, 3 );
2369 /* this should not have failed---if it did, report to client */
2371 if ( !W_ERROR_IS_OK(status_win2k) )
2376 status = delete_printer_driver(p, info.info_3, version, delete_files);
2378 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2381 free_a_printer_driver( info, 3 );
2387 /****************************************************************************
2388 Internal routine for retreiving printerdata
2389 ***************************************************************************/
2391 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2392 const char *key, const char *value, uint32 *type, uint8 **data,
2393 uint32 *needed, uint32 in_size )
2395 REGISTRY_VALUE *val;
2399 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2400 return WERR_BADFILE;
2402 *type = regval_type( val );
2404 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2406 size = regval_size( val );
2408 /* copy the min(in_size, len) */
2411 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2413 /* special case for 0 length values */
2415 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2419 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2428 DEBUG(5,("get_printer_dataex: copy done\n"));
2433 /****************************************************************************
2434 Internal routine for removing printerdata
2435 ***************************************************************************/
2437 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2439 return delete_printer_data( printer->info_2, key, value );
2442 /****************************************************************************
2443 Internal routine for storing printerdata
2444 ***************************************************************************/
2446 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2447 uint32 type, uint8 *data, int real_len )
2449 /* the registry objects enforce uniqueness based on value name */
2451 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2454 /********************************************************************
2455 GetPrinterData on a printer server Handle.
2456 ********************************************************************/
2458 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2462 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2464 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2466 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2468 SIVAL(*data, 0, 0x00);
2473 if (!StrCaseCmp(value, "BeepEnabled")) {
2475 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2477 SIVAL(*data, 0, 0x00);
2482 if (!StrCaseCmp(value, "EventLog")) {
2484 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2486 /* formally was 0x1b */
2487 SIVAL(*data, 0, 0x0);
2492 if (!StrCaseCmp(value, "NetPopup")) {
2494 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2496 SIVAL(*data, 0, 0x00);
2501 if (!StrCaseCmp(value, "MajorVersion")) {
2503 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2506 /* Windows NT 4.0 seems to not allow uploading of drivers
2507 to a server that reports 0x3 as the MajorVersion.
2508 need to investigate more how Win2k gets around this .
2511 if ( RA_WINNT == get_remote_arch() )
2520 if (!StrCaseCmp(value, "MinorVersion")) {
2522 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2530 * uint32 size = 0x114
2532 * uint32 minor = [0|1]
2533 * uint32 build = [2195|2600]
2534 * extra unicode string = e.g. "Service Pack 3"
2536 if (!StrCaseCmp(value, "OSVersion")) {
2540 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2543 SIVAL(*data, 0, *needed); /* size */
2544 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2546 SIVAL(*data, 12, 2195); /* build */
2548 /* leave extra string empty */
2554 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2555 const char *string="C:\\PRINTERS";
2557 *needed = 2*(strlen(string)+1);
2558 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2560 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2562 /* it's done by hand ready to go on the wire */
2563 for (i=0; i<strlen(string); i++) {
2564 (*data)[2*i]=string[i];
2565 (*data)[2*i+1]='\0';
2570 if (!StrCaseCmp(value, "Architecture")) {
2571 const char *string="Windows NT x86";
2573 *needed = 2*(strlen(string)+1);
2574 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2576 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2577 for (i=0; i<strlen(string); i++) {
2578 (*data)[2*i]=string[i];
2579 (*data)[2*i+1]='\0';
2584 if (!StrCaseCmp(value, "DsPresent")) {
2586 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2589 /* only show the publish check box if we are a
2590 memeber of a AD domain */
2592 if ( lp_security() == SEC_ADS )
2593 SIVAL(*data, 0, 0x01);
2595 SIVAL(*data, 0, 0x00);
2601 if (!StrCaseCmp(value, "DNSMachineName")) {
2602 const char *hostname = get_mydnsfullname();
2605 return WERR_BADFILE;
2607 *needed = 2*(strlen(hostname)+1);
2608 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2610 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2611 for (i=0; i<strlen(hostname); i++) {
2612 (*data)[2*i]=hostname[i];
2613 (*data)[2*i+1]='\0';
2619 return WERR_BADFILE;
2622 /********************************************************************
2623 * spoolss_getprinterdata
2624 ********************************************************************/
2626 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2628 POLICY_HND *handle = &q_u->handle;
2629 UNISTR2 *valuename = &q_u->valuename;
2630 uint32 in_size = q_u->size;
2631 uint32 *type = &r_u->type;
2632 uint32 *out_size = &r_u->size;
2633 uint8 **data = &r_u->data;
2634 uint32 *needed = &r_u->needed;
2637 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2638 NT_PRINTER_INFO_LEVEL *printer = NULL;
2642 * Reminder: when it's a string, the length is in BYTES
2643 * even if UNICODE is negociated.
2648 *out_size = in_size;
2650 /* in case of problem, return some default values */
2655 DEBUG(4,("_spoolss_getprinterdata\n"));
2658 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2659 status = WERR_BADFID;
2663 unistr2_to_ascii(value, valuename, sizeof(value));
2665 if ( Printer->printer_type == SPLHND_SERVER )
2666 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2669 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2670 status = WERR_BADFID;
2674 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2675 if ( !W_ERROR_IS_OK(status) )
2678 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2680 if ( strequal(value, "ChangeId") ) {
2682 *needed = sizeof(uint32);
2683 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2684 status = WERR_NOMEM;
2687 SIVAL( *data, 0, printer->info_2->changeid );
2691 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2694 if (*needed > *out_size)
2695 status = WERR_MORE_DATA;
2698 if ( !W_ERROR_IS_OK(status) )
2700 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2702 /* reply this param doesn't exist */
2705 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2707 free_a_printer( &printer, 2 );
2715 /* cleanup & exit */
2718 free_a_printer( &printer, 2 );
2723 /*********************************************************
2724 Connect to the client machine.
2725 **********************************************************/
2727 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2728 struct sockaddr_storage *client_ss, const char *remote_machine)
2731 struct cli_state *the_cli;
2732 struct sockaddr_storage rm_addr;
2734 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2735 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2736 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2740 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2741 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2745 char addr[INET6_ADDRSTRLEN];
2746 rm_addr = *client_ss;
2747 print_sockaddr(addr, sizeof(addr), &rm_addr);
2748 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2752 /* setup the connection */
2754 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2755 &rm_addr, 0, "IPC$", "IPC",
2759 0, lp_client_signing(), NULL );
2761 if ( !NT_STATUS_IS_OK( ret ) ) {
2762 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2767 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2768 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2769 cli_shutdown(the_cli);
2774 * Ok - we have an anonymous connection to the IPC$ share.
2775 * Now start the NT Domain stuff :-).
2778 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2779 if (!NT_STATUS_IS_OK(ret)) {
2780 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2781 remote_machine, nt_errstr(ret)));
2782 cli_shutdown(the_cli);
2789 /***************************************************************************
2790 Connect to the client.
2791 ****************************************************************************/
2793 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2794 uint32 localprinter, uint32 type,
2795 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2801 * If it's the first connection, contact the client
2802 * and connect to the IPC$ share anonymously
2804 if (smb_connections==0) {
2805 fstring unix_printer;
2807 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2809 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2812 messaging_register(smbd_messaging_context(), NULL,
2813 MSG_PRINTER_NOTIFY2,
2814 receive_notify2_message_list);
2815 /* Tell the connections db we're now interested in printer
2816 * notify messages. */
2817 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2821 * Tell the specific printing tdb we want messages for this printer
2822 * by registering our PID.
2825 if (!print_notify_register_pid(snum))
2826 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2830 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2838 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2839 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2840 win_errstr(result)));
2842 return (W_ERROR_IS_OK(result));
2845 /****************************************************************
2846 ****************************************************************/
2848 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2849 const struct spoolss_NotifyOption *r)
2851 struct spoolss_NotifyOption *option;
2858 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2865 if (!option->count) {
2869 option->types = talloc_zero_array(option,
2870 struct spoolss_NotifyOptionType, option->count);
2871 if (!option->types) {
2872 talloc_free(option);
2876 for (i=0; i < option->count; i++) {
2877 option->types[i] = r->types[i];
2879 if (option->types[i].count) {
2880 option->types[i].fields = talloc_zero_array(option,
2881 enum spoolss_Field, option->types[i].count);
2882 if (!option->types[i].fields) {
2883 talloc_free(option);
2886 for (k=0; k<option->types[i].count; k++) {
2887 option->types[i].fields[k] =
2888 r->types[i].fields[k];
2896 /****************************************************************
2897 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2899 * before replying OK: status=0 a rpc call is made to the workstation
2900 * asking ReplyOpenPrinter
2902 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2903 * called from api_spoolss_rffpcnex
2904 ****************************************************************/
2906 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2907 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2909 POLICY_HND *handle = r->in.handle;
2911 struct spoolss_NotifyOption *option = r->in.notify_options;
2912 struct sockaddr_storage client_ss;
2914 /* store the notify value in the printer struct */
2916 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2919 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2920 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2924 Printer->notify.flags = r->in.flags;
2925 Printer->notify.options = r->in.options;
2926 Printer->notify.printerlocal = r->in.printer_local;
2928 TALLOC_FREE(Printer->notify.option);
2929 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2931 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2933 /* Connect to the client machine and send a ReplyOpenPrinter */
2935 if ( Printer->printer_type == SPLHND_SERVER)
2937 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2938 !get_printer_snum(p, handle, &snum, NULL) )
2941 if (!interpret_string_addr(&client_ss, p->client_address,
2943 return WERR_SERVER_UNAVAILABLE;
2946 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2947 Printer->notify.printerlocal, 1,
2948 &Printer->notify.client_hnd, &client_ss))
2949 return WERR_SERVER_UNAVAILABLE;
2951 Printer->notify.client_connected=True;
2956 /*******************************************************************
2957 * fill a notify_info_data with the servername
2958 ********************************************************************/
2960 void spoolss_notify_server_name(int snum,
2961 struct spoolss_Notify *data,
2962 print_queue_struct *queue,
2963 NT_PRINTER_INFO_LEVEL *printer,
2964 TALLOC_CTX *mem_ctx)
2966 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2969 /*******************************************************************
2970 * fill a notify_info_data with the printername (not including the servername).
2971 ********************************************************************/
2973 void spoolss_notify_printer_name(int snum,
2974 struct spoolss_Notify *data,
2975 print_queue_struct *queue,
2976 NT_PRINTER_INFO_LEVEL *printer,
2977 TALLOC_CTX *mem_ctx)
2979 /* the notify name should not contain the \\server\ part */
2980 char *p = strrchr(printer->info_2->printername, '\\');
2983 p = printer->info_2->printername;
2988 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2991 /*******************************************************************
2992 * fill a notify_info_data with the servicename
2993 ********************************************************************/
2995 void spoolss_notify_share_name(int snum,
2996 struct spoolss_Notify *data,
2997 print_queue_struct *queue,
2998 NT_PRINTER_INFO_LEVEL *printer,
2999 TALLOC_CTX *mem_ctx)
3001 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
3004 /*******************************************************************
3005 * fill a notify_info_data with the port name
3006 ********************************************************************/
3008 void spoolss_notify_port_name(int snum,
3009 struct spoolss_Notify *data,
3010 print_queue_struct *queue,
3011 NT_PRINTER_INFO_LEVEL *printer,
3012 TALLOC_CTX *mem_ctx)
3014 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
3017 /*******************************************************************
3018 * fill a notify_info_data with the printername
3019 * but it doesn't exist, have to see what to do
3020 ********************************************************************/
3022 void spoolss_notify_driver_name(int snum,
3023 struct spoolss_Notify *data,
3024 print_queue_struct *queue,
3025 NT_PRINTER_INFO_LEVEL *printer,
3026 TALLOC_CTX *mem_ctx)
3028 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
3031 /*******************************************************************
3032 * fill a notify_info_data with the comment
3033 ********************************************************************/
3035 void spoolss_notify_comment(int snum,
3036 struct spoolss_Notify *data,
3037 print_queue_struct *queue,
3038 NT_PRINTER_INFO_LEVEL *printer,
3039 TALLOC_CTX *mem_ctx)
3043 if (*printer->info_2->comment == '\0') {
3044 p = lp_comment(snum);
3046 p = printer->info_2->comment;
3049 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
3052 /*******************************************************************
3053 * fill a notify_info_data with the comment
3054 * location = "Room 1, floor 2, building 3"
3055 ********************************************************************/
3057 void spoolss_notify_location(int snum,
3058 struct spoolss_Notify *data,
3059 print_queue_struct *queue,
3060 NT_PRINTER_INFO_LEVEL *printer,
3061 TALLOC_CTX *mem_ctx)
3063 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
3066 /*******************************************************************
3067 * fill a notify_info_data with the device mode
3068 * jfm:xxxx don't to it for know but that's a real problem !!!
3069 ********************************************************************/
3071 static void spoolss_notify_devmode(int snum,
3072 struct spoolss_Notify *data,
3073 print_queue_struct *queue,
3074 NT_PRINTER_INFO_LEVEL *printer,
3075 TALLOC_CTX *mem_ctx)
3077 /* for a dummy implementation we have to zero the fields */
3078 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
3081 /*******************************************************************
3082 * fill a notify_info_data with the separator file name
3083 ********************************************************************/
3085 void spoolss_notify_sepfile(int snum,
3086 struct spoolss_Notify *data,
3087 print_queue_struct *queue,
3088 NT_PRINTER_INFO_LEVEL *printer,
3089 TALLOC_CTX *mem_ctx)
3091 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
3094 /*******************************************************************
3095 * fill a notify_info_data with the print processor
3096 * jfm:xxxx return always winprint to indicate we don't do anything to it
3097 ********************************************************************/
3099 void spoolss_notify_print_processor(int snum,
3100 struct spoolss_Notify *data,
3101 print_queue_struct *queue,
3102 NT_PRINTER_INFO_LEVEL *printer,
3103 TALLOC_CTX *mem_ctx)
3105 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
3108 /*******************************************************************
3109 * fill a notify_info_data with the print processor options
3110 * jfm:xxxx send an empty string
3111 ********************************************************************/
3113 void spoolss_notify_parameters(int snum,
3114 struct spoolss_Notify *data,
3115 print_queue_struct *queue,
3116 NT_PRINTER_INFO_LEVEL *printer,
3117 TALLOC_CTX *mem_ctx)
3119 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
3122 /*******************************************************************
3123 * fill a notify_info_data with the data type
3124 * jfm:xxxx always send RAW as data type
3125 ********************************************************************/
3127 void spoolss_notify_datatype(int snum,
3128 struct spoolss_Notify *data,
3129 print_queue_struct *queue,
3130 NT_PRINTER_INFO_LEVEL *printer,
3131 TALLOC_CTX *mem_ctx)
3133 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
3136 /*******************************************************************
3137 * fill a notify_info_data with the security descriptor
3138 * jfm:xxxx send an null pointer to say no security desc
3139 * have to implement security before !
3140 ********************************************************************/
3142 static void spoolss_notify_security_desc(int snum,
3143 struct spoolss_Notify *data,
3144 print_queue_struct *queue,
3145 NT_PRINTER_INFO_LEVEL *printer,
3146 TALLOC_CTX *mem_ctx)
3148 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
3149 printer->info_2->secdesc_buf->sd_size,
3150 printer->info_2->secdesc_buf->sd);
3153 /*******************************************************************
3154 * fill a notify_info_data with the attributes
3155 * jfm:xxxx a samba printer is always shared
3156 ********************************************************************/
3158 void spoolss_notify_attributes(int snum,
3159 struct spoolss_Notify *data,
3160 print_queue_struct *queue,
3161 NT_PRINTER_INFO_LEVEL *printer,
3162 TALLOC_CTX *mem_ctx)
3164 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
3167 /*******************************************************************
3168 * fill a notify_info_data with the priority
3169 ********************************************************************/
3171 static void spoolss_notify_priority(int snum,
3172 struct spoolss_Notify *data,
3173 print_queue_struct *queue,
3174 NT_PRINTER_INFO_LEVEL *printer,
3175 TALLOC_CTX *mem_ctx)
3177 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
3180 /*******************************************************************
3181 * fill a notify_info_data with the default priority
3182 ********************************************************************/
3184 static void spoolss_notify_default_priority(int snum,
3185 struct spoolss_Notify *data,
3186 print_queue_struct *queue,
3187 NT_PRINTER_INFO_LEVEL *printer,
3188 TALLOC_CTX *mem_ctx)
3190 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
3193 /*******************************************************************
3194 * fill a notify_info_data with the start time
3195 ********************************************************************/
3197 static void spoolss_notify_start_time(int snum,
3198 struct spoolss_Notify *data,
3199 print_queue_struct *queue,
3200 NT_PRINTER_INFO_LEVEL *printer,
3201 TALLOC_CTX *mem_ctx)
3203 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
3206 /*******************************************************************
3207 * fill a notify_info_data with the until time
3208 ********************************************************************/
3210 static void spoolss_notify_until_time(int snum,
3211 struct spoolss_Notify *data,
3212 print_queue_struct *queue,
3213 NT_PRINTER_INFO_LEVEL *printer,
3214 TALLOC_CTX *mem_ctx)
3216 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
3219 /*******************************************************************
3220 * fill a notify_info_data with the status
3221 ********************************************************************/
3223 static void spoolss_notify_status(int snum,
3224 struct spoolss_Notify *data,
3225 print_queue_struct *queue,
3226 NT_PRINTER_INFO_LEVEL *printer,
3227 TALLOC_CTX *mem_ctx)
3229 print_status_struct status;
3231 print_queue_length(snum, &status);
3232 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
3235 /*******************************************************************
3236 * fill a notify_info_data with the number of jobs queued
3237 ********************************************************************/
3239 void spoolss_notify_cjobs(int snum,
3240 struct spoolss_Notify *data,
3241 print_queue_struct *queue,
3242 NT_PRINTER_INFO_LEVEL *printer,
3243 TALLOC_CTX *mem_ctx)
3245 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
3248 /*******************************************************************
3249 * fill a notify_info_data with the average ppm
3250 ********************************************************************/
3252 static void spoolss_notify_average_ppm(int snum,
3253 struct spoolss_Notify *data,
3254 print_queue_struct *queue,
3255 NT_PRINTER_INFO_LEVEL *printer,
3256 TALLOC_CTX *mem_ctx)
3258 /* always respond 8 pages per minutes */
3259 /* a little hard ! */
3260 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
3263 /*******************************************************************
3264 * fill a notify_info_data with username
3265 ********************************************************************/
3267 static void spoolss_notify_username(int snum,
3268 struct spoolss_Notify *data,
3269 print_queue_struct *queue,
3270 NT_PRINTER_INFO_LEVEL *printer,
3271 TALLOC_CTX *mem_ctx)
3273 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
3276 /*******************************************************************
3277 * fill a notify_info_data with job status
3278 ********************************************************************/
3280 static void spoolss_notify_job_status(int snum,
3281 struct spoolss_Notify *data,
3282 print_queue_struct *queue,
3283 NT_PRINTER_INFO_LEVEL *printer,
3284 TALLOC_CTX *mem_ctx)
3286 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
3289 /*******************************************************************
3290 * fill a notify_info_data with job name
3291 ********************************************************************/
3293 static void spoolss_notify_job_name(int snum,
3294 struct spoolss_Notify *data,
3295 print_queue_struct *queue,
3296 NT_PRINTER_INFO_LEVEL *printer,
3297 TALLOC_CTX *mem_ctx)
3299 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
3302 /*******************************************************************
3303 * fill a notify_info_data with job status
3304 ********************************************************************/
3306 static void spoolss_notify_job_status_string(int snum,
3307 struct spoolss_Notify *data,
3308 print_queue_struct *queue,
3309 NT_PRINTER_INFO_LEVEL *printer,
3310 TALLOC_CTX *mem_ctx)
3313 * Now we're returning job status codes we just return a "" here. JRA.
3318 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3321 switch (queue->status) {
3326 p = ""; /* NT provides the paused string */
3335 #endif /* NO LONGER NEEDED. */
3337 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3340 /*******************************************************************
3341 * fill a notify_info_data with job time
3342 ********************************************************************/
3344 static void spoolss_notify_job_time(int snum,
3345 struct spoolss_Notify *data,
3346 print_queue_struct *queue,
3347 NT_PRINTER_INFO_LEVEL *printer,
3348 TALLOC_CTX *mem_ctx)
3350 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3353 /*******************************************************************
3354 * fill a notify_info_data with job size
3355 ********************************************************************/
3357 static void spoolss_notify_job_size(int snum,
3358 struct spoolss_Notify *data,
3359 print_queue_struct *queue,
3360 NT_PRINTER_INFO_LEVEL *printer,
3361 TALLOC_CTX *mem_ctx)
3363 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3366 /*******************************************************************
3367 * fill a notify_info_data with page info
3368 ********************************************************************/
3369 static void spoolss_notify_total_pages(int snum,
3370 struct spoolss_Notify *data,
3371 print_queue_struct *queue,
3372 NT_PRINTER_INFO_LEVEL *printer,
3373 TALLOC_CTX *mem_ctx)
3375 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3378 /*******************************************************************
3379 * fill a notify_info_data with pages printed info.
3380 ********************************************************************/
3381 static void spoolss_notify_pages_printed(int snum,
3382 struct spoolss_Notify *data,
3383 print_queue_struct *queue,
3384 NT_PRINTER_INFO_LEVEL *printer,
3385 TALLOC_CTX *mem_ctx)
3387 /* Add code when back-end tracks this */
3388 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3391 /*******************************************************************
3392 Fill a notify_info_data with job position.
3393 ********************************************************************/
3395 static void spoolss_notify_job_position(int snum,
3396 struct spoolss_Notify *data,
3397 print_queue_struct *queue,
3398 NT_PRINTER_INFO_LEVEL *printer,
3399 TALLOC_CTX *mem_ctx)
3401 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3404 /*******************************************************************
3405 Fill a notify_info_data with submitted time.
3406 ********************************************************************/
3408 static void spoolss_notify_submitted_time(int snum,
3409 struct spoolss_Notify *data,
3410 print_queue_struct *queue,
3411 NT_PRINTER_INFO_LEVEL *printer,
3412 TALLOC_CTX *mem_ctx)
3414 data->data.string.string = NULL;
3415 data->data.string.size = 0;
3417 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3418 &data->data.string.string,
3419 &data->data.string.size);
3423 struct s_notify_info_data_table
3425 enum spoolss_NotifyType type;
3426 enum spoolss_Field field;
3428 enum spoolss_NotifyTable variable_type;
3429 void (*fn) (int snum, struct spoolss_Notify *data,
3430 print_queue_struct *queue,
3431 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3434 /* A table describing the various print notification constants and
3435 whether the notification data is a pointer to a variable sized
3436 buffer, a one value uint32 or a two value uint32. */
3438 static const struct s_notify_info_data_table notify_info_data_table[] =
3440 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3441 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3442 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3443 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3444 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3445 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3446 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3447 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3448 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3449 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3450 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3451 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3452 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3464 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3465 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3466 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3467 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3468 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3469 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3470 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3471 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3472 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3473 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3474 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3475 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3476 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3477 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3478 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3487 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3488 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3491 /*******************************************************************
3492 Return the variable_type of info_data structure.
3493 ********************************************************************/
3495 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3496 enum spoolss_Field field)
3500 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3501 if ( (notify_info_data_table[i].type == type) &&
3502 (notify_info_data_table[i].field == field) ) {
3503 return notify_info_data_table[i].variable_type;
3507 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3512 /****************************************************************************
3513 ****************************************************************************/
3515 static bool search_notify(enum spoolss_NotifyType type,
3516 enum spoolss_Field field,
3521 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3522 if (notify_info_data_table[i].type == type &&
3523 notify_info_data_table[i].field == field &&
3524 notify_info_data_table[i].fn != NULL) {
3533 /****************************************************************************
3534 ****************************************************************************/
3536 void construct_info_data(struct spoolss_Notify *info_data,
3537 enum spoolss_NotifyType type,
3538 enum spoolss_Field field,
3541 info_data->type = type;
3542 info_data->field = field;
3543 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3544 info_data->job_id = id;
3547 /*******************************************************************
3549 * fill a notify_info struct with info asked
3551 ********************************************************************/
3553 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3554 struct spoolss_NotifyInfo *info,
3556 const struct spoolss_NotifyOptionType *option_type,
3558 TALLOC_CTX *mem_ctx)
3561 enum spoolss_NotifyType type;
3562 enum spoolss_Field field;
3564 struct spoolss_Notify *current_data;
3565 NT_PRINTER_INFO_LEVEL *printer = NULL;
3566 print_queue_struct *queue=NULL;
3568 type = option_type->type;
3570 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3571 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3572 option_type->count, lp_servicename(snum)));
3574 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3577 for(field_num=0; field_num < option_type->count; field_num++) {
3578 field = option_type->fields[field_num];
3580 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3582 if (!search_notify(type, field, &j) )
3585 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3586 struct spoolss_Notify,
3588 if (info->notifies == NULL) {
3589 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3590 free_a_printer(&printer, 2);
3594 current_data = &info->notifies[info->count];
3596 construct_info_data(current_data, type, field, id);
3598 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3599 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3601 notify_info_data_table[j].fn(snum, current_data, queue,
3607 free_a_printer(&printer, 2);
3611 /*******************************************************************
3613 * fill a notify_info struct with info asked
3615 ********************************************************************/
3617 static bool construct_notify_jobs_info(print_queue_struct *queue,
3618 struct spoolss_NotifyInfo *info,
3619 NT_PRINTER_INFO_LEVEL *printer,
3621 const struct spoolss_NotifyOptionType *option_type,
3623 TALLOC_CTX *mem_ctx)
3626 enum spoolss_NotifyType type;
3627 enum spoolss_Field field;
3628 struct spoolss_Notify *current_data;
3630 DEBUG(4,("construct_notify_jobs_info\n"));
3632 type = option_type->type;
3634 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3635 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3636 option_type->count));
3638 for(field_num=0; field_num<option_type->count; field_num++) {
3639 field = option_type->fields[field_num];
3641 if (!search_notify(type, field, &j) )
3644 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3645 struct spoolss_Notify,
3647 if (info->notifies == NULL) {
3648 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3652 current_data=&(info->notifies[info->count]);
3654 construct_info_data(current_data, type, field, id);
3655 notify_info_data_table[j].fn(snum, current_data, queue,
3664 * JFM: The enumeration is not that simple, it's even non obvious.
3666 * let's take an example: I want to monitor the PRINTER SERVER for
3667 * the printer's name and the number of jobs currently queued.
3668 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3669 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3671 * I have 3 printers on the back of my server.
3673 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3676 * 1 printer 1 name 1
3677 * 2 printer 1 cjob 1
3678 * 3 printer 2 name 2
3679 * 4 printer 2 cjob 2
3680 * 5 printer 3 name 3
3681 * 6 printer 3 name 3
3683 * that's the print server case, the printer case is even worse.
3686 /*******************************************************************
3688 * enumerate all printers on the printserver
3689 * fill a notify_info struct with info asked
3691 ********************************************************************/
3693 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3694 struct spoolss_NotifyInfo *info,
3695 TALLOC_CTX *mem_ctx)
3698 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3699 int n_services=lp_numservices();
3701 struct spoolss_NotifyOption *option;
3702 struct spoolss_NotifyOptionType option_type;
3704 DEBUG(4,("printserver_notify_info\n"));
3709 option = Printer->notify.option;
3712 info->notifies = NULL;
3715 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3716 sending a ffpcn() request first */
3721 for (i=0; i<option->count; i++) {
3722 option_type = option->types[i];
3724 if (option_type.type != PRINTER_NOTIFY_TYPE)
3727 for (snum=0; snum<n_services; snum++)
3729 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3730 construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3736 * Debugging information, don't delete.
3739 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3740 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3741 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3743 for (i=0; i<info->count; i++) {
3744 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3745 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3746 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3753 /*******************************************************************
3755 * fill a notify_info struct with info asked
3757 ********************************************************************/
3759 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
3760 TALLOC_CTX *mem_ctx)
3763 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3766 struct spoolss_NotifyOption *option;
3767 struct spoolss_NotifyOptionType option_type;
3769 print_queue_struct *queue=NULL;
3770 print_status_struct status;
3772 DEBUG(4,("printer_notify_info\n"));
3777 option = Printer->notify.option;
3781 info->notifies = NULL;
3784 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3785 sending a ffpcn() request first */
3790 get_printer_snum(p, hnd, &snum, NULL);
3792 for (i=0; i<option->count; i++) {
3793 option_type = option->types[i];
3795 switch (option_type.type) {
3796 case PRINTER_NOTIFY_TYPE:
3797 if(construct_notify_printer_info(Printer, info, snum,
3803 case JOB_NOTIFY_TYPE: {
3804 NT_PRINTER_INFO_LEVEL *printer = NULL;
3806 count = print_queue_status(snum, &queue, &status);
3808 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3811 for (j=0; j<count; j++) {
3812 construct_notify_jobs_info(&queue[j], info,
3819 free_a_printer(&printer, 2);
3829 * Debugging information, don't delete.
3832 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3833 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3834 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3836 for (i=0; i<info->count; i++) {
3837 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3838 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3839 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3845 /****************************************************************
3846 _spoolss_RouterRefreshPrinterChangeNotify
3847 ****************************************************************/
3849 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3850 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3852 POLICY_HND *handle = r->in.handle;
3853 struct spoolss_NotifyInfo *info;
3855 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3856 WERROR result = WERR_BADFID;
3858 /* we always have a spoolss_NotifyInfo struct */
3859 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3861 result = WERR_NOMEM;
3865 *r->out.info = info;
3868 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3869 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
3873 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3876 * We are now using the change value, and
3877 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3878 * I don't have a global notification system, I'm sending back all the
3879 * informations even when _NOTHING_ has changed.
3882 /* We need to keep track of the change value to send back in
3883 RRPCN replies otherwise our updates are ignored. */
3885 Printer->notify.fnpcn = True;
3887 if (Printer->notify.client_connected) {
3888 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3889 "Saving change value in request [%x]\n",
3891 Printer->notify.change = r->in.change_low;
3894 /* just ignore the spoolss_NotifyOption */
3896 switch (Printer->printer_type) {
3898 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3901 case SPLHND_PRINTER:
3902 result = printer_notify_info(p, handle, info, p->mem_ctx);
3906 Printer->notify.fnpcn = False;
3912 /********************************************************************
3913 * construct_printer_info_0
3914 * fill a printer_info_0 struct
3915 ********************************************************************/
3917 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3919 char *chaine = NULL;
3921 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3922 counter_printer_0 *session_counter;
3923 uint32 global_counter;
3926 print_status_struct status;
3927 TALLOC_CTX *ctx = talloc_tos();
3929 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3932 init_unistr(&printer->printername, ntprinter->info_2->printername);
3934 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3936 free_a_printer(&ntprinter,2);
3940 count = print_queue_length(snum, &status);
3942 /* check if we already have a counter for this printer */
3943 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3944 if (session_counter->snum == snum)
3948 init_unistr(&printer->servername, chaine);
3950 /* it's the first time, add it to the list */
3951 if (session_counter==NULL) {
3952 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3953 free_a_printer(&ntprinter, 2);
3956 ZERO_STRUCTP(session_counter);
3957 session_counter->snum=snum;
3958 session_counter->counter=0;
3959 DLIST_ADD(counter_list, session_counter);
3963 session_counter->counter++;
3966 * the global_counter should be stored in a TDB as it's common to all the clients
3967 * and should be zeroed on samba startup
3969 global_counter=session_counter->counter;
3970 printer->cjobs = count;
3971 printer->total_jobs = 0;
3972 printer->total_bytes = 0;
3974 setuptime = (time_t)ntprinter->info_2->setuptime;
3975 t=gmtime(&setuptime);
3977 printer->year = t->tm_year+1900;
3978 printer->month = t->tm_mon+1;
3979 printer->dayofweek = t->tm_wday;
3980 printer->day = t->tm_mday;
3981 printer->hour = t->tm_hour;
3982 printer->minute = t->tm_min;
3983 printer->second = t->tm_sec;
3984 printer->milliseconds = 0;
3986 printer->global_counter = global_counter;
3987 printer->total_pages = 0;
3989 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3990 printer->major_version = 0x0005; /* NT 5 */
3991 printer->build_version = 0x0893; /* build 2195 */
3993 printer->unknown7 = 0x1;
3994 printer->unknown8 = 0x0;
3995 printer->unknown9 = 0x0;
3996 printer->session_counter = session_counter->counter;
3997 printer->unknown11 = 0x0;
3998 printer->printer_errors = 0x0; /* number of print failure */
3999 printer->unknown13 = 0x0;
4000 printer->unknown14 = 0x1;
4001 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4002 printer->unknown16 = 0x0;
4003 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4004 printer->unknown18 = 0x0;
4005 printer->status = nt_printq_status(status.status);
4006 printer->unknown20 = 0x0;
4007 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4008 printer->unknown22 = 0x0;
4009 printer->unknown23 = 0x6; /* 6 ???*/
4010 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4011 printer->unknown25 = 0;
4012 printer->unknown26 = 0;
4013 printer->unknown27 = 0;
4014 printer->unknown28 = 0;
4015 printer->unknown29 = 0;
4017 free_a_printer(&ntprinter,2);
4021 /********************************************************************
4022 * construct_printer_info_1
4023 * fill a printer_info_1 struct
4024 ********************************************************************/
4025 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4027 char *chaine = NULL;
4028 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4029 TALLOC_CTX *ctx = talloc_tos();
4031 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4034 printer->flags=flags;
4036 if (*ntprinter->info_2->comment == '\0') {
4037 init_unistr(&printer->comment, lp_comment(snum));
4038 chaine = talloc_asprintf(ctx,
4039 "%s,%s,%s", ntprinter->info_2->printername,
4040 ntprinter->info_2->drivername, lp_comment(snum));
4043 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4044 chaine = talloc_asprintf(ctx,
4045 "%s,%s,%s", ntprinter->info_2->printername,
4046 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4050 free_a_printer(&ntprinter,2);
4054 init_unistr(&printer->description, chaine);
4055 init_unistr(&printer->name, ntprinter->info_2->printername);
4057 free_a_printer(&ntprinter,2);
4062 /****************************************************************************
4063 Free a DEVMODE struct.
4064 ****************************************************************************/
4066 static void free_dev_mode(DEVICEMODE *dev)
4071 SAFE_FREE(dev->dev_private);
4076 /****************************************************************************
4077 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4078 should be valid upon entry
4079 ****************************************************************************/
4081 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4083 if ( !devmode || !ntdevmode )
4086 init_unistr(&devmode->devicename, ntdevmode->devicename);
4088 init_unistr(&devmode->formname, ntdevmode->formname);
4090 devmode->specversion = ntdevmode->specversion;
4091 devmode->driverversion = ntdevmode->driverversion;
4092 devmode->size = ntdevmode->size;
4093 devmode->driverextra = ntdevmode->driverextra;
4094 devmode->fields = ntdevmode->fields;
4096 devmode->orientation = ntdevmode->orientation;
4097 devmode->papersize = ntdevmode->papersize;
4098 devmode->paperlength = ntdevmode->paperlength;
4099 devmode->paperwidth = ntdevmode->paperwidth;
4100 devmode->scale = ntdevmode->scale;
4101 devmode->copies = ntdevmode->copies;
4102 devmode->defaultsource = ntdevmode->defaultsource;
4103 devmode->printquality = ntdevmode->printquality;
4104 devmode->color = ntdevmode->color;
4105 devmode->duplex = ntdevmode->duplex;
4106 devmode->yresolution = ntdevmode->yresolution;
4107 devmode->ttoption = ntdevmode->ttoption;
4108 devmode->collate = ntdevmode->collate;
4109 devmode->icmmethod = ntdevmode->icmmethod;
4110 devmode->icmintent = ntdevmode->icmintent;
4111 devmode->mediatype = ntdevmode->mediatype;
4112 devmode->dithertype = ntdevmode->dithertype;
4114 if (ntdevmode->nt_dev_private != NULL) {
4115 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4122 /****************************************************************************
4123 Create a DEVMODE struct. Returns malloced memory.
4124 ****************************************************************************/
4126 DEVICEMODE *construct_dev_mode(const char *servicename)
4128 NT_PRINTER_INFO_LEVEL *printer = NULL;
4129 DEVICEMODE *devmode = NULL;
4131 DEBUG(7,("construct_dev_mode\n"));
4133 DEBUGADD(8,("getting printer characteristics\n"));
4135 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4138 if ( !printer->info_2->devmode ) {
4139 DEBUG(5, ("BONG! There was no device mode!\n"));
4143 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4144 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4148 ZERO_STRUCTP(devmode);
4150 DEBUGADD(8,("loading DEVICEMODE\n"));
4152 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4153 free_dev_mode( devmode );
4158 free_a_printer(&printer,2);
4163 /********************************************************************
4164 * construct_printer_info_2
4165 * fill a printer_info_2 struct
4166 ********************************************************************/
4168 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4171 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4173 print_status_struct status;
4175 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4178 count = print_queue_length(snum, &status);
4180 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4181 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4182 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4183 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4184 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4186 if (*ntprinter->info_2->comment == '\0')
4187 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4189 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4191 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4192 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4193 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4194 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4195 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4197 printer->attributes = ntprinter->info_2->attributes;
4199 printer->priority = ntprinter->info_2->priority; /* priority */
4200 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4201 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4202 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4203 printer->status = nt_printq_status(status.status); /* status */
4204 printer->cjobs = count; /* jobs */
4205 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4207 if ( !(printer->devmode = construct_dev_mode(
4208 lp_const_servicename(snum))) )
4209 DEBUG(8, ("Returning NULL Devicemode!\n"));
4211 printer->secdesc = NULL;
4213 if ( ntprinter->info_2->secdesc_buf
4214 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4216 /* don't use talloc_steal() here unless you do a deep steal of all
4217 the SEC_DESC members */
4219 printer->secdesc = dup_sec_desc( talloc_tos(),
4220 ntprinter->info_2->secdesc_buf->sd );
4223 free_a_printer(&ntprinter, 2);
4228 /********************************************************************
4229 * construct_printer_info_3
4230 * fill a printer_info_3 struct
4231 ********************************************************************/
4233 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4235 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4236 PRINTER_INFO_3 *printer = NULL;
4238 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4242 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4243 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4244 free_a_printer(&ntprinter, 2);
4248 ZERO_STRUCTP(printer);
4250 /* These are the components of the SD we are returning. */
4252 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4253 /* don't use talloc_steal() here unless you do a deep steal of all
4254 the SEC_DESC members */
4256 printer->secdesc = dup_sec_desc( talloc_tos(),
4257 ntprinter->info_2->secdesc_buf->sd );
4260 free_a_printer(&ntprinter, 2);
4262 *pp_printer = printer;
4266 /********************************************************************
4267 * construct_printer_info_4
4268 * fill a printer_info_4 struct
4269 ********************************************************************/
4271 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4273 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4275 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4278 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4279 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4280 printer->attributes = ntprinter->info_2->attributes;
4282 free_a_printer(&ntprinter, 2);
4286 /********************************************************************
4287 * construct_printer_info_5
4288 * fill a printer_info_5 struct
4289 ********************************************************************/
4291 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4293 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4295 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4298 init_unistr(&printer->printername, ntprinter->info_2->printername);
4299 init_unistr(&printer->portname, ntprinter->info_2->portname);
4300 printer->attributes = ntprinter->info_2->attributes;
4302 /* these two are not used by NT+ according to MSDN */
4304 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4305 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4307 free_a_printer(&ntprinter, 2);
4312 /********************************************************************
4313 * construct_printer_info_6
4314 * fill a printer_info_6 struct
4315 ********************************************************************/
4317 static bool construct_printer_info_6(Printer_entry *print_hnd,
4318 PRINTER_INFO_6 *printer,
4321 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4323 print_status_struct status;
4325 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4326 lp_const_servicename(snum))))
4329 count = print_queue_length(snum, &status);
4331 printer->status = nt_printq_status(status.status);
4333 free_a_printer(&ntprinter, 2);
4338 /********************************************************************
4339 * construct_printer_info_7
4340 * fill a printer_info_7 struct
4341 ********************************************************************/
4343 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4345 char *guid_str = NULL;
4348 if (is_printer_published(print_hnd, snum, &guid)) {
4349 if (asprintf(&guid_str, "{%s}",
4350 GUID_string(talloc_tos(), &guid)) == -1) {
4353 strupper_m(guid_str);
4354 init_unistr(&printer->guid, guid_str);
4355 SAFE_FREE(guid_str);
4356 printer->action = DSPRINT_PUBLISH;
4358 init_unistr(&printer->guid, "");
4359 printer->action = DSPRINT_UNPUBLISH;
4365 /********************************************************************
4366 Spoolss_enumprinters.
4367 ********************************************************************/
4369 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4373 int n_services=lp_numservices();
4374 PRINTER_INFO_1 *printers=NULL;
4375 PRINTER_INFO_1 current_prt;
4376 WERROR result = WERR_OK;
4378 DEBUG(4,("enum_all_printers_info_1\n"));
4380 for (snum=0; snum<n_services; snum++) {
4381 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4382 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4384 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4385 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4386 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4390 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4392 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4398 /* check the required size. */
4399 for (i=0; i<*returned; i++)
4400 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4402 if (*needed > offered) {
4403 result = WERR_INSUFFICIENT_BUFFER;
4407 if (!rpcbuf_alloc_size(buffer, *needed)) {
4408 result = WERR_NOMEM;
4412 /* fill the buffer with the structures */
4413 for (i=0; i<*returned; i++)
4414 smb_io_printer_info_1("", buffer, &printers[i], 0);
4419 SAFE_FREE(printers);
4421 if ( !W_ERROR_IS_OK(result) )
4427 /********************************************************************
4428 enum_all_printers_info_1_local.
4429 *********************************************************************/
4431 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4433 DEBUG(4,("enum_all_printers_info_1_local\n"));
4435 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4438 /********************************************************************
4439 enum_all_printers_info_1_name.
4440 *********************************************************************/
4442 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4446 DEBUG(4,("enum_all_printers_info_1_name\n"));
4448 if ((name[0] == '\\') && (name[1] == '\\'))
4451 if (is_myname_or_ipaddr(s)) {
4452 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4455 return WERR_INVALID_NAME;
4458 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4459 /********************************************************************
4460 enum_all_printers_info_1_remote.
4461 *********************************************************************/
4463 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4465 PRINTER_INFO_1 *printer;
4466 fstring printername;
4469 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4470 WERROR result = WERR_OK;
4472 /* JFM: currently it's more a place holder than anything else.
4473 * In the spooler world there is a notion of server registration.
4474 * the print servers are registered on the PDC (in the same domain)
4476 * We should have a TDB here. The registration is done thru an
4477 * undocumented RPC call.
4480 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4485 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4486 slprintf(desc, sizeof(desc)-1,"%s", name);
4487 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4489 init_unistr(&printer->description, desc);
4490 init_unistr(&printer->name, printername);
4491 init_unistr(&printer->comment, comment);
4492 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4494 /* check the required size. */
4495 *needed += spoolss_size_printer_info_1(printer);
4497 if (*needed > offered) {
4498 result = WERR_INSUFFICIENT_BUFFER;
4502 if (!rpcbuf_alloc_size(buffer, *needed)) {
4503 result = WERR_NOMEM;
4507 /* fill the buffer with the structures */
4508 smb_io_printer_info_1("", buffer, printer, 0);
4514 if ( !W_ERROR_IS_OK(result) )
4522 /********************************************************************
4523 enum_all_printers_info_1_network.
4524 *********************************************************************/
4526 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4530 DEBUG(4,("enum_all_printers_info_1_network\n"));
4532 /* If we respond to a enum_printers level 1 on our name with flags
4533 set to PRINTER_ENUM_REMOTE with a list of printers then these
4534 printers incorrectly appear in the APW browse list.
4535 Specifically the printers for the server appear at the workgroup
4536 level where all the other servers in the domain are
4537 listed. Windows responds to this call with a
4538 WERR_CAN_NOT_COMPLETE so we should do the same. */
4540 if (name[0] == '\\' && name[1] == '\\')
4543 if (is_myname_or_ipaddr(s))
4544 return WERR_CAN_NOT_COMPLETE;
4546 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4549 /********************************************************************
4550 * api_spoolss_enumprinters
4552 * called from api_spoolss_enumprinters (see this to understand)
4553 ********************************************************************/
4555 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4559 int n_services=lp_numservices();
4560 PRINTER_INFO_2 *printers=NULL;
4561 PRINTER_INFO_2 current_prt;
4562 WERROR result = WERR_OK;
4566 for (snum=0; snum<n_services; snum++) {
4567 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4568 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4570 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4571 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4572 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4577 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4579 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4586 /* check the required size. */
4587 for (i=0; i<*returned; i++)
4588 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4590 if (*needed > offered) {
4591 result = WERR_INSUFFICIENT_BUFFER;
4595 if (!rpcbuf_alloc_size(buffer, *needed)) {
4596 result = WERR_NOMEM;
4600 /* fill the buffer with the structures */
4601 for (i=0; i<*returned; i++)
4602 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4607 for (i=0; i<*returned; i++)
4608 free_devmode(printers[i].devmode);
4610 SAFE_FREE(printers);
4612 if ( !W_ERROR_IS_OK(result) )
4618 /********************************************************************
4619 * handle enumeration of printers at level 1
4620 ********************************************************************/
4622 static WERROR enumprinters_level1( uint32 flags, fstring name,
4623 RPC_BUFFER *buffer, uint32 offered,
4624 uint32 *needed, uint32 *returned)
4626 /* Not all the flags are equals */
4628 if (flags & PRINTER_ENUM_LOCAL)
4629 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4631 if (flags & PRINTER_ENUM_NAME)
4632 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4634 #if 0 /* JERRY - disabled for now */
4635 if (flags & PRINTER_ENUM_REMOTE)
4636 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4639 if (flags & PRINTER_ENUM_NETWORK)
4640 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4642 return WERR_OK; /* NT4sp5 does that */
4645 /********************************************************************
4646 * handle enumeration of printers at level 2
4647 ********************************************************************/
4649 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4650 RPC_BUFFER *buffer, uint32 offered,
4651 uint32 *needed, uint32 *returned)
4653 if (flags & PRINTER_ENUM_LOCAL) {
4654 return enum_all_printers_info_2(buffer, offered, needed, returned);
4657 if (flags & PRINTER_ENUM_NAME) {
4658 if (is_myname_or_ipaddr(canon_servername(servername)))
4659 return enum_all_printers_info_2(buffer, offered, needed, returned);
4661 return WERR_INVALID_NAME;
4664 if (flags & PRINTER_ENUM_REMOTE)
4665 return WERR_UNKNOWN_LEVEL;
4670 /********************************************************************
4671 * handle enumeration of printers at level 5
4672 ********************************************************************/
4674 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4675 RPC_BUFFER *buffer, uint32 offered,
4676 uint32 *needed, uint32 *returned)
4678 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4682 /********************************************************************
4683 * api_spoolss_enumprinters
4685 * called from api_spoolss_enumprinters (see this to understand)
4686 ********************************************************************/
4688 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4690 uint32 flags = q_u->flags;
4691 UNISTR2 *servername = &q_u->servername;
4692 uint32 level = q_u->level;
4693 RPC_BUFFER *buffer = NULL;
4694 uint32 offered = q_u->offered;
4695 uint32 *needed = &r_u->needed;
4696 uint32 *returned = &r_u->returned;
4700 /* that's an [in out] buffer */
4702 if (!q_u->buffer && (offered!=0)) {
4703 return WERR_INVALID_PARAM;
4706 if (offered > MAX_RPC_DATA_SIZE) {
4707 return WERR_INVALID_PARAM;
4710 rpcbuf_move(q_u->buffer, &r_u->buffer);
4711 buffer = r_u->buffer;
4713 DEBUG(4,("_spoolss_enumprinters\n"));
4720 * flags==PRINTER_ENUM_NAME
4721 * if name=="" then enumerates all printers
4722 * if name!="" then enumerate the printer
4723 * flags==PRINTER_ENUM_REMOTE
4724 * name is NULL, enumerate printers
4725 * Level 2: name!="" enumerates printers, name can't be NULL
4726 * Level 3: doesn't exist
4727 * Level 4: does a local registry lookup
4728 * Level 5: same as Level 2
4731 unistr2_to_ascii(name, servername, sizeof(name));
4736 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4738 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4740 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4745 return WERR_UNKNOWN_LEVEL;
4748 /****************************************************************************
4749 ****************************************************************************/
4751 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4753 PRINTER_INFO_0 *printer=NULL;
4754 WERROR result = WERR_OK;
4756 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4759 construct_printer_info_0(print_hnd, printer, snum);
4761 /* check the required size. */
4762 *needed += spoolss_size_printer_info_0(printer);
4764 if (*needed > offered) {
4765 result = WERR_INSUFFICIENT_BUFFER;
4769 if (!rpcbuf_alloc_size(buffer, *needed)) {
4770 result = WERR_NOMEM;
4774 /* fill the buffer with the structures */
4775 smb_io_printer_info_0("", buffer, printer, 0);
4785 /****************************************************************************
4786 ****************************************************************************/
4788 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4790 PRINTER_INFO_1 *printer=NULL;
4791 WERROR result = WERR_OK;
4793 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4796 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4798 /* check the required size. */
4799 *needed += spoolss_size_printer_info_1(printer);
4801 if (*needed > offered) {
4802 result = WERR_INSUFFICIENT_BUFFER;
4806 if (!rpcbuf_alloc_size(buffer, *needed)) {
4807 result = WERR_NOMEM;
4811 /* fill the buffer with the structures */
4812 smb_io_printer_info_1("", buffer, printer, 0);
4821 /****************************************************************************
4822 ****************************************************************************/
4824 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4826 PRINTER_INFO_2 *printer=NULL;
4827 WERROR result = WERR_OK;
4829 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4832 construct_printer_info_2(print_hnd, printer, snum);
4834 /* check the required size. */
4835 *needed += spoolss_size_printer_info_2(printer);
4837 if (*needed > offered) {
4838 result = WERR_INSUFFICIENT_BUFFER;
4842 if (!rpcbuf_alloc_size(buffer, *needed)) {
4843 result = WERR_NOMEM;
4847 /* fill the buffer with the structures */
4848 if (!smb_io_printer_info_2("", buffer, printer, 0))
4849 result = WERR_NOMEM;
4853 free_printer_info_2(printer);
4858 /****************************************************************************
4859 ****************************************************************************/
4861 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4863 PRINTER_INFO_3 *printer=NULL;
4864 WERROR result = WERR_OK;
4866 if (!construct_printer_info_3(print_hnd, &printer, snum))
4869 /* check the required size. */
4870 *needed += spoolss_size_printer_info_3(printer);
4872 if (*needed > offered) {
4873 result = WERR_INSUFFICIENT_BUFFER;
4877 if (!rpcbuf_alloc_size(buffer, *needed)) {
4878 result = WERR_NOMEM;
4882 /* fill the buffer with the structures */
4883 smb_io_printer_info_3("", buffer, printer, 0);
4887 free_printer_info_3(printer);
4892 /****************************************************************************
4893 ****************************************************************************/
4895 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4897 PRINTER_INFO_4 *printer=NULL;
4898 WERROR result = WERR_OK;
4900 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4903 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4908 /* check the required size. */
4909 *needed += spoolss_size_printer_info_4(printer);
4911 if (*needed > offered) {
4912 result = WERR_INSUFFICIENT_BUFFER;
4916 if (!rpcbuf_alloc_size(buffer, *needed)) {
4917 result = WERR_NOMEM;
4921 /* fill the buffer with the structures */
4922 smb_io_printer_info_4("", buffer, printer, 0);
4926 free_printer_info_4(printer);
4931 /****************************************************************************
4932 ****************************************************************************/
4934 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4936 PRINTER_INFO_5 *printer=NULL;
4937 WERROR result = WERR_OK;
4939 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4942 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4943 free_printer_info_5(printer);
4947 /* check the required size. */
4948 *needed += spoolss_size_printer_info_5(printer);
4950 if (*needed > offered) {
4951 result = WERR_INSUFFICIENT_BUFFER;
4955 if (!rpcbuf_alloc_size(buffer, *needed)) {
4956 result = WERR_NOMEM;
4960 /* fill the buffer with the structures */
4961 smb_io_printer_info_5("", buffer, printer, 0);
4965 free_printer_info_5(printer);
4970 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4972 RPC_BUFFER *buffer, uint32 offered,
4975 PRINTER_INFO_6 *printer;
4976 WERROR result = WERR_OK;
4978 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4982 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4983 free_printer_info_6(printer);
4987 /* check the required size. */
4988 *needed += spoolss_size_printer_info_6(printer);
4990 if (*needed > offered) {
4991 result = WERR_INSUFFICIENT_BUFFER;
4995 if (!rpcbuf_alloc_size(buffer, *needed)) {
4996 result = WERR_NOMEM;
5000 /* fill the buffer with the structures */
5001 smb_io_printer_info_6("", buffer, printer, 0);
5005 free_printer_info_6(printer);
5010 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5012 PRINTER_INFO_7 *printer=NULL;
5013 WERROR result = WERR_OK;
5015 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5018 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5019 result = WERR_NOMEM;
5023 /* check the required size. */
5024 *needed += spoolss_size_printer_info_7(printer);
5026 if (*needed > offered) {
5027 result = WERR_INSUFFICIENT_BUFFER;
5031 if (!rpcbuf_alloc_size(buffer, *needed)) {
5032 result = WERR_NOMEM;
5037 /* fill the buffer with the structures */
5038 smb_io_printer_info_7("", buffer, printer, 0);
5042 free_printer_info_7(printer);
5047 /****************************************************************************
5048 ****************************************************************************/
5050 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5052 POLICY_HND *handle = &q_u->handle;
5053 uint32 level = q_u->level;
5054 RPC_BUFFER *buffer = NULL;
5055 uint32 offered = q_u->offered;
5056 uint32 *needed = &r_u->needed;
5057 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5061 /* that's an [in out] buffer */
5063 if (!q_u->buffer && (offered!=0)) {
5064 return WERR_INVALID_PARAM;
5067 if (offered > MAX_RPC_DATA_SIZE) {
5068 return WERR_INVALID_PARAM;
5071 rpcbuf_move(q_u->buffer, &r_u->buffer);
5072 buffer = r_u->buffer;
5076 if (!get_printer_snum(p, handle, &snum, NULL))
5081 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5083 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5085 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5087 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5089 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5091 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5093 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5095 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5097 return WERR_UNKNOWN_LEVEL;
5100 /********************************************************************
5101 * fill a DRIVER_INFO_1 struct
5102 ********************************************************************/
5104 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5106 init_unistr( &info->name, driver.info_3->name);
5109 /********************************************************************
5110 * construct_printer_driver_info_1
5111 ********************************************************************/
5113 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5115 NT_PRINTER_INFO_LEVEL *printer = NULL;
5116 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5118 ZERO_STRUCT(driver);
5120 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5121 return WERR_INVALID_PRINTER_NAME;
5123 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5124 free_a_printer(&printer, 2);
5125 return WERR_UNKNOWN_PRINTER_DRIVER;
5128 fill_printer_driver_info_1(info, driver, servername, architecture);
5130 free_a_printer(&printer,2);
5135 /********************************************************************
5136 * construct_printer_driver_info_2
5137 * fill a printer_info_2 struct
5138 ********************************************************************/
5140 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5142 TALLOC_CTX *ctx = talloc_tos();
5144 const char *cservername = canon_servername(servername);
5146 info->version=driver.info_3->cversion;
5148 init_unistr( &info->name, driver.info_3->name );
5149 init_unistr( &info->architecture, driver.info_3->environment );
5151 if (strlen(driver.info_3->driverpath)) {
5152 temp = talloc_asprintf(ctx,
5155 driver.info_3->driverpath);
5156 init_unistr( &info->driverpath, temp );
5158 init_unistr( &info->driverpath, "" );
5162 if (strlen(driver.info_3->datafile)) {
5163 temp = talloc_asprintf(ctx,
5166 driver.info_3->datafile);
5167 init_unistr( &info->datafile, temp );
5169 init_unistr( &info->datafile, "" );
5172 if (strlen(driver.info_3->configfile)) {
5173 temp = talloc_asprintf(ctx,
5176 driver.info_3->configfile);
5177 init_unistr( &info->configfile, temp );
5179 init_unistr( &info->configfile, "" );
5182 /********************************************************************
5183 * construct_printer_driver_info_2
5184 * fill a printer_info_2 struct
5185 ********************************************************************/
5187 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5189 NT_PRINTER_INFO_LEVEL *printer = NULL;
5190 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5192 ZERO_STRUCT(printer);
5193 ZERO_STRUCT(driver);
5195 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5196 return WERR_INVALID_PRINTER_NAME;
5198 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5199 free_a_printer(&printer, 2);
5200 return WERR_UNKNOWN_PRINTER_DRIVER;
5203 fill_printer_driver_info_2(info, driver, servername);
5205 free_a_printer(&printer,2);
5210 /********************************************************************
5211 * copy a strings array and convert to UNICODE
5213 * convert an array of ascii string to a UNICODE string
5214 ********************************************************************/
5216 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5222 TALLOC_CTX *ctx = talloc_tos();
5224 DEBUG(6,("init_unistr_array\n"));
5228 if ( !char_array ) {
5233 v = ""; /* hack to handle null lists */
5236 /* hack to allow this to be used in places other than when generating
5237 the list of dependent files */
5241 line = talloc_asprintf(ctx,
5243 canon_servername(servername),
5246 line = talloc_strdup(ctx, v);
5250 SAFE_FREE(*uni_array);
5253 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5255 /* add one extra unit16 for the second terminating NULL */
5257 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5258 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5265 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5270 /* special case for ""; we need to add both NULL's here */
5272 (*uni_array)[j++]=0x0000;
5273 (*uni_array)[j]=0x0000;
5276 DEBUGADD(6,("last one:done\n"));
5278 /* return size of array in uint16's */
5283 /********************************************************************
5284 * construct_printer_info_3
5285 * fill a printer_info_3 struct
5286 ********************************************************************/
5288 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5291 TALLOC_CTX *ctx = talloc_tos();
5292 const char *cservername = canon_servername(servername);
5296 info->version=driver.info_3->cversion;
5298 init_unistr( &info->name, driver.info_3->name );
5299 init_unistr( &info->architecture, driver.info_3->environment );
5301 if (strlen(driver.info_3->driverpath)) {
5302 temp = talloc_asprintf(ctx,
5305 driver.info_3->driverpath);
5306 init_unistr( &info->driverpath, temp );
5308 init_unistr( &info->driverpath, "" );
5311 if (strlen(driver.info_3->datafile)) {
5312 temp = talloc_asprintf(ctx,
5315 driver.info_3->datafile);
5316 init_unistr( &info->datafile, temp );
5318 init_unistr( &info->datafile, "" );
5321 if (strlen(driver.info_3->configfile)) {
5322 temp = talloc_asprintf(ctx,
5325 driver.info_3->configfile);
5326 init_unistr( &info->configfile, temp );
5328 init_unistr( &info->configfile, "" );
5331 if (strlen(driver.info_3->helpfile)) {
5332 temp = talloc_asprintf(ctx,
5335 driver.info_3->helpfile);
5336 init_unistr( &info->helpfile, temp );
5338 init_unistr( &info->helpfile, "" );
5341 init_unistr( &info->monitorname, driver.info_3->monitorname );
5342 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5344 info->dependentfiles=NULL;
5345 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5348 /********************************************************************
5349 * construct_printer_info_3
5350 * fill a printer_info_3 struct
5351 ********************************************************************/
5353 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5355 NT_PRINTER_INFO_LEVEL *printer = NULL;
5356 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5358 ZERO_STRUCT(driver);
5360 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5361 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5362 if (!W_ERROR_IS_OK(status))
5363 return WERR_INVALID_PRINTER_NAME;
5365 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5366 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5371 * I put this code in during testing. Helpful when commenting out the
5372 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5373 * as win2k always queries the driver using an infor level of 6.
5374 * I've left it in (but ifdef'd out) because I'll probably
5375 * use it in experimentation again in the future. --jerry 22/01/2002
5378 if (!W_ERROR_IS_OK(status)) {
5380 * Is this a W2k client ?
5383 /* Yes - try again with a WinNT driver. */
5385 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5386 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5390 if (!W_ERROR_IS_OK(status)) {
5391 free_a_printer(&printer,2);
5392 return WERR_UNKNOWN_PRINTER_DRIVER;
5400 fill_printer_driver_info_3(info, driver, servername);
5402 free_a_printer(&printer,2);
5407 /********************************************************************
5408 * construct_printer_info_6
5409 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5410 ********************************************************************/
5412 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5416 TALLOC_CTX *ctx = talloc_tos();
5417 const char *cservername = canon_servername(servername);
5420 memset(&nullstr, '\0', sizeof(fstring));
5422 info->version=driver.info_3->cversion;
5424 init_unistr( &info->name, driver.info_3->name );
5425 init_unistr( &info->architecture, driver.info_3->environment );
5427 if (strlen(driver.info_3->driverpath)) {
5428 temp = talloc_asprintf(ctx,
5431 driver.info_3->driverpath);
5432 init_unistr( &info->driverpath, temp );
5434 init_unistr( &info->driverpath, "" );
5437 if (strlen(driver.info_3->datafile)) {
5438 temp = talloc_asprintf(ctx,
5441 driver.info_3->datafile);
5442 init_unistr( &info->datafile, temp );
5444 init_unistr( &info->datafile, "" );
5447 if (strlen(driver.info_3->configfile)) {
5448 temp = talloc_asprintf(ctx,
5451 driver.info_3->configfile);
5452 init_unistr( &info->configfile, temp );
5454 init_unistr( &info->configfile, "" );
5457 if (strlen(driver.info_3->helpfile)) {
5458 temp = talloc_asprintf(ctx,
5461 driver.info_3->helpfile);
5462 init_unistr( &info->helpfile, temp );
5464 init_unistr( &info->helpfile, "" );
5467 init_unistr( &info->monitorname, driver.info_3->monitorname );
5468 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5470 info->dependentfiles = NULL;
5471 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5473 info->previousdrivernames=NULL;
5474 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5476 info->driver_date=0;
5479 info->driver_version_low=0;
5480 info->driver_version_high=0;
5482 init_unistr( &info->mfgname, "");
5483 init_unistr( &info->oem_url, "");
5484 init_unistr( &info->hardware_id, "");
5485 init_unistr( &info->provider, "");
5488 /********************************************************************
5489 * construct_printer_info_6
5490 * fill a printer_info_6 struct
5491 ********************************************************************/
5493 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5494 const char *servername, fstring architecture, uint32 version)
5496 NT_PRINTER_INFO_LEVEL *printer = NULL;
5497 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5500 ZERO_STRUCT(driver);
5502 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5504 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5506 if (!W_ERROR_IS_OK(status))
5507 return WERR_INVALID_PRINTER_NAME;
5509 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5511 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5513 if (!W_ERROR_IS_OK(status))
5516 * Is this a W2k client ?
5520 free_a_printer(&printer,2);
5521 return WERR_UNKNOWN_PRINTER_DRIVER;
5524 /* Yes - try again with a WinNT driver. */
5526 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5527 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5528 if (!W_ERROR_IS_OK(status)) {
5529 free_a_printer(&printer,2);
5530 return WERR_UNKNOWN_PRINTER_DRIVER;
5534 fill_printer_driver_info_6(info, driver, servername);
5536 free_a_printer(&printer,2);
5537 free_a_printer_driver(driver, 3);
5542 /****************************************************************************
5543 ****************************************************************************/
5545 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5547 SAFE_FREE(info->dependentfiles);
5550 /****************************************************************************
5551 ****************************************************************************/
5553 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5555 SAFE_FREE(info->dependentfiles);
5558 /****************************************************************************
5559 ****************************************************************************/
5561 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5563 DRIVER_INFO_1 *info=NULL;
5566 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5569 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5570 if (!W_ERROR_IS_OK(result))
5573 /* check the required size. */
5574 *needed += spoolss_size_printer_driver_info_1(info);
5576 if (*needed > offered) {
5577 result = WERR_INSUFFICIENT_BUFFER;
5581 if (!rpcbuf_alloc_size(buffer, *needed)) {
5582 result = WERR_NOMEM;
5586 /* fill the buffer with the structures */
5587 smb_io_printer_driver_info_1("", buffer, info, 0);
5596 /****************************************************************************
5597 ****************************************************************************/
5599 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5601 DRIVER_INFO_2 *info=NULL;
5604 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5607 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5608 if (!W_ERROR_IS_OK(result))
5611 /* check the required size. */
5612 *needed += spoolss_size_printer_driver_info_2(info);
5614 if (*needed > offered) {
5615 result = WERR_INSUFFICIENT_BUFFER;
5619 if (!rpcbuf_alloc_size(buffer, *needed)) {
5620 result = WERR_NOMEM;
5624 /* fill the buffer with the structures */
5625 smb_io_printer_driver_info_2("", buffer, info, 0);
5634 /****************************************************************************
5635 ****************************************************************************/
5637 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5644 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5645 if (!W_ERROR_IS_OK(result))
5648 /* check the required size. */
5649 *needed += spoolss_size_printer_driver_info_3(&info);
5651 if (*needed > offered) {
5652 result = WERR_INSUFFICIENT_BUFFER;
5656 if (!rpcbuf_alloc_size(buffer, *needed)) {
5657 result = WERR_NOMEM;
5661 /* fill the buffer with the structures */
5662 smb_io_printer_driver_info_3("", buffer, &info, 0);
5665 free_printer_driver_info_3(&info);
5670 /****************************************************************************
5671 ****************************************************************************/
5673 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5680 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5681 if (!W_ERROR_IS_OK(result))
5684 /* check the required size. */
5685 *needed += spoolss_size_printer_driver_info_6(&info);
5687 if (*needed > offered) {
5688 result = WERR_INSUFFICIENT_BUFFER;
5692 if (!rpcbuf_alloc_size(buffer, *needed)) {
5693 result = WERR_NOMEM;
5697 /* fill the buffer with the structures */
5698 smb_io_printer_driver_info_6("", buffer, &info, 0);
5701 free_printer_driver_info_6(&info);
5706 /****************************************************************************
5707 ****************************************************************************/
5709 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5711 POLICY_HND *handle = &q_u->handle;
5712 UNISTR2 *uni_arch = &q_u->architecture;
5713 uint32 level = q_u->level;
5714 uint32 clientmajorversion = q_u->clientmajorversion;
5715 RPC_BUFFER *buffer = NULL;
5716 uint32 offered = q_u->offered;
5717 uint32 *needed = &r_u->needed;
5718 uint32 *servermajorversion = &r_u->servermajorversion;
5719 uint32 *serverminorversion = &r_u->serverminorversion;
5720 Printer_entry *printer;
5723 fstring architecture;
5726 /* that's an [in out] buffer */
5728 if (!q_u->buffer && (offered!=0)) {
5729 return WERR_INVALID_PARAM;
5732 if (offered > MAX_RPC_DATA_SIZE) {
5733 return WERR_INVALID_PARAM;
5736 rpcbuf_move(q_u->buffer, &r_u->buffer);
5737 buffer = r_u->buffer;
5739 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5741 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5742 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5743 return WERR_INVALID_PRINTER_NAME;
5747 *servermajorversion = 0;
5748 *serverminorversion = 0;
5750 fstrcpy(servername, get_server_name( printer ));
5751 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5753 if (!get_printer_snum(p, handle, &snum, NULL))
5758 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5760 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5762 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5764 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5767 /* apparently this call is the equivalent of
5768 EnumPrinterDataEx() for the DsDriver key */
5773 return WERR_UNKNOWN_LEVEL;
5777 /****************************************************************
5778 _spoolss_StartPagePrinter
5779 ****************************************************************/
5781 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5782 struct spoolss_StartPagePrinter *r)
5784 POLICY_HND *handle = r->in.handle;
5786 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5789 DEBUG(3,("_spoolss_StartPagePrinter: "
5790 "Error in startpageprinter printer handle\n"));
5794 Printer->page_started=True;
5798 /****************************************************************
5799 _spoolss_EndPagePrinter
5800 ****************************************************************/
5802 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5803 struct spoolss_EndPagePrinter *r)
5805 POLICY_HND *handle = r->in.handle;
5808 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5811 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5812 OUR_HANDLE(handle)));
5816 if (!get_printer_snum(p, handle, &snum, NULL))
5819 Printer->page_started=False;
5820 print_job_endpage(snum, Printer->jobid);
5825 /****************************************************************
5826 _spoolss_StartDocPrinter
5827 ****************************************************************/
5829 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5830 struct spoolss_StartDocPrinter *r)
5832 POLICY_HND *handle = r->in.handle;
5833 uint32_t *jobid = r->out.job_id;
5834 struct spoolss_DocumentInfo1 *info_1;
5836 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5839 DEBUG(2,("_spoolss_StartDocPrinter: "
5840 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5844 if (r->in.level != 1) {
5845 return WERR_UNKNOWN_LEVEL;
5848 info_1 = r->in.info.info1;
5851 * a nice thing with NT is it doesn't listen to what you tell it.
5852 * when asked to send _only_ RAW datas, it tries to send datas
5855 * So I add checks like in NT Server ...
5858 if (info_1->datatype) {
5859 if (strcmp(info_1->datatype, "RAW") != 0) {
5861 return WERR_INVALID_DATATYPE;
5865 /* get the share number of the printer */
5866 if (!get_printer_snum(p, handle, &snum, NULL)) {
5870 Printer->jobid = print_job_start(p->server_info, snum,
5871 CONST_DISCARD(char *,info_1->document_name),
5872 Printer->nt_devmode);
5874 /* An error occured in print_job_start() so return an appropriate
5877 if (Printer->jobid == -1) {
5878 return map_werror_from_unix(errno);
5881 Printer->document_started=True;
5882 (*jobid) = Printer->jobid;
5887 /****************************************************************
5888 _spoolss_EndDocPrinter
5889 ****************************************************************/
5891 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5892 struct spoolss_EndDocPrinter *r)
5894 POLICY_HND *handle = r->in.handle;
5896 return _spoolss_enddocprinter_internal(p, handle);
5899 /****************************************************************
5900 _spoolss_WritePrinter
5901 ****************************************************************/
5903 WERROR _spoolss_WritePrinter(pipes_struct *p,
5904 struct spoolss_WritePrinter *r)
5906 POLICY_HND *handle = r->in.handle;
5907 uint32 buffer_size = r->in._data_size;
5908 uint8 *buffer = r->in.data.data;
5909 uint32 *buffer_written = &r->in._data_size;
5911 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5914 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5915 OUR_HANDLE(handle)));
5916 *r->out.num_written = r->in._data_size;
5920 if (!get_printer_snum(p, handle, &snum, NULL))
5923 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5924 (SMB_OFF_T)-1, (size_t)buffer_size);
5925 if (*buffer_written == (uint32)-1) {
5926 *r->out.num_written = 0;
5927 if (errno == ENOSPC)
5928 return WERR_NO_SPOOL_SPACE;
5930 return WERR_ACCESS_DENIED;
5933 *r->out.num_written = r->in._data_size;
5938 /********************************************************************
5939 * api_spoolss_getprinter
5940 * called from the spoolss dispatcher
5942 ********************************************************************/
5944 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5948 WERROR errcode = WERR_BADFUNC;
5949 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5952 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5956 if (!get_printer_snum(p, handle, &snum, NULL))
5960 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5961 if (print_queue_pause(p->server_info, snum, &errcode)) {
5965 case SPOOLSS_PRINTER_CONTROL_RESUME:
5966 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5967 if (print_queue_resume(p->server_info, snum, &errcode)) {
5971 case SPOOLSS_PRINTER_CONTROL_PURGE:
5972 if (print_queue_purge(p->server_info, snum, &errcode)) {
5977 return WERR_UNKNOWN_LEVEL;
5984 /****************************************************************
5985 _spoolss_AbortPrinter
5986 * From MSDN: "Deletes printer's spool file if printer is configured
5988 ****************************************************************/
5990 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5991 struct spoolss_AbortPrinter *r)
5993 POLICY_HND *handle = r->in.handle;
5994 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5996 WERROR errcode = WERR_OK;
5999 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6000 OUR_HANDLE(handle)));
6004 if (!get_printer_snum(p, handle, &snum, NULL))
6007 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6012 /********************************************************************
6013 * called by spoolss_api_setprinter
6014 * when updating a printer description
6015 ********************************************************************/
6017 static WERROR update_printer_sec(POLICY_HND *handle,
6018 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6020 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6024 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6026 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6027 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6028 OUR_HANDLE(handle)));
6030 result = WERR_BADFID;
6035 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6036 result = WERR_INVALID_PARAM;
6040 /* Check the user has permissions to change the security
6041 descriptor. By experimentation with two NT machines, the user
6042 requires Full Access to the printer to change security
6045 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6046 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6047 result = WERR_ACCESS_DENIED;
6051 /* NT seems to like setting the security descriptor even though
6052 nothing may have actually changed. */
6054 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6055 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6056 result = WERR_BADFID;
6060 if (DEBUGLEVEL >= 10) {
6064 the_acl = old_secdesc_ctr->sd->dacl;
6065 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6066 PRINTERNAME(snum), the_acl->num_aces));
6068 for (i = 0; i < the_acl->num_aces; i++) {
6069 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6070 &the_acl->aces[i].trustee),
6071 the_acl->aces[i].access_mask));
6074 the_acl = secdesc_ctr->sd->dacl;
6077 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6078 PRINTERNAME(snum), the_acl->num_aces));
6080 for (i = 0; i < the_acl->num_aces; i++) {
6081 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6082 &the_acl->aces[i].trustee),
6083 the_acl->aces[i].access_mask));
6086 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6090 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6091 if (!new_secdesc_ctr) {
6092 result = WERR_NOMEM;
6096 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6101 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6108 /********************************************************************
6109 Canonicalize printer info from a client
6111 ATTN: It does not matter what we set the servername to hear
6112 since we do the necessary work in get_a_printer() to set it to
6113 the correct value based on what the client sent in the
6114 _spoolss_open_printer_ex().
6115 ********************************************************************/
6117 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6119 fstring printername;
6122 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6123 "portname=%s drivername=%s comment=%s location=%s\n",
6124 info->servername, info->printername, info->sharename,
6125 info->portname, info->drivername, info->comment, info->location));
6127 /* we force some elements to "correct" values */
6128 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6129 fstrcpy(info->sharename, lp_servicename(snum));
6131 /* check to see if we allow printername != sharename */
6133 if ( lp_force_printername(snum) ) {
6134 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6135 global_myname(), info->sharename );
6138 /* make sure printername is in \\server\printername format */
6140 fstrcpy( printername, info->printername );
6142 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6143 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6147 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6148 global_myname(), p );
6151 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6152 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6159 /****************************************************************************
6160 ****************************************************************************/
6162 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6164 char *cmd = lp_addport_cmd();
6165 char *command = NULL;
6167 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6168 bool is_print_op = False;
6171 return WERR_ACCESS_DENIED;
6174 command = talloc_asprintf(ctx,
6175 "%s \"%s\" \"%s\"", cmd, portname, uri );
6181 is_print_op = user_has_privileges( token, &se_printop );
6183 DEBUG(10,("Running [%s]\n", command));
6185 /********* BEGIN SePrintOperatorPrivilege **********/
6190 ret = smbrun(command, NULL);
6195 /********* END SePrintOperatorPrivilege **********/
6197 DEBUGADD(10,("returned [%d]\n", ret));
6199 TALLOC_FREE(command);
6202 return WERR_ACCESS_DENIED;
6208 /****************************************************************************
6209 ****************************************************************************/
6211 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6213 char *cmd = lp_addprinter_cmd();
6215 char *command = NULL;
6219 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6220 bool is_print_op = False;
6221 char *remote_machine = talloc_strdup(ctx, "%m");
6223 if (!remote_machine) {
6226 remote_machine = talloc_sub_basic(ctx,
6227 current_user_info.smb_name,
6228 current_user_info.domain,
6230 if (!remote_machine) {
6234 command = talloc_asprintf(ctx,
6235 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6236 cmd, printer->info_2->printername, printer->info_2->sharename,
6237 printer->info_2->portname, printer->info_2->drivername,
6238 printer->info_2->location, printer->info_2->comment, remote_machine);
6244 is_print_op = user_has_privileges( token, &se_printop );
6246 DEBUG(10,("Running [%s]\n", command));
6248 /********* BEGIN SePrintOperatorPrivilege **********/
6253 if ( (ret = smbrun(command, &fd)) == 0 ) {
6254 /* Tell everyone we updated smb.conf. */
6255 message_send_all(smbd_messaging_context(),
6256 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6262 /********* END SePrintOperatorPrivilege **********/
6264 DEBUGADD(10,("returned [%d]\n", ret));
6266 TALLOC_FREE(command);
6267 TALLOC_FREE(remote_machine);
6275 /* reload our services immediately */
6276 reload_services( False );
6279 /* Get lines and convert them back to dos-codepage */
6280 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6281 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6284 /* Set the portname to what the script says the portname should be. */
6285 /* but don't require anything to be return from the script exit a good error code */
6288 /* Set the portname to what the script says the portname should be. */
6289 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6290 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6293 TALLOC_FREE(qlines);
6298 /********************************************************************
6299 * Called by spoolss_api_setprinter
6300 * when updating a printer description.
6301 ********************************************************************/
6303 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6304 struct spoolss_SetPrinterInfoCtr *info_ctr,
6305 struct spoolss_DeviceMode *devmode)
6308 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6309 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6314 DEBUG(8,("update_printer\n"));
6319 result = WERR_BADFID;
6323 if (!get_printer_snum(p, handle, &snum, NULL)) {
6324 result = WERR_BADFID;
6328 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6329 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6330 result = WERR_BADFID;
6334 DEBUGADD(8,("Converting info_2 struct\n"));
6337 * convert_printer_info converts the incoming
6338 * info from the client and overwrites the info
6339 * just read from the tdb in the pointer 'printer'.
6342 if (!convert_printer_info_new(info_ctr, printer)) {
6343 result = WERR_NOMEM;
6348 /* we have a valid devmode
6349 convert it and link it*/
6351 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6352 if (!convert_devicemode_new(printer->info_2->printername,
6354 &printer->info_2->devmode)) {
6355 result = WERR_NOMEM;
6360 /* Do sanity check on the requested changes for Samba */
6362 if (!check_printer_ok(printer->info_2, snum)) {
6363 result = WERR_INVALID_PARAM;
6367 /* FIXME!!! If the driver has changed we really should verify that
6368 it is installed before doing much else --jerry */
6370 /* Check calling user has permission to update printer description */
6372 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6373 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6374 result = WERR_ACCESS_DENIED;
6378 /* Call addprinter hook */
6379 /* Check changes to see if this is really needed */
6381 if ( *lp_addprinter_cmd()
6382 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6383 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6384 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6385 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6387 /* add_printer_hook() will call reload_services() */
6389 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6391 result = WERR_ACCESS_DENIED;
6397 * When a *new* driver is bound to a printer, the drivername is used to
6398 * lookup previously saved driver initialization info, which is then
6399 * bound to the printer, simulating what happens in the Windows arch.
6401 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6403 if (!set_driver_init(printer, 2))
6405 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6406 printer->info_2->drivername));
6409 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6410 printer->info_2->drivername));
6412 notify_printer_driver(snum, printer->info_2->drivername);
6416 * flag which changes actually occured. This is a small subset of
6417 * all the possible changes. We also have to update things in the
6421 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6422 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6423 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6424 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6426 notify_printer_comment(snum, printer->info_2->comment);
6429 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6430 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6431 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6432 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6434 notify_printer_sharename(snum, printer->info_2->sharename);
6437 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6440 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6443 pname = printer->info_2->printername;
6446 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6447 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6448 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6450 notify_printer_printername( snum, pname );
6453 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6454 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6455 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6456 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6458 notify_printer_port(snum, printer->info_2->portname);
6461 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6462 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6463 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6464 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6466 notify_printer_location(snum, printer->info_2->location);
6469 /* here we need to update some more DsSpooler keys */
6470 /* uNCName, serverName, shortServerName */
6472 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6473 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6474 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6475 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6476 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6478 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6479 global_myname(), printer->info_2->sharename );
6480 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6481 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6482 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6484 /* Update printer info */
6485 result = mod_a_printer(printer, 2);
6488 free_a_printer(&printer, 2);
6489 free_a_printer(&old_printer, 2);
6495 /****************************************************************************
6496 ****************************************************************************/
6497 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6498 struct spoolss_SetPrinterInfo7 *info7)
6502 Printer_entry *Printer;
6504 if ( lp_security() != SEC_ADS ) {
6505 return WERR_UNKNOWN_LEVEL;
6508 Printer = find_printer_index_by_hnd(p, handle);
6510 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6515 if (!get_printer_snum(p, handle, &snum, NULL))
6518 nt_printer_publish(Printer, snum, info7->action);
6522 return WERR_UNKNOWN_LEVEL;
6526 /****************************************************************
6528 ****************************************************************/
6530 WERROR _spoolss_SetPrinter(pipes_struct *p,
6531 struct spoolss_SetPrinter *r)
6533 POLICY_HND *handle = r->in.handle;
6536 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6539 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6540 OUR_HANDLE(handle)));
6544 /* check the level */
6545 switch (r->in.info_ctr->level) {
6547 return control_printer(handle, r->in.command, p);
6549 result = update_printer(p, handle,
6551 r->in.devmode_ctr->devmode);
6552 if (!W_ERROR_IS_OK(result))
6554 if (r->in.secdesc_ctr->sd)
6555 result = update_printer_sec(handle, p,
6559 return update_printer_sec(handle, p,
6562 return publish_or_unpublish_printer(p, handle,
6563 r->in.info_ctr->info.info7);
6565 return WERR_UNKNOWN_LEVEL;
6569 /****************************************************************
6570 _spoolss_FindClosePrinterNotify
6571 ****************************************************************/
6573 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6574 struct spoolss_FindClosePrinterNotify *r)
6576 POLICY_HND *handle = r->in.handle;
6577 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6580 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6581 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6585 if (Printer->notify.client_connected==True) {
6588 if ( Printer->printer_type == SPLHND_SERVER)
6590 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6591 !get_printer_snum(p, handle, &snum, NULL) )
6594 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6597 Printer->notify.flags=0;
6598 Printer->notify.options=0;
6599 Printer->notify.localmachine[0]='\0';
6600 Printer->notify.printerlocal=0;
6601 TALLOC_FREE(Printer->notify.option);
6602 Printer->notify.client_connected=False;
6607 /****************************************************************
6609 ****************************************************************/
6611 WERROR _spoolss_AddJob(pipes_struct *p,
6612 struct spoolss_AddJob *r)
6614 if (!r->in.buffer && (r->in.offered != 0)) {
6615 return WERR_INVALID_PARAM;
6618 /* this is what a NT server returns for AddJob. AddJob must fail on
6619 * non-local printers */
6621 if (r->in.level != 1) {
6622 return WERR_UNKNOWN_LEVEL;
6625 return WERR_INVALID_PARAM;
6628 /****************************************************************************
6629 ****************************************************************************/
6631 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6632 int position, int snum,
6633 const NT_PRINTER_INFO_LEVEL *ntprinter)
6637 t=gmtime(&queue->time);
6639 job_info->jobid=queue->job;
6640 init_unistr(&job_info->printername, lp_servicename(snum));
6641 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6642 init_unistr(&job_info->username, queue->fs_user);
6643 init_unistr(&job_info->document, queue->fs_file);
6644 init_unistr(&job_info->datatype, "RAW");
6645 init_unistr(&job_info->text_status, "");
6646 job_info->status=nt_printj_status(queue->status);
6647 job_info->priority=queue->priority;
6648 job_info->position=position;
6649 job_info->totalpages=queue->page_count;
6650 job_info->pagesprinted=0;
6652 make_systemtime(&job_info->submitted, t);
6655 /****************************************************************************
6656 ****************************************************************************/
6658 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6659 int position, int snum,
6660 const NT_PRINTER_INFO_LEVEL *ntprinter,
6661 DEVICEMODE *devmode)
6665 t=gmtime(&queue->time);
6667 job_info->jobid=queue->job;
6669 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6671 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6672 init_unistr(&job_info->username, queue->fs_user);
6673 init_unistr(&job_info->document, queue->fs_file);
6674 init_unistr(&job_info->notifyname, queue->fs_user);
6675 init_unistr(&job_info->datatype, "RAW");
6676 init_unistr(&job_info->printprocessor, "winprint");
6677 init_unistr(&job_info->parameters, "");
6678 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6679 init_unistr(&job_info->text_status, "");
6681 /* and here the security descriptor */
6683 job_info->status=nt_printj_status(queue->status);
6684 job_info->priority=queue->priority;
6685 job_info->position=position;
6686 job_info->starttime=0;
6687 job_info->untiltime=0;
6688 job_info->totalpages=queue->page_count;
6689 job_info->size=queue->size;
6690 make_systemtime(&(job_info->submitted), t);
6691 job_info->timeelapsed=0;
6692 job_info->pagesprinted=0;
6694 job_info->devmode = devmode;
6699 /****************************************************************************
6700 Enumjobs at level 1.
6701 ****************************************************************************/
6703 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6704 const NT_PRINTER_INFO_LEVEL *ntprinter,
6705 RPC_BUFFER *buffer, uint32 offered,
6706 uint32 *needed, uint32 *returned)
6710 WERROR result = WERR_OK;
6712 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6718 for (i=0; i<*returned; i++)
6719 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6721 /* check the required size. */
6722 for (i=0; i<*returned; i++)
6723 (*needed) += spoolss_size_job_info_1(&info[i]);
6725 if (*needed > offered) {
6726 result = WERR_INSUFFICIENT_BUFFER;
6730 if (!rpcbuf_alloc_size(buffer, *needed)) {
6731 result = WERR_NOMEM;
6735 /* fill the buffer with the structures */
6736 for (i=0; i<*returned; i++)
6737 smb_io_job_info_1("", buffer, &info[i], 0);
6743 if ( !W_ERROR_IS_OK(result) )
6749 /****************************************************************************
6750 Enumjobs at level 2.
6751 ****************************************************************************/
6753 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6754 const NT_PRINTER_INFO_LEVEL *ntprinter,
6755 RPC_BUFFER *buffer, uint32 offered,
6756 uint32 *needed, uint32 *returned)
6758 JOB_INFO_2 *info = NULL;
6760 WERROR result = WERR_OK;
6761 DEVICEMODE *devmode = NULL;
6763 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6768 /* this should not be a failure condition if the devmode is NULL */
6770 devmode = construct_dev_mode(lp_const_servicename(snum));
6772 for (i=0; i<*returned; i++)
6773 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6775 /* check the required size. */
6776 for (i=0; i<*returned; i++)
6777 (*needed) += spoolss_size_job_info_2(&info[i]);
6779 if (*needed > offered) {
6780 result = WERR_INSUFFICIENT_BUFFER;
6784 if (!rpcbuf_alloc_size(buffer, *needed)) {
6785 result = WERR_NOMEM;
6789 /* fill the buffer with the structures */
6790 for (i=0; i<*returned; i++)
6791 smb_io_job_info_2("", buffer, &info[i], 0);
6794 free_devmode(devmode);
6797 if ( !W_ERROR_IS_OK(result) )
6804 /****************************************************************************
6806 ****************************************************************************/
6808 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6810 POLICY_HND *handle = &q_u->handle;
6811 uint32 level = q_u->level;
6812 RPC_BUFFER *buffer = NULL;
6813 uint32 offered = q_u->offered;
6814 uint32 *needed = &r_u->needed;
6815 uint32 *returned = &r_u->returned;
6817 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6819 print_status_struct prt_status;
6820 print_queue_struct *queue=NULL;
6822 /* that's an [in out] buffer */
6824 if (!q_u->buffer && (offered!=0)) {
6825 return WERR_INVALID_PARAM;
6828 if (offered > MAX_RPC_DATA_SIZE) {
6829 return WERR_INVALID_PARAM;
6832 rpcbuf_move(q_u->buffer, &r_u->buffer);
6833 buffer = r_u->buffer;
6835 DEBUG(4,("_spoolss_enumjobs\n"));
6840 /* lookup the printer snum and tdb entry */
6842 if (!get_printer_snum(p, handle, &snum, NULL))
6845 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6846 if ( !W_ERROR_IS_OK(wret) )
6849 *returned = print_queue_status(snum, &queue, &prt_status);
6850 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6852 if (*returned == 0) {
6854 free_a_printer(&ntprinter, 2);
6860 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6863 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6867 wret = WERR_UNKNOWN_LEVEL;
6872 free_a_printer( &ntprinter, 2 );
6876 /****************************************************************
6877 _spoolss_ScheduleJob
6878 ****************************************************************/
6880 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6881 struct spoolss_ScheduleJob *r)
6886 /****************************************************************
6888 ****************************************************************/
6890 WERROR _spoolss_SetJob(pipes_struct *p,
6891 struct spoolss_SetJob *r)
6893 POLICY_HND *handle = r->in.handle;
6894 uint32 jobid = r->in.job_id;
6895 uint32 command = r->in.command;
6898 WERROR errcode = WERR_BADFUNC;
6900 if (!get_printer_snum(p, handle, &snum, NULL)) {
6904 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6905 return WERR_INVALID_PRINTER_NAME;
6909 case SPOOLSS_JOB_CONTROL_CANCEL:
6910 case SPOOLSS_JOB_CONTROL_DELETE:
6911 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6915 case SPOOLSS_JOB_CONTROL_PAUSE:
6916 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6920 case SPOOLSS_JOB_CONTROL_RESTART:
6921 case SPOOLSS_JOB_CONTROL_RESUME:
6922 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6927 return WERR_UNKNOWN_LEVEL;
6933 /****************************************************************************
6934 Enumerates all printer drivers at level 1.
6935 ****************************************************************************/
6937 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6942 fstring *list = NULL;
6943 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6944 DRIVER_INFO_1 *driver_info_1=NULL;
6945 WERROR result = WERR_OK;
6949 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6951 ndrivers=get_ntdrivers(&list, architecture, version);
6952 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6954 if(ndrivers == -1) {
6955 SAFE_FREE(driver_info_1);
6960 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6961 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6967 for (i=0; i<ndrivers; i++) {
6969 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6970 ZERO_STRUCT(driver);
6971 status = get_a_printer_driver(&driver, 3, list[i],
6972 architecture, version);
6973 if (!W_ERROR_IS_OK(status)) {
6975 SAFE_FREE(driver_info_1);
6978 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6979 free_a_printer_driver(driver, 3);
6982 *returned+=ndrivers;
6986 /* check the required size. */
6987 for (i=0; i<*returned; i++) {
6988 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6989 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6992 if (*needed > offered) {
6993 result = WERR_INSUFFICIENT_BUFFER;
6997 if (!rpcbuf_alloc_size(buffer, *needed)) {
6998 result = WERR_NOMEM;
7002 /* fill the buffer with the driver structures */
7003 for (i=0; i<*returned; i++) {
7004 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7005 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7009 SAFE_FREE(driver_info_1);
7011 if ( !W_ERROR_IS_OK(result) )
7017 /****************************************************************************
7018 Enumerates all printer drivers at level 2.
7019 ****************************************************************************/
7021 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7026 fstring *list = NULL;
7027 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7028 DRIVER_INFO_2 *driver_info_2=NULL;
7029 WERROR result = WERR_OK;
7033 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7035 ndrivers=get_ntdrivers(&list, architecture, version);
7036 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7038 if(ndrivers == -1) {
7039 SAFE_FREE(driver_info_2);
7044 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7045 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7051 for (i=0; i<ndrivers; i++) {
7054 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7055 ZERO_STRUCT(driver);
7056 status = get_a_printer_driver(&driver, 3, list[i],
7057 architecture, version);
7058 if (!W_ERROR_IS_OK(status)) {
7060 SAFE_FREE(driver_info_2);
7063 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7064 free_a_printer_driver(driver, 3);
7067 *returned+=ndrivers;
7071 /* check the required size. */
7072 for (i=0; i<*returned; i++) {
7073 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7074 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7077 if (*needed > offered) {
7078 result = WERR_INSUFFICIENT_BUFFER;
7082 if (!rpcbuf_alloc_size(buffer, *needed)) {
7083 result = WERR_NOMEM;
7087 /* fill the buffer with the form structures */
7088 for (i=0; i<*returned; i++) {
7089 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7090 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7094 SAFE_FREE(driver_info_2);
7096 if ( !W_ERROR_IS_OK(result) )
7102 /****************************************************************************
7103 Enumerates all printer drivers at level 3.
7104 ****************************************************************************/
7106 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7111 fstring *list = NULL;
7112 DRIVER_INFO_3 *driver_info_3=NULL;
7113 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7114 WERROR result = WERR_OK;
7118 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7120 ndrivers=get_ntdrivers(&list, architecture, version);
7121 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7123 if(ndrivers == -1) {
7124 SAFE_FREE(driver_info_3);
7129 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7130 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7136 for (i=0; i<ndrivers; i++) {
7139 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7140 ZERO_STRUCT(driver);
7141 status = get_a_printer_driver(&driver, 3, list[i],
7142 architecture, version);
7143 if (!W_ERROR_IS_OK(status)) {
7145 SAFE_FREE(driver_info_3);
7148 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7149 free_a_printer_driver(driver, 3);
7152 *returned+=ndrivers;
7156 /* check the required size. */
7157 for (i=0; i<*returned; i++) {
7158 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7159 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7162 if (*needed > offered) {
7163 result = WERR_INSUFFICIENT_BUFFER;
7167 if (!rpcbuf_alloc_size(buffer, *needed)) {
7168 result = WERR_NOMEM;
7172 /* fill the buffer with the driver structures */
7173 for (i=0; i<*returned; i++) {
7174 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7175 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7179 for (i=0; i<*returned; i++) {
7180 SAFE_FREE(driver_info_3[i].dependentfiles);
7183 SAFE_FREE(driver_info_3);
7185 if ( !W_ERROR_IS_OK(result) )
7191 /****************************************************************************
7192 Enumerates all printer drivers.
7193 ****************************************************************************/
7195 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7197 uint32 level = q_u->level;
7198 RPC_BUFFER *buffer = NULL;
7199 uint32 offered = q_u->offered;
7200 uint32 *needed = &r_u->needed;
7201 uint32 *returned = &r_u->returned;
7202 const char *cservername;
7204 fstring architecture;
7206 /* that's an [in out] buffer */
7208 if (!q_u->buffer && (offered!=0)) {
7209 return WERR_INVALID_PARAM;
7212 if (offered > MAX_RPC_DATA_SIZE) {
7213 return WERR_INVALID_PARAM;
7216 rpcbuf_move(q_u->buffer, &r_u->buffer);
7217 buffer = r_u->buffer;
7219 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7224 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7225 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7227 cservername = canon_servername(servername);
7229 if (!is_myname_or_ipaddr(cservername))
7230 return WERR_UNKNOWN_PRINTER_DRIVER;
7234 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7236 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7238 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7240 return WERR_UNKNOWN_LEVEL;
7244 /****************************************************************************
7245 ****************************************************************************/
7247 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7249 form->flag=list->flag;
7250 init_unistr(&form->name, list->name);
7251 form->width=list->width;
7252 form->length=list->length;
7253 form->left=list->left;
7254 form->top=list->top;
7255 form->right=list->right;
7256 form->bottom=list->bottom;
7259 /****************************************************************************
7260 ****************************************************************************/
7262 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7263 struct spoolss_FormInfo1 *form,
7264 nt_forms_struct *list)
7266 form->form_name = talloc_strdup(mem_ctx, list->name);
7267 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7269 form->flags = list->flag;
7270 form->size.width = list->width;
7271 form->size.height = list->length;
7272 form->area.left = list->left;
7273 form->area.top = list->top;
7274 form->area.right = list->right;
7275 form->area.bottom = list->bottom;
7280 /****************************************************************
7282 ****************************************************************/
7284 WERROR _spoolss_EnumForms(pipes_struct *p,
7285 struct spoolss_EnumForms *r)
7287 nt_forms_struct *list=NULL;
7288 nt_forms_struct *builtinlist=NULL;
7289 union spoolss_FormInfo *info;
7291 uint32_t numbuiltinforms;
7292 size_t buffer_size = 0;
7297 /* that's an [in out] buffer */
7299 if (!r->in.buffer && (r->in.offered != 0) ) {
7300 return WERR_INVALID_PARAM;
7303 DEBUG(4,("_spoolss_EnumForms\n"));
7304 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7305 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7307 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7308 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7309 count = get_ntforms(&list);
7310 DEBUGADD(5,("Number of user forms [%d]\n", count));
7311 count += numbuiltinforms;
7314 SAFE_FREE(builtinlist);
7316 return WERR_NO_MORE_ITEMS;
7319 info = TALLOC_ARRAY(p->mem_ctx, union spoolss_FormInfo, count);
7321 SAFE_FREE(builtinlist);
7326 switch (r->in.level) {
7328 /* construct the list of form structures */
7329 for (i=0; i<numbuiltinforms; i++) {
7330 DEBUGADD(6,("Filling form number [%d]\n",i));
7331 fill_form_info_1(info, &info[i].info1, &builtinlist[i]);
7334 SAFE_FREE(builtinlist);
7336 for (; i<count; i++) {
7337 DEBUGADD(6,("Filling form number [%d]\n",i));
7338 fill_form_info_1(info, &info[i].info1, &list[i-numbuiltinforms]);
7343 /* check the required size. */
7344 for (i=0; i<numbuiltinforms; i++) {
7345 DEBUGADD(6,("adding form [%d]'s size\n",i));
7346 buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
7348 for (; i<count; i++) {
7349 DEBUGADD(6,("adding form [%d]'s size\n",i));
7350 buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
7353 *r->out.needed = buffer_size;
7355 if (*r->out.needed > r->in.offered) {
7357 return WERR_INSUFFICIENT_BUFFER;
7360 *r->out.count = count;
7361 *r->out.info = info;
7367 SAFE_FREE(builtinlist);
7368 return WERR_UNKNOWN_LEVEL;
7372 /****************************************************************
7374 ****************************************************************/
7376 WERROR _spoolss_GetForm(pipes_struct *p,
7377 struct spoolss_GetForm *r)
7379 uint32 level = r->in.level;
7380 uint32 offered = r->in.offered;
7381 uint32 *needed = r->out.needed;
7383 nt_forms_struct *list=NULL;
7384 nt_forms_struct builtin_form;
7386 union spoolss_FormInfo info;
7387 struct spoolss_FormInfo1 form_1;
7388 int numofforms=0, i=0;
7390 /* that's an [in out] buffer */
7392 if (!r->in.buffer && (offered!=0)) {
7393 return WERR_INVALID_PARAM;
7396 DEBUG(4,("_spoolss_GetForm\n"));
7397 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7398 DEBUGADD(5,("Info level [%d]\n", level));
7400 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7401 if (!foundBuiltin) {
7402 numofforms = get_ntforms(&list);
7403 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7405 if (numofforms == 0)
7409 ZERO_STRUCT(form_1);
7414 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7417 /* Check if the requested name is in the list of form structures */
7418 for (i=0; i<numofforms; i++) {
7420 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7421 list[i].name, r->in.form_name));
7423 if (strequal(r->in.form_name, list[i].name)) {
7424 DEBUGADD(6,("Found form %s number [%d]\n",
7425 r->in.form_name, i));
7426 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7432 if (i == numofforms) {
7436 /* check the required size. */
7438 info.info1 = form_1;
7440 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7442 if (*needed > offered) {
7444 return WERR_INSUFFICIENT_BUFFER;
7447 r->out.info->info1 = form_1;
7449 /* fill the buffer with the form structures */
7450 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7451 r->in.form_name, i));
7457 return WERR_UNKNOWN_LEVEL;
7461 /****************************************************************************
7462 ****************************************************************************/
7464 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7466 init_unistr(&port->port_name, name);
7469 /****************************************************************************
7470 TODO: This probably needs distinguish between TCP/IP and Local ports
7472 ****************************************************************************/
7474 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7476 init_unistr(&port->port_name, name);
7477 init_unistr(&port->monitor_name, "Local Monitor");
7478 init_unistr(&port->description, SPL_LOCAL_PORT );
7479 port->port_type=PORT_TYPE_WRITE;
7484 /****************************************************************************
7485 wrapper around the enumer ports command
7486 ****************************************************************************/
7488 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7490 char *cmd = lp_enumports_cmd();
7491 char **qlines = NULL;
7492 char *command = NULL;
7500 /* if no hook then just fill in the default port */
7503 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7506 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7507 TALLOC_FREE(qlines);
7514 /* we have a valid enumport command */
7516 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7521 DEBUG(10,("Running [%s]\n", command));
7522 ret = smbrun(command, &fd);
7523 DEBUG(10,("Returned [%d]\n", ret));
7524 TALLOC_FREE(command);
7529 return WERR_ACCESS_DENIED;
7533 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7534 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7544 /****************************************************************************
7546 ****************************************************************************/
7548 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7550 PORT_INFO_1 *ports=NULL;
7552 WERROR result = WERR_OK;
7553 char **qlines = NULL;
7556 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7557 if (!W_ERROR_IS_OK(result)) {
7558 TALLOC_FREE(qlines);
7563 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7564 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7565 win_errstr(WERR_NOMEM)));
7566 TALLOC_FREE(qlines);
7570 for (i=0; i<numlines; i++) {
7571 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7572 fill_port_1(&ports[i], qlines[i]);
7575 TALLOC_FREE(qlines);
7577 *returned = numlines;
7579 /* check the required size. */
7580 for (i=0; i<*returned; i++) {
7581 DEBUGADD(6,("adding port [%d]'s size\n", i));
7582 *needed += spoolss_size_port_info_1(&ports[i]);
7585 if (*needed > offered) {
7586 result = WERR_INSUFFICIENT_BUFFER;
7590 if (!rpcbuf_alloc_size(buffer, *needed)) {
7591 result = WERR_NOMEM;
7595 /* fill the buffer with the ports structures */
7596 for (i=0; i<*returned; i++) {
7597 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7598 smb_io_port_1("", buffer, &ports[i], 0);
7604 if ( !W_ERROR_IS_OK(result) )
7610 /****************************************************************************
7612 ****************************************************************************/
7614 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7616 PORT_INFO_2 *ports=NULL;
7618 WERROR result = WERR_OK;
7619 char **qlines = NULL;
7622 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7623 if ( !W_ERROR_IS_OK(result)) {
7624 TALLOC_FREE(qlines);
7629 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7630 TALLOC_FREE(qlines);
7634 for (i=0; i<numlines; i++) {
7635 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7636 fill_port_2(&(ports[i]), qlines[i]);
7640 TALLOC_FREE(qlines);
7642 *returned = numlines;
7644 /* check the required size. */
7645 for (i=0; i<*returned; i++) {
7646 DEBUGADD(6,("adding port [%d]'s size\n", i));
7647 *needed += spoolss_size_port_info_2(&ports[i]);
7650 if (*needed > offered) {
7651 result = WERR_INSUFFICIENT_BUFFER;
7655 if (!rpcbuf_alloc_size(buffer, *needed)) {
7656 result = WERR_NOMEM;
7660 /* fill the buffer with the ports structures */
7661 for (i=0; i<*returned; i++) {
7662 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7663 smb_io_port_2("", buffer, &ports[i], 0);
7669 if ( !W_ERROR_IS_OK(result) )
7675 /****************************************************************************
7677 ****************************************************************************/
7679 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7681 uint32 level = q_u->level;
7682 RPC_BUFFER *buffer = NULL;
7683 uint32 offered = q_u->offered;
7684 uint32 *needed = &r_u->needed;
7685 uint32 *returned = &r_u->returned;
7687 /* that's an [in out] buffer */
7689 if (!q_u->buffer && (offered!=0)) {
7690 return WERR_INVALID_PARAM;
7693 if (offered > MAX_RPC_DATA_SIZE) {
7694 return WERR_INVALID_PARAM;
7697 rpcbuf_move(q_u->buffer, &r_u->buffer);
7698 buffer = r_u->buffer;
7700 DEBUG(4,("_spoolss_enumports\n"));
7707 return enumports_level_1(buffer, offered, needed, returned);
7709 return enumports_level_2(buffer, offered, needed, returned);
7711 return WERR_UNKNOWN_LEVEL;
7715 /****************************************************************************
7716 ****************************************************************************/
7718 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7720 struct spoolss_SetPrinterInfoCtr *info_ctr,
7721 struct spoolss_DeviceMode *devmode,
7722 struct security_descriptor *sec_desc,
7723 struct spoolss_UserLevelCtr *user_ctr,
7726 NT_PRINTER_INFO_LEVEL *printer = NULL;
7729 WERROR err = WERR_OK;
7731 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7732 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7736 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7737 if (!convert_printer_info_new(info_ctr, printer)) {
7738 free_a_printer(&printer, 2);
7742 /* check to see if the printer already exists */
7744 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7745 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7746 printer->info_2->sharename));
7747 free_a_printer(&printer, 2);
7748 return WERR_PRINTER_ALREADY_EXISTS;
7751 /* FIXME!!! smbd should check to see if the driver is installed before
7752 trying to add a printer like this --jerry */
7754 if (*lp_addprinter_cmd() ) {
7755 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7757 free_a_printer(&printer,2);
7758 return WERR_ACCESS_DENIED;
7761 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7762 "smb.conf parameter \"addprinter command\" is defined. This"
7763 "parameter must exist for this call to succeed\n",
7764 printer->info_2->sharename ));
7767 /* use our primary netbios name since get_a_printer() will convert
7768 it to what the client expects on a case by case basis */
7770 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7771 printer->info_2->sharename);
7774 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7775 free_a_printer(&printer,2);
7776 return WERR_ACCESS_DENIED;
7779 /* you must be a printer admin to add a new printer */
7780 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7781 free_a_printer(&printer,2);
7782 return WERR_ACCESS_DENIED;
7786 * Do sanity check on the requested changes for Samba.
7789 if (!check_printer_ok(printer->info_2, snum)) {
7790 free_a_printer(&printer,2);
7791 return WERR_INVALID_PARAM;
7795 * When a printer is created, the drivername bound to the printer is used
7796 * to lookup previously saved driver initialization info, which is then
7797 * bound to the new printer, simulating what happens in the Windows arch.
7802 set_driver_init(printer, 2);
7806 /* A valid devmode was included, convert and link it
7808 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7810 if (!convert_devicemode_new(printer->info_2->printername,
7812 &printer->info_2->devmode))
7816 /* write the ASCII on disk */
7817 err = mod_a_printer(printer, 2);
7818 if (!W_ERROR_IS_OK(err)) {
7819 free_a_printer(&printer,2);
7823 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7824 /* Handle open failed - remove addition. */
7825 del_a_printer(printer->info_2->sharename);
7826 free_a_printer(&printer,2);
7827 ZERO_STRUCTP(handle);
7828 return WERR_ACCESS_DENIED;
7831 update_c_setprinter(False);
7832 free_a_printer(&printer,2);
7837 /****************************************************************
7838 _spoolss_AddPrinterEx
7839 ****************************************************************/
7841 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7842 struct spoolss_AddPrinterEx *r)
7844 switch (r->in.info_ctr->level) {
7846 /* we don't handle yet */
7847 /* but I know what to do ... */
7848 return WERR_UNKNOWN_LEVEL;
7850 return spoolss_addprinterex_level_2(p, r->in.server,
7852 r->in.devmode_ctr->devmode,
7853 r->in.secdesc_ctr->sd,
7854 r->in.userlevel_ctr,
7857 return WERR_UNKNOWN_LEVEL;
7861 /****************************************************************
7862 _spoolss_AddPrinterDriver
7863 ****************************************************************/
7865 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7866 struct spoolss_AddPrinterDriver *r)
7868 uint32_t level = r->in.info_ctr->level;
7869 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7870 WERROR err = WERR_OK;
7871 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7872 fstring driver_name;
7876 switch (p->hdr_req.opnum) {
7877 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7878 fn = "_spoolss_AddPrinterDriver";
7880 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7881 fn = "_spoolss_AddPrinterDriverEx";
7884 return WERR_INVALID_PARAM;
7889 if (level != 3 && level != 6) {
7890 /* Clever hack from Martin Zielinski <mz@seh.de>
7891 * to allow downgrade from level 8 (Vista).
7893 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7894 return WERR_UNKNOWN_LEVEL;
7897 ZERO_STRUCT(driver);
7899 if (!convert_printer_driver_info(info, &driver, level)) {
7904 DEBUG(5,("Cleaning driver's information\n"));
7905 err = clean_up_driver_struct(p, driver, level);
7906 if (!W_ERROR_IS_OK(err))
7909 DEBUG(5,("Moving driver to final destination\n"));
7910 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7915 if (add_a_printer_driver(driver, level)!=0) {
7916 err = WERR_ACCESS_DENIED;
7922 fstrcpy(driver_name,
7923 driver.info_3->name ? driver.info_3->name : "");
7926 fstrcpy(driver_name,
7927 driver.info_6->name ? driver.info_6->name : "");
7932 * I think this is where he DrvUpgradePrinter() hook would be
7933 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7934 * server. Right now, we just need to send ourselves a message
7935 * to update each printer bound to this driver. --jerry
7938 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7939 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7944 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7945 * decide if the driver init data should be deleted. The rules are:
7946 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7947 * 2) delete init data only if there is no 2k/Xp driver
7948 * 3) always delete init data
7949 * The generalized rule is always use init data from the highest order driver.
7950 * It is necessary to follow the driver install by an initialization step to
7951 * finish off this process.
7954 version = driver.info_3->cversion;
7955 else if (level == 6)
7956 version = driver.info_6->version;
7961 * 9x printer driver - never delete init data
7964 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7969 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7970 * there is no 2k/Xp driver init data for this driver name.
7974 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7976 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7978 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7980 if (!del_driver_init(driver_name))
7981 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7985 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7987 free_a_printer_driver(driver1,3);
7988 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7995 * 2k or Xp printer driver - always delete init data
7998 if (!del_driver_init(driver_name))
7999 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
8004 DEBUG(0,("%s: invalid level=%d\n", fn, level));
8010 free_a_printer_driver(driver, level);
8014 /****************************************************************
8015 _spoolss_AddPrinterDriverEx
8016 ****************************************************************/
8018 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8019 struct spoolss_AddPrinterDriverEx *r)
8021 struct spoolss_AddPrinterDriver a;
8024 * we only support the semantics of AddPrinterDriver()
8025 * i.e. only copy files that are newer than existing ones
8028 if (r->in.flags != APD_COPY_NEW_FILES) {
8029 return WERR_ACCESS_DENIED;
8032 a.in.servername = r->in.servername;
8033 a.in.info_ctr = r->in.info_ctr;
8035 return _spoolss_AddPrinterDriver(p, &a);
8038 /****************************************************************************
8039 ****************************************************************************/
8041 struct _spoolss_paths {
8047 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
8049 static const struct _spoolss_paths spoolss_paths[]= {
8050 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
8051 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
8054 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
8055 const char *servername,
8056 const char *environment,
8060 const char *pservername = NULL;
8061 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8062 const char *short_archi;
8066 /* environment may be empty */
8067 if (environment && strlen(environment)) {
8068 long_archi = environment;
8071 /* servername may be empty */
8072 if (servername && strlen(servername)) {
8073 pservername = canon_servername(servername);
8075 if (!is_myname_or_ipaddr(pservername)) {
8076 return WERR_INVALID_PARAM;
8080 if (!(short_archi = get_short_archi(long_archi))) {
8081 return WERR_INVALID_ENVIRONMENT;
8084 switch (component) {
8085 case SPOOLSS_PRTPROCS_PATH:
8086 case SPOOLSS_DRIVER_PATH:
8088 *path = talloc_asprintf(mem_ctx,
8091 spoolss_paths[component].share,
8094 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
8095 SPOOLSS_DEFAULT_SERVER_PATH,
8096 spoolss_paths[component].dir,
8101 return WERR_INVALID_PARAM;
8111 /****************************************************************************
8112 ****************************************************************************/
8114 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8115 const char *servername,
8116 const char *environment,
8117 struct spoolss_DriverDirectoryInfo1 *r,
8124 werr = compose_spoolss_server_path(mem_ctx,
8127 SPOOLSS_DRIVER_PATH,
8129 if (!W_ERROR_IS_OK(werr)) {
8133 DEBUG(4,("printer driver directory: [%s]\n", path));
8135 r->directory_name = path;
8137 *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
8139 if (*needed > offered) {
8141 return WERR_INSUFFICIENT_BUFFER;
8147 /****************************************************************
8148 _spoolss_GetPrinterDriverDirectory
8149 ****************************************************************/
8151 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8152 struct spoolss_GetPrinterDriverDirectory *r)
8156 /* that's an [in out] buffer */
8158 if (!r->in.buffer && (r->in.offered != 0)) {
8159 return WERR_INVALID_PARAM;
8162 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
8167 /* r->in.level is ignored */
8169 werror = getprinterdriverdir_level_1(p->mem_ctx,
8172 &r->out.info->info1,
8175 if (!W_ERROR_IS_OK(werror)) {
8176 TALLOC_FREE(r->out.info);
8182 /****************************************************************************
8183 ****************************************************************************/
8185 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8187 POLICY_HND *handle = &q_u->handle;
8188 uint32 idx = q_u->index;
8189 uint32 in_value_len = q_u->valuesize;
8190 uint32 in_data_len = q_u->datasize;
8191 uint32 *out_max_value_len = &r_u->valuesize;
8192 uint16 **out_value = &r_u->value;
8193 uint32 *out_value_len = &r_u->realvaluesize;
8194 uint32 *out_type = &r_u->type;
8195 uint32 *out_max_data_len = &r_u->datasize;
8196 uint8 **data_out = &r_u->data;
8197 uint32 *out_data_len = &r_u->realdatasize;
8199 NT_PRINTER_INFO_LEVEL *printer = NULL;
8201 uint32 biggest_valuesize;
8202 uint32 biggest_datasize;
8204 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8207 REGISTRY_VALUE *val = NULL;
8208 NT_PRINTER_DATA *p_data;
8209 int i, key_index, num_values;
8214 *out_max_data_len = 0;
8218 DEBUG(5,("spoolss_enumprinterdata\n"));
8221 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8225 if (!get_printer_snum(p,handle, &snum, NULL))
8228 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8229 if (!W_ERROR_IS_OK(result))
8232 p_data = printer->info_2->data;
8233 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8238 * The NT machine wants to know the biggest size of value and data
8240 * cf: MSDN EnumPrinterData remark section
8243 if ( !in_value_len && !in_data_len && (key_index != -1) )
8245 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8247 biggest_valuesize = 0;
8248 biggest_datasize = 0;
8250 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8252 for ( i=0; i<num_values; i++ )
8254 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8256 name_length = strlen(val->valuename);
8257 if ( strlen(val->valuename) > biggest_valuesize )
8258 biggest_valuesize = name_length;
8260 if ( val->size > biggest_datasize )
8261 biggest_datasize = val->size;
8263 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8267 /* the value is an UNICODE string but real_value_size is the length
8268 in bytes including the trailing 0 */
8270 *out_value_len = 2 * (1+biggest_valuesize);
8271 *out_data_len = biggest_datasize;
8273 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8279 * the value len is wrong in NT sp3
8280 * that's the number of bytes not the number of unicode chars
8283 if ( key_index != -1 )
8284 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8289 /* out_value should default to "" or else NT4 has
8290 problems unmarshalling the response */
8292 *out_max_value_len=(in_value_len/sizeof(uint16));
8295 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8297 result = WERR_NOMEM;
8300 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8306 /* the data is counted in bytes */
8308 *out_max_data_len = in_data_len;
8309 *out_data_len = in_data_len;
8311 /* only allocate when given a non-zero data_len */
8313 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8315 result = WERR_NOMEM;
8319 result = WERR_NO_MORE_ITEMS;
8325 * - counted in bytes in the request
8326 * - counted in UNICODE chars in the max reply
8327 * - counted in bytes in the real size
8329 * take a pause *before* coding not *during* coding
8333 *out_max_value_len=(in_value_len/sizeof(uint16));
8335 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8337 result = WERR_NOMEM;
8341 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8349 *out_type = regval_type( val );
8351 /* data - counted in bytes */
8353 *out_max_data_len = in_data_len;
8354 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8356 result = WERR_NOMEM;
8359 data_len = regval_size(val);
8360 if ( *data_out && data_len )
8361 memcpy( *data_out, regval_data_p(val), data_len );
8362 *out_data_len = data_len;
8366 free_a_printer(&printer, 2);
8370 /****************************************************************************
8371 ****************************************************************************/
8373 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8375 POLICY_HND *handle = &q_u->handle;
8376 UNISTR2 *value = &q_u->value;
8377 uint32 type = q_u->type;
8378 uint8 *data = q_u->data;
8379 uint32 real_len = q_u->real_len;
8381 NT_PRINTER_INFO_LEVEL *printer = NULL;
8383 WERROR status = WERR_OK;
8384 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8387 DEBUG(5,("spoolss_setprinterdata\n"));
8390 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8394 if ( Printer->printer_type == SPLHND_SERVER ) {
8395 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8396 return WERR_INVALID_PARAM;
8399 if (!get_printer_snum(p,handle, &snum, NULL))
8403 * Access check : NT returns "access denied" if you make a
8404 * SetPrinterData call without the necessary privildge.
8405 * we were originally returning OK if nothing changed
8406 * which made Win2k issue **a lot** of SetPrinterData
8407 * when connecting to a printer --jerry
8410 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8412 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8413 status = WERR_ACCESS_DENIED;
8417 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8418 if (!W_ERROR_IS_OK(status))
8421 unistr2_to_ascii(valuename, value, sizeof(valuename));
8424 * When client side code sets a magic printer data key, detect it and save
8425 * the current printer data and the magic key's data (its the DEVMODE) for
8426 * future printer/driver initializations.
8428 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8430 /* Set devmode and printer initialization info */
8431 status = save_driver_init( printer, 2, data, real_len );
8433 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8437 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8438 type, data, real_len );
8439 if ( W_ERROR_IS_OK(status) )
8440 status = mod_a_printer(printer, 2);
8444 free_a_printer(&printer, 2);
8449 /****************************************************************
8450 _spoolss_ResetPrinter
8451 ****************************************************************/
8453 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8454 struct spoolss_ResetPrinter *r)
8456 POLICY_HND *handle = r->in.handle;
8457 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8460 DEBUG(5,("_spoolss_ResetPrinter\n"));
8463 * All we do is to check to see if the handle and queue is valid.
8464 * This call really doesn't mean anything to us because we only
8465 * support RAW printing. --jerry
8469 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8470 OUR_HANDLE(handle)));
8474 if (!get_printer_snum(p,handle, &snum, NULL))
8478 /* blindly return success */
8482 /****************************************************************
8483 _spoolss_DeletePrinterData
8484 ****************************************************************/
8486 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8487 struct spoolss_DeletePrinterData *r)
8489 POLICY_HND *handle = r->in.handle;
8490 NT_PRINTER_INFO_LEVEL *printer = NULL;
8492 WERROR status = WERR_OK;
8493 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8495 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8498 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8499 OUR_HANDLE(handle)));
8503 if (!get_printer_snum(p, handle, &snum, NULL))
8506 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8507 DEBUG(3, ("_spoolss_DeletePrinterData: "
8508 "printer properties change denied by handle\n"));
8509 return WERR_ACCESS_DENIED;
8512 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8513 if (!W_ERROR_IS_OK(status))
8516 if (!r->in.value_name) {
8517 free_a_printer(&printer, 2);
8521 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8524 if ( W_ERROR_IS_OK(status) )
8525 mod_a_printer( printer, 2 );
8527 free_a_printer(&printer, 2);
8532 /****************************************************************
8534 ****************************************************************/
8536 WERROR _spoolss_AddForm(pipes_struct *p,
8537 struct spoolss_AddForm *r)
8539 POLICY_HND *handle = r->in.handle;
8540 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8541 nt_forms_struct tmpForm;
8543 WERROR status = WERR_OK;
8544 NT_PRINTER_INFO_LEVEL *printer = NULL;
8547 nt_forms_struct *list=NULL;
8548 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8550 DEBUG(5,("_spoolss_AddForm\n"));
8553 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8554 OUR_HANDLE(handle)));
8559 /* forms can be added on printer of on the print server handle */
8561 if ( Printer->printer_type == SPLHND_PRINTER )
8563 if (!get_printer_snum(p,handle, &snum, NULL))
8566 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8567 if (!W_ERROR_IS_OK(status))
8571 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8572 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8573 status = WERR_ACCESS_DENIED;
8577 /* can't add if builtin */
8579 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8580 status = WERR_FILE_EXISTS;
8584 count = get_ntforms(&list);
8586 if(!add_a_form(&list, form, &count)) {
8587 status = WERR_NOMEM;
8591 write_ntforms(&list, count);
8594 * ChangeID must always be set if this is a printer
8597 if ( Printer->printer_type == SPLHND_PRINTER )
8598 status = mod_a_printer(printer, 2);
8602 free_a_printer(&printer, 2);
8608 /****************************************************************
8610 ****************************************************************/
8612 WERROR _spoolss_DeleteForm(pipes_struct *p,
8613 struct spoolss_DeleteForm *r)
8615 POLICY_HND *handle = r->in.handle;
8616 const char *form_name = r->in.form_name;
8617 nt_forms_struct tmpForm;
8619 nt_forms_struct *list=NULL;
8620 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8622 WERROR status = WERR_OK;
8623 NT_PRINTER_INFO_LEVEL *printer = NULL;
8625 DEBUG(5,("_spoolss_DeleteForm\n"));
8628 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8629 OUR_HANDLE(handle)));
8633 /* forms can be deleted on printer of on the print server handle */
8635 if ( Printer->printer_type == SPLHND_PRINTER )
8637 if (!get_printer_snum(p,handle, &snum, NULL))
8640 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8641 if (!W_ERROR_IS_OK(status))
8645 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8646 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8647 status = WERR_ACCESS_DENIED;
8651 /* can't delete if builtin */
8653 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8654 status = WERR_INVALID_PARAM;
8658 count = get_ntforms(&list);
8660 if ( !delete_a_form(&list, form_name, &count, &status ))
8664 * ChangeID must always be set if this is a printer
8667 if ( Printer->printer_type == SPLHND_PRINTER )
8668 status = mod_a_printer(printer, 2);
8672 free_a_printer(&printer, 2);
8678 /****************************************************************
8680 ****************************************************************/
8682 WERROR _spoolss_SetForm(pipes_struct *p,
8683 struct spoolss_SetForm *r)
8685 POLICY_HND *handle = r->in.handle;
8686 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8687 nt_forms_struct tmpForm;
8689 WERROR status = WERR_OK;
8690 NT_PRINTER_INFO_LEVEL *printer = NULL;
8693 nt_forms_struct *list=NULL;
8694 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8696 DEBUG(5,("_spoolss_SetForm\n"));
8699 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8700 OUR_HANDLE(handle)));
8704 /* forms can be modified on printer of on the print server handle */
8706 if ( Printer->printer_type == SPLHND_PRINTER )
8708 if (!get_printer_snum(p,handle, &snum, NULL))
8711 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8712 if (!W_ERROR_IS_OK(status))
8716 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8717 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8718 status = WERR_ACCESS_DENIED;
8722 /* can't set if builtin */
8723 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8724 status = WERR_INVALID_PARAM;
8728 count = get_ntforms(&list);
8729 update_a_form(&list, form, count);
8730 write_ntforms(&list, count);
8733 * ChangeID must always be set if this is a printer
8736 if ( Printer->printer_type == SPLHND_PRINTER )
8737 status = mod_a_printer(printer, 2);
8742 free_a_printer(&printer, 2);
8748 /****************************************************************************
8749 enumprintprocessors level 1.
8750 ****************************************************************************/
8752 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8754 PRINTPROCESSOR_1 *info_1=NULL;
8755 WERROR result = WERR_OK;
8757 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8762 init_unistr(&info_1->name, "winprint");
8764 *needed += spoolss_size_printprocessor_info_1(info_1);
8766 if (*needed > offered) {
8767 result = WERR_INSUFFICIENT_BUFFER;
8771 if (!rpcbuf_alloc_size(buffer, *needed)) {
8772 result = WERR_NOMEM;
8776 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8781 if ( !W_ERROR_IS_OK(result) )
8787 /****************************************************************************
8788 ****************************************************************************/
8790 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8792 uint32 level = q_u->level;
8793 RPC_BUFFER *buffer = NULL;
8794 uint32 offered = q_u->offered;
8795 uint32 *needed = &r_u->needed;
8796 uint32 *returned = &r_u->returned;
8798 /* that's an [in out] buffer */
8800 if (!q_u->buffer && (offered!=0)) {
8801 return WERR_INVALID_PARAM;
8804 if (offered > MAX_RPC_DATA_SIZE) {
8805 return WERR_INVALID_PARAM;
8808 rpcbuf_move(q_u->buffer, &r_u->buffer);
8809 buffer = r_u->buffer;
8811 DEBUG(5,("spoolss_enumprintprocessors\n"));
8814 * Enumerate the print processors ...
8816 * Just reply with "winprint", to keep NT happy
8817 * and I can use my nice printer checker.
8825 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8827 return WERR_UNKNOWN_LEVEL;
8831 /****************************************************************************
8832 enumprintprocdatatypes level 1.
8833 ****************************************************************************/
8835 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8837 PRINTPROCDATATYPE_1 *info_1=NULL;
8838 WERROR result = WERR_OK;
8840 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8845 init_unistr(&info_1->name, "RAW");
8847 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8849 if (*needed > offered) {
8850 result = WERR_INSUFFICIENT_BUFFER;
8854 if (!rpcbuf_alloc_size(buffer, *needed)) {
8855 result = WERR_NOMEM;
8859 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8864 if ( !W_ERROR_IS_OK(result) )
8870 /****************************************************************************
8871 ****************************************************************************/
8873 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8875 uint32 level = q_u->level;
8876 RPC_BUFFER *buffer = NULL;
8877 uint32 offered = q_u->offered;
8878 uint32 *needed = &r_u->needed;
8879 uint32 *returned = &r_u->returned;
8881 /* that's an [in out] buffer */
8883 if (!q_u->buffer && (offered!=0)) {
8884 return WERR_INVALID_PARAM;
8887 if (offered > MAX_RPC_DATA_SIZE) {
8888 return WERR_INVALID_PARAM;
8891 rpcbuf_move(q_u->buffer, &r_u->buffer);
8892 buffer = r_u->buffer;
8894 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8901 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8903 return WERR_UNKNOWN_LEVEL;
8907 /****************************************************************************
8908 enumprintmonitors level 1.
8909 ****************************************************************************/
8911 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8913 PRINTMONITOR_1 *info_1;
8914 WERROR result = WERR_OK;
8917 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8922 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8923 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8925 for ( i=0; i<*returned; i++ ) {
8926 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8929 if (*needed > offered) {
8930 result = WERR_INSUFFICIENT_BUFFER;
8934 if (!rpcbuf_alloc_size(buffer, *needed)) {
8935 result = WERR_NOMEM;
8939 for ( i=0; i<*returned; i++ ) {
8940 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8946 if ( !W_ERROR_IS_OK(result) )
8952 /****************************************************************************
8953 enumprintmonitors level 2.
8954 ****************************************************************************/
8956 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8958 PRINTMONITOR_2 *info_2;
8959 WERROR result = WERR_OK;
8962 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8967 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8968 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8969 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8971 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8972 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8973 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8975 for ( i=0; i<*returned; i++ ) {
8976 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8979 if (*needed > offered) {
8980 result = WERR_INSUFFICIENT_BUFFER;
8984 if (!rpcbuf_alloc_size(buffer, *needed)) {
8985 result = WERR_NOMEM;
8989 for ( i=0; i<*returned; i++ ) {
8990 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8996 if ( !W_ERROR_IS_OK(result) )
9002 /****************************************************************************
9003 ****************************************************************************/
9005 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
9007 uint32 level = q_u->level;
9008 RPC_BUFFER *buffer = NULL;
9009 uint32 offered = q_u->offered;
9010 uint32 *needed = &r_u->needed;
9011 uint32 *returned = &r_u->returned;
9013 /* that's an [in out] buffer */
9015 if (!q_u->buffer && (offered!=0)) {
9016 return WERR_INVALID_PARAM;
9019 if (offered > MAX_RPC_DATA_SIZE) {
9020 return WERR_INVALID_PARAM;
9023 rpcbuf_move(q_u->buffer, &r_u->buffer);
9024 buffer = r_u->buffer;
9026 DEBUG(5,("spoolss_enumprintmonitors\n"));
9029 * Enumerate the print monitors ...
9031 * Just reply with "Local Port", to keep NT happy
9032 * and I can use my nice printer checker.
9040 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9042 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9044 return WERR_UNKNOWN_LEVEL;
9048 /****************************************************************************
9049 ****************************************************************************/
9051 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9052 NT_PRINTER_INFO_LEVEL *ntprinter,
9053 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9058 JOB_INFO_1 *info_1=NULL;
9059 WERROR result = WERR_OK;
9061 info_1=SMB_MALLOC_P(JOB_INFO_1);
9063 if (info_1 == NULL) {
9067 for (i=0; i<count && found==False; i++) {
9068 if ((*queue)[i].job==(int)jobid)
9074 /* NT treats not found as bad param... yet another bad choice */
9075 return WERR_INVALID_PARAM;
9078 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9080 *needed += spoolss_size_job_info_1(info_1);
9082 if (*needed > offered) {
9083 result = WERR_INSUFFICIENT_BUFFER;
9087 if (!rpcbuf_alloc_size(buffer, *needed)) {
9088 result = WERR_NOMEM;
9092 smb_io_job_info_1("", buffer, info_1, 0);
9100 /****************************************************************************
9101 ****************************************************************************/
9103 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9104 NT_PRINTER_INFO_LEVEL *ntprinter,
9105 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9112 DEVICEMODE *devmode = NULL;
9113 NT_DEVICEMODE *nt_devmode = NULL;
9115 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9118 ZERO_STRUCTP(info_2);
9120 for ( i=0; i<count && found==False; i++ )
9122 if ((*queue)[i].job == (int)jobid)
9127 /* NT treats not found as bad param... yet another bad
9129 result = WERR_INVALID_PARAM;
9134 * if the print job does not have a DEVMODE associated with it,
9135 * just use the one for the printer. A NULL devicemode is not
9136 * a failure condition
9139 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9140 devmode = construct_dev_mode(lp_const_servicename(snum));
9142 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9143 ZERO_STRUCTP( devmode );
9144 convert_nt_devicemode( devmode, nt_devmode );
9148 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9150 *needed += spoolss_size_job_info_2(info_2);
9152 if (*needed > offered) {
9153 result = WERR_INSUFFICIENT_BUFFER;
9157 if (!rpcbuf_alloc_size(buffer, *needed)) {
9158 result = WERR_NOMEM;
9162 smb_io_job_info_2("", buffer, info_2, 0);
9167 /* Cleanup allocated memory */
9169 free_job_info_2(info_2); /* Also frees devmode */
9175 /****************************************************************************
9176 ****************************************************************************/
9178 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9180 POLICY_HND *handle = &q_u->handle;
9181 uint32 jobid = q_u->jobid;
9182 uint32 level = q_u->level;
9183 RPC_BUFFER *buffer = NULL;
9184 uint32 offered = q_u->offered;
9185 uint32 *needed = &r_u->needed;
9186 WERROR wstatus = WERR_OK;
9187 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9190 print_queue_struct *queue = NULL;
9191 print_status_struct prt_status;
9193 /* that's an [in out] buffer */
9195 if (!q_u->buffer && (offered!=0)) {
9196 return WERR_INVALID_PARAM;
9199 if (offered > MAX_RPC_DATA_SIZE) {
9200 return WERR_INVALID_PARAM;
9203 rpcbuf_move(q_u->buffer, &r_u->buffer);
9204 buffer = r_u->buffer;
9206 DEBUG(5,("spoolss_getjob\n"));
9210 if (!get_printer_snum(p, handle, &snum, NULL))
9213 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9214 if ( !W_ERROR_IS_OK(wstatus) )
9217 count = print_queue_status(snum, &queue, &prt_status);
9219 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9220 count, prt_status.status, prt_status.message));
9224 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9225 buffer, offered, needed);
9228 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9229 buffer, offered, needed);
9232 wstatus = WERR_UNKNOWN_LEVEL;
9237 free_a_printer( &ntprinter, 2 );
9242 /****************************************************************
9243 _spoolss_GetPrinterDataEx
9245 From MSDN documentation of GetPrinterDataEx: pass request
9246 to GetPrinterData if key is "PrinterDriverData".
9247 ****************************************************************/
9249 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9250 struct spoolss_GetPrinterDataEx *r)
9252 POLICY_HND *handle = r->in.handle;
9254 const char *keyname = r->in.key_name;
9255 const char *valuename = r->in.value_name;
9257 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9259 NT_PRINTER_INFO_LEVEL *printer = NULL;
9261 WERROR status = WERR_OK;
9263 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9265 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9266 keyname, valuename));
9268 /* in case of problem, return some default values */
9274 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9275 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9276 status = WERR_BADFID;
9280 /* Is the handle to a printer or to the server? */
9282 if (Printer->printer_type == SPLHND_SERVER) {
9283 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9284 "Not implemented for server handles yet\n"));
9285 status = WERR_INVALID_PARAM;
9289 if ( !get_printer_snum(p,handle, &snum, NULL) )
9292 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9293 if ( !W_ERROR_IS_OK(status) )
9296 /* check to see if the keyname is valid */
9297 if ( !strlen(keyname) ) {
9298 status = WERR_INVALID_PARAM;
9302 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9303 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9304 "Invalid keyname [%s]\n", keyname ));
9305 free_a_printer( &printer, 2 );
9306 status = WERR_BADFILE;
9310 /* When given a new keyname, we should just create it */
9312 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9313 r->out.type, &data, r->out.needed,
9316 if (*r->out.needed > r->in.offered) {
9317 status = WERR_MORE_DATA;
9320 if (W_ERROR_IS_OK(status)) {
9321 memcpy(r->out.buffer, data, r->in.offered);
9326 free_a_printer( &printer, 2 );
9331 /****************************************************************
9332 _spoolss_SetPrinterDataEx
9333 ****************************************************************/
9335 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9336 struct spoolss_SetPrinterDataEx *r)
9338 POLICY_HND *handle = r->in.handle;
9339 NT_PRINTER_INFO_LEVEL *printer = NULL;
9341 WERROR status = WERR_OK;
9342 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9345 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9347 /* From MSDN documentation of SetPrinterDataEx: pass request to
9348 SetPrinterData if key is "PrinterDriverData" */
9351 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9352 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9356 if ( Printer->printer_type == SPLHND_SERVER ) {
9357 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9358 "Not implemented for server handles yet\n"));
9359 return WERR_INVALID_PARAM;
9362 if ( !get_printer_snum(p,handle, &snum, NULL) )
9366 * Access check : NT returns "access denied" if you make a
9367 * SetPrinterData call without the necessary privildge.
9368 * we were originally returning OK if nothing changed
9369 * which made Win2k issue **a lot** of SetPrinterData
9370 * when connecting to a printer --jerry
9373 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9375 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9376 "change denied by handle access permissions\n"));
9377 return WERR_ACCESS_DENIED;
9380 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9381 if (!W_ERROR_IS_OK(status))
9384 /* check for OID in valuename */
9386 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9392 /* save the registry data */
9394 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9395 r->in.type, r->in.buffer, r->in.offered );
9397 if ( W_ERROR_IS_OK(status) )
9399 /* save the OID if one was specified */
9401 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9402 r->in.key_name, SPOOL_OID_KEY);
9408 * I'm not checking the status here on purpose. Don't know
9409 * if this is right, but I'm returning the status from the
9410 * previous set_printer_dataex() call. I have no idea if
9411 * this is right. --jerry
9414 set_printer_dataex( printer, str, r->in.value_name,
9415 REG_SZ, (uint8 *)oid_string,
9416 strlen(oid_string)+1 );
9419 status = mod_a_printer(printer, 2);
9422 free_a_printer(&printer, 2);
9427 /****************************************************************
9428 _spoolss_DeletePrinterDataEx
9429 ****************************************************************/
9431 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9432 struct spoolss_DeletePrinterDataEx *r)
9434 POLICY_HND *handle = r->in.handle;
9435 NT_PRINTER_INFO_LEVEL *printer = NULL;
9437 WERROR status = WERR_OK;
9438 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9440 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9443 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9444 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9448 if (!get_printer_snum(p, handle, &snum, NULL))
9451 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9452 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9453 "printer properties change denied by handle\n"));
9454 return WERR_ACCESS_DENIED;
9457 if (!r->in.value_name || !r->in.key_name) {
9461 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9462 if (!W_ERROR_IS_OK(status))
9465 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9467 if ( W_ERROR_IS_OK(status) )
9468 mod_a_printer( printer, 2 );
9470 free_a_printer(&printer, 2);
9475 /********************************************************************
9476 * spoolss_enumprinterkey
9477 ********************************************************************/
9480 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9483 fstring *keynames = NULL;
9484 uint16 *enumkeys = NULL;
9487 POLICY_HND *handle = &q_u->handle;
9488 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9489 NT_PRINTER_DATA *data;
9490 NT_PRINTER_INFO_LEVEL *printer = NULL;
9492 WERROR status = WERR_BADFILE;
9495 DEBUG(4,("_spoolss_enumprinterkey\n"));
9498 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9502 if ( !get_printer_snum(p,handle, &snum, NULL) )
9505 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9506 if (!W_ERROR_IS_OK(status))
9509 /* get the list of subkey names */
9511 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9512 data = printer->info_2->data;
9514 num_keys = get_printer_subkeys( data, key, &keynames );
9516 if ( num_keys == -1 ) {
9517 status = WERR_BADFILE;
9521 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9523 r_u->needed = printerkey_len*2;
9525 if ( q_u->size < r_u->needed ) {
9526 status = WERR_MORE_DATA;
9530 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9531 status = WERR_NOMEM;
9537 if ( q_u->size < r_u->needed )
9538 status = WERR_MORE_DATA;
9541 free_a_printer( &printer, 2 );
9542 SAFE_FREE( keynames );
9547 /****************************************************************
9548 _spoolss_DeletePrinterKey
9549 ****************************************************************/
9551 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9552 struct spoolss_DeletePrinterKey *r)
9554 POLICY_HND *handle = r->in.handle;
9555 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9556 NT_PRINTER_INFO_LEVEL *printer = NULL;
9560 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9563 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9564 OUR_HANDLE(handle)));
9568 /* if keyname == NULL, return error */
9570 if ( !r->in.key_name )
9571 return WERR_INVALID_PARAM;
9573 if (!get_printer_snum(p, handle, &snum, NULL))
9576 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9577 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9578 "printer properties change denied by handle\n"));
9579 return WERR_ACCESS_DENIED;
9582 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9583 if (!W_ERROR_IS_OK(status))
9586 /* delete the key and all subneys */
9588 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9590 if ( W_ERROR_IS_OK(status) )
9591 status = mod_a_printer(printer, 2);
9593 free_a_printer( &printer, 2 );
9599 /********************************************************************
9600 * spoolss_enumprinterdataex
9601 ********************************************************************/
9603 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9605 POLICY_HND *handle = &q_u->handle;
9606 uint32 in_size = q_u->size;
9609 NT_PRINTER_INFO_LEVEL *printer = NULL;
9610 PRINTER_ENUM_VALUES *enum_values = NULL;
9611 NT_PRINTER_DATA *p_data;
9613 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9618 REGISTRY_VALUE *val;
9623 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9626 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9631 * first check for a keyname of NULL or "". Win2k seems to send
9632 * this a lot and we should send back WERR_INVALID_PARAM
9633 * no need to spend time looking up the printer in this case.
9637 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9638 if ( !strlen(key) ) {
9639 result = WERR_INVALID_PARAM;
9643 /* get the printer off of disk */
9645 if (!get_printer_snum(p,handle, &snum, NULL))
9648 ZERO_STRUCT(printer);
9649 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9650 if (!W_ERROR_IS_OK(result))
9653 /* now look for a match on the key name */
9655 p_data = printer->info_2->data;
9657 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9658 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9660 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9661 result = WERR_INVALID_PARAM;
9668 /* allocate the memory for the array of pointers -- if necessary */
9670 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9673 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9675 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9676 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9677 result = WERR_NOMEM;
9681 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9685 * loop through all params and build the array to pass
9686 * back to the client
9689 for ( i=0; i<num_entries; i++ )
9691 /* lookup the registry value */
9693 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9694 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9698 value_name = regval_name( val );
9699 init_unistr( &enum_values[i].valuename, value_name );
9700 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9701 enum_values[i].type = regval_type( val );
9703 data_len = regval_size( val );
9705 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9707 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9709 result = WERR_NOMEM;
9713 enum_values[i].data_len = data_len;
9715 /* keep track of the size of the array in bytes */
9717 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9720 /* housekeeping information in the reply */
9722 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9723 * the hand marshalled container size is a multiple
9724 * of 4 bytes for RPC alignment.
9728 needed += 4-(needed % 4);
9731 r_u->needed = needed;
9732 r_u->returned = num_entries;
9734 if (needed > in_size) {
9735 result = WERR_MORE_DATA;
9739 /* copy data into the reply */
9741 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9742 response buffer size is != the offered buffer size
9744 r_u->ctr.size = r_u->needed;
9746 r_u->ctr.size = in_size;
9748 r_u->ctr.size_of_array = r_u->returned;
9749 r_u->ctr.values = enum_values;
9753 free_a_printer(&printer, 2);
9758 /****************************************************************************
9759 ****************************************************************************/
9761 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9762 const char *servername,
9763 const char *environment,
9764 struct spoolss_PrintProcessorDirectoryInfo1 *r,
9771 werr = compose_spoolss_server_path(mem_ctx,
9774 SPOOLSS_PRTPROCS_PATH,
9776 if (!W_ERROR_IS_OK(werr)) {
9780 DEBUG(4,("print processor directory: [%s]\n", path));
9782 r->directory_name = path;
9784 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
9786 if (*needed > offered) {
9788 return WERR_INSUFFICIENT_BUFFER;
9794 /****************************************************************
9795 _spoolss_GetPrintProcessorDirectory
9796 ****************************************************************/
9798 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9799 struct spoolss_GetPrintProcessorDirectory *r)
9803 /* that's an [in out] buffer */
9805 if (!r->in.buffer && (r->in.offered != 0)) {
9806 return WERR_INVALID_PARAM;
9809 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9814 /* r->in.level is ignored */
9816 result = getprintprocessordirectory_level_1(p->mem_ctx,
9819 &r->out.info->info1,
9822 if (!W_ERROR_IS_OK(result)) {
9823 TALLOC_FREE(r->out.info);
9829 /*******************************************************************
9830 ********************************************************************/
9832 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9833 const char *dllname)
9835 enum ndr_err_code ndr_err;
9836 struct spoolss_MonitorUi ui;
9838 ui.dll_name = dllname;
9840 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9841 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9842 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9843 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9845 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9848 /*******************************************************************
9849 Streams the monitor UI DLL name in UNICODE
9850 *******************************************************************/
9852 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9853 NT_USER_TOKEN *token, DATA_BLOB *in,
9854 DATA_BLOB *out, uint32_t *needed)
9856 const char *dllname = "tcpmonui.dll";
9858 *needed = (strlen(dllname)+1) * 2;
9860 if (out->length < *needed) {
9861 return WERR_INSUFFICIENT_BUFFER;
9864 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9871 /*******************************************************************
9872 ********************************************************************/
9874 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9875 struct spoolss_PortData1 *port1,
9876 const DATA_BLOB *buf)
9878 enum ndr_err_code ndr_err;
9879 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9880 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9881 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9882 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9884 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9887 /*******************************************************************
9888 ********************************************************************/
9890 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9891 struct spoolss_PortData2 *port2,
9892 const DATA_BLOB *buf)
9894 enum ndr_err_code ndr_err;
9895 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9896 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9897 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9898 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9900 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9903 /*******************************************************************
9904 Create a new TCP/IP port
9905 *******************************************************************/
9907 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9908 NT_USER_TOKEN *token, DATA_BLOB *in,
9909 DATA_BLOB *out, uint32_t *needed)
9911 struct spoolss_PortData1 port1;
9912 struct spoolss_PortData2 port2;
9913 char *device_uri = NULL;
9916 const char *portname;
9917 const char *hostaddress;
9919 uint32_t port_number;
9922 /* peek for spoolss_PortData version */
9924 if (!in || (in->length < (128 + 4))) {
9925 return WERR_GENERAL_FAILURE;
9928 version = IVAL(in->data, 128);
9934 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9938 portname = port1.portname;
9939 hostaddress = port1.hostaddress;
9940 queue = port1.queue;
9941 protocol = port1.protocol;
9942 port_number = port1.port_number;
9948 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9952 portname = port2.portname;
9953 hostaddress = port2.hostaddress;
9954 queue = port2.queue;
9955 protocol = port2.protocol;
9956 port_number = port2.port_number;
9960 DEBUG(1,("xcvtcp_addport: "
9961 "unknown version of port_data: %d\n", version));
9962 return WERR_UNKNOWN_PORT;
9965 /* create the device URI and call the add_port_hook() */
9968 case PROTOCOL_RAWTCP_TYPE:
9969 device_uri = talloc_asprintf(mem_ctx,
9970 "socket://%s:%d/", hostaddress,
9974 case PROTOCOL_LPR_TYPE:
9975 device_uri = talloc_asprintf(mem_ctx,
9976 "lpr://%s/%s", hostaddress, queue );
9980 return WERR_UNKNOWN_PORT;
9987 return add_port_hook(mem_ctx, token, portname, device_uri);
9990 /*******************************************************************
9991 *******************************************************************/
9993 struct xcv_api_table xcvtcp_cmds[] = {
9994 { "MonitorUI", xcvtcp_monitorui },
9995 { "AddPort", xcvtcp_addport},
9999 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
10000 NT_USER_TOKEN *token, const char *command,
10007 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
10009 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
10010 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
10011 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10014 return WERR_BADFUNC;
10017 /*******************************************************************
10018 *******************************************************************/
10019 #if 0 /* don't support management using the "Local Port" monitor */
10021 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10022 NT_USER_TOKEN *token, DATA_BLOB *in,
10023 DATA_BLOB *out, uint32_t *needed)
10025 const char *dllname = "localui.dll";
10027 *needed = (strlen(dllname)+1) * 2;
10029 if (out->length < *needed) {
10030 return WERR_INSUFFICIENT_BUFFER;
10033 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10040 /*******************************************************************
10041 *******************************************************************/
10043 struct xcv_api_table xcvlocal_cmds[] = {
10044 { "MonitorUI", xcvlocal_monitorui },
10048 struct xcv_api_table xcvlocal_cmds[] = {
10055 /*******************************************************************
10056 *******************************************************************/
10058 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10059 NT_USER_TOKEN *token, const char *command,
10060 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10065 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10067 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10068 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10069 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10071 return WERR_BADFUNC;
10074 /****************************************************************
10076 ****************************************************************/
10078 WERROR _spoolss_XcvData(pipes_struct *p,
10079 struct spoolss_XcvData *r)
10081 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10082 DATA_BLOB out_data;
10086 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10087 OUR_HANDLE(r->in.handle)));
10088 return WERR_BADFID;
10091 /* Has to be a handle to the TCP/IP port monitor */
10093 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10094 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10095 return WERR_BADFID;
10098 /* requires administrative access to the server */
10100 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10101 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10102 return WERR_ACCESS_DENIED;
10105 /* Allocate the outgoing buffer */
10107 if (r->in.out_data_size) {
10108 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10109 if (out_data.data == NULL) {
10114 switch ( Printer->printer_type ) {
10115 case SPLHND_PORTMON_TCP:
10116 werror = process_xcvtcp_command(p->mem_ctx,
10117 p->server_info->ptok,
10118 r->in.function_name,
10119 &r->in.in_data, &out_data,
10122 case SPLHND_PORTMON_LOCAL:
10123 werror = process_xcvlocal_command(p->mem_ctx,
10124 p->server_info->ptok,
10125 r->in.function_name,
10126 &r->in.in_data, &out_data,
10130 werror = WERR_INVALID_PRINT_MONITOR;
10133 if (!W_ERROR_IS_OK(werror)) {
10137 *r->out.status_code = 0;
10139 memcpy(r->out.out_data, out_data.data, out_data.length);
10144 /****************************************************************
10145 _spoolss_AddPrintProcessor
10146 ****************************************************************/
10148 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10149 struct spoolss_AddPrintProcessor *r)
10151 /* for now, just indicate success and ignore the add. We'll
10152 automatically set the winprint processor for printer
10153 entries later. Used to debug the LexMark Optra S 1855 PCL
10159 /****************************************************************
10160 _spoolss_EnumPrinters
10161 ****************************************************************/
10163 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10164 struct spoolss_EnumPrinters *r)
10166 p->rng_fault_state = true;
10167 return WERR_NOT_SUPPORTED;
10170 /****************************************************************
10172 ****************************************************************/
10174 WERROR _spoolss_GetJob(pipes_struct *p,
10175 struct spoolss_GetJob *r)
10177 p->rng_fault_state = true;
10178 return WERR_NOT_SUPPORTED;
10181 /****************************************************************
10183 ****************************************************************/
10185 WERROR _spoolss_EnumJobs(pipes_struct *p,
10186 struct spoolss_EnumJobs *r)
10188 p->rng_fault_state = true;
10189 return WERR_NOT_SUPPORTED;
10192 /****************************************************************
10193 _spoolss_AddPrinter
10194 ****************************************************************/
10196 WERROR _spoolss_AddPrinter(pipes_struct *p,
10197 struct spoolss_AddPrinter *r)
10199 p->rng_fault_state = true;
10200 return WERR_NOT_SUPPORTED;
10203 /****************************************************************
10204 _spoolss_GetPrinter
10205 ****************************************************************/
10207 WERROR _spoolss_GetPrinter(pipes_struct *p,
10208 struct spoolss_GetPrinter *r)
10210 p->rng_fault_state = true;
10211 return WERR_NOT_SUPPORTED;
10214 /****************************************************************
10215 _spoolss_EnumPrinterDrivers
10216 ****************************************************************/
10218 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10219 struct spoolss_EnumPrinterDrivers *r)
10221 p->rng_fault_state = true;
10222 return WERR_NOT_SUPPORTED;
10225 /****************************************************************
10226 _spoolss_GetPrinterDriver
10227 ****************************************************************/
10229 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10230 struct spoolss_GetPrinterDriver *r)
10232 p->rng_fault_state = true;
10233 return WERR_NOT_SUPPORTED;
10236 /****************************************************************
10237 _spoolss_EnumPrintProcessors
10238 ****************************************************************/
10240 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10241 struct spoolss_EnumPrintProcessors *r)
10243 p->rng_fault_state = true;
10244 return WERR_NOT_SUPPORTED;
10247 /****************************************************************
10248 _spoolss_ReadPrinter
10249 ****************************************************************/
10251 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10252 struct spoolss_ReadPrinter *r)
10254 p->rng_fault_state = true;
10255 return WERR_NOT_SUPPORTED;
10258 /****************************************************************
10259 _spoolss_GetPrinterData
10260 ****************************************************************/
10262 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10263 struct spoolss_GetPrinterData *r)
10265 p->rng_fault_state = true;
10266 return WERR_NOT_SUPPORTED;
10269 /****************************************************************
10270 _spoolss_SetPrinterData
10271 ****************************************************************/
10273 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10274 struct spoolss_SetPrinterData *r)
10276 p->rng_fault_state = true;
10277 return WERR_NOT_SUPPORTED;
10280 /****************************************************************
10281 _spoolss_WaitForPrinterChange
10282 ****************************************************************/
10284 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10285 struct spoolss_WaitForPrinterChange *r)
10287 p->rng_fault_state = true;
10288 return WERR_NOT_SUPPORTED;
10291 /****************************************************************
10293 ****************************************************************/
10295 WERROR _spoolss_EnumPorts(pipes_struct *p,
10296 struct spoolss_EnumPorts *r)
10298 p->rng_fault_state = true;
10299 return WERR_NOT_SUPPORTED;
10302 /****************************************************************
10303 _spoolss_EnumMonitors
10304 ****************************************************************/
10306 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10307 struct spoolss_EnumMonitors *r)
10309 p->rng_fault_state = true;
10310 return WERR_NOT_SUPPORTED;
10313 /****************************************************************
10315 ****************************************************************/
10317 WERROR _spoolss_AddPort(pipes_struct *p,
10318 struct spoolss_AddPort *r)
10320 p->rng_fault_state = true;
10321 return WERR_NOT_SUPPORTED;
10324 /****************************************************************
10325 _spoolss_ConfigurePort
10326 ****************************************************************/
10328 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10329 struct spoolss_ConfigurePort *r)
10331 p->rng_fault_state = true;
10332 return WERR_NOT_SUPPORTED;
10335 /****************************************************************
10336 _spoolss_DeletePort
10337 ****************************************************************/
10339 WERROR _spoolss_DeletePort(pipes_struct *p,
10340 struct spoolss_DeletePort *r)
10342 p->rng_fault_state = true;
10343 return WERR_NOT_SUPPORTED;
10346 /****************************************************************
10347 _spoolss_CreatePrinterIC
10348 ****************************************************************/
10350 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10351 struct spoolss_CreatePrinterIC *r)
10353 p->rng_fault_state = true;
10354 return WERR_NOT_SUPPORTED;
10357 /****************************************************************
10358 _spoolss_PlayGDIScriptOnPrinterIC
10359 ****************************************************************/
10361 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10362 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10364 p->rng_fault_state = true;
10365 return WERR_NOT_SUPPORTED;
10368 /****************************************************************
10369 _spoolss_DeletePrinterIC
10370 ****************************************************************/
10372 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10373 struct spoolss_DeletePrinterIC *r)
10375 p->rng_fault_state = true;
10376 return WERR_NOT_SUPPORTED;
10379 /****************************************************************
10380 _spoolss_AddPrinterConnection
10381 ****************************************************************/
10383 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10384 struct spoolss_AddPrinterConnection *r)
10386 p->rng_fault_state = true;
10387 return WERR_NOT_SUPPORTED;
10390 /****************************************************************
10391 _spoolss_DeletePrinterConnection
10392 ****************************************************************/
10394 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10395 struct spoolss_DeletePrinterConnection *r)
10397 p->rng_fault_state = true;
10398 return WERR_NOT_SUPPORTED;
10401 /****************************************************************
10402 _spoolss_PrinterMessageBox
10403 ****************************************************************/
10405 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10406 struct spoolss_PrinterMessageBox *r)
10408 p->rng_fault_state = true;
10409 return WERR_NOT_SUPPORTED;
10412 /****************************************************************
10413 _spoolss_AddMonitor
10414 ****************************************************************/
10416 WERROR _spoolss_AddMonitor(pipes_struct *p,
10417 struct spoolss_AddMonitor *r)
10419 p->rng_fault_state = true;
10420 return WERR_NOT_SUPPORTED;
10423 /****************************************************************
10424 _spoolss_DeleteMonitor
10425 ****************************************************************/
10427 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10428 struct spoolss_DeleteMonitor *r)
10430 p->rng_fault_state = true;
10431 return WERR_NOT_SUPPORTED;
10434 /****************************************************************
10435 _spoolss_DeletePrintProcessor
10436 ****************************************************************/
10438 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10439 struct spoolss_DeletePrintProcessor *r)
10441 p->rng_fault_state = true;
10442 return WERR_NOT_SUPPORTED;
10445 /****************************************************************
10446 _spoolss_AddPrintProvidor
10447 ****************************************************************/
10449 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10450 struct spoolss_AddPrintProvidor *r)
10452 p->rng_fault_state = true;
10453 return WERR_NOT_SUPPORTED;
10456 /****************************************************************
10457 _spoolss_DeletePrintProvidor
10458 ****************************************************************/
10460 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10461 struct spoolss_DeletePrintProvidor *r)
10463 p->rng_fault_state = true;
10464 return WERR_NOT_SUPPORTED;
10467 /****************************************************************
10468 _spoolss_EnumPrintProcDataTypes
10469 ****************************************************************/
10471 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10472 struct spoolss_EnumPrintProcDataTypes *r)
10474 p->rng_fault_state = true;
10475 return WERR_NOT_SUPPORTED;
10478 /****************************************************************
10479 _spoolss_GetPrinterDriver2
10480 ****************************************************************/
10482 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10483 struct spoolss_GetPrinterDriver2 *r)
10485 p->rng_fault_state = true;
10486 return WERR_NOT_SUPPORTED;
10489 /****************************************************************
10490 _spoolss_FindFirstPrinterChangeNotification
10491 ****************************************************************/
10493 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10494 struct spoolss_FindFirstPrinterChangeNotification *r)
10496 p->rng_fault_state = true;
10497 return WERR_NOT_SUPPORTED;
10500 /****************************************************************
10501 _spoolss_FindNextPrinterChangeNotification
10502 ****************************************************************/
10504 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10505 struct spoolss_FindNextPrinterChangeNotification *r)
10507 p->rng_fault_state = true;
10508 return WERR_NOT_SUPPORTED;
10511 /****************************************************************
10512 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10513 ****************************************************************/
10515 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10516 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10518 p->rng_fault_state = true;
10519 return WERR_NOT_SUPPORTED;
10522 /****************************************************************
10523 _spoolss_ReplyOpenPrinter
10524 ****************************************************************/
10526 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10527 struct spoolss_ReplyOpenPrinter *r)
10529 p->rng_fault_state = true;
10530 return WERR_NOT_SUPPORTED;
10533 /****************************************************************
10534 _spoolss_RouterReplyPrinter
10535 ****************************************************************/
10537 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10538 struct spoolss_RouterReplyPrinter *r)
10540 p->rng_fault_state = true;
10541 return WERR_NOT_SUPPORTED;
10544 /****************************************************************
10545 _spoolss_ReplyClosePrinter
10546 ****************************************************************/
10548 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10549 struct spoolss_ReplyClosePrinter *r)
10551 p->rng_fault_state = true;
10552 return WERR_NOT_SUPPORTED;
10555 /****************************************************************
10557 ****************************************************************/
10559 WERROR _spoolss_AddPortEx(pipes_struct *p,
10560 struct spoolss_AddPortEx *r)
10562 p->rng_fault_state = true;
10563 return WERR_NOT_SUPPORTED;
10566 /****************************************************************
10567 _spoolss_RouterFindFirstPrinterChangeNotification
10568 ****************************************************************/
10570 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10571 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10573 p->rng_fault_state = true;
10574 return WERR_NOT_SUPPORTED;
10577 /****************************************************************
10578 _spoolss_SpoolerInit
10579 ****************************************************************/
10581 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10582 struct spoolss_SpoolerInit *r)
10584 p->rng_fault_state = true;
10585 return WERR_NOT_SUPPORTED;
10588 /****************************************************************
10589 _spoolss_ResetPrinterEx
10590 ****************************************************************/
10592 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10593 struct spoolss_ResetPrinterEx *r)
10595 p->rng_fault_state = true;
10596 return WERR_NOT_SUPPORTED;
10599 /****************************************************************
10600 _spoolss_RouterReplyPrinterEx
10601 ****************************************************************/
10603 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10604 struct spoolss_RouterReplyPrinterEx *r)
10606 p->rng_fault_state = true;
10607 return WERR_NOT_SUPPORTED;
10610 /****************************************************************
10612 ****************************************************************/
10614 WERROR _spoolss_44(pipes_struct *p,
10615 struct spoolss_44 *r)
10617 p->rng_fault_state = true;
10618 return WERR_NOT_SUPPORTED;
10621 /****************************************************************
10623 ****************************************************************/
10625 WERROR _spoolss_47(pipes_struct *p,
10626 struct spoolss_47 *r)
10628 p->rng_fault_state = true;
10629 return WERR_NOT_SUPPORTED;
10632 /****************************************************************
10633 _spoolss_EnumPrinterData
10634 ****************************************************************/
10636 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10637 struct spoolss_EnumPrinterData *r)
10639 p->rng_fault_state = true;
10640 return WERR_NOT_SUPPORTED;
10643 /****************************************************************
10645 ****************************************************************/
10647 WERROR _spoolss_4a(pipes_struct *p,
10648 struct spoolss_4a *r)
10650 p->rng_fault_state = true;
10651 return WERR_NOT_SUPPORTED;
10654 /****************************************************************
10656 ****************************************************************/
10658 WERROR _spoolss_4b(pipes_struct *p,
10659 struct spoolss_4b *r)
10661 p->rng_fault_state = true;
10662 return WERR_NOT_SUPPORTED;
10665 /****************************************************************
10667 ****************************************************************/
10669 WERROR _spoolss_4c(pipes_struct *p,
10670 struct spoolss_4c *r)
10672 p->rng_fault_state = true;
10673 return WERR_NOT_SUPPORTED;
10676 /****************************************************************
10677 _spoolss_EnumPrinterDataEx
10678 ****************************************************************/
10680 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10681 struct spoolss_EnumPrinterDataEx *r)
10683 p->rng_fault_state = true;
10684 return WERR_NOT_SUPPORTED;
10687 /****************************************************************
10688 _spoolss_EnumPrinterKey
10689 ****************************************************************/
10691 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10692 struct spoolss_EnumPrinterKey *r)
10694 p->rng_fault_state = true;
10695 return WERR_NOT_SUPPORTED;
10698 /****************************************************************
10700 ****************************************************************/
10702 WERROR _spoolss_53(pipes_struct *p,
10703 struct spoolss_53 *r)
10705 p->rng_fault_state = true;
10706 return WERR_NOT_SUPPORTED;
10709 /****************************************************************
10711 ****************************************************************/
10713 WERROR _spoolss_55(pipes_struct *p,
10714 struct spoolss_55 *r)
10716 p->rng_fault_state = true;
10717 return WERR_NOT_SUPPORTED;
10720 /****************************************************************
10722 ****************************************************************/
10724 WERROR _spoolss_56(pipes_struct *p,
10725 struct spoolss_56 *r)
10727 p->rng_fault_state = true;
10728 return WERR_NOT_SUPPORTED;
10731 /****************************************************************
10733 ****************************************************************/
10735 WERROR _spoolss_57(pipes_struct *p,
10736 struct spoolss_57 *r)
10738 p->rng_fault_state = true;
10739 return WERR_NOT_SUPPORTED;
10742 /****************************************************************
10744 ****************************************************************/
10746 WERROR _spoolss_5a(pipes_struct *p,
10747 struct spoolss_5a *r)
10749 p->rng_fault_state = true;
10750 return WERR_NOT_SUPPORTED;
10753 /****************************************************************
10755 ****************************************************************/
10757 WERROR _spoolss_5b(pipes_struct *p,
10758 struct spoolss_5b *r)
10760 p->rng_fault_state = true;
10761 return WERR_NOT_SUPPORTED;
10764 /****************************************************************
10766 ****************************************************************/
10768 WERROR _spoolss_5c(pipes_struct *p,
10769 struct spoolss_5c *r)
10771 p->rng_fault_state = true;
10772 return WERR_NOT_SUPPORTED;
10775 /****************************************************************
10777 ****************************************************************/
10779 WERROR _spoolss_5d(pipes_struct *p,
10780 struct spoolss_5d *r)
10782 p->rng_fault_state = true;
10783 return WERR_NOT_SUPPORTED;
10786 /****************************************************************
10788 ****************************************************************/
10790 WERROR _spoolss_5e(pipes_struct *p,
10791 struct spoolss_5e *r)
10793 p->rng_fault_state = true;
10794 return WERR_NOT_SUPPORTED;
10797 /****************************************************************
10799 ****************************************************************/
10801 WERROR _spoolss_5f(pipes_struct *p,
10802 struct spoolss_5f *r)
10804 p->rng_fault_state = true;
10805 return WERR_NOT_SUPPORTED;