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 fill_print_processor1
8735 ****************************************************************************/
8737 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8738 struct spoolss_PrintProcessorInfo1 *r,
8739 const char *print_processor_name)
8741 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8742 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8747 /****************************************************************************
8748 enumprintprocessors level 1.
8749 ****************************************************************************/
8751 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8752 union spoolss_PrintProcessorInfo **info_p,
8757 union spoolss_PrintProcessorInfo *info;
8760 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8761 W_ERROR_HAVE_NO_MEMORY(info);
8765 result = fill_print_processor1(info, &info[0].info1, "winprint");
8766 if (!W_ERROR_IS_OK(result)) {
8770 *needed += ndr_size_spoolss_PrintProcessorInfo1(&info[0].info1, NULL, 0);
8772 if (*needed > offered) {
8773 result = WERR_INSUFFICIENT_BUFFER;
8778 if (!W_ERROR_IS_OK(result)) {
8789 /****************************************************************
8790 _spoolss_EnumPrintProcessors
8791 ****************************************************************/
8793 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8794 struct spoolss_EnumPrintProcessors *r)
8796 /* that's an [in out] buffer */
8798 if (!r->in.buffer && (r->in.offered != 0)) {
8799 return WERR_INVALID_PARAM;
8802 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8805 * Enumerate the print processors ...
8807 * Just reply with "winprint", to keep NT happy
8808 * and I can use my nice printer checker.
8813 *r->out.info = NULL;
8815 switch (r->in.level) {
8817 return enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8818 r->in.offered, r->out.needed,
8821 return WERR_UNKNOWN_LEVEL;
8825 /****************************************************************************
8826 fill_printprocdatatype1
8827 ****************************************************************************/
8829 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8830 struct spoolss_PrintProcDataTypesInfo1 *r,
8831 const char *name_array)
8833 r->name_array = talloc_strdup(mem_ctx, name_array);
8834 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8839 /****************************************************************************
8840 enumprintprocdatatypes level 1.
8841 ****************************************************************************/
8843 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8844 union spoolss_PrintProcDataTypesInfo **info_p,
8850 union spoolss_PrintProcDataTypesInfo *info;
8852 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8853 W_ERROR_HAVE_NO_MEMORY(info);
8857 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8858 if (!W_ERROR_IS_OK(result)) {
8862 *needed += ndr_size_spoolss_PrintProcDataTypesInfo1(&info[0].info1, NULL, 0);
8864 if (*needed > offered) {
8865 result = WERR_INSUFFICIENT_BUFFER;
8870 if (!W_ERROR_IS_OK(result)) {
8881 /****************************************************************
8882 _spoolss_EnumPrintProcDataTypes
8883 ****************************************************************/
8885 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8886 struct spoolss_EnumPrintProcDataTypes *r)
8888 /* that's an [in out] buffer */
8890 if (!r->in.buffer && (r->in.offered != 0)) {
8891 return WERR_INVALID_PARAM;
8894 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8898 *r->out.info = NULL;
8900 switch (r->in.level) {
8902 return enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8903 r->in.offered, r->out.needed,
8906 return WERR_UNKNOWN_LEVEL;
8910 /****************************************************************************
8911 enumprintmonitors level 1.
8912 ****************************************************************************/
8914 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8916 PRINTMONITOR_1 *info_1;
8917 WERROR result = WERR_OK;
8920 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8925 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8926 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8928 for ( i=0; i<*returned; i++ ) {
8929 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8932 if (*needed > offered) {
8933 result = WERR_INSUFFICIENT_BUFFER;
8937 if (!rpcbuf_alloc_size(buffer, *needed)) {
8938 result = WERR_NOMEM;
8942 for ( i=0; i<*returned; i++ ) {
8943 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8949 if ( !W_ERROR_IS_OK(result) )
8955 /****************************************************************************
8956 enumprintmonitors level 2.
8957 ****************************************************************************/
8959 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8961 PRINTMONITOR_2 *info_2;
8962 WERROR result = WERR_OK;
8965 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8970 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8971 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8972 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8974 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8975 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8976 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8978 for ( i=0; i<*returned; i++ ) {
8979 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8982 if (*needed > offered) {
8983 result = WERR_INSUFFICIENT_BUFFER;
8987 if (!rpcbuf_alloc_size(buffer, *needed)) {
8988 result = WERR_NOMEM;
8992 for ( i=0; i<*returned; i++ ) {
8993 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8999 if ( !W_ERROR_IS_OK(result) )
9005 /****************************************************************************
9006 ****************************************************************************/
9008 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
9010 uint32 level = q_u->level;
9011 RPC_BUFFER *buffer = NULL;
9012 uint32 offered = q_u->offered;
9013 uint32 *needed = &r_u->needed;
9014 uint32 *returned = &r_u->returned;
9016 /* that's an [in out] buffer */
9018 if (!q_u->buffer && (offered!=0)) {
9019 return WERR_INVALID_PARAM;
9022 if (offered > MAX_RPC_DATA_SIZE) {
9023 return WERR_INVALID_PARAM;
9026 rpcbuf_move(q_u->buffer, &r_u->buffer);
9027 buffer = r_u->buffer;
9029 DEBUG(5,("spoolss_enumprintmonitors\n"));
9032 * Enumerate the print monitors ...
9034 * Just reply with "Local Port", to keep NT happy
9035 * and I can use my nice printer checker.
9043 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9045 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9047 return WERR_UNKNOWN_LEVEL;
9051 /****************************************************************************
9052 ****************************************************************************/
9054 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9055 NT_PRINTER_INFO_LEVEL *ntprinter,
9056 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9061 JOB_INFO_1 *info_1=NULL;
9062 WERROR result = WERR_OK;
9064 info_1=SMB_MALLOC_P(JOB_INFO_1);
9066 if (info_1 == NULL) {
9070 for (i=0; i<count && found==False; i++) {
9071 if ((*queue)[i].job==(int)jobid)
9077 /* NT treats not found as bad param... yet another bad choice */
9078 return WERR_INVALID_PARAM;
9081 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9083 *needed += spoolss_size_job_info_1(info_1);
9085 if (*needed > offered) {
9086 result = WERR_INSUFFICIENT_BUFFER;
9090 if (!rpcbuf_alloc_size(buffer, *needed)) {
9091 result = WERR_NOMEM;
9095 smb_io_job_info_1("", buffer, info_1, 0);
9103 /****************************************************************************
9104 ****************************************************************************/
9106 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9107 NT_PRINTER_INFO_LEVEL *ntprinter,
9108 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9115 DEVICEMODE *devmode = NULL;
9116 NT_DEVICEMODE *nt_devmode = NULL;
9118 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9121 ZERO_STRUCTP(info_2);
9123 for ( i=0; i<count && found==False; i++ )
9125 if ((*queue)[i].job == (int)jobid)
9130 /* NT treats not found as bad param... yet another bad
9132 result = WERR_INVALID_PARAM;
9137 * if the print job does not have a DEVMODE associated with it,
9138 * just use the one for the printer. A NULL devicemode is not
9139 * a failure condition
9142 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9143 devmode = construct_dev_mode(lp_const_servicename(snum));
9145 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9146 ZERO_STRUCTP( devmode );
9147 convert_nt_devicemode( devmode, nt_devmode );
9151 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9153 *needed += spoolss_size_job_info_2(info_2);
9155 if (*needed > offered) {
9156 result = WERR_INSUFFICIENT_BUFFER;
9160 if (!rpcbuf_alloc_size(buffer, *needed)) {
9161 result = WERR_NOMEM;
9165 smb_io_job_info_2("", buffer, info_2, 0);
9170 /* Cleanup allocated memory */
9172 free_job_info_2(info_2); /* Also frees devmode */
9178 /****************************************************************************
9179 ****************************************************************************/
9181 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9183 POLICY_HND *handle = &q_u->handle;
9184 uint32 jobid = q_u->jobid;
9185 uint32 level = q_u->level;
9186 RPC_BUFFER *buffer = NULL;
9187 uint32 offered = q_u->offered;
9188 uint32 *needed = &r_u->needed;
9189 WERROR wstatus = WERR_OK;
9190 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9193 print_queue_struct *queue = NULL;
9194 print_status_struct prt_status;
9196 /* that's an [in out] buffer */
9198 if (!q_u->buffer && (offered!=0)) {
9199 return WERR_INVALID_PARAM;
9202 if (offered > MAX_RPC_DATA_SIZE) {
9203 return WERR_INVALID_PARAM;
9206 rpcbuf_move(q_u->buffer, &r_u->buffer);
9207 buffer = r_u->buffer;
9209 DEBUG(5,("spoolss_getjob\n"));
9213 if (!get_printer_snum(p, handle, &snum, NULL))
9216 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9217 if ( !W_ERROR_IS_OK(wstatus) )
9220 count = print_queue_status(snum, &queue, &prt_status);
9222 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9223 count, prt_status.status, prt_status.message));
9227 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9228 buffer, offered, needed);
9231 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9232 buffer, offered, needed);
9235 wstatus = WERR_UNKNOWN_LEVEL;
9240 free_a_printer( &ntprinter, 2 );
9245 /****************************************************************
9246 _spoolss_GetPrinterDataEx
9248 From MSDN documentation of GetPrinterDataEx: pass request
9249 to GetPrinterData if key is "PrinterDriverData".
9250 ****************************************************************/
9252 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9253 struct spoolss_GetPrinterDataEx *r)
9255 POLICY_HND *handle = r->in.handle;
9257 const char *keyname = r->in.key_name;
9258 const char *valuename = r->in.value_name;
9260 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9262 NT_PRINTER_INFO_LEVEL *printer = NULL;
9264 WERROR status = WERR_OK;
9266 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9268 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9269 keyname, valuename));
9271 /* in case of problem, return some default values */
9277 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9278 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9279 status = WERR_BADFID;
9283 /* Is the handle to a printer or to the server? */
9285 if (Printer->printer_type == SPLHND_SERVER) {
9286 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9287 "Not implemented for server handles yet\n"));
9288 status = WERR_INVALID_PARAM;
9292 if ( !get_printer_snum(p,handle, &snum, NULL) )
9295 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9296 if ( !W_ERROR_IS_OK(status) )
9299 /* check to see if the keyname is valid */
9300 if ( !strlen(keyname) ) {
9301 status = WERR_INVALID_PARAM;
9305 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9306 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9307 "Invalid keyname [%s]\n", keyname ));
9308 free_a_printer( &printer, 2 );
9309 status = WERR_BADFILE;
9313 /* When given a new keyname, we should just create it */
9315 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9316 r->out.type, &data, r->out.needed,
9319 if (*r->out.needed > r->in.offered) {
9320 status = WERR_MORE_DATA;
9323 if (W_ERROR_IS_OK(status)) {
9324 memcpy(r->out.buffer, data, r->in.offered);
9329 free_a_printer( &printer, 2 );
9334 /****************************************************************
9335 _spoolss_SetPrinterDataEx
9336 ****************************************************************/
9338 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9339 struct spoolss_SetPrinterDataEx *r)
9341 POLICY_HND *handle = r->in.handle;
9342 NT_PRINTER_INFO_LEVEL *printer = NULL;
9344 WERROR status = WERR_OK;
9345 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9348 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9350 /* From MSDN documentation of SetPrinterDataEx: pass request to
9351 SetPrinterData if key is "PrinterDriverData" */
9354 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9355 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9359 if ( Printer->printer_type == SPLHND_SERVER ) {
9360 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9361 "Not implemented for server handles yet\n"));
9362 return WERR_INVALID_PARAM;
9365 if ( !get_printer_snum(p,handle, &snum, NULL) )
9369 * Access check : NT returns "access denied" if you make a
9370 * SetPrinterData call without the necessary privildge.
9371 * we were originally returning OK if nothing changed
9372 * which made Win2k issue **a lot** of SetPrinterData
9373 * when connecting to a printer --jerry
9376 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9378 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9379 "change denied by handle access permissions\n"));
9380 return WERR_ACCESS_DENIED;
9383 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9384 if (!W_ERROR_IS_OK(status))
9387 /* check for OID in valuename */
9389 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9395 /* save the registry data */
9397 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9398 r->in.type, r->in.buffer, r->in.offered );
9400 if ( W_ERROR_IS_OK(status) )
9402 /* save the OID if one was specified */
9404 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9405 r->in.key_name, SPOOL_OID_KEY);
9411 * I'm not checking the status here on purpose. Don't know
9412 * if this is right, but I'm returning the status from the
9413 * previous set_printer_dataex() call. I have no idea if
9414 * this is right. --jerry
9417 set_printer_dataex( printer, str, r->in.value_name,
9418 REG_SZ, (uint8 *)oid_string,
9419 strlen(oid_string)+1 );
9422 status = mod_a_printer(printer, 2);
9425 free_a_printer(&printer, 2);
9430 /****************************************************************
9431 _spoolss_DeletePrinterDataEx
9432 ****************************************************************/
9434 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9435 struct spoolss_DeletePrinterDataEx *r)
9437 POLICY_HND *handle = r->in.handle;
9438 NT_PRINTER_INFO_LEVEL *printer = NULL;
9440 WERROR status = WERR_OK;
9441 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9443 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9446 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9447 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9451 if (!get_printer_snum(p, handle, &snum, NULL))
9454 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9455 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9456 "printer properties change denied by handle\n"));
9457 return WERR_ACCESS_DENIED;
9460 if (!r->in.value_name || !r->in.key_name) {
9464 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9465 if (!W_ERROR_IS_OK(status))
9468 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9470 if ( W_ERROR_IS_OK(status) )
9471 mod_a_printer( printer, 2 );
9473 free_a_printer(&printer, 2);
9478 /********************************************************************
9479 * spoolss_enumprinterkey
9480 ********************************************************************/
9483 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9486 fstring *keynames = NULL;
9487 uint16 *enumkeys = NULL;
9490 POLICY_HND *handle = &q_u->handle;
9491 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9492 NT_PRINTER_DATA *data;
9493 NT_PRINTER_INFO_LEVEL *printer = NULL;
9495 WERROR status = WERR_BADFILE;
9498 DEBUG(4,("_spoolss_enumprinterkey\n"));
9501 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9505 if ( !get_printer_snum(p,handle, &snum, NULL) )
9508 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9509 if (!W_ERROR_IS_OK(status))
9512 /* get the list of subkey names */
9514 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9515 data = printer->info_2->data;
9517 num_keys = get_printer_subkeys( data, key, &keynames );
9519 if ( num_keys == -1 ) {
9520 status = WERR_BADFILE;
9524 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9526 r_u->needed = printerkey_len*2;
9528 if ( q_u->size < r_u->needed ) {
9529 status = WERR_MORE_DATA;
9533 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9534 status = WERR_NOMEM;
9540 if ( q_u->size < r_u->needed )
9541 status = WERR_MORE_DATA;
9544 free_a_printer( &printer, 2 );
9545 SAFE_FREE( keynames );
9550 /****************************************************************
9551 _spoolss_DeletePrinterKey
9552 ****************************************************************/
9554 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9555 struct spoolss_DeletePrinterKey *r)
9557 POLICY_HND *handle = r->in.handle;
9558 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9559 NT_PRINTER_INFO_LEVEL *printer = NULL;
9563 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9566 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9567 OUR_HANDLE(handle)));
9571 /* if keyname == NULL, return error */
9573 if ( !r->in.key_name )
9574 return WERR_INVALID_PARAM;
9576 if (!get_printer_snum(p, handle, &snum, NULL))
9579 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9580 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9581 "printer properties change denied by handle\n"));
9582 return WERR_ACCESS_DENIED;
9585 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9586 if (!W_ERROR_IS_OK(status))
9589 /* delete the key and all subneys */
9591 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9593 if ( W_ERROR_IS_OK(status) )
9594 status = mod_a_printer(printer, 2);
9596 free_a_printer( &printer, 2 );
9602 /********************************************************************
9603 * spoolss_enumprinterdataex
9604 ********************************************************************/
9606 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9608 POLICY_HND *handle = &q_u->handle;
9609 uint32 in_size = q_u->size;
9612 NT_PRINTER_INFO_LEVEL *printer = NULL;
9613 PRINTER_ENUM_VALUES *enum_values = NULL;
9614 NT_PRINTER_DATA *p_data;
9616 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9621 REGISTRY_VALUE *val;
9626 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9629 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9634 * first check for a keyname of NULL or "". Win2k seems to send
9635 * this a lot and we should send back WERR_INVALID_PARAM
9636 * no need to spend time looking up the printer in this case.
9640 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9641 if ( !strlen(key) ) {
9642 result = WERR_INVALID_PARAM;
9646 /* get the printer off of disk */
9648 if (!get_printer_snum(p,handle, &snum, NULL))
9651 ZERO_STRUCT(printer);
9652 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9653 if (!W_ERROR_IS_OK(result))
9656 /* now look for a match on the key name */
9658 p_data = printer->info_2->data;
9660 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9661 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9663 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9664 result = WERR_INVALID_PARAM;
9671 /* allocate the memory for the array of pointers -- if necessary */
9673 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9676 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9678 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9679 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9680 result = WERR_NOMEM;
9684 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9688 * loop through all params and build the array to pass
9689 * back to the client
9692 for ( i=0; i<num_entries; i++ )
9694 /* lookup the registry value */
9696 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9697 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9701 value_name = regval_name( val );
9702 init_unistr( &enum_values[i].valuename, value_name );
9703 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9704 enum_values[i].type = regval_type( val );
9706 data_len = regval_size( val );
9708 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9710 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9712 result = WERR_NOMEM;
9716 enum_values[i].data_len = data_len;
9718 /* keep track of the size of the array in bytes */
9720 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9723 /* housekeeping information in the reply */
9725 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9726 * the hand marshalled container size is a multiple
9727 * of 4 bytes for RPC alignment.
9731 needed += 4-(needed % 4);
9734 r_u->needed = needed;
9735 r_u->returned = num_entries;
9737 if (needed > in_size) {
9738 result = WERR_MORE_DATA;
9742 /* copy data into the reply */
9744 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9745 response buffer size is != the offered buffer size
9747 r_u->ctr.size = r_u->needed;
9749 r_u->ctr.size = in_size;
9751 r_u->ctr.size_of_array = r_u->returned;
9752 r_u->ctr.values = enum_values;
9756 free_a_printer(&printer, 2);
9761 /****************************************************************************
9762 ****************************************************************************/
9764 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9765 const char *servername,
9766 const char *environment,
9767 struct spoolss_PrintProcessorDirectoryInfo1 *r,
9774 werr = compose_spoolss_server_path(mem_ctx,
9777 SPOOLSS_PRTPROCS_PATH,
9779 if (!W_ERROR_IS_OK(werr)) {
9783 DEBUG(4,("print processor directory: [%s]\n", path));
9785 r->directory_name = path;
9787 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
9789 if (*needed > offered) {
9791 return WERR_INSUFFICIENT_BUFFER;
9797 /****************************************************************
9798 _spoolss_GetPrintProcessorDirectory
9799 ****************************************************************/
9801 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9802 struct spoolss_GetPrintProcessorDirectory *r)
9806 /* that's an [in out] buffer */
9808 if (!r->in.buffer && (r->in.offered != 0)) {
9809 return WERR_INVALID_PARAM;
9812 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9817 /* r->in.level is ignored */
9819 result = getprintprocessordirectory_level_1(p->mem_ctx,
9822 &r->out.info->info1,
9825 if (!W_ERROR_IS_OK(result)) {
9826 TALLOC_FREE(r->out.info);
9832 /*******************************************************************
9833 ********************************************************************/
9835 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9836 const char *dllname)
9838 enum ndr_err_code ndr_err;
9839 struct spoolss_MonitorUi ui;
9841 ui.dll_name = dllname;
9843 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9844 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9845 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9846 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9848 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9851 /*******************************************************************
9852 Streams the monitor UI DLL name in UNICODE
9853 *******************************************************************/
9855 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9856 NT_USER_TOKEN *token, DATA_BLOB *in,
9857 DATA_BLOB *out, uint32_t *needed)
9859 const char *dllname = "tcpmonui.dll";
9861 *needed = (strlen(dllname)+1) * 2;
9863 if (out->length < *needed) {
9864 return WERR_INSUFFICIENT_BUFFER;
9867 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9874 /*******************************************************************
9875 ********************************************************************/
9877 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9878 struct spoolss_PortData1 *port1,
9879 const DATA_BLOB *buf)
9881 enum ndr_err_code ndr_err;
9882 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9883 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9884 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9885 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9887 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9890 /*******************************************************************
9891 ********************************************************************/
9893 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9894 struct spoolss_PortData2 *port2,
9895 const DATA_BLOB *buf)
9897 enum ndr_err_code ndr_err;
9898 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9899 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9900 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9901 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9903 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9906 /*******************************************************************
9907 Create a new TCP/IP port
9908 *******************************************************************/
9910 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9911 NT_USER_TOKEN *token, DATA_BLOB *in,
9912 DATA_BLOB *out, uint32_t *needed)
9914 struct spoolss_PortData1 port1;
9915 struct spoolss_PortData2 port2;
9916 char *device_uri = NULL;
9919 const char *portname;
9920 const char *hostaddress;
9922 uint32_t port_number;
9925 /* peek for spoolss_PortData version */
9927 if (!in || (in->length < (128 + 4))) {
9928 return WERR_GENERAL_FAILURE;
9931 version = IVAL(in->data, 128);
9937 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9941 portname = port1.portname;
9942 hostaddress = port1.hostaddress;
9943 queue = port1.queue;
9944 protocol = port1.protocol;
9945 port_number = port1.port_number;
9951 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9955 portname = port2.portname;
9956 hostaddress = port2.hostaddress;
9957 queue = port2.queue;
9958 protocol = port2.protocol;
9959 port_number = port2.port_number;
9963 DEBUG(1,("xcvtcp_addport: "
9964 "unknown version of port_data: %d\n", version));
9965 return WERR_UNKNOWN_PORT;
9968 /* create the device URI and call the add_port_hook() */
9971 case PROTOCOL_RAWTCP_TYPE:
9972 device_uri = talloc_asprintf(mem_ctx,
9973 "socket://%s:%d/", hostaddress,
9977 case PROTOCOL_LPR_TYPE:
9978 device_uri = talloc_asprintf(mem_ctx,
9979 "lpr://%s/%s", hostaddress, queue );
9983 return WERR_UNKNOWN_PORT;
9990 return add_port_hook(mem_ctx, token, portname, device_uri);
9993 /*******************************************************************
9994 *******************************************************************/
9996 struct xcv_api_table xcvtcp_cmds[] = {
9997 { "MonitorUI", xcvtcp_monitorui },
9998 { "AddPort", xcvtcp_addport},
10002 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
10003 NT_USER_TOKEN *token, const char *command,
10010 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
10012 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
10013 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
10014 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10017 return WERR_BADFUNC;
10020 /*******************************************************************
10021 *******************************************************************/
10022 #if 0 /* don't support management using the "Local Port" monitor */
10024 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10025 NT_USER_TOKEN *token, DATA_BLOB *in,
10026 DATA_BLOB *out, uint32_t *needed)
10028 const char *dllname = "localui.dll";
10030 *needed = (strlen(dllname)+1) * 2;
10032 if (out->length < *needed) {
10033 return WERR_INSUFFICIENT_BUFFER;
10036 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10043 /*******************************************************************
10044 *******************************************************************/
10046 struct xcv_api_table xcvlocal_cmds[] = {
10047 { "MonitorUI", xcvlocal_monitorui },
10051 struct xcv_api_table xcvlocal_cmds[] = {
10058 /*******************************************************************
10059 *******************************************************************/
10061 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10062 NT_USER_TOKEN *token, const char *command,
10063 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10068 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10070 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10071 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10072 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10074 return WERR_BADFUNC;
10077 /****************************************************************
10079 ****************************************************************/
10081 WERROR _spoolss_XcvData(pipes_struct *p,
10082 struct spoolss_XcvData *r)
10084 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10085 DATA_BLOB out_data = data_blob_null;
10089 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10090 OUR_HANDLE(r->in.handle)));
10091 return WERR_BADFID;
10094 /* Has to be a handle to the TCP/IP port monitor */
10096 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10097 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10098 return WERR_BADFID;
10101 /* requires administrative access to the server */
10103 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10104 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10105 return WERR_ACCESS_DENIED;
10108 /* Allocate the outgoing buffer */
10110 if (r->in.out_data_size) {
10111 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10112 if (out_data.data == NULL) {
10117 switch ( Printer->printer_type ) {
10118 case SPLHND_PORTMON_TCP:
10119 werror = process_xcvtcp_command(p->mem_ctx,
10120 p->server_info->ptok,
10121 r->in.function_name,
10122 &r->in.in_data, &out_data,
10125 case SPLHND_PORTMON_LOCAL:
10126 werror = process_xcvlocal_command(p->mem_ctx,
10127 p->server_info->ptok,
10128 r->in.function_name,
10129 &r->in.in_data, &out_data,
10133 werror = WERR_INVALID_PRINT_MONITOR;
10136 if (!W_ERROR_IS_OK(werror)) {
10140 *r->out.status_code = 0;
10142 memcpy(r->out.out_data, out_data.data, out_data.length);
10147 /****************************************************************
10148 _spoolss_AddPrintProcessor
10149 ****************************************************************/
10151 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10152 struct spoolss_AddPrintProcessor *r)
10154 /* for now, just indicate success and ignore the add. We'll
10155 automatically set the winprint processor for printer
10156 entries later. Used to debug the LexMark Optra S 1855 PCL
10162 /****************************************************************
10163 _spoolss_EnumPrinters
10164 ****************************************************************/
10166 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10167 struct spoolss_EnumPrinters *r)
10169 p->rng_fault_state = true;
10170 return WERR_NOT_SUPPORTED;
10173 /****************************************************************
10175 ****************************************************************/
10177 WERROR _spoolss_GetJob(pipes_struct *p,
10178 struct spoolss_GetJob *r)
10180 p->rng_fault_state = true;
10181 return WERR_NOT_SUPPORTED;
10184 /****************************************************************
10186 ****************************************************************/
10188 WERROR _spoolss_EnumJobs(pipes_struct *p,
10189 struct spoolss_EnumJobs *r)
10191 p->rng_fault_state = true;
10192 return WERR_NOT_SUPPORTED;
10195 /****************************************************************
10196 _spoolss_AddPrinter
10197 ****************************************************************/
10199 WERROR _spoolss_AddPrinter(pipes_struct *p,
10200 struct spoolss_AddPrinter *r)
10202 p->rng_fault_state = true;
10203 return WERR_NOT_SUPPORTED;
10206 /****************************************************************
10207 _spoolss_GetPrinter
10208 ****************************************************************/
10210 WERROR _spoolss_GetPrinter(pipes_struct *p,
10211 struct spoolss_GetPrinter *r)
10213 p->rng_fault_state = true;
10214 return WERR_NOT_SUPPORTED;
10217 /****************************************************************
10218 _spoolss_EnumPrinterDrivers
10219 ****************************************************************/
10221 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10222 struct spoolss_EnumPrinterDrivers *r)
10224 p->rng_fault_state = true;
10225 return WERR_NOT_SUPPORTED;
10228 /****************************************************************
10229 _spoolss_GetPrinterDriver
10230 ****************************************************************/
10232 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10233 struct spoolss_GetPrinterDriver *r)
10235 p->rng_fault_state = true;
10236 return WERR_NOT_SUPPORTED;
10239 /****************************************************************
10240 _spoolss_ReadPrinter
10241 ****************************************************************/
10243 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10244 struct spoolss_ReadPrinter *r)
10246 p->rng_fault_state = true;
10247 return WERR_NOT_SUPPORTED;
10250 /****************************************************************
10251 _spoolss_GetPrinterData
10252 ****************************************************************/
10254 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10255 struct spoolss_GetPrinterData *r)
10257 p->rng_fault_state = true;
10258 return WERR_NOT_SUPPORTED;
10261 /****************************************************************
10262 _spoolss_SetPrinterData
10263 ****************************************************************/
10265 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10266 struct spoolss_SetPrinterData *r)
10268 p->rng_fault_state = true;
10269 return WERR_NOT_SUPPORTED;
10272 /****************************************************************
10273 _spoolss_WaitForPrinterChange
10274 ****************************************************************/
10276 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10277 struct spoolss_WaitForPrinterChange *r)
10279 p->rng_fault_state = true;
10280 return WERR_NOT_SUPPORTED;
10283 /****************************************************************
10285 ****************************************************************/
10287 WERROR _spoolss_EnumPorts(pipes_struct *p,
10288 struct spoolss_EnumPorts *r)
10290 p->rng_fault_state = true;
10291 return WERR_NOT_SUPPORTED;
10294 /****************************************************************
10295 _spoolss_EnumMonitors
10296 ****************************************************************/
10298 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10299 struct spoolss_EnumMonitors *r)
10301 p->rng_fault_state = true;
10302 return WERR_NOT_SUPPORTED;
10305 /****************************************************************
10307 ****************************************************************/
10309 WERROR _spoolss_AddPort(pipes_struct *p,
10310 struct spoolss_AddPort *r)
10312 p->rng_fault_state = true;
10313 return WERR_NOT_SUPPORTED;
10316 /****************************************************************
10317 _spoolss_ConfigurePort
10318 ****************************************************************/
10320 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10321 struct spoolss_ConfigurePort *r)
10323 p->rng_fault_state = true;
10324 return WERR_NOT_SUPPORTED;
10327 /****************************************************************
10328 _spoolss_DeletePort
10329 ****************************************************************/
10331 WERROR _spoolss_DeletePort(pipes_struct *p,
10332 struct spoolss_DeletePort *r)
10334 p->rng_fault_state = true;
10335 return WERR_NOT_SUPPORTED;
10338 /****************************************************************
10339 _spoolss_CreatePrinterIC
10340 ****************************************************************/
10342 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10343 struct spoolss_CreatePrinterIC *r)
10345 p->rng_fault_state = true;
10346 return WERR_NOT_SUPPORTED;
10349 /****************************************************************
10350 _spoolss_PlayGDIScriptOnPrinterIC
10351 ****************************************************************/
10353 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10354 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10356 p->rng_fault_state = true;
10357 return WERR_NOT_SUPPORTED;
10360 /****************************************************************
10361 _spoolss_DeletePrinterIC
10362 ****************************************************************/
10364 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10365 struct spoolss_DeletePrinterIC *r)
10367 p->rng_fault_state = true;
10368 return WERR_NOT_SUPPORTED;
10371 /****************************************************************
10372 _spoolss_AddPrinterConnection
10373 ****************************************************************/
10375 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10376 struct spoolss_AddPrinterConnection *r)
10378 p->rng_fault_state = true;
10379 return WERR_NOT_SUPPORTED;
10382 /****************************************************************
10383 _spoolss_DeletePrinterConnection
10384 ****************************************************************/
10386 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10387 struct spoolss_DeletePrinterConnection *r)
10389 p->rng_fault_state = true;
10390 return WERR_NOT_SUPPORTED;
10393 /****************************************************************
10394 _spoolss_PrinterMessageBox
10395 ****************************************************************/
10397 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10398 struct spoolss_PrinterMessageBox *r)
10400 p->rng_fault_state = true;
10401 return WERR_NOT_SUPPORTED;
10404 /****************************************************************
10405 _spoolss_AddMonitor
10406 ****************************************************************/
10408 WERROR _spoolss_AddMonitor(pipes_struct *p,
10409 struct spoolss_AddMonitor *r)
10411 p->rng_fault_state = true;
10412 return WERR_NOT_SUPPORTED;
10415 /****************************************************************
10416 _spoolss_DeleteMonitor
10417 ****************************************************************/
10419 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10420 struct spoolss_DeleteMonitor *r)
10422 p->rng_fault_state = true;
10423 return WERR_NOT_SUPPORTED;
10426 /****************************************************************
10427 _spoolss_DeletePrintProcessor
10428 ****************************************************************/
10430 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10431 struct spoolss_DeletePrintProcessor *r)
10433 p->rng_fault_state = true;
10434 return WERR_NOT_SUPPORTED;
10437 /****************************************************************
10438 _spoolss_AddPrintProvidor
10439 ****************************************************************/
10441 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10442 struct spoolss_AddPrintProvidor *r)
10444 p->rng_fault_state = true;
10445 return WERR_NOT_SUPPORTED;
10448 /****************************************************************
10449 _spoolss_DeletePrintProvidor
10450 ****************************************************************/
10452 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10453 struct spoolss_DeletePrintProvidor *r)
10455 p->rng_fault_state = true;
10456 return WERR_NOT_SUPPORTED;
10459 /****************************************************************
10460 _spoolss_GetPrinterDriver2
10461 ****************************************************************/
10463 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10464 struct spoolss_GetPrinterDriver2 *r)
10466 p->rng_fault_state = true;
10467 return WERR_NOT_SUPPORTED;
10470 /****************************************************************
10471 _spoolss_FindFirstPrinterChangeNotification
10472 ****************************************************************/
10474 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10475 struct spoolss_FindFirstPrinterChangeNotification *r)
10477 p->rng_fault_state = true;
10478 return WERR_NOT_SUPPORTED;
10481 /****************************************************************
10482 _spoolss_FindNextPrinterChangeNotification
10483 ****************************************************************/
10485 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10486 struct spoolss_FindNextPrinterChangeNotification *r)
10488 p->rng_fault_state = true;
10489 return WERR_NOT_SUPPORTED;
10492 /****************************************************************
10493 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10494 ****************************************************************/
10496 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10497 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10499 p->rng_fault_state = true;
10500 return WERR_NOT_SUPPORTED;
10503 /****************************************************************
10504 _spoolss_ReplyOpenPrinter
10505 ****************************************************************/
10507 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10508 struct spoolss_ReplyOpenPrinter *r)
10510 p->rng_fault_state = true;
10511 return WERR_NOT_SUPPORTED;
10514 /****************************************************************
10515 _spoolss_RouterReplyPrinter
10516 ****************************************************************/
10518 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10519 struct spoolss_RouterReplyPrinter *r)
10521 p->rng_fault_state = true;
10522 return WERR_NOT_SUPPORTED;
10525 /****************************************************************
10526 _spoolss_ReplyClosePrinter
10527 ****************************************************************/
10529 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10530 struct spoolss_ReplyClosePrinter *r)
10532 p->rng_fault_state = true;
10533 return WERR_NOT_SUPPORTED;
10536 /****************************************************************
10538 ****************************************************************/
10540 WERROR _spoolss_AddPortEx(pipes_struct *p,
10541 struct spoolss_AddPortEx *r)
10543 p->rng_fault_state = true;
10544 return WERR_NOT_SUPPORTED;
10547 /****************************************************************
10548 _spoolss_RouterFindFirstPrinterChangeNotification
10549 ****************************************************************/
10551 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10552 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10554 p->rng_fault_state = true;
10555 return WERR_NOT_SUPPORTED;
10558 /****************************************************************
10559 _spoolss_SpoolerInit
10560 ****************************************************************/
10562 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10563 struct spoolss_SpoolerInit *r)
10565 p->rng_fault_state = true;
10566 return WERR_NOT_SUPPORTED;
10569 /****************************************************************
10570 _spoolss_ResetPrinterEx
10571 ****************************************************************/
10573 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10574 struct spoolss_ResetPrinterEx *r)
10576 p->rng_fault_state = true;
10577 return WERR_NOT_SUPPORTED;
10580 /****************************************************************
10581 _spoolss_RouterReplyPrinterEx
10582 ****************************************************************/
10584 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10585 struct spoolss_RouterReplyPrinterEx *r)
10587 p->rng_fault_state = true;
10588 return WERR_NOT_SUPPORTED;
10591 /****************************************************************
10593 ****************************************************************/
10595 WERROR _spoolss_44(pipes_struct *p,
10596 struct spoolss_44 *r)
10598 p->rng_fault_state = true;
10599 return WERR_NOT_SUPPORTED;
10602 /****************************************************************
10604 ****************************************************************/
10606 WERROR _spoolss_47(pipes_struct *p,
10607 struct spoolss_47 *r)
10609 p->rng_fault_state = true;
10610 return WERR_NOT_SUPPORTED;
10613 /****************************************************************
10614 _spoolss_EnumPrinterData
10615 ****************************************************************/
10617 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10618 struct spoolss_EnumPrinterData *r)
10620 p->rng_fault_state = true;
10621 return WERR_NOT_SUPPORTED;
10624 /****************************************************************
10626 ****************************************************************/
10628 WERROR _spoolss_4a(pipes_struct *p,
10629 struct spoolss_4a *r)
10631 p->rng_fault_state = true;
10632 return WERR_NOT_SUPPORTED;
10635 /****************************************************************
10637 ****************************************************************/
10639 WERROR _spoolss_4b(pipes_struct *p,
10640 struct spoolss_4b *r)
10642 p->rng_fault_state = true;
10643 return WERR_NOT_SUPPORTED;
10646 /****************************************************************
10648 ****************************************************************/
10650 WERROR _spoolss_4c(pipes_struct *p,
10651 struct spoolss_4c *r)
10653 p->rng_fault_state = true;
10654 return WERR_NOT_SUPPORTED;
10657 /****************************************************************
10658 _spoolss_EnumPrinterDataEx
10659 ****************************************************************/
10661 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10662 struct spoolss_EnumPrinterDataEx *r)
10664 p->rng_fault_state = true;
10665 return WERR_NOT_SUPPORTED;
10668 /****************************************************************
10669 _spoolss_EnumPrinterKey
10670 ****************************************************************/
10672 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10673 struct spoolss_EnumPrinterKey *r)
10675 p->rng_fault_state = true;
10676 return WERR_NOT_SUPPORTED;
10679 /****************************************************************
10681 ****************************************************************/
10683 WERROR _spoolss_53(pipes_struct *p,
10684 struct spoolss_53 *r)
10686 p->rng_fault_state = true;
10687 return WERR_NOT_SUPPORTED;
10690 /****************************************************************
10692 ****************************************************************/
10694 WERROR _spoolss_55(pipes_struct *p,
10695 struct spoolss_55 *r)
10697 p->rng_fault_state = true;
10698 return WERR_NOT_SUPPORTED;
10701 /****************************************************************
10703 ****************************************************************/
10705 WERROR _spoolss_56(pipes_struct *p,
10706 struct spoolss_56 *r)
10708 p->rng_fault_state = true;
10709 return WERR_NOT_SUPPORTED;
10712 /****************************************************************
10714 ****************************************************************/
10716 WERROR _spoolss_57(pipes_struct *p,
10717 struct spoolss_57 *r)
10719 p->rng_fault_state = true;
10720 return WERR_NOT_SUPPORTED;
10723 /****************************************************************
10725 ****************************************************************/
10727 WERROR _spoolss_5a(pipes_struct *p,
10728 struct spoolss_5a *r)
10730 p->rng_fault_state = true;
10731 return WERR_NOT_SUPPORTED;
10734 /****************************************************************
10736 ****************************************************************/
10738 WERROR _spoolss_5b(pipes_struct *p,
10739 struct spoolss_5b *r)
10741 p->rng_fault_state = true;
10742 return WERR_NOT_SUPPORTED;
10745 /****************************************************************
10747 ****************************************************************/
10749 WERROR _spoolss_5c(pipes_struct *p,
10750 struct spoolss_5c *r)
10752 p->rng_fault_state = true;
10753 return WERR_NOT_SUPPORTED;
10756 /****************************************************************
10758 ****************************************************************/
10760 WERROR _spoolss_5d(pipes_struct *p,
10761 struct spoolss_5d *r)
10763 p->rng_fault_state = true;
10764 return WERR_NOT_SUPPORTED;
10767 /****************************************************************
10769 ****************************************************************/
10771 WERROR _spoolss_5e(pipes_struct *p,
10772 struct spoolss_5e *r)
10774 p->rng_fault_state = true;
10775 return WERR_NOT_SUPPORTED;
10778 /****************************************************************
10780 ****************************************************************/
10782 WERROR _spoolss_5f(pipes_struct *p,
10783 struct spoolss_5f *r)
10785 p->rng_fault_state = true;
10786 return WERR_NOT_SUPPORTED;