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 WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7248 struct spoolss_FormInfo1 *form,
7249 nt_forms_struct *list)
7251 form->form_name = talloc_strdup(mem_ctx, list->name);
7252 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7254 form->flags = list->flag;
7255 form->size.width = list->width;
7256 form->size.height = list->length;
7257 form->area.left = list->left;
7258 form->area.top = list->top;
7259 form->area.right = list->right;
7260 form->area.bottom = list->bottom;
7265 /****************************************************************
7267 ****************************************************************/
7269 WERROR _spoolss_EnumForms(pipes_struct *p,
7270 struct spoolss_EnumForms *r)
7272 nt_forms_struct *list=NULL;
7273 nt_forms_struct *builtinlist=NULL;
7274 union spoolss_FormInfo *info;
7276 uint32_t numbuiltinforms;
7277 size_t buffer_size = 0;
7282 /* that's an [in out] buffer */
7284 if (!r->in.buffer && (r->in.offered != 0) ) {
7285 return WERR_INVALID_PARAM;
7288 DEBUG(4,("_spoolss_EnumForms\n"));
7289 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
7290 DEBUGADD(5,("Info level [%d]\n", r->in.level));
7292 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7293 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7294 count = get_ntforms(&list);
7295 DEBUGADD(5,("Number of user forms [%d]\n", count));
7296 count += numbuiltinforms;
7299 SAFE_FREE(builtinlist);
7301 return WERR_NO_MORE_ITEMS;
7304 info = TALLOC_ARRAY(p->mem_ctx, union spoolss_FormInfo, count);
7306 SAFE_FREE(builtinlist);
7311 switch (r->in.level) {
7313 /* construct the list of form structures */
7314 for (i=0; i<numbuiltinforms; i++) {
7315 DEBUGADD(6,("Filling form number [%d]\n",i));
7316 fill_form_info_1(info, &info[i].info1, &builtinlist[i]);
7319 SAFE_FREE(builtinlist);
7321 for (; i<count; i++) {
7322 DEBUGADD(6,("Filling form number [%d]\n",i));
7323 fill_form_info_1(info, &info[i].info1, &list[i-numbuiltinforms]);
7328 /* check the required size. */
7329 for (i=0; i<numbuiltinforms; i++) {
7330 DEBUGADD(6,("adding form [%d]'s size\n",i));
7331 buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
7333 for (; i<count; i++) {
7334 DEBUGADD(6,("adding form [%d]'s size\n",i));
7335 buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
7338 *r->out.needed = buffer_size;
7340 if (*r->out.needed > r->in.offered) {
7342 return WERR_INSUFFICIENT_BUFFER;
7345 *r->out.count = count;
7346 *r->out.info = info;
7352 SAFE_FREE(builtinlist);
7353 return WERR_UNKNOWN_LEVEL;
7357 /****************************************************************
7359 ****************************************************************/
7361 WERROR _spoolss_GetForm(pipes_struct *p,
7362 struct spoolss_GetForm *r)
7364 uint32 level = r->in.level;
7365 uint32 offered = r->in.offered;
7366 uint32 *needed = r->out.needed;
7368 nt_forms_struct *list=NULL;
7369 nt_forms_struct builtin_form;
7371 union spoolss_FormInfo info;
7372 struct spoolss_FormInfo1 form_1;
7373 int numofforms=0, i=0;
7375 /* that's an [in out] buffer */
7377 if (!r->in.buffer && (offered!=0)) {
7378 return WERR_INVALID_PARAM;
7381 DEBUG(4,("_spoolss_GetForm\n"));
7382 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7383 DEBUGADD(5,("Info level [%d]\n", level));
7385 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7386 if (!foundBuiltin) {
7387 numofforms = get_ntforms(&list);
7388 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7390 if (numofforms == 0)
7394 ZERO_STRUCT(form_1);
7399 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7402 /* Check if the requested name is in the list of form structures */
7403 for (i=0; i<numofforms; i++) {
7405 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7406 list[i].name, r->in.form_name));
7408 if (strequal(r->in.form_name, list[i].name)) {
7409 DEBUGADD(6,("Found form %s number [%d]\n",
7410 r->in.form_name, i));
7411 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7417 if (i == numofforms) {
7421 /* check the required size. */
7423 info.info1 = form_1;
7425 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7427 if (*needed > offered) {
7429 return WERR_INSUFFICIENT_BUFFER;
7432 r->out.info->info1 = form_1;
7434 /* fill the buffer with the form structures */
7435 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7436 r->in.form_name, i));
7442 return WERR_UNKNOWN_LEVEL;
7446 /****************************************************************************
7447 ****************************************************************************/
7449 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7451 init_unistr(&port->port_name, name);
7454 /****************************************************************************
7455 TODO: This probably needs distinguish between TCP/IP and Local ports
7457 ****************************************************************************/
7459 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7461 init_unistr(&port->port_name, name);
7462 init_unistr(&port->monitor_name, "Local Monitor");
7463 init_unistr(&port->description, SPL_LOCAL_PORT );
7464 port->port_type=PORT_TYPE_WRITE;
7469 /****************************************************************************
7470 wrapper around the enumer ports command
7471 ****************************************************************************/
7473 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7475 char *cmd = lp_enumports_cmd();
7476 char **qlines = NULL;
7477 char *command = NULL;
7485 /* if no hook then just fill in the default port */
7488 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7491 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7492 TALLOC_FREE(qlines);
7499 /* we have a valid enumport command */
7501 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7506 DEBUG(10,("Running [%s]\n", command));
7507 ret = smbrun(command, &fd);
7508 DEBUG(10,("Returned [%d]\n", ret));
7509 TALLOC_FREE(command);
7514 return WERR_ACCESS_DENIED;
7518 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7519 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7529 /****************************************************************************
7531 ****************************************************************************/
7533 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7535 PORT_INFO_1 *ports=NULL;
7537 WERROR result = WERR_OK;
7538 char **qlines = NULL;
7541 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7542 if (!W_ERROR_IS_OK(result)) {
7543 TALLOC_FREE(qlines);
7548 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7549 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7550 win_errstr(WERR_NOMEM)));
7551 TALLOC_FREE(qlines);
7555 for (i=0; i<numlines; i++) {
7556 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7557 fill_port_1(&ports[i], qlines[i]);
7560 TALLOC_FREE(qlines);
7562 *returned = numlines;
7564 /* check the required size. */
7565 for (i=0; i<*returned; i++) {
7566 DEBUGADD(6,("adding port [%d]'s size\n", i));
7567 *needed += spoolss_size_port_info_1(&ports[i]);
7570 if (*needed > offered) {
7571 result = WERR_INSUFFICIENT_BUFFER;
7575 if (!rpcbuf_alloc_size(buffer, *needed)) {
7576 result = WERR_NOMEM;
7580 /* fill the buffer with the ports structures */
7581 for (i=0; i<*returned; i++) {
7582 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7583 smb_io_port_1("", buffer, &ports[i], 0);
7589 if ( !W_ERROR_IS_OK(result) )
7595 /****************************************************************************
7597 ****************************************************************************/
7599 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7601 PORT_INFO_2 *ports=NULL;
7603 WERROR result = WERR_OK;
7604 char **qlines = NULL;
7607 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7608 if ( !W_ERROR_IS_OK(result)) {
7609 TALLOC_FREE(qlines);
7614 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7615 TALLOC_FREE(qlines);
7619 for (i=0; i<numlines; i++) {
7620 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7621 fill_port_2(&(ports[i]), qlines[i]);
7625 TALLOC_FREE(qlines);
7627 *returned = numlines;
7629 /* check the required size. */
7630 for (i=0; i<*returned; i++) {
7631 DEBUGADD(6,("adding port [%d]'s size\n", i));
7632 *needed += spoolss_size_port_info_2(&ports[i]);
7635 if (*needed > offered) {
7636 result = WERR_INSUFFICIENT_BUFFER;
7640 if (!rpcbuf_alloc_size(buffer, *needed)) {
7641 result = WERR_NOMEM;
7645 /* fill the buffer with the ports structures */
7646 for (i=0; i<*returned; i++) {
7647 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7648 smb_io_port_2("", buffer, &ports[i], 0);
7654 if ( !W_ERROR_IS_OK(result) )
7660 /****************************************************************************
7662 ****************************************************************************/
7664 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7666 uint32 level = q_u->level;
7667 RPC_BUFFER *buffer = NULL;
7668 uint32 offered = q_u->offered;
7669 uint32 *needed = &r_u->needed;
7670 uint32 *returned = &r_u->returned;
7672 /* that's an [in out] buffer */
7674 if (!q_u->buffer && (offered!=0)) {
7675 return WERR_INVALID_PARAM;
7678 if (offered > MAX_RPC_DATA_SIZE) {
7679 return WERR_INVALID_PARAM;
7682 rpcbuf_move(q_u->buffer, &r_u->buffer);
7683 buffer = r_u->buffer;
7685 DEBUG(4,("_spoolss_enumports\n"));
7692 return enumports_level_1(buffer, offered, needed, returned);
7694 return enumports_level_2(buffer, offered, needed, returned);
7696 return WERR_UNKNOWN_LEVEL;
7700 /****************************************************************************
7701 ****************************************************************************/
7703 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7705 struct spoolss_SetPrinterInfoCtr *info_ctr,
7706 struct spoolss_DeviceMode *devmode,
7707 struct security_descriptor *sec_desc,
7708 struct spoolss_UserLevelCtr *user_ctr,
7711 NT_PRINTER_INFO_LEVEL *printer = NULL;
7714 WERROR err = WERR_OK;
7716 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7717 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7721 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7722 if (!convert_printer_info_new(info_ctr, printer)) {
7723 free_a_printer(&printer, 2);
7727 /* check to see if the printer already exists */
7729 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7730 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7731 printer->info_2->sharename));
7732 free_a_printer(&printer, 2);
7733 return WERR_PRINTER_ALREADY_EXISTS;
7736 /* FIXME!!! smbd should check to see if the driver is installed before
7737 trying to add a printer like this --jerry */
7739 if (*lp_addprinter_cmd() ) {
7740 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7742 free_a_printer(&printer,2);
7743 return WERR_ACCESS_DENIED;
7746 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7747 "smb.conf parameter \"addprinter command\" is defined. This"
7748 "parameter must exist for this call to succeed\n",
7749 printer->info_2->sharename ));
7752 /* use our primary netbios name since get_a_printer() will convert
7753 it to what the client expects on a case by case basis */
7755 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7756 printer->info_2->sharename);
7759 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7760 free_a_printer(&printer,2);
7761 return WERR_ACCESS_DENIED;
7764 /* you must be a printer admin to add a new printer */
7765 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7766 free_a_printer(&printer,2);
7767 return WERR_ACCESS_DENIED;
7771 * Do sanity check on the requested changes for Samba.
7774 if (!check_printer_ok(printer->info_2, snum)) {
7775 free_a_printer(&printer,2);
7776 return WERR_INVALID_PARAM;
7780 * When a printer is created, the drivername bound to the printer is used
7781 * to lookup previously saved driver initialization info, which is then
7782 * bound to the new printer, simulating what happens in the Windows arch.
7787 set_driver_init(printer, 2);
7791 /* A valid devmode was included, convert and link it
7793 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7795 if (!convert_devicemode_new(printer->info_2->printername,
7797 &printer->info_2->devmode))
7801 /* write the ASCII on disk */
7802 err = mod_a_printer(printer, 2);
7803 if (!W_ERROR_IS_OK(err)) {
7804 free_a_printer(&printer,2);
7808 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7809 /* Handle open failed - remove addition. */
7810 del_a_printer(printer->info_2->sharename);
7811 free_a_printer(&printer,2);
7812 ZERO_STRUCTP(handle);
7813 return WERR_ACCESS_DENIED;
7816 update_c_setprinter(False);
7817 free_a_printer(&printer,2);
7822 /****************************************************************
7823 _spoolss_AddPrinterEx
7824 ****************************************************************/
7826 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7827 struct spoolss_AddPrinterEx *r)
7829 switch (r->in.info_ctr->level) {
7831 /* we don't handle yet */
7832 /* but I know what to do ... */
7833 return WERR_UNKNOWN_LEVEL;
7835 return spoolss_addprinterex_level_2(p, r->in.server,
7837 r->in.devmode_ctr->devmode,
7838 r->in.secdesc_ctr->sd,
7839 r->in.userlevel_ctr,
7842 return WERR_UNKNOWN_LEVEL;
7846 /****************************************************************
7847 _spoolss_AddPrinterDriver
7848 ****************************************************************/
7850 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7851 struct spoolss_AddPrinterDriver *r)
7853 uint32_t level = r->in.info_ctr->level;
7854 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7855 WERROR err = WERR_OK;
7856 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7857 fstring driver_name;
7861 switch (p->hdr_req.opnum) {
7862 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7863 fn = "_spoolss_AddPrinterDriver";
7865 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7866 fn = "_spoolss_AddPrinterDriverEx";
7869 return WERR_INVALID_PARAM;
7874 if (level != 3 && level != 6) {
7875 /* Clever hack from Martin Zielinski <mz@seh.de>
7876 * to allow downgrade from level 8 (Vista).
7878 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7879 return WERR_UNKNOWN_LEVEL;
7882 ZERO_STRUCT(driver);
7884 if (!convert_printer_driver_info(info, &driver, level)) {
7889 DEBUG(5,("Cleaning driver's information\n"));
7890 err = clean_up_driver_struct(p, driver, level);
7891 if (!W_ERROR_IS_OK(err))
7894 DEBUG(5,("Moving driver to final destination\n"));
7895 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7900 if (add_a_printer_driver(driver, level)!=0) {
7901 err = WERR_ACCESS_DENIED;
7907 fstrcpy(driver_name,
7908 driver.info_3->name ? driver.info_3->name : "");
7911 fstrcpy(driver_name,
7912 driver.info_6->name ? driver.info_6->name : "");
7917 * I think this is where he DrvUpgradePrinter() hook would be
7918 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7919 * server. Right now, we just need to send ourselves a message
7920 * to update each printer bound to this driver. --jerry
7923 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7924 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7929 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7930 * decide if the driver init data should be deleted. The rules are:
7931 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7932 * 2) delete init data only if there is no 2k/Xp driver
7933 * 3) always delete init data
7934 * The generalized rule is always use init data from the highest order driver.
7935 * It is necessary to follow the driver install by an initialization step to
7936 * finish off this process.
7939 version = driver.info_3->cversion;
7940 else if (level == 6)
7941 version = driver.info_6->version;
7946 * 9x printer driver - never delete init data
7949 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7954 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7955 * there is no 2k/Xp driver init data for this driver name.
7959 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7961 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7963 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7965 if (!del_driver_init(driver_name))
7966 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7970 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7972 free_a_printer_driver(driver1,3);
7973 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7980 * 2k or Xp printer driver - always delete init data
7983 if (!del_driver_init(driver_name))
7984 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7989 DEBUG(0,("%s: invalid level=%d\n", fn, level));
7995 free_a_printer_driver(driver, level);
7999 /****************************************************************
8000 _spoolss_AddPrinterDriverEx
8001 ****************************************************************/
8003 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8004 struct spoolss_AddPrinterDriverEx *r)
8006 struct spoolss_AddPrinterDriver a;
8009 * we only support the semantics of AddPrinterDriver()
8010 * i.e. only copy files that are newer than existing ones
8013 if (r->in.flags != APD_COPY_NEW_FILES) {
8014 return WERR_ACCESS_DENIED;
8017 a.in.servername = r->in.servername;
8018 a.in.info_ctr = r->in.info_ctr;
8020 return _spoolss_AddPrinterDriver(p, &a);
8023 /****************************************************************************
8024 ****************************************************************************/
8026 struct _spoolss_paths {
8032 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
8034 static const struct _spoolss_paths spoolss_paths[]= {
8035 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
8036 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
8039 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
8040 const char *servername,
8041 const char *environment,
8045 const char *pservername = NULL;
8046 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8047 const char *short_archi;
8051 /* environment may be empty */
8052 if (environment && strlen(environment)) {
8053 long_archi = environment;
8056 /* servername may be empty */
8057 if (servername && strlen(servername)) {
8058 pservername = canon_servername(servername);
8060 if (!is_myname_or_ipaddr(pservername)) {
8061 return WERR_INVALID_PARAM;
8065 if (!(short_archi = get_short_archi(long_archi))) {
8066 return WERR_INVALID_ENVIRONMENT;
8069 switch (component) {
8070 case SPOOLSS_PRTPROCS_PATH:
8071 case SPOOLSS_DRIVER_PATH:
8073 *path = talloc_asprintf(mem_ctx,
8076 spoolss_paths[component].share,
8079 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
8080 SPOOLSS_DEFAULT_SERVER_PATH,
8081 spoolss_paths[component].dir,
8086 return WERR_INVALID_PARAM;
8096 /****************************************************************************
8097 ****************************************************************************/
8099 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8100 const char *servername,
8101 const char *environment,
8102 struct spoolss_DriverDirectoryInfo1 *r,
8109 werr = compose_spoolss_server_path(mem_ctx,
8112 SPOOLSS_DRIVER_PATH,
8114 if (!W_ERROR_IS_OK(werr)) {
8118 DEBUG(4,("printer driver directory: [%s]\n", path));
8120 r->directory_name = path;
8122 *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
8124 if (*needed > offered) {
8126 return WERR_INSUFFICIENT_BUFFER;
8132 /****************************************************************
8133 _spoolss_GetPrinterDriverDirectory
8134 ****************************************************************/
8136 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8137 struct spoolss_GetPrinterDriverDirectory *r)
8141 /* that's an [in out] buffer */
8143 if (!r->in.buffer && (r->in.offered != 0)) {
8144 return WERR_INVALID_PARAM;
8147 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
8152 /* r->in.level is ignored */
8154 werror = getprinterdriverdir_level_1(p->mem_ctx,
8157 &r->out.info->info1,
8160 if (!W_ERROR_IS_OK(werror)) {
8161 TALLOC_FREE(r->out.info);
8167 /****************************************************************************
8168 ****************************************************************************/
8170 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8172 POLICY_HND *handle = &q_u->handle;
8173 uint32 idx = q_u->index;
8174 uint32 in_value_len = q_u->valuesize;
8175 uint32 in_data_len = q_u->datasize;
8176 uint32 *out_max_value_len = &r_u->valuesize;
8177 uint16 **out_value = &r_u->value;
8178 uint32 *out_value_len = &r_u->realvaluesize;
8179 uint32 *out_type = &r_u->type;
8180 uint32 *out_max_data_len = &r_u->datasize;
8181 uint8 **data_out = &r_u->data;
8182 uint32 *out_data_len = &r_u->realdatasize;
8184 NT_PRINTER_INFO_LEVEL *printer = NULL;
8186 uint32 biggest_valuesize;
8187 uint32 biggest_datasize;
8189 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8192 REGISTRY_VALUE *val = NULL;
8193 NT_PRINTER_DATA *p_data;
8194 int i, key_index, num_values;
8199 *out_max_data_len = 0;
8203 DEBUG(5,("spoolss_enumprinterdata\n"));
8206 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8210 if (!get_printer_snum(p,handle, &snum, NULL))
8213 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8214 if (!W_ERROR_IS_OK(result))
8217 p_data = printer->info_2->data;
8218 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8223 * The NT machine wants to know the biggest size of value and data
8225 * cf: MSDN EnumPrinterData remark section
8228 if ( !in_value_len && !in_data_len && (key_index != -1) )
8230 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8232 biggest_valuesize = 0;
8233 biggest_datasize = 0;
8235 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8237 for ( i=0; i<num_values; i++ )
8239 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8241 name_length = strlen(val->valuename);
8242 if ( strlen(val->valuename) > biggest_valuesize )
8243 biggest_valuesize = name_length;
8245 if ( val->size > biggest_datasize )
8246 biggest_datasize = val->size;
8248 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8252 /* the value is an UNICODE string but real_value_size is the length
8253 in bytes including the trailing 0 */
8255 *out_value_len = 2 * (1+biggest_valuesize);
8256 *out_data_len = biggest_datasize;
8258 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8264 * the value len is wrong in NT sp3
8265 * that's the number of bytes not the number of unicode chars
8268 if ( key_index != -1 )
8269 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8274 /* out_value should default to "" or else NT4 has
8275 problems unmarshalling the response */
8277 *out_max_value_len=(in_value_len/sizeof(uint16));
8280 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8282 result = WERR_NOMEM;
8285 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8291 /* the data is counted in bytes */
8293 *out_max_data_len = in_data_len;
8294 *out_data_len = in_data_len;
8296 /* only allocate when given a non-zero data_len */
8298 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8300 result = WERR_NOMEM;
8304 result = WERR_NO_MORE_ITEMS;
8310 * - counted in bytes in the request
8311 * - counted in UNICODE chars in the max reply
8312 * - counted in bytes in the real size
8314 * take a pause *before* coding not *during* coding
8318 *out_max_value_len=(in_value_len/sizeof(uint16));
8320 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8322 result = WERR_NOMEM;
8326 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8334 *out_type = regval_type( val );
8336 /* data - counted in bytes */
8338 *out_max_data_len = in_data_len;
8339 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8341 result = WERR_NOMEM;
8344 data_len = regval_size(val);
8345 if ( *data_out && data_len )
8346 memcpy( *data_out, regval_data_p(val), data_len );
8347 *out_data_len = data_len;
8351 free_a_printer(&printer, 2);
8355 /****************************************************************************
8356 ****************************************************************************/
8358 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8360 POLICY_HND *handle = &q_u->handle;
8361 UNISTR2 *value = &q_u->value;
8362 uint32 type = q_u->type;
8363 uint8 *data = q_u->data;
8364 uint32 real_len = q_u->real_len;
8366 NT_PRINTER_INFO_LEVEL *printer = NULL;
8368 WERROR status = WERR_OK;
8369 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8372 DEBUG(5,("spoolss_setprinterdata\n"));
8375 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8379 if ( Printer->printer_type == SPLHND_SERVER ) {
8380 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8381 return WERR_INVALID_PARAM;
8384 if (!get_printer_snum(p,handle, &snum, NULL))
8388 * Access check : NT returns "access denied" if you make a
8389 * SetPrinterData call without the necessary privildge.
8390 * we were originally returning OK if nothing changed
8391 * which made Win2k issue **a lot** of SetPrinterData
8392 * when connecting to a printer --jerry
8395 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8397 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8398 status = WERR_ACCESS_DENIED;
8402 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8403 if (!W_ERROR_IS_OK(status))
8406 unistr2_to_ascii(valuename, value, sizeof(valuename));
8409 * When client side code sets a magic printer data key, detect it and save
8410 * the current printer data and the magic key's data (its the DEVMODE) for
8411 * future printer/driver initializations.
8413 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8415 /* Set devmode and printer initialization info */
8416 status = save_driver_init( printer, 2, data, real_len );
8418 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8422 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8423 type, data, real_len );
8424 if ( W_ERROR_IS_OK(status) )
8425 status = mod_a_printer(printer, 2);
8429 free_a_printer(&printer, 2);
8434 /****************************************************************
8435 _spoolss_ResetPrinter
8436 ****************************************************************/
8438 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8439 struct spoolss_ResetPrinter *r)
8441 POLICY_HND *handle = r->in.handle;
8442 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8445 DEBUG(5,("_spoolss_ResetPrinter\n"));
8448 * All we do is to check to see if the handle and queue is valid.
8449 * This call really doesn't mean anything to us because we only
8450 * support RAW printing. --jerry
8454 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8455 OUR_HANDLE(handle)));
8459 if (!get_printer_snum(p,handle, &snum, NULL))
8463 /* blindly return success */
8467 /****************************************************************
8468 _spoolss_DeletePrinterData
8469 ****************************************************************/
8471 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8472 struct spoolss_DeletePrinterData *r)
8474 POLICY_HND *handle = r->in.handle;
8475 NT_PRINTER_INFO_LEVEL *printer = NULL;
8477 WERROR status = WERR_OK;
8478 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8480 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8483 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8484 OUR_HANDLE(handle)));
8488 if (!get_printer_snum(p, handle, &snum, NULL))
8491 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8492 DEBUG(3, ("_spoolss_DeletePrinterData: "
8493 "printer properties change denied by handle\n"));
8494 return WERR_ACCESS_DENIED;
8497 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8498 if (!W_ERROR_IS_OK(status))
8501 if (!r->in.value_name) {
8502 free_a_printer(&printer, 2);
8506 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8509 if ( W_ERROR_IS_OK(status) )
8510 mod_a_printer( printer, 2 );
8512 free_a_printer(&printer, 2);
8517 /****************************************************************
8519 ****************************************************************/
8521 WERROR _spoolss_AddForm(pipes_struct *p,
8522 struct spoolss_AddForm *r)
8524 POLICY_HND *handle = r->in.handle;
8525 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8526 nt_forms_struct tmpForm;
8528 WERROR status = WERR_OK;
8529 NT_PRINTER_INFO_LEVEL *printer = NULL;
8532 nt_forms_struct *list=NULL;
8533 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8535 DEBUG(5,("_spoolss_AddForm\n"));
8538 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8539 OUR_HANDLE(handle)));
8544 /* forms can be added on printer of on the print server handle */
8546 if ( Printer->printer_type == SPLHND_PRINTER )
8548 if (!get_printer_snum(p,handle, &snum, NULL))
8551 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8552 if (!W_ERROR_IS_OK(status))
8556 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8557 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8558 status = WERR_ACCESS_DENIED;
8562 /* can't add if builtin */
8564 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8565 status = WERR_FILE_EXISTS;
8569 count = get_ntforms(&list);
8571 if(!add_a_form(&list, form, &count)) {
8572 status = WERR_NOMEM;
8576 write_ntforms(&list, count);
8579 * ChangeID must always be set if this is a printer
8582 if ( Printer->printer_type == SPLHND_PRINTER )
8583 status = mod_a_printer(printer, 2);
8587 free_a_printer(&printer, 2);
8593 /****************************************************************
8595 ****************************************************************/
8597 WERROR _spoolss_DeleteForm(pipes_struct *p,
8598 struct spoolss_DeleteForm *r)
8600 POLICY_HND *handle = r->in.handle;
8601 const char *form_name = r->in.form_name;
8602 nt_forms_struct tmpForm;
8604 nt_forms_struct *list=NULL;
8605 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8607 WERROR status = WERR_OK;
8608 NT_PRINTER_INFO_LEVEL *printer = NULL;
8610 DEBUG(5,("_spoolss_DeleteForm\n"));
8613 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8614 OUR_HANDLE(handle)));
8618 /* forms can be deleted on printer of on the print server handle */
8620 if ( Printer->printer_type == SPLHND_PRINTER )
8622 if (!get_printer_snum(p,handle, &snum, NULL))
8625 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8626 if (!W_ERROR_IS_OK(status))
8630 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8631 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8632 status = WERR_ACCESS_DENIED;
8636 /* can't delete if builtin */
8638 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8639 status = WERR_INVALID_PARAM;
8643 count = get_ntforms(&list);
8645 if ( !delete_a_form(&list, form_name, &count, &status ))
8649 * ChangeID must always be set if this is a printer
8652 if ( Printer->printer_type == SPLHND_PRINTER )
8653 status = mod_a_printer(printer, 2);
8657 free_a_printer(&printer, 2);
8663 /****************************************************************
8665 ****************************************************************/
8667 WERROR _spoolss_SetForm(pipes_struct *p,
8668 struct spoolss_SetForm *r)
8670 POLICY_HND *handle = r->in.handle;
8671 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8672 nt_forms_struct tmpForm;
8674 WERROR status = WERR_OK;
8675 NT_PRINTER_INFO_LEVEL *printer = NULL;
8678 nt_forms_struct *list=NULL;
8679 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8681 DEBUG(5,("_spoolss_SetForm\n"));
8684 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8685 OUR_HANDLE(handle)));
8689 /* forms can be modified on printer of on the print server handle */
8691 if ( Printer->printer_type == SPLHND_PRINTER )
8693 if (!get_printer_snum(p,handle, &snum, NULL))
8696 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8697 if (!W_ERROR_IS_OK(status))
8701 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8702 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8703 status = WERR_ACCESS_DENIED;
8707 /* can't set if builtin */
8708 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8709 status = WERR_INVALID_PARAM;
8713 count = get_ntforms(&list);
8714 update_a_form(&list, form, count);
8715 write_ntforms(&list, count);
8718 * ChangeID must always be set if this is a printer
8721 if ( Printer->printer_type == SPLHND_PRINTER )
8722 status = mod_a_printer(printer, 2);
8727 free_a_printer(&printer, 2);
8733 /****************************************************************************
8734 enumprintprocessors level 1.
8735 ****************************************************************************/
8737 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8739 PRINTPROCESSOR_1 *info_1=NULL;
8740 WERROR result = WERR_OK;
8742 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8747 init_unistr(&info_1->name, "winprint");
8749 *needed += spoolss_size_printprocessor_info_1(info_1);
8751 if (*needed > offered) {
8752 result = WERR_INSUFFICIENT_BUFFER;
8756 if (!rpcbuf_alloc_size(buffer, *needed)) {
8757 result = WERR_NOMEM;
8761 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8766 if ( !W_ERROR_IS_OK(result) )
8772 /****************************************************************************
8773 ****************************************************************************/
8775 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8777 uint32 level = q_u->level;
8778 RPC_BUFFER *buffer = NULL;
8779 uint32 offered = q_u->offered;
8780 uint32 *needed = &r_u->needed;
8781 uint32 *returned = &r_u->returned;
8783 /* that's an [in out] buffer */
8785 if (!q_u->buffer && (offered!=0)) {
8786 return WERR_INVALID_PARAM;
8789 if (offered > MAX_RPC_DATA_SIZE) {
8790 return WERR_INVALID_PARAM;
8793 rpcbuf_move(q_u->buffer, &r_u->buffer);
8794 buffer = r_u->buffer;
8796 DEBUG(5,("spoolss_enumprintprocessors\n"));
8799 * Enumerate the print processors ...
8801 * Just reply with "winprint", to keep NT happy
8802 * and I can use my nice printer checker.
8810 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8812 return WERR_UNKNOWN_LEVEL;
8816 /****************************************************************************
8817 enumprintprocdatatypes level 1.
8818 ****************************************************************************/
8820 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8822 PRINTPROCDATATYPE_1 *info_1=NULL;
8823 WERROR result = WERR_OK;
8825 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8830 init_unistr(&info_1->name, "RAW");
8832 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8834 if (*needed > offered) {
8835 result = WERR_INSUFFICIENT_BUFFER;
8839 if (!rpcbuf_alloc_size(buffer, *needed)) {
8840 result = WERR_NOMEM;
8844 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8849 if ( !W_ERROR_IS_OK(result) )
8855 /****************************************************************************
8856 ****************************************************************************/
8858 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8860 uint32 level = q_u->level;
8861 RPC_BUFFER *buffer = NULL;
8862 uint32 offered = q_u->offered;
8863 uint32 *needed = &r_u->needed;
8864 uint32 *returned = &r_u->returned;
8866 /* that's an [in out] buffer */
8868 if (!q_u->buffer && (offered!=0)) {
8869 return WERR_INVALID_PARAM;
8872 if (offered > MAX_RPC_DATA_SIZE) {
8873 return WERR_INVALID_PARAM;
8876 rpcbuf_move(q_u->buffer, &r_u->buffer);
8877 buffer = r_u->buffer;
8879 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8886 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8888 return WERR_UNKNOWN_LEVEL;
8892 /****************************************************************************
8893 enumprintmonitors level 1.
8894 ****************************************************************************/
8896 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8898 PRINTMONITOR_1 *info_1;
8899 WERROR result = WERR_OK;
8902 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8907 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8908 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8910 for ( i=0; i<*returned; i++ ) {
8911 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8914 if (*needed > offered) {
8915 result = WERR_INSUFFICIENT_BUFFER;
8919 if (!rpcbuf_alloc_size(buffer, *needed)) {
8920 result = WERR_NOMEM;
8924 for ( i=0; i<*returned; i++ ) {
8925 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8931 if ( !W_ERROR_IS_OK(result) )
8937 /****************************************************************************
8938 enumprintmonitors level 2.
8939 ****************************************************************************/
8941 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8943 PRINTMONITOR_2 *info_2;
8944 WERROR result = WERR_OK;
8947 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8952 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8953 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8954 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8956 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8957 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8958 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8960 for ( i=0; i<*returned; i++ ) {
8961 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8964 if (*needed > offered) {
8965 result = WERR_INSUFFICIENT_BUFFER;
8969 if (!rpcbuf_alloc_size(buffer, *needed)) {
8970 result = WERR_NOMEM;
8974 for ( i=0; i<*returned; i++ ) {
8975 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8981 if ( !W_ERROR_IS_OK(result) )
8987 /****************************************************************************
8988 ****************************************************************************/
8990 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8992 uint32 level = q_u->level;
8993 RPC_BUFFER *buffer = NULL;
8994 uint32 offered = q_u->offered;
8995 uint32 *needed = &r_u->needed;
8996 uint32 *returned = &r_u->returned;
8998 /* that's an [in out] buffer */
9000 if (!q_u->buffer && (offered!=0)) {
9001 return WERR_INVALID_PARAM;
9004 if (offered > MAX_RPC_DATA_SIZE) {
9005 return WERR_INVALID_PARAM;
9008 rpcbuf_move(q_u->buffer, &r_u->buffer);
9009 buffer = r_u->buffer;
9011 DEBUG(5,("spoolss_enumprintmonitors\n"));
9014 * Enumerate the print monitors ...
9016 * Just reply with "Local Port", to keep NT happy
9017 * and I can use my nice printer checker.
9025 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9027 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9029 return WERR_UNKNOWN_LEVEL;
9033 /****************************************************************************
9034 ****************************************************************************/
9036 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9037 NT_PRINTER_INFO_LEVEL *ntprinter,
9038 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9043 JOB_INFO_1 *info_1=NULL;
9044 WERROR result = WERR_OK;
9046 info_1=SMB_MALLOC_P(JOB_INFO_1);
9048 if (info_1 == NULL) {
9052 for (i=0; i<count && found==False; i++) {
9053 if ((*queue)[i].job==(int)jobid)
9059 /* NT treats not found as bad param... yet another bad choice */
9060 return WERR_INVALID_PARAM;
9063 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9065 *needed += spoolss_size_job_info_1(info_1);
9067 if (*needed > offered) {
9068 result = WERR_INSUFFICIENT_BUFFER;
9072 if (!rpcbuf_alloc_size(buffer, *needed)) {
9073 result = WERR_NOMEM;
9077 smb_io_job_info_1("", buffer, info_1, 0);
9085 /****************************************************************************
9086 ****************************************************************************/
9088 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9089 NT_PRINTER_INFO_LEVEL *ntprinter,
9090 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9097 DEVICEMODE *devmode = NULL;
9098 NT_DEVICEMODE *nt_devmode = NULL;
9100 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9103 ZERO_STRUCTP(info_2);
9105 for ( i=0; i<count && found==False; i++ )
9107 if ((*queue)[i].job == (int)jobid)
9112 /* NT treats not found as bad param... yet another bad
9114 result = WERR_INVALID_PARAM;
9119 * if the print job does not have a DEVMODE associated with it,
9120 * just use the one for the printer. A NULL devicemode is not
9121 * a failure condition
9124 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9125 devmode = construct_dev_mode(lp_const_servicename(snum));
9127 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9128 ZERO_STRUCTP( devmode );
9129 convert_nt_devicemode( devmode, nt_devmode );
9133 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9135 *needed += spoolss_size_job_info_2(info_2);
9137 if (*needed > offered) {
9138 result = WERR_INSUFFICIENT_BUFFER;
9142 if (!rpcbuf_alloc_size(buffer, *needed)) {
9143 result = WERR_NOMEM;
9147 smb_io_job_info_2("", buffer, info_2, 0);
9152 /* Cleanup allocated memory */
9154 free_job_info_2(info_2); /* Also frees devmode */
9160 /****************************************************************************
9161 ****************************************************************************/
9163 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9165 POLICY_HND *handle = &q_u->handle;
9166 uint32 jobid = q_u->jobid;
9167 uint32 level = q_u->level;
9168 RPC_BUFFER *buffer = NULL;
9169 uint32 offered = q_u->offered;
9170 uint32 *needed = &r_u->needed;
9171 WERROR wstatus = WERR_OK;
9172 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9175 print_queue_struct *queue = NULL;
9176 print_status_struct prt_status;
9178 /* that's an [in out] buffer */
9180 if (!q_u->buffer && (offered!=0)) {
9181 return WERR_INVALID_PARAM;
9184 if (offered > MAX_RPC_DATA_SIZE) {
9185 return WERR_INVALID_PARAM;
9188 rpcbuf_move(q_u->buffer, &r_u->buffer);
9189 buffer = r_u->buffer;
9191 DEBUG(5,("spoolss_getjob\n"));
9195 if (!get_printer_snum(p, handle, &snum, NULL))
9198 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9199 if ( !W_ERROR_IS_OK(wstatus) )
9202 count = print_queue_status(snum, &queue, &prt_status);
9204 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9205 count, prt_status.status, prt_status.message));
9209 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9210 buffer, offered, needed);
9213 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9214 buffer, offered, needed);
9217 wstatus = WERR_UNKNOWN_LEVEL;
9222 free_a_printer( &ntprinter, 2 );
9227 /****************************************************************
9228 _spoolss_GetPrinterDataEx
9230 From MSDN documentation of GetPrinterDataEx: pass request
9231 to GetPrinterData if key is "PrinterDriverData".
9232 ****************************************************************/
9234 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9235 struct spoolss_GetPrinterDataEx *r)
9237 POLICY_HND *handle = r->in.handle;
9239 const char *keyname = r->in.key_name;
9240 const char *valuename = r->in.value_name;
9242 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9244 NT_PRINTER_INFO_LEVEL *printer = NULL;
9246 WERROR status = WERR_OK;
9248 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9250 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9251 keyname, valuename));
9253 /* in case of problem, return some default values */
9259 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9260 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9261 status = WERR_BADFID;
9265 /* Is the handle to a printer or to the server? */
9267 if (Printer->printer_type == SPLHND_SERVER) {
9268 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9269 "Not implemented for server handles yet\n"));
9270 status = WERR_INVALID_PARAM;
9274 if ( !get_printer_snum(p,handle, &snum, NULL) )
9277 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9278 if ( !W_ERROR_IS_OK(status) )
9281 /* check to see if the keyname is valid */
9282 if ( !strlen(keyname) ) {
9283 status = WERR_INVALID_PARAM;
9287 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9288 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9289 "Invalid keyname [%s]\n", keyname ));
9290 free_a_printer( &printer, 2 );
9291 status = WERR_BADFILE;
9295 /* When given a new keyname, we should just create it */
9297 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9298 r->out.type, &data, r->out.needed,
9301 if (*r->out.needed > r->in.offered) {
9302 status = WERR_MORE_DATA;
9305 if (W_ERROR_IS_OK(status)) {
9306 memcpy(r->out.buffer, data, r->in.offered);
9311 free_a_printer( &printer, 2 );
9316 /****************************************************************
9317 _spoolss_SetPrinterDataEx
9318 ****************************************************************/
9320 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9321 struct spoolss_SetPrinterDataEx *r)
9323 POLICY_HND *handle = r->in.handle;
9324 NT_PRINTER_INFO_LEVEL *printer = NULL;
9326 WERROR status = WERR_OK;
9327 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9330 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9332 /* From MSDN documentation of SetPrinterDataEx: pass request to
9333 SetPrinterData if key is "PrinterDriverData" */
9336 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9337 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9341 if ( Printer->printer_type == SPLHND_SERVER ) {
9342 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9343 "Not implemented for server handles yet\n"));
9344 return WERR_INVALID_PARAM;
9347 if ( !get_printer_snum(p,handle, &snum, NULL) )
9351 * Access check : NT returns "access denied" if you make a
9352 * SetPrinterData call without the necessary privildge.
9353 * we were originally returning OK if nothing changed
9354 * which made Win2k issue **a lot** of SetPrinterData
9355 * when connecting to a printer --jerry
9358 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9360 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9361 "change denied by handle access permissions\n"));
9362 return WERR_ACCESS_DENIED;
9365 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9366 if (!W_ERROR_IS_OK(status))
9369 /* check for OID in valuename */
9371 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9377 /* save the registry data */
9379 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9380 r->in.type, r->in.buffer, r->in.offered );
9382 if ( W_ERROR_IS_OK(status) )
9384 /* save the OID if one was specified */
9386 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9387 r->in.key_name, SPOOL_OID_KEY);
9393 * I'm not checking the status here on purpose. Don't know
9394 * if this is right, but I'm returning the status from the
9395 * previous set_printer_dataex() call. I have no idea if
9396 * this is right. --jerry
9399 set_printer_dataex( printer, str, r->in.value_name,
9400 REG_SZ, (uint8 *)oid_string,
9401 strlen(oid_string)+1 );
9404 status = mod_a_printer(printer, 2);
9407 free_a_printer(&printer, 2);
9412 /****************************************************************
9413 _spoolss_DeletePrinterDataEx
9414 ****************************************************************/
9416 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9417 struct spoolss_DeletePrinterDataEx *r)
9419 POLICY_HND *handle = r->in.handle;
9420 NT_PRINTER_INFO_LEVEL *printer = NULL;
9422 WERROR status = WERR_OK;
9423 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9425 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9428 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9429 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9433 if (!get_printer_snum(p, handle, &snum, NULL))
9436 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9437 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9438 "printer properties change denied by handle\n"));
9439 return WERR_ACCESS_DENIED;
9442 if (!r->in.value_name || !r->in.key_name) {
9446 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9447 if (!W_ERROR_IS_OK(status))
9450 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9452 if ( W_ERROR_IS_OK(status) )
9453 mod_a_printer( printer, 2 );
9455 free_a_printer(&printer, 2);
9460 /********************************************************************
9461 * spoolss_enumprinterkey
9462 ********************************************************************/
9465 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9468 fstring *keynames = NULL;
9469 uint16 *enumkeys = NULL;
9472 POLICY_HND *handle = &q_u->handle;
9473 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9474 NT_PRINTER_DATA *data;
9475 NT_PRINTER_INFO_LEVEL *printer = NULL;
9477 WERROR status = WERR_BADFILE;
9480 DEBUG(4,("_spoolss_enumprinterkey\n"));
9483 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9487 if ( !get_printer_snum(p,handle, &snum, NULL) )
9490 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9491 if (!W_ERROR_IS_OK(status))
9494 /* get the list of subkey names */
9496 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9497 data = printer->info_2->data;
9499 num_keys = get_printer_subkeys( data, key, &keynames );
9501 if ( num_keys == -1 ) {
9502 status = WERR_BADFILE;
9506 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9508 r_u->needed = printerkey_len*2;
9510 if ( q_u->size < r_u->needed ) {
9511 status = WERR_MORE_DATA;
9515 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9516 status = WERR_NOMEM;
9522 if ( q_u->size < r_u->needed )
9523 status = WERR_MORE_DATA;
9526 free_a_printer( &printer, 2 );
9527 SAFE_FREE( keynames );
9532 /****************************************************************
9533 _spoolss_DeletePrinterKey
9534 ****************************************************************/
9536 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9537 struct spoolss_DeletePrinterKey *r)
9539 POLICY_HND *handle = r->in.handle;
9540 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9541 NT_PRINTER_INFO_LEVEL *printer = NULL;
9545 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9548 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9549 OUR_HANDLE(handle)));
9553 /* if keyname == NULL, return error */
9555 if ( !r->in.key_name )
9556 return WERR_INVALID_PARAM;
9558 if (!get_printer_snum(p, handle, &snum, NULL))
9561 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9562 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9563 "printer properties change denied by handle\n"));
9564 return WERR_ACCESS_DENIED;
9567 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9568 if (!W_ERROR_IS_OK(status))
9571 /* delete the key and all subneys */
9573 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9575 if ( W_ERROR_IS_OK(status) )
9576 status = mod_a_printer(printer, 2);
9578 free_a_printer( &printer, 2 );
9584 /********************************************************************
9585 * spoolss_enumprinterdataex
9586 ********************************************************************/
9588 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9590 POLICY_HND *handle = &q_u->handle;
9591 uint32 in_size = q_u->size;
9594 NT_PRINTER_INFO_LEVEL *printer = NULL;
9595 PRINTER_ENUM_VALUES *enum_values = NULL;
9596 NT_PRINTER_DATA *p_data;
9598 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9603 REGISTRY_VALUE *val;
9608 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9611 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9616 * first check for a keyname of NULL or "". Win2k seems to send
9617 * this a lot and we should send back WERR_INVALID_PARAM
9618 * no need to spend time looking up the printer in this case.
9622 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9623 if ( !strlen(key) ) {
9624 result = WERR_INVALID_PARAM;
9628 /* get the printer off of disk */
9630 if (!get_printer_snum(p,handle, &snum, NULL))
9633 ZERO_STRUCT(printer);
9634 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9635 if (!W_ERROR_IS_OK(result))
9638 /* now look for a match on the key name */
9640 p_data = printer->info_2->data;
9642 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9643 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9645 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9646 result = WERR_INVALID_PARAM;
9653 /* allocate the memory for the array of pointers -- if necessary */
9655 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9658 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9660 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9661 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9662 result = WERR_NOMEM;
9666 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9670 * loop through all params and build the array to pass
9671 * back to the client
9674 for ( i=0; i<num_entries; i++ )
9676 /* lookup the registry value */
9678 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9679 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9683 value_name = regval_name( val );
9684 init_unistr( &enum_values[i].valuename, value_name );
9685 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9686 enum_values[i].type = regval_type( val );
9688 data_len = regval_size( val );
9690 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9692 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9694 result = WERR_NOMEM;
9698 enum_values[i].data_len = data_len;
9700 /* keep track of the size of the array in bytes */
9702 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9705 /* housekeeping information in the reply */
9707 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9708 * the hand marshalled container size is a multiple
9709 * of 4 bytes for RPC alignment.
9713 needed += 4-(needed % 4);
9716 r_u->needed = needed;
9717 r_u->returned = num_entries;
9719 if (needed > in_size) {
9720 result = WERR_MORE_DATA;
9724 /* copy data into the reply */
9726 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9727 response buffer size is != the offered buffer size
9729 r_u->ctr.size = r_u->needed;
9731 r_u->ctr.size = in_size;
9733 r_u->ctr.size_of_array = r_u->returned;
9734 r_u->ctr.values = enum_values;
9738 free_a_printer(&printer, 2);
9743 /****************************************************************************
9744 ****************************************************************************/
9746 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9747 const char *servername,
9748 const char *environment,
9749 struct spoolss_PrintProcessorDirectoryInfo1 *r,
9756 werr = compose_spoolss_server_path(mem_ctx,
9759 SPOOLSS_PRTPROCS_PATH,
9761 if (!W_ERROR_IS_OK(werr)) {
9765 DEBUG(4,("print processor directory: [%s]\n", path));
9767 r->directory_name = path;
9769 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
9771 if (*needed > offered) {
9773 return WERR_INSUFFICIENT_BUFFER;
9779 /****************************************************************
9780 _spoolss_GetPrintProcessorDirectory
9781 ****************************************************************/
9783 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9784 struct spoolss_GetPrintProcessorDirectory *r)
9788 /* that's an [in out] buffer */
9790 if (!r->in.buffer && (r->in.offered != 0)) {
9791 return WERR_INVALID_PARAM;
9794 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9799 /* r->in.level is ignored */
9801 result = getprintprocessordirectory_level_1(p->mem_ctx,
9804 &r->out.info->info1,
9807 if (!W_ERROR_IS_OK(result)) {
9808 TALLOC_FREE(r->out.info);
9814 /*******************************************************************
9815 ********************************************************************/
9817 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9818 const char *dllname)
9820 enum ndr_err_code ndr_err;
9821 struct spoolss_MonitorUi ui;
9823 ui.dll_name = dllname;
9825 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9826 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9827 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9828 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9830 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9833 /*******************************************************************
9834 Streams the monitor UI DLL name in UNICODE
9835 *******************************************************************/
9837 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9838 NT_USER_TOKEN *token, DATA_BLOB *in,
9839 DATA_BLOB *out, uint32_t *needed)
9841 const char *dllname = "tcpmonui.dll";
9843 *needed = (strlen(dllname)+1) * 2;
9845 if (out->length < *needed) {
9846 return WERR_INSUFFICIENT_BUFFER;
9849 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9856 /*******************************************************************
9857 ********************************************************************/
9859 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9860 struct spoolss_PortData1 *port1,
9861 const DATA_BLOB *buf)
9863 enum ndr_err_code ndr_err;
9864 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9865 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9866 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9867 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9869 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9872 /*******************************************************************
9873 ********************************************************************/
9875 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9876 struct spoolss_PortData2 *port2,
9877 const DATA_BLOB *buf)
9879 enum ndr_err_code ndr_err;
9880 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9881 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9882 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9883 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9885 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9888 /*******************************************************************
9889 Create a new TCP/IP port
9890 *******************************************************************/
9892 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9893 NT_USER_TOKEN *token, DATA_BLOB *in,
9894 DATA_BLOB *out, uint32_t *needed)
9896 struct spoolss_PortData1 port1;
9897 struct spoolss_PortData2 port2;
9898 char *device_uri = NULL;
9901 const char *portname;
9902 const char *hostaddress;
9904 uint32_t port_number;
9907 /* peek for spoolss_PortData version */
9909 if (!in || (in->length < (128 + 4))) {
9910 return WERR_GENERAL_FAILURE;
9913 version = IVAL(in->data, 128);
9919 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9923 portname = port1.portname;
9924 hostaddress = port1.hostaddress;
9925 queue = port1.queue;
9926 protocol = port1.protocol;
9927 port_number = port1.port_number;
9933 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9937 portname = port2.portname;
9938 hostaddress = port2.hostaddress;
9939 queue = port2.queue;
9940 protocol = port2.protocol;
9941 port_number = port2.port_number;
9945 DEBUG(1,("xcvtcp_addport: "
9946 "unknown version of port_data: %d\n", version));
9947 return WERR_UNKNOWN_PORT;
9950 /* create the device URI and call the add_port_hook() */
9953 case PROTOCOL_RAWTCP_TYPE:
9954 device_uri = talloc_asprintf(mem_ctx,
9955 "socket://%s:%d/", hostaddress,
9959 case PROTOCOL_LPR_TYPE:
9960 device_uri = talloc_asprintf(mem_ctx,
9961 "lpr://%s/%s", hostaddress, queue );
9965 return WERR_UNKNOWN_PORT;
9972 return add_port_hook(mem_ctx, token, portname, device_uri);
9975 /*******************************************************************
9976 *******************************************************************/
9978 struct xcv_api_table xcvtcp_cmds[] = {
9979 { "MonitorUI", xcvtcp_monitorui },
9980 { "AddPort", xcvtcp_addport},
9984 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9985 NT_USER_TOKEN *token, const char *command,
9992 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9994 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9995 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9996 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9999 return WERR_BADFUNC;
10002 /*******************************************************************
10003 *******************************************************************/
10004 #if 0 /* don't support management using the "Local Port" monitor */
10006 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10007 NT_USER_TOKEN *token, DATA_BLOB *in,
10008 DATA_BLOB *out, uint32_t *needed)
10010 const char *dllname = "localui.dll";
10012 *needed = (strlen(dllname)+1) * 2;
10014 if (out->length < *needed) {
10015 return WERR_INSUFFICIENT_BUFFER;
10018 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10025 /*******************************************************************
10026 *******************************************************************/
10028 struct xcv_api_table xcvlocal_cmds[] = {
10029 { "MonitorUI", xcvlocal_monitorui },
10033 struct xcv_api_table xcvlocal_cmds[] = {
10040 /*******************************************************************
10041 *******************************************************************/
10043 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10044 NT_USER_TOKEN *token, const char *command,
10045 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10050 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10052 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10053 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10054 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10056 return WERR_BADFUNC;
10059 /****************************************************************
10061 ****************************************************************/
10063 WERROR _spoolss_XcvData(pipes_struct *p,
10064 struct spoolss_XcvData *r)
10066 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10067 DATA_BLOB out_data = data_blob_null;
10071 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10072 OUR_HANDLE(r->in.handle)));
10073 return WERR_BADFID;
10076 /* Has to be a handle to the TCP/IP port monitor */
10078 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10079 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10080 return WERR_BADFID;
10083 /* requires administrative access to the server */
10085 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10086 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10087 return WERR_ACCESS_DENIED;
10090 /* Allocate the outgoing buffer */
10092 if (r->in.out_data_size) {
10093 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10094 if (out_data.data == NULL) {
10099 switch ( Printer->printer_type ) {
10100 case SPLHND_PORTMON_TCP:
10101 werror = process_xcvtcp_command(p->mem_ctx,
10102 p->server_info->ptok,
10103 r->in.function_name,
10104 &r->in.in_data, &out_data,
10107 case SPLHND_PORTMON_LOCAL:
10108 werror = process_xcvlocal_command(p->mem_ctx,
10109 p->server_info->ptok,
10110 r->in.function_name,
10111 &r->in.in_data, &out_data,
10115 werror = WERR_INVALID_PRINT_MONITOR;
10118 if (!W_ERROR_IS_OK(werror)) {
10122 *r->out.status_code = 0;
10124 memcpy(r->out.out_data, out_data.data, out_data.length);
10129 /****************************************************************
10130 _spoolss_AddPrintProcessor
10131 ****************************************************************/
10133 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10134 struct spoolss_AddPrintProcessor *r)
10136 /* for now, just indicate success and ignore the add. We'll
10137 automatically set the winprint processor for printer
10138 entries later. Used to debug the LexMark Optra S 1855 PCL
10144 /****************************************************************
10145 _spoolss_EnumPrinters
10146 ****************************************************************/
10148 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10149 struct spoolss_EnumPrinters *r)
10151 p->rng_fault_state = true;
10152 return WERR_NOT_SUPPORTED;
10155 /****************************************************************
10157 ****************************************************************/
10159 WERROR _spoolss_GetJob(pipes_struct *p,
10160 struct spoolss_GetJob *r)
10162 p->rng_fault_state = true;
10163 return WERR_NOT_SUPPORTED;
10166 /****************************************************************
10168 ****************************************************************/
10170 WERROR _spoolss_EnumJobs(pipes_struct *p,
10171 struct spoolss_EnumJobs *r)
10173 p->rng_fault_state = true;
10174 return WERR_NOT_SUPPORTED;
10177 /****************************************************************
10178 _spoolss_AddPrinter
10179 ****************************************************************/
10181 WERROR _spoolss_AddPrinter(pipes_struct *p,
10182 struct spoolss_AddPrinter *r)
10184 p->rng_fault_state = true;
10185 return WERR_NOT_SUPPORTED;
10188 /****************************************************************
10189 _spoolss_GetPrinter
10190 ****************************************************************/
10192 WERROR _spoolss_GetPrinter(pipes_struct *p,
10193 struct spoolss_GetPrinter *r)
10195 p->rng_fault_state = true;
10196 return WERR_NOT_SUPPORTED;
10199 /****************************************************************
10200 _spoolss_EnumPrinterDrivers
10201 ****************************************************************/
10203 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10204 struct spoolss_EnumPrinterDrivers *r)
10206 p->rng_fault_state = true;
10207 return WERR_NOT_SUPPORTED;
10210 /****************************************************************
10211 _spoolss_GetPrinterDriver
10212 ****************************************************************/
10214 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10215 struct spoolss_GetPrinterDriver *r)
10217 p->rng_fault_state = true;
10218 return WERR_NOT_SUPPORTED;
10221 /****************************************************************
10222 _spoolss_EnumPrintProcessors
10223 ****************************************************************/
10225 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10226 struct spoolss_EnumPrintProcessors *r)
10228 p->rng_fault_state = true;
10229 return WERR_NOT_SUPPORTED;
10232 /****************************************************************
10233 _spoolss_ReadPrinter
10234 ****************************************************************/
10236 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10237 struct spoolss_ReadPrinter *r)
10239 p->rng_fault_state = true;
10240 return WERR_NOT_SUPPORTED;
10243 /****************************************************************
10244 _spoolss_GetPrinterData
10245 ****************************************************************/
10247 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10248 struct spoolss_GetPrinterData *r)
10250 p->rng_fault_state = true;
10251 return WERR_NOT_SUPPORTED;
10254 /****************************************************************
10255 _spoolss_SetPrinterData
10256 ****************************************************************/
10258 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10259 struct spoolss_SetPrinterData *r)
10261 p->rng_fault_state = true;
10262 return WERR_NOT_SUPPORTED;
10265 /****************************************************************
10266 _spoolss_WaitForPrinterChange
10267 ****************************************************************/
10269 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10270 struct spoolss_WaitForPrinterChange *r)
10272 p->rng_fault_state = true;
10273 return WERR_NOT_SUPPORTED;
10276 /****************************************************************
10278 ****************************************************************/
10280 WERROR _spoolss_EnumPorts(pipes_struct *p,
10281 struct spoolss_EnumPorts *r)
10283 p->rng_fault_state = true;
10284 return WERR_NOT_SUPPORTED;
10287 /****************************************************************
10288 _spoolss_EnumMonitors
10289 ****************************************************************/
10291 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10292 struct spoolss_EnumMonitors *r)
10294 p->rng_fault_state = true;
10295 return WERR_NOT_SUPPORTED;
10298 /****************************************************************
10300 ****************************************************************/
10302 WERROR _spoolss_AddPort(pipes_struct *p,
10303 struct spoolss_AddPort *r)
10305 p->rng_fault_state = true;
10306 return WERR_NOT_SUPPORTED;
10309 /****************************************************************
10310 _spoolss_ConfigurePort
10311 ****************************************************************/
10313 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10314 struct spoolss_ConfigurePort *r)
10316 p->rng_fault_state = true;
10317 return WERR_NOT_SUPPORTED;
10320 /****************************************************************
10321 _spoolss_DeletePort
10322 ****************************************************************/
10324 WERROR _spoolss_DeletePort(pipes_struct *p,
10325 struct spoolss_DeletePort *r)
10327 p->rng_fault_state = true;
10328 return WERR_NOT_SUPPORTED;
10331 /****************************************************************
10332 _spoolss_CreatePrinterIC
10333 ****************************************************************/
10335 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10336 struct spoolss_CreatePrinterIC *r)
10338 p->rng_fault_state = true;
10339 return WERR_NOT_SUPPORTED;
10342 /****************************************************************
10343 _spoolss_PlayGDIScriptOnPrinterIC
10344 ****************************************************************/
10346 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10347 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10349 p->rng_fault_state = true;
10350 return WERR_NOT_SUPPORTED;
10353 /****************************************************************
10354 _spoolss_DeletePrinterIC
10355 ****************************************************************/
10357 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10358 struct spoolss_DeletePrinterIC *r)
10360 p->rng_fault_state = true;
10361 return WERR_NOT_SUPPORTED;
10364 /****************************************************************
10365 _spoolss_AddPrinterConnection
10366 ****************************************************************/
10368 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10369 struct spoolss_AddPrinterConnection *r)
10371 p->rng_fault_state = true;
10372 return WERR_NOT_SUPPORTED;
10375 /****************************************************************
10376 _spoolss_DeletePrinterConnection
10377 ****************************************************************/
10379 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10380 struct spoolss_DeletePrinterConnection *r)
10382 p->rng_fault_state = true;
10383 return WERR_NOT_SUPPORTED;
10386 /****************************************************************
10387 _spoolss_PrinterMessageBox
10388 ****************************************************************/
10390 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10391 struct spoolss_PrinterMessageBox *r)
10393 p->rng_fault_state = true;
10394 return WERR_NOT_SUPPORTED;
10397 /****************************************************************
10398 _spoolss_AddMonitor
10399 ****************************************************************/
10401 WERROR _spoolss_AddMonitor(pipes_struct *p,
10402 struct spoolss_AddMonitor *r)
10404 p->rng_fault_state = true;
10405 return WERR_NOT_SUPPORTED;
10408 /****************************************************************
10409 _spoolss_DeleteMonitor
10410 ****************************************************************/
10412 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10413 struct spoolss_DeleteMonitor *r)
10415 p->rng_fault_state = true;
10416 return WERR_NOT_SUPPORTED;
10419 /****************************************************************
10420 _spoolss_DeletePrintProcessor
10421 ****************************************************************/
10423 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10424 struct spoolss_DeletePrintProcessor *r)
10426 p->rng_fault_state = true;
10427 return WERR_NOT_SUPPORTED;
10430 /****************************************************************
10431 _spoolss_AddPrintProvidor
10432 ****************************************************************/
10434 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10435 struct spoolss_AddPrintProvidor *r)
10437 p->rng_fault_state = true;
10438 return WERR_NOT_SUPPORTED;
10441 /****************************************************************
10442 _spoolss_DeletePrintProvidor
10443 ****************************************************************/
10445 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10446 struct spoolss_DeletePrintProvidor *r)
10448 p->rng_fault_state = true;
10449 return WERR_NOT_SUPPORTED;
10452 /****************************************************************
10453 _spoolss_EnumPrintProcDataTypes
10454 ****************************************************************/
10456 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10457 struct spoolss_EnumPrintProcDataTypes *r)
10459 p->rng_fault_state = true;
10460 return WERR_NOT_SUPPORTED;
10463 /****************************************************************
10464 _spoolss_GetPrinterDriver2
10465 ****************************************************************/
10467 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10468 struct spoolss_GetPrinterDriver2 *r)
10470 p->rng_fault_state = true;
10471 return WERR_NOT_SUPPORTED;
10474 /****************************************************************
10475 _spoolss_FindFirstPrinterChangeNotification
10476 ****************************************************************/
10478 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10479 struct spoolss_FindFirstPrinterChangeNotification *r)
10481 p->rng_fault_state = true;
10482 return WERR_NOT_SUPPORTED;
10485 /****************************************************************
10486 _spoolss_FindNextPrinterChangeNotification
10487 ****************************************************************/
10489 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10490 struct spoolss_FindNextPrinterChangeNotification *r)
10492 p->rng_fault_state = true;
10493 return WERR_NOT_SUPPORTED;
10496 /****************************************************************
10497 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10498 ****************************************************************/
10500 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10501 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10503 p->rng_fault_state = true;
10504 return WERR_NOT_SUPPORTED;
10507 /****************************************************************
10508 _spoolss_ReplyOpenPrinter
10509 ****************************************************************/
10511 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10512 struct spoolss_ReplyOpenPrinter *r)
10514 p->rng_fault_state = true;
10515 return WERR_NOT_SUPPORTED;
10518 /****************************************************************
10519 _spoolss_RouterReplyPrinter
10520 ****************************************************************/
10522 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10523 struct spoolss_RouterReplyPrinter *r)
10525 p->rng_fault_state = true;
10526 return WERR_NOT_SUPPORTED;
10529 /****************************************************************
10530 _spoolss_ReplyClosePrinter
10531 ****************************************************************/
10533 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10534 struct spoolss_ReplyClosePrinter *r)
10536 p->rng_fault_state = true;
10537 return WERR_NOT_SUPPORTED;
10540 /****************************************************************
10542 ****************************************************************/
10544 WERROR _spoolss_AddPortEx(pipes_struct *p,
10545 struct spoolss_AddPortEx *r)
10547 p->rng_fault_state = true;
10548 return WERR_NOT_SUPPORTED;
10551 /****************************************************************
10552 _spoolss_RouterFindFirstPrinterChangeNotification
10553 ****************************************************************/
10555 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10556 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10558 p->rng_fault_state = true;
10559 return WERR_NOT_SUPPORTED;
10562 /****************************************************************
10563 _spoolss_SpoolerInit
10564 ****************************************************************/
10566 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10567 struct spoolss_SpoolerInit *r)
10569 p->rng_fault_state = true;
10570 return WERR_NOT_SUPPORTED;
10573 /****************************************************************
10574 _spoolss_ResetPrinterEx
10575 ****************************************************************/
10577 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10578 struct spoolss_ResetPrinterEx *r)
10580 p->rng_fault_state = true;
10581 return WERR_NOT_SUPPORTED;
10584 /****************************************************************
10585 _spoolss_RouterReplyPrinterEx
10586 ****************************************************************/
10588 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10589 struct spoolss_RouterReplyPrinterEx *r)
10591 p->rng_fault_state = true;
10592 return WERR_NOT_SUPPORTED;
10595 /****************************************************************
10597 ****************************************************************/
10599 WERROR _spoolss_44(pipes_struct *p,
10600 struct spoolss_44 *r)
10602 p->rng_fault_state = true;
10603 return WERR_NOT_SUPPORTED;
10606 /****************************************************************
10608 ****************************************************************/
10610 WERROR _spoolss_47(pipes_struct *p,
10611 struct spoolss_47 *r)
10613 p->rng_fault_state = true;
10614 return WERR_NOT_SUPPORTED;
10617 /****************************************************************
10618 _spoolss_EnumPrinterData
10619 ****************************************************************/
10621 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10622 struct spoolss_EnumPrinterData *r)
10624 p->rng_fault_state = true;
10625 return WERR_NOT_SUPPORTED;
10628 /****************************************************************
10630 ****************************************************************/
10632 WERROR _spoolss_4a(pipes_struct *p,
10633 struct spoolss_4a *r)
10635 p->rng_fault_state = true;
10636 return WERR_NOT_SUPPORTED;
10639 /****************************************************************
10641 ****************************************************************/
10643 WERROR _spoolss_4b(pipes_struct *p,
10644 struct spoolss_4b *r)
10646 p->rng_fault_state = true;
10647 return WERR_NOT_SUPPORTED;
10650 /****************************************************************
10652 ****************************************************************/
10654 WERROR _spoolss_4c(pipes_struct *p,
10655 struct spoolss_4c *r)
10657 p->rng_fault_state = true;
10658 return WERR_NOT_SUPPORTED;
10661 /****************************************************************
10662 _spoolss_EnumPrinterDataEx
10663 ****************************************************************/
10665 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10666 struct spoolss_EnumPrinterDataEx *r)
10668 p->rng_fault_state = true;
10669 return WERR_NOT_SUPPORTED;
10672 /****************************************************************
10673 _spoolss_EnumPrinterKey
10674 ****************************************************************/
10676 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10677 struct spoolss_EnumPrinterKey *r)
10679 p->rng_fault_state = true;
10680 return WERR_NOT_SUPPORTED;
10683 /****************************************************************
10685 ****************************************************************/
10687 WERROR _spoolss_53(pipes_struct *p,
10688 struct spoolss_53 *r)
10690 p->rng_fault_state = true;
10691 return WERR_NOT_SUPPORTED;
10694 /****************************************************************
10696 ****************************************************************/
10698 WERROR _spoolss_55(pipes_struct *p,
10699 struct spoolss_55 *r)
10701 p->rng_fault_state = true;
10702 return WERR_NOT_SUPPORTED;
10705 /****************************************************************
10707 ****************************************************************/
10709 WERROR _spoolss_56(pipes_struct *p,
10710 struct spoolss_56 *r)
10712 p->rng_fault_state = true;
10713 return WERR_NOT_SUPPORTED;
10716 /****************************************************************
10718 ****************************************************************/
10720 WERROR _spoolss_57(pipes_struct *p,
10721 struct spoolss_57 *r)
10723 p->rng_fault_state = true;
10724 return WERR_NOT_SUPPORTED;
10727 /****************************************************************
10729 ****************************************************************/
10731 WERROR _spoolss_5a(pipes_struct *p,
10732 struct spoolss_5a *r)
10734 p->rng_fault_state = true;
10735 return WERR_NOT_SUPPORTED;
10738 /****************************************************************
10740 ****************************************************************/
10742 WERROR _spoolss_5b(pipes_struct *p,
10743 struct spoolss_5b *r)
10745 p->rng_fault_state = true;
10746 return WERR_NOT_SUPPORTED;
10749 /****************************************************************
10751 ****************************************************************/
10753 WERROR _spoolss_5c(pipes_struct *p,
10754 struct spoolss_5c *r)
10756 p->rng_fault_state = true;
10757 return WERR_NOT_SUPPORTED;
10760 /****************************************************************
10762 ****************************************************************/
10764 WERROR _spoolss_5d(pipes_struct *p,
10765 struct spoolss_5d *r)
10767 p->rng_fault_state = true;
10768 return WERR_NOT_SUPPORTED;
10771 /****************************************************************
10773 ****************************************************************/
10775 WERROR _spoolss_5e(pipes_struct *p,
10776 struct spoolss_5e *r)
10778 p->rng_fault_state = true;
10779 return WERR_NOT_SUPPORTED;
10782 /****************************************************************
10784 ****************************************************************/
10786 WERROR _spoolss_5f(pipes_struct *p,
10787 struct spoolss_5f *r)
10789 p->rng_fault_state = true;
10790 return WERR_NOT_SUPPORTED;