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;
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; 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 = SPOOL_DS_PUBLISH;
4358 init_unistr(&printer->guid, "");
4359 printer->action = SPOOL_DS_UNPUBLISH;
4365 /********************************************************************
4366 Spoolss_enumprinters.
4367 ********************************************************************/
4369 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4373 int n_services=lp_numservices();
4374 PRINTER_INFO_1 *printers=NULL;
4375 PRINTER_INFO_1 current_prt;
4376 WERROR result = WERR_OK;
4378 DEBUG(4,("enum_all_printers_info_1\n"));
4380 for (snum=0; snum<n_services; snum++) {
4381 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4382 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4384 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4385 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4386 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4390 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4392 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4398 /* check the required size. */
4399 for (i=0; i<*returned; i++)
4400 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4402 if (*needed > offered) {
4403 result = WERR_INSUFFICIENT_BUFFER;
4407 if (!rpcbuf_alloc_size(buffer, *needed)) {
4408 result = WERR_NOMEM;
4412 /* fill the buffer with the structures */
4413 for (i=0; i<*returned; i++)
4414 smb_io_printer_info_1("", buffer, &printers[i], 0);
4419 SAFE_FREE(printers);
4421 if ( !W_ERROR_IS_OK(result) )
4427 /********************************************************************
4428 enum_all_printers_info_1_local.
4429 *********************************************************************/
4431 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4433 DEBUG(4,("enum_all_printers_info_1_local\n"));
4435 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4438 /********************************************************************
4439 enum_all_printers_info_1_name.
4440 *********************************************************************/
4442 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4446 DEBUG(4,("enum_all_printers_info_1_name\n"));
4448 if ((name[0] == '\\') && (name[1] == '\\'))
4451 if (is_myname_or_ipaddr(s)) {
4452 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4455 return WERR_INVALID_NAME;
4458 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4459 /********************************************************************
4460 enum_all_printers_info_1_remote.
4461 *********************************************************************/
4463 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4465 PRINTER_INFO_1 *printer;
4466 fstring printername;
4469 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4470 WERROR result = WERR_OK;
4472 /* JFM: currently it's more a place holder than anything else.
4473 * In the spooler world there is a notion of server registration.
4474 * the print servers are registered on the PDC (in the same domain)
4476 * We should have a TDB here. The registration is done thru an
4477 * undocumented RPC call.
4480 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4485 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4486 slprintf(desc, sizeof(desc)-1,"%s", name);
4487 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4489 init_unistr(&printer->description, desc);
4490 init_unistr(&printer->name, printername);
4491 init_unistr(&printer->comment, comment);
4492 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4494 /* check the required size. */
4495 *needed += spoolss_size_printer_info_1(printer);
4497 if (*needed > offered) {
4498 result = WERR_INSUFFICIENT_BUFFER;
4502 if (!rpcbuf_alloc_size(buffer, *needed)) {
4503 result = WERR_NOMEM;
4507 /* fill the buffer with the structures */
4508 smb_io_printer_info_1("", buffer, printer, 0);
4514 if ( !W_ERROR_IS_OK(result) )
4522 /********************************************************************
4523 enum_all_printers_info_1_network.
4524 *********************************************************************/
4526 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4530 DEBUG(4,("enum_all_printers_info_1_network\n"));
4532 /* If we respond to a enum_printers level 1 on our name with flags
4533 set to PRINTER_ENUM_REMOTE with a list of printers then these
4534 printers incorrectly appear in the APW browse list.
4535 Specifically the printers for the server appear at the workgroup
4536 level where all the other servers in the domain are
4537 listed. Windows responds to this call with a
4538 WERR_CAN_NOT_COMPLETE so we should do the same. */
4540 if (name[0] == '\\' && name[1] == '\\')
4543 if (is_myname_or_ipaddr(s))
4544 return WERR_CAN_NOT_COMPLETE;
4546 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4549 /********************************************************************
4550 * api_spoolss_enumprinters
4552 * called from api_spoolss_enumprinters (see this to understand)
4553 ********************************************************************/
4555 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4559 int n_services=lp_numservices();
4560 PRINTER_INFO_2 *printers=NULL;
4561 PRINTER_INFO_2 current_prt;
4562 WERROR result = WERR_OK;
4566 for (snum=0; snum<n_services; snum++) {
4567 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4568 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4570 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4571 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4572 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4577 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4579 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4586 /* check the required size. */
4587 for (i=0; i<*returned; i++)
4588 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4590 if (*needed > offered) {
4591 result = WERR_INSUFFICIENT_BUFFER;
4595 if (!rpcbuf_alloc_size(buffer, *needed)) {
4596 result = WERR_NOMEM;
4600 /* fill the buffer with the structures */
4601 for (i=0; i<*returned; i++)
4602 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4607 for (i=0; i<*returned; i++)
4608 free_devmode(printers[i].devmode);
4610 SAFE_FREE(printers);
4612 if ( !W_ERROR_IS_OK(result) )
4618 /********************************************************************
4619 * handle enumeration of printers at level 1
4620 ********************************************************************/
4622 static WERROR enumprinters_level1( uint32 flags, fstring name,
4623 RPC_BUFFER *buffer, uint32 offered,
4624 uint32 *needed, uint32 *returned)
4626 /* Not all the flags are equals */
4628 if (flags & PRINTER_ENUM_LOCAL)
4629 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4631 if (flags & PRINTER_ENUM_NAME)
4632 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4634 #if 0 /* JERRY - disabled for now */
4635 if (flags & PRINTER_ENUM_REMOTE)
4636 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4639 if (flags & PRINTER_ENUM_NETWORK)
4640 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4642 return WERR_OK; /* NT4sp5 does that */
4645 /********************************************************************
4646 * handle enumeration of printers at level 2
4647 ********************************************************************/
4649 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4650 RPC_BUFFER *buffer, uint32 offered,
4651 uint32 *needed, uint32 *returned)
4653 if (flags & PRINTER_ENUM_LOCAL) {
4654 return enum_all_printers_info_2(buffer, offered, needed, returned);
4657 if (flags & PRINTER_ENUM_NAME) {
4658 if (is_myname_or_ipaddr(canon_servername(servername)))
4659 return enum_all_printers_info_2(buffer, offered, needed, returned);
4661 return WERR_INVALID_NAME;
4664 if (flags & PRINTER_ENUM_REMOTE)
4665 return WERR_UNKNOWN_LEVEL;
4670 /********************************************************************
4671 * handle enumeration of printers at level 5
4672 ********************************************************************/
4674 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4675 RPC_BUFFER *buffer, uint32 offered,
4676 uint32 *needed, uint32 *returned)
4678 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4682 /********************************************************************
4683 * api_spoolss_enumprinters
4685 * called from api_spoolss_enumprinters (see this to understand)
4686 ********************************************************************/
4688 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4690 uint32 flags = q_u->flags;
4691 UNISTR2 *servername = &q_u->servername;
4692 uint32 level = q_u->level;
4693 RPC_BUFFER *buffer = NULL;
4694 uint32 offered = q_u->offered;
4695 uint32 *needed = &r_u->needed;
4696 uint32 *returned = &r_u->returned;
4700 /* that's an [in out] buffer */
4702 if (!q_u->buffer && (offered!=0)) {
4703 return WERR_INVALID_PARAM;
4706 if (offered > MAX_RPC_DATA_SIZE) {
4707 return WERR_INVALID_PARAM;
4710 rpcbuf_move(q_u->buffer, &r_u->buffer);
4711 buffer = r_u->buffer;
4713 DEBUG(4,("_spoolss_enumprinters\n"));
4720 * flags==PRINTER_ENUM_NAME
4721 * if name=="" then enumerates all printers
4722 * if name!="" then enumerate the printer
4723 * flags==PRINTER_ENUM_REMOTE
4724 * name is NULL, enumerate printers
4725 * Level 2: name!="" enumerates printers, name can't be NULL
4726 * Level 3: doesn't exist
4727 * Level 4: does a local registry lookup
4728 * Level 5: same as Level 2
4731 unistr2_to_ascii(name, servername, sizeof(name));
4736 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4738 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4740 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4745 return WERR_UNKNOWN_LEVEL;
4748 /****************************************************************************
4749 ****************************************************************************/
4751 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4753 PRINTER_INFO_0 *printer=NULL;
4754 WERROR result = WERR_OK;
4756 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4759 construct_printer_info_0(print_hnd, printer, snum);
4761 /* check the required size. */
4762 *needed += spoolss_size_printer_info_0(printer);
4764 if (*needed > offered) {
4765 result = WERR_INSUFFICIENT_BUFFER;
4769 if (!rpcbuf_alloc_size(buffer, *needed)) {
4770 result = WERR_NOMEM;
4774 /* fill the buffer with the structures */
4775 smb_io_printer_info_0("", buffer, printer, 0);
4785 /****************************************************************************
4786 ****************************************************************************/
4788 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4790 PRINTER_INFO_1 *printer=NULL;
4791 WERROR result = WERR_OK;
4793 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4796 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4798 /* check the required size. */
4799 *needed += spoolss_size_printer_info_1(printer);
4801 if (*needed > offered) {
4802 result = WERR_INSUFFICIENT_BUFFER;
4806 if (!rpcbuf_alloc_size(buffer, *needed)) {
4807 result = WERR_NOMEM;
4811 /* fill the buffer with the structures */
4812 smb_io_printer_info_1("", buffer, printer, 0);
4821 /****************************************************************************
4822 ****************************************************************************/
4824 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4826 PRINTER_INFO_2 *printer=NULL;
4827 WERROR result = WERR_OK;
4829 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4832 construct_printer_info_2(print_hnd, printer, snum);
4834 /* check the required size. */
4835 *needed += spoolss_size_printer_info_2(printer);
4837 if (*needed > offered) {
4838 result = WERR_INSUFFICIENT_BUFFER;
4842 if (!rpcbuf_alloc_size(buffer, *needed)) {
4843 result = WERR_NOMEM;
4847 /* fill the buffer with the structures */
4848 if (!smb_io_printer_info_2("", buffer, printer, 0))
4849 result = WERR_NOMEM;
4853 free_printer_info_2(printer);
4858 /****************************************************************************
4859 ****************************************************************************/
4861 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4863 PRINTER_INFO_3 *printer=NULL;
4864 WERROR result = WERR_OK;
4866 if (!construct_printer_info_3(print_hnd, &printer, snum))
4869 /* check the required size. */
4870 *needed += spoolss_size_printer_info_3(printer);
4872 if (*needed > offered) {
4873 result = WERR_INSUFFICIENT_BUFFER;
4877 if (!rpcbuf_alloc_size(buffer, *needed)) {
4878 result = WERR_NOMEM;
4882 /* fill the buffer with the structures */
4883 smb_io_printer_info_3("", buffer, printer, 0);
4887 free_printer_info_3(printer);
4892 /****************************************************************************
4893 ****************************************************************************/
4895 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4897 PRINTER_INFO_4 *printer=NULL;
4898 WERROR result = WERR_OK;
4900 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4903 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4908 /* check the required size. */
4909 *needed += spoolss_size_printer_info_4(printer);
4911 if (*needed > offered) {
4912 result = WERR_INSUFFICIENT_BUFFER;
4916 if (!rpcbuf_alloc_size(buffer, *needed)) {
4917 result = WERR_NOMEM;
4921 /* fill the buffer with the structures */
4922 smb_io_printer_info_4("", buffer, printer, 0);
4926 free_printer_info_4(printer);
4931 /****************************************************************************
4932 ****************************************************************************/
4934 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4936 PRINTER_INFO_5 *printer=NULL;
4937 WERROR result = WERR_OK;
4939 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4942 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4943 free_printer_info_5(printer);
4947 /* check the required size. */
4948 *needed += spoolss_size_printer_info_5(printer);
4950 if (*needed > offered) {
4951 result = WERR_INSUFFICIENT_BUFFER;
4955 if (!rpcbuf_alloc_size(buffer, *needed)) {
4956 result = WERR_NOMEM;
4960 /* fill the buffer with the structures */
4961 smb_io_printer_info_5("", buffer, printer, 0);
4965 free_printer_info_5(printer);
4970 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4972 RPC_BUFFER *buffer, uint32 offered,
4975 PRINTER_INFO_6 *printer;
4976 WERROR result = WERR_OK;
4978 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4982 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4983 free_printer_info_6(printer);
4987 /* check the required size. */
4988 *needed += spoolss_size_printer_info_6(printer);
4990 if (*needed > offered) {
4991 result = WERR_INSUFFICIENT_BUFFER;
4995 if (!rpcbuf_alloc_size(buffer, *needed)) {
4996 result = WERR_NOMEM;
5000 /* fill the buffer with the structures */
5001 smb_io_printer_info_6("", buffer, printer, 0);
5005 free_printer_info_6(printer);
5010 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5012 PRINTER_INFO_7 *printer=NULL;
5013 WERROR result = WERR_OK;
5015 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5018 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5019 result = WERR_NOMEM;
5023 /* check the required size. */
5024 *needed += spoolss_size_printer_info_7(printer);
5026 if (*needed > offered) {
5027 result = WERR_INSUFFICIENT_BUFFER;
5031 if (!rpcbuf_alloc_size(buffer, *needed)) {
5032 result = WERR_NOMEM;
5037 /* fill the buffer with the structures */
5038 smb_io_printer_info_7("", buffer, printer, 0);
5042 free_printer_info_7(printer);
5047 /****************************************************************************
5048 ****************************************************************************/
5050 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5052 POLICY_HND *handle = &q_u->handle;
5053 uint32 level = q_u->level;
5054 RPC_BUFFER *buffer = NULL;
5055 uint32 offered = q_u->offered;
5056 uint32 *needed = &r_u->needed;
5057 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5061 /* that's an [in out] buffer */
5063 if (!q_u->buffer && (offered!=0)) {
5064 return WERR_INVALID_PARAM;
5067 if (offered > MAX_RPC_DATA_SIZE) {
5068 return WERR_INVALID_PARAM;
5071 rpcbuf_move(q_u->buffer, &r_u->buffer);
5072 buffer = r_u->buffer;
5076 if (!get_printer_snum(p, handle, &snum, NULL))
5081 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5083 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5085 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5087 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5089 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5091 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5093 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5095 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5097 return WERR_UNKNOWN_LEVEL;
5100 /********************************************************************
5101 * fill a DRIVER_INFO_1 struct
5102 ********************************************************************/
5104 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5106 init_unistr( &info->name, driver.info_3->name);
5109 /********************************************************************
5110 * construct_printer_driver_info_1
5111 ********************************************************************/
5113 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5115 NT_PRINTER_INFO_LEVEL *printer = NULL;
5116 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5118 ZERO_STRUCT(driver);
5120 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5121 return WERR_INVALID_PRINTER_NAME;
5123 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5124 free_a_printer(&printer, 2);
5125 return WERR_UNKNOWN_PRINTER_DRIVER;
5128 fill_printer_driver_info_1(info, driver, servername, architecture);
5130 free_a_printer(&printer,2);
5135 /********************************************************************
5136 * construct_printer_driver_info_2
5137 * fill a printer_info_2 struct
5138 ********************************************************************/
5140 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5142 TALLOC_CTX *ctx = talloc_tos();
5144 const char *cservername = canon_servername(servername);
5146 info->version=driver.info_3->cversion;
5148 init_unistr( &info->name, driver.info_3->name );
5149 init_unistr( &info->architecture, driver.info_3->environment );
5151 if (strlen(driver.info_3->driverpath)) {
5152 temp = talloc_asprintf(ctx,
5155 driver.info_3->driverpath);
5156 init_unistr( &info->driverpath, temp );
5158 init_unistr( &info->driverpath, "" );
5162 if (strlen(driver.info_3->datafile)) {
5163 temp = talloc_asprintf(ctx,
5166 driver.info_3->datafile);
5167 init_unistr( &info->datafile, temp );
5169 init_unistr( &info->datafile, "" );
5172 if (strlen(driver.info_3->configfile)) {
5173 temp = talloc_asprintf(ctx,
5176 driver.info_3->configfile);
5177 init_unistr( &info->configfile, temp );
5179 init_unistr( &info->configfile, "" );
5182 /********************************************************************
5183 * construct_printer_driver_info_2
5184 * fill a printer_info_2 struct
5185 ********************************************************************/
5187 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5189 NT_PRINTER_INFO_LEVEL *printer = NULL;
5190 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5192 ZERO_STRUCT(printer);
5193 ZERO_STRUCT(driver);
5195 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5196 return WERR_INVALID_PRINTER_NAME;
5198 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5199 free_a_printer(&printer, 2);
5200 return WERR_UNKNOWN_PRINTER_DRIVER;
5203 fill_printer_driver_info_2(info, driver, servername);
5205 free_a_printer(&printer,2);
5210 /********************************************************************
5211 * copy a strings array and convert to UNICODE
5213 * convert an array of ascii string to a UNICODE string
5214 ********************************************************************/
5216 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5222 TALLOC_CTX *ctx = talloc_tos();
5224 DEBUG(6,("init_unistr_array\n"));
5228 if ( !char_array ) {
5233 v = ""; /* hack to handle null lists */
5236 /* hack to allow this to be used in places other than when generating
5237 the list of dependent files */
5241 line = talloc_asprintf(ctx,
5243 canon_servername(servername),
5246 line = talloc_strdup(ctx, v);
5250 SAFE_FREE(*uni_array);
5253 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5255 /* add one extra unit16 for the second terminating NULL */
5257 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5258 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5265 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5270 /* special case for ""; we need to add both NULL's here */
5272 (*uni_array)[j++]=0x0000;
5273 (*uni_array)[j]=0x0000;
5276 DEBUGADD(6,("last one:done\n"));
5278 /* return size of array in uint16's */
5283 /********************************************************************
5284 * construct_printer_info_3
5285 * fill a printer_info_3 struct
5286 ********************************************************************/
5288 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5291 TALLOC_CTX *ctx = talloc_tos();
5292 const char *cservername = canon_servername(servername);
5296 info->version=driver.info_3->cversion;
5298 init_unistr( &info->name, driver.info_3->name );
5299 init_unistr( &info->architecture, driver.info_3->environment );
5301 if (strlen(driver.info_3->driverpath)) {
5302 temp = talloc_asprintf(ctx,
5305 driver.info_3->driverpath);
5306 init_unistr( &info->driverpath, temp );
5308 init_unistr( &info->driverpath, "" );
5311 if (strlen(driver.info_3->datafile)) {
5312 temp = talloc_asprintf(ctx,
5315 driver.info_3->datafile);
5316 init_unistr( &info->datafile, temp );
5318 init_unistr( &info->datafile, "" );
5321 if (strlen(driver.info_3->configfile)) {
5322 temp = talloc_asprintf(ctx,
5325 driver.info_3->configfile);
5326 init_unistr( &info->configfile, temp );
5328 init_unistr( &info->configfile, "" );
5331 if (strlen(driver.info_3->helpfile)) {
5332 temp = talloc_asprintf(ctx,
5335 driver.info_3->helpfile);
5336 init_unistr( &info->helpfile, temp );
5338 init_unistr( &info->helpfile, "" );
5341 init_unistr( &info->monitorname, driver.info_3->monitorname );
5342 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5344 info->dependentfiles=NULL;
5345 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5348 /********************************************************************
5349 * construct_printer_info_3
5350 * fill a printer_info_3 struct
5351 ********************************************************************/
5353 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5355 NT_PRINTER_INFO_LEVEL *printer = NULL;
5356 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5358 ZERO_STRUCT(driver);
5360 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5361 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5362 if (!W_ERROR_IS_OK(status))
5363 return WERR_INVALID_PRINTER_NAME;
5365 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5366 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5371 * I put this code in during testing. Helpful when commenting out the
5372 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5373 * as win2k always queries the driver using an infor level of 6.
5374 * I've left it in (but ifdef'd out) because I'll probably
5375 * use it in experimentation again in the future. --jerry 22/01/2002
5378 if (!W_ERROR_IS_OK(status)) {
5380 * Is this a W2k client ?
5383 /* Yes - try again with a WinNT driver. */
5385 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5386 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5390 if (!W_ERROR_IS_OK(status)) {
5391 free_a_printer(&printer,2);
5392 return WERR_UNKNOWN_PRINTER_DRIVER;
5400 fill_printer_driver_info_3(info, driver, servername);
5402 free_a_printer(&printer,2);
5407 /********************************************************************
5408 * construct_printer_info_6
5409 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5410 ********************************************************************/
5412 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5416 TALLOC_CTX *ctx = talloc_tos();
5417 const char *cservername = canon_servername(servername);
5420 memset(&nullstr, '\0', sizeof(fstring));
5422 info->version=driver.info_3->cversion;
5424 init_unistr( &info->name, driver.info_3->name );
5425 init_unistr( &info->architecture, driver.info_3->environment );
5427 if (strlen(driver.info_3->driverpath)) {
5428 temp = talloc_asprintf(ctx,
5431 driver.info_3->driverpath);
5432 init_unistr( &info->driverpath, temp );
5434 init_unistr( &info->driverpath, "" );
5437 if (strlen(driver.info_3->datafile)) {
5438 temp = talloc_asprintf(ctx,
5441 driver.info_3->datafile);
5442 init_unistr( &info->datafile, temp );
5444 init_unistr( &info->datafile, "" );
5447 if (strlen(driver.info_3->configfile)) {
5448 temp = talloc_asprintf(ctx,
5451 driver.info_3->configfile);
5452 init_unistr( &info->configfile, temp );
5454 init_unistr( &info->configfile, "" );
5457 if (strlen(driver.info_3->helpfile)) {
5458 temp = talloc_asprintf(ctx,
5461 driver.info_3->helpfile);
5462 init_unistr( &info->helpfile, temp );
5464 init_unistr( &info->helpfile, "" );
5467 init_unistr( &info->monitorname, driver.info_3->monitorname );
5468 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5470 info->dependentfiles = NULL;
5471 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5473 info->previousdrivernames=NULL;
5474 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5476 info->driver_date=0;
5479 info->driver_version_low=0;
5480 info->driver_version_high=0;
5482 init_unistr( &info->mfgname, "");
5483 init_unistr( &info->oem_url, "");
5484 init_unistr( &info->hardware_id, "");
5485 init_unistr( &info->provider, "");
5488 /********************************************************************
5489 * construct_printer_info_6
5490 * fill a printer_info_6 struct
5491 ********************************************************************/
5493 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5494 const char *servername, fstring architecture, uint32 version)
5496 NT_PRINTER_INFO_LEVEL *printer = NULL;
5497 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5500 ZERO_STRUCT(driver);
5502 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5504 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5506 if (!W_ERROR_IS_OK(status))
5507 return WERR_INVALID_PRINTER_NAME;
5509 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5511 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5513 if (!W_ERROR_IS_OK(status))
5516 * Is this a W2k client ?
5520 free_a_printer(&printer,2);
5521 return WERR_UNKNOWN_PRINTER_DRIVER;
5524 /* Yes - try again with a WinNT driver. */
5526 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5527 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5528 if (!W_ERROR_IS_OK(status)) {
5529 free_a_printer(&printer,2);
5530 return WERR_UNKNOWN_PRINTER_DRIVER;
5534 fill_printer_driver_info_6(info, driver, servername);
5536 free_a_printer(&printer,2);
5537 free_a_printer_driver(driver, 3);
5542 /****************************************************************************
5543 ****************************************************************************/
5545 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5547 SAFE_FREE(info->dependentfiles);
5550 /****************************************************************************
5551 ****************************************************************************/
5553 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5555 SAFE_FREE(info->dependentfiles);
5558 /****************************************************************************
5559 ****************************************************************************/
5561 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5563 DRIVER_INFO_1 *info=NULL;
5566 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5569 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5570 if (!W_ERROR_IS_OK(result))
5573 /* check the required size. */
5574 *needed += spoolss_size_printer_driver_info_1(info);
5576 if (*needed > offered) {
5577 result = WERR_INSUFFICIENT_BUFFER;
5581 if (!rpcbuf_alloc_size(buffer, *needed)) {
5582 result = WERR_NOMEM;
5586 /* fill the buffer with the structures */
5587 smb_io_printer_driver_info_1("", buffer, info, 0);
5596 /****************************************************************************
5597 ****************************************************************************/
5599 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5601 DRIVER_INFO_2 *info=NULL;
5604 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5607 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5608 if (!W_ERROR_IS_OK(result))
5611 /* check the required size. */
5612 *needed += spoolss_size_printer_driver_info_2(info);
5614 if (*needed > offered) {
5615 result = WERR_INSUFFICIENT_BUFFER;
5619 if (!rpcbuf_alloc_size(buffer, *needed)) {
5620 result = WERR_NOMEM;
5624 /* fill the buffer with the structures */
5625 smb_io_printer_driver_info_2("", buffer, info, 0);
5634 /****************************************************************************
5635 ****************************************************************************/
5637 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5644 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5645 if (!W_ERROR_IS_OK(result))
5648 /* check the required size. */
5649 *needed += spoolss_size_printer_driver_info_3(&info);
5651 if (*needed > offered) {
5652 result = WERR_INSUFFICIENT_BUFFER;
5656 if (!rpcbuf_alloc_size(buffer, *needed)) {
5657 result = WERR_NOMEM;
5661 /* fill the buffer with the structures */
5662 smb_io_printer_driver_info_3("", buffer, &info, 0);
5665 free_printer_driver_info_3(&info);
5670 /****************************************************************************
5671 ****************************************************************************/
5673 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5680 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5681 if (!W_ERROR_IS_OK(result))
5684 /* check the required size. */
5685 *needed += spoolss_size_printer_driver_info_6(&info);
5687 if (*needed > offered) {
5688 result = WERR_INSUFFICIENT_BUFFER;
5692 if (!rpcbuf_alloc_size(buffer, *needed)) {
5693 result = WERR_NOMEM;
5697 /* fill the buffer with the structures */
5698 smb_io_printer_driver_info_6("", buffer, &info, 0);
5701 free_printer_driver_info_6(&info);
5706 /****************************************************************************
5707 ****************************************************************************/
5709 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5711 POLICY_HND *handle = &q_u->handle;
5712 UNISTR2 *uni_arch = &q_u->architecture;
5713 uint32 level = q_u->level;
5714 uint32 clientmajorversion = q_u->clientmajorversion;
5715 RPC_BUFFER *buffer = NULL;
5716 uint32 offered = q_u->offered;
5717 uint32 *needed = &r_u->needed;
5718 uint32 *servermajorversion = &r_u->servermajorversion;
5719 uint32 *serverminorversion = &r_u->serverminorversion;
5720 Printer_entry *printer;
5723 fstring architecture;
5726 /* that's an [in out] buffer */
5728 if (!q_u->buffer && (offered!=0)) {
5729 return WERR_INVALID_PARAM;
5732 if (offered > MAX_RPC_DATA_SIZE) {
5733 return WERR_INVALID_PARAM;
5736 rpcbuf_move(q_u->buffer, &r_u->buffer);
5737 buffer = r_u->buffer;
5739 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5741 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5742 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5743 return WERR_INVALID_PRINTER_NAME;
5747 *servermajorversion = 0;
5748 *serverminorversion = 0;
5750 fstrcpy(servername, get_server_name( printer ));
5751 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5753 if (!get_printer_snum(p, handle, &snum, NULL))
5758 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5760 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5762 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5764 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5767 /* apparently this call is the equivalent of
5768 EnumPrinterDataEx() for the DsDriver key */
5773 return WERR_UNKNOWN_LEVEL;
5777 /****************************************************************
5778 _spoolss_StartPagePrinter
5779 ****************************************************************/
5781 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5782 struct spoolss_StartPagePrinter *r)
5784 POLICY_HND *handle = r->in.handle;
5786 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5789 DEBUG(3,("_spoolss_StartPagePrinter: "
5790 "Error in startpageprinter printer handle\n"));
5794 Printer->page_started=True;
5798 /****************************************************************
5799 _spoolss_EndPagePrinter
5800 ****************************************************************/
5802 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5803 struct spoolss_EndPagePrinter *r)
5805 POLICY_HND *handle = r->in.handle;
5808 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5811 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5812 OUR_HANDLE(handle)));
5816 if (!get_printer_snum(p, handle, &snum, NULL))
5819 Printer->page_started=False;
5820 print_job_endpage(snum, Printer->jobid);
5825 /****************************************************************
5826 _spoolss_StartDocPrinter
5827 ****************************************************************/
5829 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5830 struct spoolss_StartDocPrinter *r)
5832 POLICY_HND *handle = r->in.handle;
5833 uint32_t *jobid = r->out.job_id;
5834 struct spoolss_DocumentInfo1 *info_1;
5836 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5839 DEBUG(2,("_spoolss_StartDocPrinter: "
5840 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5844 if (r->in.level != 1) {
5845 return WERR_UNKNOWN_LEVEL;
5848 info_1 = r->in.info.info1;
5851 * a nice thing with NT is it doesn't listen to what you tell it.
5852 * when asked to send _only_ RAW datas, it tries to send datas
5855 * So I add checks like in NT Server ...
5858 if (info_1->datatype) {
5859 if (strcmp(info_1->datatype, "RAW") != 0) {
5861 return WERR_INVALID_DATATYPE;
5865 /* get the share number of the printer */
5866 if (!get_printer_snum(p, handle, &snum, NULL)) {
5870 Printer->jobid = print_job_start(p->server_info, snum,
5871 CONST_DISCARD(char *,info_1->document_name),
5872 Printer->nt_devmode);
5874 /* An error occured in print_job_start() so return an appropriate
5877 if (Printer->jobid == -1) {
5878 return map_werror_from_unix(errno);
5881 Printer->document_started=True;
5882 (*jobid) = Printer->jobid;
5887 /****************************************************************
5888 _spoolss_EndDocPrinter
5889 ****************************************************************/
5891 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5892 struct spoolss_EndDocPrinter *r)
5894 POLICY_HND *handle = r->in.handle;
5896 return _spoolss_enddocprinter_internal(p, handle);
5899 /****************************************************************
5900 _spoolss_WritePrinter
5901 ****************************************************************/
5903 WERROR _spoolss_WritePrinter(pipes_struct *p,
5904 struct spoolss_WritePrinter *r)
5906 POLICY_HND *handle = r->in.handle;
5907 uint32 buffer_size = r->in._data_size;
5908 uint8 *buffer = r->in.data.data;
5909 uint32 *buffer_written = &r->in._data_size;
5911 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5914 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5915 OUR_HANDLE(handle)));
5916 *r->out.num_written = r->in._data_size;
5920 if (!get_printer_snum(p, handle, &snum, NULL))
5923 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5924 (SMB_OFF_T)-1, (size_t)buffer_size);
5925 if (*buffer_written == (uint32)-1) {
5926 *r->out.num_written = 0;
5927 if (errno == ENOSPC)
5928 return WERR_NO_SPOOL_SPACE;
5930 return WERR_ACCESS_DENIED;
5933 *r->out.num_written = r->in._data_size;
5938 /********************************************************************
5939 * api_spoolss_getprinter
5940 * called from the spoolss dispatcher
5942 ********************************************************************/
5944 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5948 WERROR errcode = WERR_BADFUNC;
5949 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5952 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5956 if (!get_printer_snum(p, handle, &snum, NULL))
5960 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5961 if (print_queue_pause(p->server_info, snum, &errcode)) {
5965 case SPOOLSS_PRINTER_CONTROL_RESUME:
5966 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5967 if (print_queue_resume(p->server_info, snum, &errcode)) {
5971 case SPOOLSS_PRINTER_CONTROL_PURGE:
5972 if (print_queue_purge(p->server_info, snum, &errcode)) {
5977 return WERR_UNKNOWN_LEVEL;
5984 /****************************************************************
5985 _spoolss_AbortPrinter
5986 * From MSDN: "Deletes printer's spool file if printer is configured
5988 ****************************************************************/
5990 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5991 struct spoolss_AbortPrinter *r)
5993 POLICY_HND *handle = r->in.handle;
5994 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5996 WERROR errcode = WERR_OK;
5999 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6000 OUR_HANDLE(handle)));
6004 if (!get_printer_snum(p, handle, &snum, NULL))
6007 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6012 /********************************************************************
6013 * called by spoolss_api_setprinter
6014 * when updating a printer description
6015 ********************************************************************/
6017 static WERROR update_printer_sec(POLICY_HND *handle,
6018 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6020 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6024 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6026 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6027 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6028 OUR_HANDLE(handle)));
6030 result = WERR_BADFID;
6035 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6036 result = WERR_INVALID_PARAM;
6040 /* Check the user has permissions to change the security
6041 descriptor. By experimentation with two NT machines, the user
6042 requires Full Access to the printer to change security
6045 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6046 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6047 result = WERR_ACCESS_DENIED;
6051 /* NT seems to like setting the security descriptor even though
6052 nothing may have actually changed. */
6054 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6055 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6056 result = WERR_BADFID;
6060 if (DEBUGLEVEL >= 10) {
6064 the_acl = old_secdesc_ctr->sd->dacl;
6065 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6066 PRINTERNAME(snum), the_acl->num_aces));
6068 for (i = 0; i < the_acl->num_aces; i++) {
6069 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6070 &the_acl->aces[i].trustee),
6071 the_acl->aces[i].access_mask));
6074 the_acl = secdesc_ctr->sd->dacl;
6077 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6078 PRINTERNAME(snum), the_acl->num_aces));
6080 for (i = 0; i < the_acl->num_aces; i++) {
6081 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6082 &the_acl->aces[i].trustee),
6083 the_acl->aces[i].access_mask));
6086 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6090 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6091 if (!new_secdesc_ctr) {
6092 result = WERR_NOMEM;
6096 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6101 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6108 /********************************************************************
6109 Canonicalize printer info from a client
6111 ATTN: It does not matter what we set the servername to hear
6112 since we do the necessary work in get_a_printer() to set it to
6113 the correct value based on what the client sent in the
6114 _spoolss_open_printer_ex().
6115 ********************************************************************/
6117 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6119 fstring printername;
6122 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6123 "portname=%s drivername=%s comment=%s location=%s\n",
6124 info->servername, info->printername, info->sharename,
6125 info->portname, info->drivername, info->comment, info->location));
6127 /* we force some elements to "correct" values */
6128 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6129 fstrcpy(info->sharename, lp_servicename(snum));
6131 /* check to see if we allow printername != sharename */
6133 if ( lp_force_printername(snum) ) {
6134 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6135 global_myname(), info->sharename );
6138 /* make sure printername is in \\server\printername format */
6140 fstrcpy( printername, info->printername );
6142 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6143 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6147 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6148 global_myname(), p );
6151 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6152 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6159 /****************************************************************************
6160 ****************************************************************************/
6162 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6164 char *cmd = lp_addport_cmd();
6165 char *command = NULL;
6167 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6168 bool is_print_op = False;
6171 return WERR_ACCESS_DENIED;
6174 command = talloc_asprintf(ctx,
6175 "%s \"%s\" \"%s\"", cmd, portname, uri );
6181 is_print_op = user_has_privileges( token, &se_printop );
6183 DEBUG(10,("Running [%s]\n", command));
6185 /********* BEGIN SePrintOperatorPrivilege **********/
6190 ret = smbrun(command, NULL);
6195 /********* END SePrintOperatorPrivilege **********/
6197 DEBUGADD(10,("returned [%d]\n", ret));
6199 TALLOC_FREE(command);
6202 return WERR_ACCESS_DENIED;
6208 /****************************************************************************
6209 ****************************************************************************/
6211 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6213 char *cmd = lp_addprinter_cmd();
6215 char *command = NULL;
6219 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6220 bool is_print_op = False;
6221 char *remote_machine = talloc_strdup(ctx, "%m");
6223 if (!remote_machine) {
6226 remote_machine = talloc_sub_basic(ctx,
6227 current_user_info.smb_name,
6228 current_user_info.domain,
6230 if (!remote_machine) {
6234 command = talloc_asprintf(ctx,
6235 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6236 cmd, printer->info_2->printername, printer->info_2->sharename,
6237 printer->info_2->portname, printer->info_2->drivername,
6238 printer->info_2->location, printer->info_2->comment, remote_machine);
6244 is_print_op = user_has_privileges( token, &se_printop );
6246 DEBUG(10,("Running [%s]\n", command));
6248 /********* BEGIN SePrintOperatorPrivilege **********/
6253 if ( (ret = smbrun(command, &fd)) == 0 ) {
6254 /* Tell everyone we updated smb.conf. */
6255 message_send_all(smbd_messaging_context(),
6256 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6262 /********* END SePrintOperatorPrivilege **********/
6264 DEBUGADD(10,("returned [%d]\n", ret));
6266 TALLOC_FREE(command);
6267 TALLOC_FREE(remote_machine);
6275 /* reload our services immediately */
6276 reload_services( False );
6279 /* Get lines and convert them back to dos-codepage */
6280 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6281 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6284 /* Set the portname to what the script says the portname should be. */
6285 /* but don't require anything to be return from the script exit a good error code */
6288 /* Set the portname to what the script says the portname should be. */
6289 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6290 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6293 TALLOC_FREE(qlines);
6298 /********************************************************************
6299 * Called by spoolss_api_setprinter
6300 * when updating a printer description.
6301 ********************************************************************/
6303 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6304 struct spoolss_SetPrinterInfoCtr *info_ctr,
6305 struct spoolss_DeviceMode *devmode)
6308 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6309 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6314 DEBUG(8,("update_printer\n"));
6319 result = WERR_BADFID;
6323 if (!get_printer_snum(p, handle, &snum, NULL)) {
6324 result = WERR_BADFID;
6328 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6329 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6330 result = WERR_BADFID;
6334 DEBUGADD(8,("Converting info_2 struct\n"));
6337 * convert_printer_info converts the incoming
6338 * info from the client and overwrites the info
6339 * just read from the tdb in the pointer 'printer'.
6342 if (!convert_printer_info_new(info_ctr, printer)) {
6343 result = WERR_NOMEM;
6348 /* we have a valid devmode
6349 convert it and link it*/
6351 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6352 if (!convert_devicemode_new(printer->info_2->printername,
6354 &printer->info_2->devmode)) {
6355 result = WERR_NOMEM;
6360 /* Do sanity check on the requested changes for Samba */
6362 if (!check_printer_ok(printer->info_2, snum)) {
6363 result = WERR_INVALID_PARAM;
6367 /* FIXME!!! If the driver has changed we really should verify that
6368 it is installed before doing much else --jerry */
6370 /* Check calling user has permission to update printer description */
6372 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6373 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6374 result = WERR_ACCESS_DENIED;
6378 /* Call addprinter hook */
6379 /* Check changes to see if this is really needed */
6381 if ( *lp_addprinter_cmd()
6382 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6383 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6384 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6385 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6387 /* add_printer_hook() will call reload_services() */
6389 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6391 result = WERR_ACCESS_DENIED;
6397 * When a *new* driver is bound to a printer, the drivername is used to
6398 * lookup previously saved driver initialization info, which is then
6399 * bound to the printer, simulating what happens in the Windows arch.
6401 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6403 if (!set_driver_init(printer, 2))
6405 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6406 printer->info_2->drivername));
6409 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6410 printer->info_2->drivername));
6412 notify_printer_driver(snum, printer->info_2->drivername);
6416 * flag which changes actually occured. This is a small subset of
6417 * all the possible changes. We also have to update things in the
6421 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6422 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6423 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6424 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6426 notify_printer_comment(snum, printer->info_2->comment);
6429 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6430 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6431 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6432 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6434 notify_printer_sharename(snum, printer->info_2->sharename);
6437 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6440 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6443 pname = printer->info_2->printername;
6446 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6447 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6448 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6450 notify_printer_printername( snum, pname );
6453 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6454 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6455 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6456 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6458 notify_printer_port(snum, printer->info_2->portname);
6461 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6462 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6463 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6464 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6466 notify_printer_location(snum, printer->info_2->location);
6469 /* here we need to update some more DsSpooler keys */
6470 /* uNCName, serverName, shortServerName */
6472 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6473 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6474 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6475 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6476 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6478 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6479 global_myname(), printer->info_2->sharename );
6480 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6481 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6482 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6484 /* Update printer info */
6485 result = mod_a_printer(printer, 2);
6488 free_a_printer(&printer, 2);
6489 free_a_printer(&old_printer, 2);
6495 /****************************************************************************
6496 ****************************************************************************/
6497 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6498 struct spoolss_SetPrinterInfo7 *info7)
6502 Printer_entry *Printer;
6504 if ( lp_security() != SEC_ADS ) {
6505 return WERR_UNKNOWN_LEVEL;
6508 Printer = find_printer_index_by_hnd(p, handle);
6510 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6515 if (!get_printer_snum(p, handle, &snum, NULL))
6518 nt_printer_publish(Printer, snum, info7->action);
6522 return WERR_UNKNOWN_LEVEL;
6526 /****************************************************************
6528 ****************************************************************/
6530 WERROR _spoolss_SetPrinter(pipes_struct *p,
6531 struct spoolss_SetPrinter *r)
6533 POLICY_HND *handle = r->in.handle;
6536 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6539 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6540 OUR_HANDLE(handle)));
6544 /* check the level */
6545 switch (r->in.info_ctr->level) {
6547 return control_printer(handle, r->in.command, p);
6549 result = update_printer(p, handle,
6551 r->in.devmode_ctr->devmode);
6552 if (!W_ERROR_IS_OK(result))
6554 if (r->in.secdesc_ctr->sd)
6555 result = update_printer_sec(handle, p,
6559 return update_printer_sec(handle, p,
6562 return publish_or_unpublish_printer(p, handle,
6563 r->in.info_ctr->info.info7);
6565 return WERR_UNKNOWN_LEVEL;
6569 /****************************************************************
6570 _spoolss_FindClosePrinterNotify
6571 ****************************************************************/
6573 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6574 struct spoolss_FindClosePrinterNotify *r)
6576 POLICY_HND *handle = r->in.handle;
6577 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6580 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6581 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6585 if (Printer->notify.client_connected==True) {
6588 if ( Printer->printer_type == SPLHND_SERVER)
6590 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6591 !get_printer_snum(p, handle, &snum, NULL) )
6594 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6597 Printer->notify.flags=0;
6598 Printer->notify.options=0;
6599 Printer->notify.localmachine[0]='\0';
6600 Printer->notify.printerlocal=0;
6601 TALLOC_FREE(Printer->notify.option);
6602 Printer->notify.client_connected=False;
6607 /****************************************************************
6609 ****************************************************************/
6611 WERROR _spoolss_AddJob(pipes_struct *p,
6612 struct spoolss_AddJob *r)
6614 if (!r->in.buffer && (r->in.offered != 0)) {
6615 return WERR_INVALID_PARAM;
6618 /* this is what a NT server returns for AddJob. AddJob must fail on
6619 * non-local printers */
6621 if (r->in.level != 1) {
6622 return WERR_UNKNOWN_LEVEL;
6625 return WERR_INVALID_PARAM;
6628 /****************************************************************************
6629 ****************************************************************************/
6631 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6632 int position, int snum,
6633 const NT_PRINTER_INFO_LEVEL *ntprinter)
6637 t=gmtime(&queue->time);
6639 job_info->jobid=queue->job;
6640 init_unistr(&job_info->printername, lp_servicename(snum));
6641 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6642 init_unistr(&job_info->username, queue->fs_user);
6643 init_unistr(&job_info->document, queue->fs_file);
6644 init_unistr(&job_info->datatype, "RAW");
6645 init_unistr(&job_info->text_status, "");
6646 job_info->status=nt_printj_status(queue->status);
6647 job_info->priority=queue->priority;
6648 job_info->position=position;
6649 job_info->totalpages=queue->page_count;
6650 job_info->pagesprinted=0;
6652 make_systemtime(&job_info->submitted, t);
6655 /****************************************************************************
6656 ****************************************************************************/
6658 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6659 int position, int snum,
6660 const NT_PRINTER_INFO_LEVEL *ntprinter,
6661 DEVICEMODE *devmode)
6665 t=gmtime(&queue->time);
6667 job_info->jobid=queue->job;
6669 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6671 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6672 init_unistr(&job_info->username, queue->fs_user);
6673 init_unistr(&job_info->document, queue->fs_file);
6674 init_unistr(&job_info->notifyname, queue->fs_user);
6675 init_unistr(&job_info->datatype, "RAW");
6676 init_unistr(&job_info->printprocessor, "winprint");
6677 init_unistr(&job_info->parameters, "");
6678 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6679 init_unistr(&job_info->text_status, "");
6681 /* and here the security descriptor */
6683 job_info->status=nt_printj_status(queue->status);
6684 job_info->priority=queue->priority;
6685 job_info->position=position;
6686 job_info->starttime=0;
6687 job_info->untiltime=0;
6688 job_info->totalpages=queue->page_count;
6689 job_info->size=queue->size;
6690 make_systemtime(&(job_info->submitted), t);
6691 job_info->timeelapsed=0;
6692 job_info->pagesprinted=0;
6694 job_info->devmode = devmode;
6699 /****************************************************************************
6700 Enumjobs at level 1.
6701 ****************************************************************************/
6703 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6704 const NT_PRINTER_INFO_LEVEL *ntprinter,
6705 RPC_BUFFER *buffer, uint32 offered,
6706 uint32 *needed, uint32 *returned)
6710 WERROR result = WERR_OK;
6712 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6718 for (i=0; i<*returned; i++)
6719 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6721 /* check the required size. */
6722 for (i=0; i<*returned; i++)
6723 (*needed) += spoolss_size_job_info_1(&info[i]);
6725 if (*needed > offered) {
6726 result = WERR_INSUFFICIENT_BUFFER;
6730 if (!rpcbuf_alloc_size(buffer, *needed)) {
6731 result = WERR_NOMEM;
6735 /* fill the buffer with the structures */
6736 for (i=0; i<*returned; i++)
6737 smb_io_job_info_1("", buffer, &info[i], 0);
6743 if ( !W_ERROR_IS_OK(result) )
6749 /****************************************************************************
6750 Enumjobs at level 2.
6751 ****************************************************************************/
6753 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6754 const NT_PRINTER_INFO_LEVEL *ntprinter,
6755 RPC_BUFFER *buffer, uint32 offered,
6756 uint32 *needed, uint32 *returned)
6758 JOB_INFO_2 *info = NULL;
6760 WERROR result = WERR_OK;
6761 DEVICEMODE *devmode = NULL;
6763 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6768 /* this should not be a failure condition if the devmode is NULL */
6770 devmode = construct_dev_mode(lp_const_servicename(snum));
6772 for (i=0; i<*returned; i++)
6773 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6775 /* check the required size. */
6776 for (i=0; i<*returned; i++)
6777 (*needed) += spoolss_size_job_info_2(&info[i]);
6779 if (*needed > offered) {
6780 result = WERR_INSUFFICIENT_BUFFER;
6784 if (!rpcbuf_alloc_size(buffer, *needed)) {
6785 result = WERR_NOMEM;
6789 /* fill the buffer with the structures */
6790 for (i=0; i<*returned; i++)
6791 smb_io_job_info_2("", buffer, &info[i], 0);
6794 free_devmode(devmode);
6797 if ( !W_ERROR_IS_OK(result) )
6804 /****************************************************************************
6806 ****************************************************************************/
6808 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6810 POLICY_HND *handle = &q_u->handle;
6811 uint32 level = q_u->level;
6812 RPC_BUFFER *buffer = NULL;
6813 uint32 offered = q_u->offered;
6814 uint32 *needed = &r_u->needed;
6815 uint32 *returned = &r_u->returned;
6817 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6819 print_status_struct prt_status;
6820 print_queue_struct *queue=NULL;
6822 /* that's an [in out] buffer */
6824 if (!q_u->buffer && (offered!=0)) {
6825 return WERR_INVALID_PARAM;
6828 if (offered > MAX_RPC_DATA_SIZE) {
6829 return WERR_INVALID_PARAM;
6832 rpcbuf_move(q_u->buffer, &r_u->buffer);
6833 buffer = r_u->buffer;
6835 DEBUG(4,("_spoolss_enumjobs\n"));
6840 /* lookup the printer snum and tdb entry */
6842 if (!get_printer_snum(p, handle, &snum, NULL))
6845 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6846 if ( !W_ERROR_IS_OK(wret) )
6849 *returned = print_queue_status(snum, &queue, &prt_status);
6850 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6852 if (*returned == 0) {
6854 free_a_printer(&ntprinter, 2);
6860 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6863 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6867 wret = WERR_UNKNOWN_LEVEL;
6872 free_a_printer( &ntprinter, 2 );
6876 /****************************************************************
6877 _spoolss_ScheduleJob
6878 ****************************************************************/
6880 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6881 struct spoolss_ScheduleJob *r)
6886 /****************************************************************
6888 ****************************************************************/
6890 WERROR _spoolss_SetJob(pipes_struct *p,
6891 struct spoolss_SetJob *r)
6893 POLICY_HND *handle = r->in.handle;
6894 uint32 jobid = r->in.job_id;
6895 uint32 command = r->in.command;
6898 WERROR errcode = WERR_BADFUNC;
6900 if (!get_printer_snum(p, handle, &snum, NULL)) {
6904 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6905 return WERR_INVALID_PRINTER_NAME;
6909 case SPOOLSS_JOB_CONTROL_CANCEL:
6910 case SPOOLSS_JOB_CONTROL_DELETE:
6911 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6915 case SPOOLSS_JOB_CONTROL_PAUSE:
6916 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6920 case SPOOLSS_JOB_CONTROL_RESTART:
6921 case SPOOLSS_JOB_CONTROL_RESUME:
6922 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6927 return WERR_UNKNOWN_LEVEL;
6933 /****************************************************************************
6934 Enumerates all printer drivers at level 1.
6935 ****************************************************************************/
6937 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6942 fstring *list = NULL;
6943 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6944 DRIVER_INFO_1 *driver_info_1=NULL;
6945 WERROR result = WERR_OK;
6949 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6951 ndrivers=get_ntdrivers(&list, architecture, version);
6952 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6954 if(ndrivers == -1) {
6955 SAFE_FREE(driver_info_1);
6960 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6961 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6967 for (i=0; i<ndrivers; i++) {
6969 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6970 ZERO_STRUCT(driver);
6971 status = get_a_printer_driver(&driver, 3, list[i],
6972 architecture, version);
6973 if (!W_ERROR_IS_OK(status)) {
6975 SAFE_FREE(driver_info_1);
6978 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6979 free_a_printer_driver(driver, 3);
6982 *returned+=ndrivers;
6986 /* check the required size. */
6987 for (i=0; i<*returned; i++) {
6988 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6989 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6992 if (*needed > offered) {
6993 result = WERR_INSUFFICIENT_BUFFER;
6997 if (!rpcbuf_alloc_size(buffer, *needed)) {
6998 result = WERR_NOMEM;
7002 /* fill the buffer with the driver structures */
7003 for (i=0; i<*returned; i++) {
7004 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7005 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7009 SAFE_FREE(driver_info_1);
7011 if ( !W_ERROR_IS_OK(result) )
7017 /****************************************************************************
7018 Enumerates all printer drivers at level 2.
7019 ****************************************************************************/
7021 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7026 fstring *list = NULL;
7027 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7028 DRIVER_INFO_2 *driver_info_2=NULL;
7029 WERROR result = WERR_OK;
7033 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7035 ndrivers=get_ntdrivers(&list, architecture, version);
7036 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7038 if(ndrivers == -1) {
7039 SAFE_FREE(driver_info_2);
7044 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7045 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7051 for (i=0; i<ndrivers; i++) {
7054 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7055 ZERO_STRUCT(driver);
7056 status = get_a_printer_driver(&driver, 3, list[i],
7057 architecture, version);
7058 if (!W_ERROR_IS_OK(status)) {
7060 SAFE_FREE(driver_info_2);
7063 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7064 free_a_printer_driver(driver, 3);
7067 *returned+=ndrivers;
7071 /* check the required size. */
7072 for (i=0; i<*returned; i++) {
7073 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7074 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7077 if (*needed > offered) {
7078 result = WERR_INSUFFICIENT_BUFFER;
7082 if (!rpcbuf_alloc_size(buffer, *needed)) {
7083 result = WERR_NOMEM;
7087 /* fill the buffer with the form structures */
7088 for (i=0; i<*returned; i++) {
7089 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7090 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7094 SAFE_FREE(driver_info_2);
7096 if ( !W_ERROR_IS_OK(result) )
7102 /****************************************************************************
7103 Enumerates all printer drivers at level 3.
7104 ****************************************************************************/
7106 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7111 fstring *list = NULL;
7112 DRIVER_INFO_3 *driver_info_3=NULL;
7113 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7114 WERROR result = WERR_OK;
7118 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7120 ndrivers=get_ntdrivers(&list, architecture, version);
7121 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7123 if(ndrivers == -1) {
7124 SAFE_FREE(driver_info_3);
7129 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7130 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7136 for (i=0; i<ndrivers; i++) {
7139 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7140 ZERO_STRUCT(driver);
7141 status = get_a_printer_driver(&driver, 3, list[i],
7142 architecture, version);
7143 if (!W_ERROR_IS_OK(status)) {
7145 SAFE_FREE(driver_info_3);
7148 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7149 free_a_printer_driver(driver, 3);
7152 *returned+=ndrivers;
7156 /* check the required size. */
7157 for (i=0; i<*returned; i++) {
7158 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7159 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7162 if (*needed > offered) {
7163 result = WERR_INSUFFICIENT_BUFFER;
7167 if (!rpcbuf_alloc_size(buffer, *needed)) {
7168 result = WERR_NOMEM;
7172 /* fill the buffer with the driver structures */
7173 for (i=0; i<*returned; i++) {
7174 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7175 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7179 for (i=0; i<*returned; i++) {
7180 SAFE_FREE(driver_info_3[i].dependentfiles);
7183 SAFE_FREE(driver_info_3);
7185 if ( !W_ERROR_IS_OK(result) )
7191 /****************************************************************************
7192 Enumerates all printer drivers.
7193 ****************************************************************************/
7195 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7197 uint32 level = q_u->level;
7198 RPC_BUFFER *buffer = NULL;
7199 uint32 offered = q_u->offered;
7200 uint32 *needed = &r_u->needed;
7201 uint32 *returned = &r_u->returned;
7202 const char *cservername;
7204 fstring architecture;
7206 /* that's an [in out] buffer */
7208 if (!q_u->buffer && (offered!=0)) {
7209 return WERR_INVALID_PARAM;
7212 if (offered > MAX_RPC_DATA_SIZE) {
7213 return WERR_INVALID_PARAM;
7216 rpcbuf_move(q_u->buffer, &r_u->buffer);
7217 buffer = r_u->buffer;
7219 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7224 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7225 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7227 cservername = canon_servername(servername);
7229 if (!is_myname_or_ipaddr(cservername))
7230 return WERR_UNKNOWN_PRINTER_DRIVER;
7234 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7236 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7238 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7240 return WERR_UNKNOWN_LEVEL;
7244 /****************************************************************************
7245 ****************************************************************************/
7247 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7249 form->flag=list->flag;
7250 init_unistr(&form->name, list->name);
7251 form->width=list->width;
7252 form->length=list->length;
7253 form->left=list->left;
7254 form->top=list->top;
7255 form->right=list->right;
7256 form->bottom=list->bottom;
7259 /****************************************************************************
7260 ****************************************************************************/
7262 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7263 struct spoolss_FormInfo1 *form,
7264 nt_forms_struct *list)
7266 form->form_name = talloc_strdup(mem_ctx, list->name);
7267 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7269 form->flags = list->flag;
7270 form->size.width = list->width;
7271 form->size.height = list->length;
7272 form->area.left = list->left;
7273 form->area.top = list->top;
7274 form->area.right = list->right;
7275 form->area.bottom = list->bottom;
7280 /****************************************************************************
7281 ****************************************************************************/
7283 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7285 uint32 level = q_u->level;
7286 RPC_BUFFER *buffer = NULL;
7287 uint32 offered = q_u->offered;
7288 uint32 *needed = &r_u->needed;
7289 uint32 *numofforms = &r_u->numofforms;
7290 uint32 numbuiltinforms;
7292 nt_forms_struct *list=NULL;
7293 nt_forms_struct *builtinlist=NULL;
7298 /* that's an [in out] buffer */
7300 if (!q_u->buffer && (offered!=0) ) {
7301 return WERR_INVALID_PARAM;
7304 if (offered > MAX_RPC_DATA_SIZE) {
7305 return WERR_INVALID_PARAM;
7308 rpcbuf_move(q_u->buffer, &r_u->buffer);
7309 buffer = r_u->buffer;
7311 DEBUG(4,("_spoolss_enumforms\n"));
7312 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7313 DEBUGADD(5,("Info level [%d]\n", level));
7315 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7316 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7317 *numofforms = get_ntforms(&list);
7318 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7319 *numofforms += numbuiltinforms;
7321 if (*numofforms == 0) {
7322 SAFE_FREE(builtinlist);
7324 return WERR_NO_MORE_ITEMS;
7329 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7330 SAFE_FREE(builtinlist);
7336 /* construct the list of form structures */
7337 for (i=0; i<numbuiltinforms; i++) {
7338 DEBUGADD(6,("Filling form number [%d]\n",i));
7339 fill_form_1(&forms_1[i], &builtinlist[i]);
7342 SAFE_FREE(builtinlist);
7344 for (; i<*numofforms; i++) {
7345 DEBUGADD(6,("Filling form number [%d]\n",i));
7346 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7351 /* check the required size. */
7352 for (i=0; i<numbuiltinforms; i++) {
7353 DEBUGADD(6,("adding form [%d]'s size\n",i));
7354 buffer_size += spoolss_size_form_1(&forms_1[i]);
7356 for (; i<*numofforms; i++) {
7357 DEBUGADD(6,("adding form [%d]'s size\n",i));
7358 buffer_size += spoolss_size_form_1(&forms_1[i]);
7361 *needed=buffer_size;
7363 if (*needed > offered) {
7366 return WERR_INSUFFICIENT_BUFFER;
7369 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7375 /* fill the buffer with the form structures */
7376 for (i=0; i<numbuiltinforms; i++) {
7377 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7378 smb_io_form_1("", buffer, &forms_1[i], 0);
7380 for (; i<*numofforms; i++) {
7381 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7382 smb_io_form_1("", buffer, &forms_1[i], 0);
7391 SAFE_FREE(builtinlist);
7392 return WERR_UNKNOWN_LEVEL;
7396 /****************************************************************
7398 ****************************************************************/
7400 WERROR _spoolss_GetForm(pipes_struct *p,
7401 struct spoolss_GetForm *r)
7403 uint32 level = r->in.level;
7404 uint32 offered = r->in.offered;
7405 uint32 *needed = r->out.needed;
7407 nt_forms_struct *list=NULL;
7408 nt_forms_struct builtin_form;
7410 union spoolss_FormInfo info;
7411 struct spoolss_FormInfo1 form_1;
7412 int numofforms=0, i=0;
7414 /* that's an [in out] buffer */
7416 if (!r->in.buffer && (offered!=0)) {
7417 return WERR_INVALID_PARAM;
7420 DEBUG(4,("_spoolss_GetForm\n"));
7421 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7422 DEBUGADD(5,("Info level [%d]\n", level));
7424 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7425 if (!foundBuiltin) {
7426 numofforms = get_ntforms(&list);
7427 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7429 if (numofforms == 0)
7433 ZERO_STRUCT(form_1);
7438 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7441 /* Check if the requested name is in the list of form structures */
7442 for (i=0; i<numofforms; i++) {
7444 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7445 list[i].name, r->in.form_name));
7447 if (strequal(r->in.form_name, list[i].name)) {
7448 DEBUGADD(6,("Found form %s number [%d]\n",
7449 r->in.form_name, i));
7450 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7456 if (i == numofforms) {
7460 /* check the required size. */
7462 info.info1 = form_1;
7464 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7466 if (*needed > offered) {
7468 return WERR_INSUFFICIENT_BUFFER;
7471 r->out.info->info1 = form_1;
7473 /* fill the buffer with the form structures */
7474 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7475 r->in.form_name, i));
7481 return WERR_UNKNOWN_LEVEL;
7485 /****************************************************************************
7486 ****************************************************************************/
7488 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7490 init_unistr(&port->port_name, name);
7493 /****************************************************************************
7494 TODO: This probably needs distinguish between TCP/IP and Local ports
7496 ****************************************************************************/
7498 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7500 init_unistr(&port->port_name, name);
7501 init_unistr(&port->monitor_name, "Local Monitor");
7502 init_unistr(&port->description, SPL_LOCAL_PORT );
7503 port->port_type=PORT_TYPE_WRITE;
7508 /****************************************************************************
7509 wrapper around the enumer ports command
7510 ****************************************************************************/
7512 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7514 char *cmd = lp_enumports_cmd();
7515 char **qlines = NULL;
7516 char *command = NULL;
7524 /* if no hook then just fill in the default port */
7527 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7530 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7531 TALLOC_FREE(qlines);
7538 /* we have a valid enumport command */
7540 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7545 DEBUG(10,("Running [%s]\n", command));
7546 ret = smbrun(command, &fd);
7547 DEBUG(10,("Returned [%d]\n", ret));
7548 TALLOC_FREE(command);
7553 return WERR_ACCESS_DENIED;
7557 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7558 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7568 /****************************************************************************
7570 ****************************************************************************/
7572 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7574 PORT_INFO_1 *ports=NULL;
7576 WERROR result = WERR_OK;
7577 char **qlines = NULL;
7580 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7581 if (!W_ERROR_IS_OK(result)) {
7582 TALLOC_FREE(qlines);
7587 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7588 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7589 win_errstr(WERR_NOMEM)));
7590 TALLOC_FREE(qlines);
7594 for (i=0; i<numlines; i++) {
7595 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7596 fill_port_1(&ports[i], qlines[i]);
7599 TALLOC_FREE(qlines);
7601 *returned = numlines;
7603 /* check the required size. */
7604 for (i=0; i<*returned; i++) {
7605 DEBUGADD(6,("adding port [%d]'s size\n", i));
7606 *needed += spoolss_size_port_info_1(&ports[i]);
7609 if (*needed > offered) {
7610 result = WERR_INSUFFICIENT_BUFFER;
7614 if (!rpcbuf_alloc_size(buffer, *needed)) {
7615 result = WERR_NOMEM;
7619 /* fill the buffer with the ports structures */
7620 for (i=0; i<*returned; i++) {
7621 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7622 smb_io_port_1("", buffer, &ports[i], 0);
7628 if ( !W_ERROR_IS_OK(result) )
7634 /****************************************************************************
7636 ****************************************************************************/
7638 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7640 PORT_INFO_2 *ports=NULL;
7642 WERROR result = WERR_OK;
7643 char **qlines = NULL;
7646 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7647 if ( !W_ERROR_IS_OK(result)) {
7648 TALLOC_FREE(qlines);
7653 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7654 TALLOC_FREE(qlines);
7658 for (i=0; i<numlines; i++) {
7659 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7660 fill_port_2(&(ports[i]), qlines[i]);
7664 TALLOC_FREE(qlines);
7666 *returned = numlines;
7668 /* check the required size. */
7669 for (i=0; i<*returned; i++) {
7670 DEBUGADD(6,("adding port [%d]'s size\n", i));
7671 *needed += spoolss_size_port_info_2(&ports[i]);
7674 if (*needed > offered) {
7675 result = WERR_INSUFFICIENT_BUFFER;
7679 if (!rpcbuf_alloc_size(buffer, *needed)) {
7680 result = WERR_NOMEM;
7684 /* fill the buffer with the ports structures */
7685 for (i=0; i<*returned; i++) {
7686 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7687 smb_io_port_2("", buffer, &ports[i], 0);
7693 if ( !W_ERROR_IS_OK(result) )
7699 /****************************************************************************
7701 ****************************************************************************/
7703 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7705 uint32 level = q_u->level;
7706 RPC_BUFFER *buffer = NULL;
7707 uint32 offered = q_u->offered;
7708 uint32 *needed = &r_u->needed;
7709 uint32 *returned = &r_u->returned;
7711 /* that's an [in out] buffer */
7713 if (!q_u->buffer && (offered!=0)) {
7714 return WERR_INVALID_PARAM;
7717 if (offered > MAX_RPC_DATA_SIZE) {
7718 return WERR_INVALID_PARAM;
7721 rpcbuf_move(q_u->buffer, &r_u->buffer);
7722 buffer = r_u->buffer;
7724 DEBUG(4,("_spoolss_enumports\n"));
7731 return enumports_level_1(buffer, offered, needed, returned);
7733 return enumports_level_2(buffer, offered, needed, returned);
7735 return WERR_UNKNOWN_LEVEL;
7739 /****************************************************************************
7740 ****************************************************************************/
7742 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7744 struct spoolss_SetPrinterInfoCtr *info_ctr,
7745 struct spoolss_DeviceMode *devmode,
7746 struct security_descriptor *sec_desc,
7747 struct spoolss_UserLevelCtr *user_ctr,
7750 NT_PRINTER_INFO_LEVEL *printer = NULL;
7753 WERROR err = WERR_OK;
7755 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7756 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7760 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7761 if (!convert_printer_info_new(info_ctr, printer)) {
7762 free_a_printer(&printer, 2);
7766 /* check to see if the printer already exists */
7768 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7769 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7770 printer->info_2->sharename));
7771 free_a_printer(&printer, 2);
7772 return WERR_PRINTER_ALREADY_EXISTS;
7775 /* FIXME!!! smbd should check to see if the driver is installed before
7776 trying to add a printer like this --jerry */
7778 if (*lp_addprinter_cmd() ) {
7779 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7781 free_a_printer(&printer,2);
7782 return WERR_ACCESS_DENIED;
7785 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7786 "smb.conf parameter \"addprinter command\" is defined. This"
7787 "parameter must exist for this call to succeed\n",
7788 printer->info_2->sharename ));
7791 /* use our primary netbios name since get_a_printer() will convert
7792 it to what the client expects on a case by case basis */
7794 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7795 printer->info_2->sharename);
7798 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7799 free_a_printer(&printer,2);
7800 return WERR_ACCESS_DENIED;
7803 /* you must be a printer admin to add a new printer */
7804 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7805 free_a_printer(&printer,2);
7806 return WERR_ACCESS_DENIED;
7810 * Do sanity check on the requested changes for Samba.
7813 if (!check_printer_ok(printer->info_2, snum)) {
7814 free_a_printer(&printer,2);
7815 return WERR_INVALID_PARAM;
7819 * When a printer is created, the drivername bound to the printer is used
7820 * to lookup previously saved driver initialization info, which is then
7821 * bound to the new printer, simulating what happens in the Windows arch.
7826 set_driver_init(printer, 2);
7830 /* A valid devmode was included, convert and link it
7832 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7834 if (!convert_devicemode_new(printer->info_2->printername,
7836 &printer->info_2->devmode))
7840 /* write the ASCII on disk */
7841 err = mod_a_printer(printer, 2);
7842 if (!W_ERROR_IS_OK(err)) {
7843 free_a_printer(&printer,2);
7847 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7848 /* Handle open failed - remove addition. */
7849 del_a_printer(printer->info_2->sharename);
7850 free_a_printer(&printer,2);
7851 ZERO_STRUCTP(handle);
7852 return WERR_ACCESS_DENIED;
7855 update_c_setprinter(False);
7856 free_a_printer(&printer,2);
7861 /****************************************************************
7862 _spoolss_AddPrinterEx
7863 ****************************************************************/
7865 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7866 struct spoolss_AddPrinterEx *r)
7868 switch (r->in.info_ctr->level) {
7870 /* we don't handle yet */
7871 /* but I know what to do ... */
7872 return WERR_UNKNOWN_LEVEL;
7874 return spoolss_addprinterex_level_2(p, r->in.server,
7876 r->in.devmode_ctr->devmode,
7877 r->in.secdesc_ctr->sd,
7878 r->in.userlevel_ctr,
7881 return WERR_UNKNOWN_LEVEL;
7885 /****************************************************************
7886 _spoolss_AddPrinterDriver
7887 ****************************************************************/
7889 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7890 struct spoolss_AddPrinterDriver *r)
7892 uint32_t level = r->in.info_ctr->level;
7893 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7894 WERROR err = WERR_OK;
7895 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7896 fstring driver_name;
7900 switch (p->hdr_req.opnum) {
7901 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7902 fn = "_spoolss_AddPrinterDriver";
7904 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7905 fn = "_spoolss_AddPrinterDriverEx";
7908 return WERR_INVALID_PARAM;
7913 if (level != 3 && level != 6) {
7914 /* Clever hack from Martin Zielinski <mz@seh.de>
7915 * to allow downgrade from level 8 (Vista).
7917 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7918 return WERR_UNKNOWN_LEVEL;
7921 ZERO_STRUCT(driver);
7923 if (!convert_printer_driver_info(info, &driver, level)) {
7928 DEBUG(5,("Cleaning driver's information\n"));
7929 err = clean_up_driver_struct(p, driver, level);
7930 if (!W_ERROR_IS_OK(err))
7933 DEBUG(5,("Moving driver to final destination\n"));
7934 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7939 if (add_a_printer_driver(driver, level)!=0) {
7940 err = WERR_ACCESS_DENIED;
7946 fstrcpy(driver_name,
7947 driver.info_3->name ? driver.info_3->name : "");
7950 fstrcpy(driver_name,
7951 driver.info_6->name ? driver.info_6->name : "");
7956 * I think this is where he DrvUpgradePrinter() hook would be
7957 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7958 * server. Right now, we just need to send ourselves a message
7959 * to update each printer bound to this driver. --jerry
7962 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7963 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7968 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7969 * decide if the driver init data should be deleted. The rules are:
7970 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7971 * 2) delete init data only if there is no 2k/Xp driver
7972 * 3) always delete init data
7973 * The generalized rule is always use init data from the highest order driver.
7974 * It is necessary to follow the driver install by an initialization step to
7975 * finish off this process.
7978 version = driver.info_3->cversion;
7979 else if (level == 6)
7980 version = driver.info_6->version;
7985 * 9x printer driver - never delete init data
7988 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7993 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7994 * there is no 2k/Xp driver init data for this driver name.
7998 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
8000 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
8002 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
8004 if (!del_driver_init(driver_name))
8005 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
8009 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
8011 free_a_printer_driver(driver1,3);
8012 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
8019 * 2k or Xp printer driver - always delete init data
8022 if (!del_driver_init(driver_name))
8023 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
8028 DEBUG(0,("%s: invalid level=%d\n", fn, level));
8034 free_a_printer_driver(driver, level);
8038 /****************************************************************
8039 _spoolss_AddPrinterDriverEx
8040 ****************************************************************/
8042 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8043 struct spoolss_AddPrinterDriverEx *r)
8045 struct spoolss_AddPrinterDriver a;
8048 * we only support the semantics of AddPrinterDriver()
8049 * i.e. only copy files that are newer than existing ones
8052 if (r->in.flags != APD_COPY_NEW_FILES) {
8053 return WERR_ACCESS_DENIED;
8056 a.in.servername = r->in.servername;
8057 a.in.info_ctr = r->in.info_ctr;
8059 return _spoolss_AddPrinterDriver(p, &a);
8062 /****************************************************************************
8063 ****************************************************************************/
8065 struct _spoolss_paths {
8071 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
8073 static const struct _spoolss_paths spoolss_paths[]= {
8074 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
8075 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
8078 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
8079 const char *servername,
8080 const char *environment,
8084 const char *pservername = NULL;
8085 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8086 const char *short_archi;
8090 /* environment may be empty */
8091 if (environment && strlen(environment)) {
8092 long_archi = environment;
8095 /* servername may be empty */
8096 if (servername && strlen(servername)) {
8097 pservername = canon_servername(servername);
8099 if (!is_myname_or_ipaddr(pservername)) {
8100 return WERR_INVALID_PARAM;
8104 if (!(short_archi = get_short_archi(long_archi))) {
8105 return WERR_INVALID_ENVIRONMENT;
8108 switch (component) {
8109 case SPOOLSS_PRTPROCS_PATH:
8110 case SPOOLSS_DRIVER_PATH:
8112 *path = talloc_asprintf(mem_ctx,
8115 spoolss_paths[component].share,
8118 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
8119 SPOOLSS_DEFAULT_SERVER_PATH,
8120 spoolss_paths[component].dir,
8125 return WERR_INVALID_PARAM;
8135 /****************************************************************************
8136 ****************************************************************************/
8138 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8139 const char *servername,
8140 const char *environment,
8141 struct spoolss_DriverDirectoryInfo1 *r,
8148 werr = compose_spoolss_server_path(mem_ctx,
8151 SPOOLSS_DRIVER_PATH,
8153 if (!W_ERROR_IS_OK(werr)) {
8157 DEBUG(4,("printer driver directory: [%s]\n", path));
8159 r->directory_name = path;
8161 *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
8163 if (*needed > offered) {
8165 return WERR_INSUFFICIENT_BUFFER;
8171 /****************************************************************
8172 _spoolss_GetPrinterDriverDirectory
8173 ****************************************************************/
8175 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8176 struct spoolss_GetPrinterDriverDirectory *r)
8180 /* that's an [in out] buffer */
8182 if (!r->in.buffer && (r->in.offered != 0)) {
8183 return WERR_INVALID_PARAM;
8186 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
8191 /* r->in.level is ignored */
8193 werror = getprinterdriverdir_level_1(p->mem_ctx,
8196 &r->out.info->info1,
8199 if (!W_ERROR_IS_OK(werror)) {
8200 TALLOC_FREE(r->out.info);
8206 /****************************************************************************
8207 ****************************************************************************/
8209 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8211 POLICY_HND *handle = &q_u->handle;
8212 uint32 idx = q_u->index;
8213 uint32 in_value_len = q_u->valuesize;
8214 uint32 in_data_len = q_u->datasize;
8215 uint32 *out_max_value_len = &r_u->valuesize;
8216 uint16 **out_value = &r_u->value;
8217 uint32 *out_value_len = &r_u->realvaluesize;
8218 uint32 *out_type = &r_u->type;
8219 uint32 *out_max_data_len = &r_u->datasize;
8220 uint8 **data_out = &r_u->data;
8221 uint32 *out_data_len = &r_u->realdatasize;
8223 NT_PRINTER_INFO_LEVEL *printer = NULL;
8225 uint32 biggest_valuesize;
8226 uint32 biggest_datasize;
8228 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8231 REGISTRY_VALUE *val = NULL;
8232 NT_PRINTER_DATA *p_data;
8233 int i, key_index, num_values;
8238 *out_max_data_len = 0;
8242 DEBUG(5,("spoolss_enumprinterdata\n"));
8245 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8249 if (!get_printer_snum(p,handle, &snum, NULL))
8252 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8253 if (!W_ERROR_IS_OK(result))
8256 p_data = printer->info_2->data;
8257 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8262 * The NT machine wants to know the biggest size of value and data
8264 * cf: MSDN EnumPrinterData remark section
8267 if ( !in_value_len && !in_data_len && (key_index != -1) )
8269 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8271 biggest_valuesize = 0;
8272 biggest_datasize = 0;
8274 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8276 for ( i=0; i<num_values; i++ )
8278 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8280 name_length = strlen(val->valuename);
8281 if ( strlen(val->valuename) > biggest_valuesize )
8282 biggest_valuesize = name_length;
8284 if ( val->size > biggest_datasize )
8285 biggest_datasize = val->size;
8287 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8291 /* the value is an UNICODE string but real_value_size is the length
8292 in bytes including the trailing 0 */
8294 *out_value_len = 2 * (1+biggest_valuesize);
8295 *out_data_len = biggest_datasize;
8297 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8303 * the value len is wrong in NT sp3
8304 * that's the number of bytes not the number of unicode chars
8307 if ( key_index != -1 )
8308 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8313 /* out_value should default to "" or else NT4 has
8314 problems unmarshalling the response */
8316 *out_max_value_len=(in_value_len/sizeof(uint16));
8319 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8321 result = WERR_NOMEM;
8324 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8330 /* the data is counted in bytes */
8332 *out_max_data_len = in_data_len;
8333 *out_data_len = in_data_len;
8335 /* only allocate when given a non-zero data_len */
8337 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8339 result = WERR_NOMEM;
8343 result = WERR_NO_MORE_ITEMS;
8349 * - counted in bytes in the request
8350 * - counted in UNICODE chars in the max reply
8351 * - counted in bytes in the real size
8353 * take a pause *before* coding not *during* coding
8357 *out_max_value_len=(in_value_len/sizeof(uint16));
8359 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8361 result = WERR_NOMEM;
8365 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8373 *out_type = regval_type( val );
8375 /* data - counted in bytes */
8377 *out_max_data_len = in_data_len;
8378 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8380 result = WERR_NOMEM;
8383 data_len = regval_size(val);
8384 if ( *data_out && data_len )
8385 memcpy( *data_out, regval_data_p(val), data_len );
8386 *out_data_len = data_len;
8390 free_a_printer(&printer, 2);
8394 /****************************************************************************
8395 ****************************************************************************/
8397 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8399 POLICY_HND *handle = &q_u->handle;
8400 UNISTR2 *value = &q_u->value;
8401 uint32 type = q_u->type;
8402 uint8 *data = q_u->data;
8403 uint32 real_len = q_u->real_len;
8405 NT_PRINTER_INFO_LEVEL *printer = NULL;
8407 WERROR status = WERR_OK;
8408 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8411 DEBUG(5,("spoolss_setprinterdata\n"));
8414 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8418 if ( Printer->printer_type == SPLHND_SERVER ) {
8419 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8420 return WERR_INVALID_PARAM;
8423 if (!get_printer_snum(p,handle, &snum, NULL))
8427 * Access check : NT returns "access denied" if you make a
8428 * SetPrinterData call without the necessary privildge.
8429 * we were originally returning OK if nothing changed
8430 * which made Win2k issue **a lot** of SetPrinterData
8431 * when connecting to a printer --jerry
8434 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8436 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8437 status = WERR_ACCESS_DENIED;
8441 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8442 if (!W_ERROR_IS_OK(status))
8445 unistr2_to_ascii(valuename, value, sizeof(valuename));
8448 * When client side code sets a magic printer data key, detect it and save
8449 * the current printer data and the magic key's data (its the DEVMODE) for
8450 * future printer/driver initializations.
8452 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8454 /* Set devmode and printer initialization info */
8455 status = save_driver_init( printer, 2, data, real_len );
8457 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8461 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8462 type, data, real_len );
8463 if ( W_ERROR_IS_OK(status) )
8464 status = mod_a_printer(printer, 2);
8468 free_a_printer(&printer, 2);
8473 /****************************************************************
8474 _spoolss_ResetPrinter
8475 ****************************************************************/
8477 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8478 struct spoolss_ResetPrinter *r)
8480 POLICY_HND *handle = r->in.handle;
8481 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8484 DEBUG(5,("_spoolss_ResetPrinter\n"));
8487 * All we do is to check to see if the handle and queue is valid.
8488 * This call really doesn't mean anything to us because we only
8489 * support RAW printing. --jerry
8493 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8494 OUR_HANDLE(handle)));
8498 if (!get_printer_snum(p,handle, &snum, NULL))
8502 /* blindly return success */
8506 /****************************************************************
8507 _spoolss_DeletePrinterData
8508 ****************************************************************/
8510 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8511 struct spoolss_DeletePrinterData *r)
8513 POLICY_HND *handle = r->in.handle;
8514 NT_PRINTER_INFO_LEVEL *printer = NULL;
8516 WERROR status = WERR_OK;
8517 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8519 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8522 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8523 OUR_HANDLE(handle)));
8527 if (!get_printer_snum(p, handle, &snum, NULL))
8530 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8531 DEBUG(3, ("_spoolss_DeletePrinterData: "
8532 "printer properties change denied by handle\n"));
8533 return WERR_ACCESS_DENIED;
8536 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8537 if (!W_ERROR_IS_OK(status))
8540 if (!r->in.value_name) {
8541 free_a_printer(&printer, 2);
8545 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8548 if ( W_ERROR_IS_OK(status) )
8549 mod_a_printer( printer, 2 );
8551 free_a_printer(&printer, 2);
8556 /****************************************************************
8558 ****************************************************************/
8560 WERROR _spoolss_AddForm(pipes_struct *p,
8561 struct spoolss_AddForm *r)
8563 POLICY_HND *handle = r->in.handle;
8564 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8565 nt_forms_struct tmpForm;
8567 WERROR status = WERR_OK;
8568 NT_PRINTER_INFO_LEVEL *printer = NULL;
8571 nt_forms_struct *list=NULL;
8572 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8574 DEBUG(5,("_spoolss_AddForm\n"));
8577 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8578 OUR_HANDLE(handle)));
8583 /* forms can be added on printer of on the print server handle */
8585 if ( Printer->printer_type == SPLHND_PRINTER )
8587 if (!get_printer_snum(p,handle, &snum, NULL))
8590 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8591 if (!W_ERROR_IS_OK(status))
8595 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8596 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8597 status = WERR_ACCESS_DENIED;
8601 /* can't add if builtin */
8603 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8604 status = WERR_FILE_EXISTS;
8608 count = get_ntforms(&list);
8610 if(!add_a_form(&list, form, &count)) {
8611 status = WERR_NOMEM;
8615 write_ntforms(&list, count);
8618 * ChangeID must always be set if this is a printer
8621 if ( Printer->printer_type == SPLHND_PRINTER )
8622 status = mod_a_printer(printer, 2);
8626 free_a_printer(&printer, 2);
8632 /****************************************************************
8634 ****************************************************************/
8636 WERROR _spoolss_DeleteForm(pipes_struct *p,
8637 struct spoolss_DeleteForm *r)
8639 POLICY_HND *handle = r->in.handle;
8640 const char *form_name = r->in.form_name;
8641 nt_forms_struct tmpForm;
8643 nt_forms_struct *list=NULL;
8644 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8646 WERROR status = WERR_OK;
8647 NT_PRINTER_INFO_LEVEL *printer = NULL;
8649 DEBUG(5,("_spoolss_DeleteForm\n"));
8652 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8653 OUR_HANDLE(handle)));
8657 /* forms can be deleted on printer of on the print server handle */
8659 if ( Printer->printer_type == SPLHND_PRINTER )
8661 if (!get_printer_snum(p,handle, &snum, NULL))
8664 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8665 if (!W_ERROR_IS_OK(status))
8669 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8670 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8671 status = WERR_ACCESS_DENIED;
8675 /* can't delete if builtin */
8677 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8678 status = WERR_INVALID_PARAM;
8682 count = get_ntforms(&list);
8684 if ( !delete_a_form(&list, form_name, &count, &status ))
8688 * ChangeID must always be set if this is a printer
8691 if ( Printer->printer_type == SPLHND_PRINTER )
8692 status = mod_a_printer(printer, 2);
8696 free_a_printer(&printer, 2);
8702 /****************************************************************
8704 ****************************************************************/
8706 WERROR _spoolss_SetForm(pipes_struct *p,
8707 struct spoolss_SetForm *r)
8709 POLICY_HND *handle = r->in.handle;
8710 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8711 nt_forms_struct tmpForm;
8713 WERROR status = WERR_OK;
8714 NT_PRINTER_INFO_LEVEL *printer = NULL;
8717 nt_forms_struct *list=NULL;
8718 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8720 DEBUG(5,("_spoolss_SetForm\n"));
8723 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8724 OUR_HANDLE(handle)));
8728 /* forms can be modified on printer of on the print server handle */
8730 if ( Printer->printer_type == SPLHND_PRINTER )
8732 if (!get_printer_snum(p,handle, &snum, NULL))
8735 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8736 if (!W_ERROR_IS_OK(status))
8740 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8741 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8742 status = WERR_ACCESS_DENIED;
8746 /* can't set if builtin */
8747 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8748 status = WERR_INVALID_PARAM;
8752 count = get_ntforms(&list);
8753 update_a_form(&list, form, count);
8754 write_ntforms(&list, count);
8757 * ChangeID must always be set if this is a printer
8760 if ( Printer->printer_type == SPLHND_PRINTER )
8761 status = mod_a_printer(printer, 2);
8766 free_a_printer(&printer, 2);
8772 /****************************************************************************
8773 enumprintprocessors level 1.
8774 ****************************************************************************/
8776 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8778 PRINTPROCESSOR_1 *info_1=NULL;
8779 WERROR result = WERR_OK;
8781 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8786 init_unistr(&info_1->name, "winprint");
8788 *needed += spoolss_size_printprocessor_info_1(info_1);
8790 if (*needed > offered) {
8791 result = WERR_INSUFFICIENT_BUFFER;
8795 if (!rpcbuf_alloc_size(buffer, *needed)) {
8796 result = WERR_NOMEM;
8800 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8805 if ( !W_ERROR_IS_OK(result) )
8811 /****************************************************************************
8812 ****************************************************************************/
8814 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8816 uint32 level = q_u->level;
8817 RPC_BUFFER *buffer = NULL;
8818 uint32 offered = q_u->offered;
8819 uint32 *needed = &r_u->needed;
8820 uint32 *returned = &r_u->returned;
8822 /* that's an [in out] buffer */
8824 if (!q_u->buffer && (offered!=0)) {
8825 return WERR_INVALID_PARAM;
8828 if (offered > MAX_RPC_DATA_SIZE) {
8829 return WERR_INVALID_PARAM;
8832 rpcbuf_move(q_u->buffer, &r_u->buffer);
8833 buffer = r_u->buffer;
8835 DEBUG(5,("spoolss_enumprintprocessors\n"));
8838 * Enumerate the print processors ...
8840 * Just reply with "winprint", to keep NT happy
8841 * and I can use my nice printer checker.
8849 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8851 return WERR_UNKNOWN_LEVEL;
8855 /****************************************************************************
8856 enumprintprocdatatypes level 1.
8857 ****************************************************************************/
8859 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8861 PRINTPROCDATATYPE_1 *info_1=NULL;
8862 WERROR result = WERR_OK;
8864 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8869 init_unistr(&info_1->name, "RAW");
8871 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8873 if (*needed > offered) {
8874 result = WERR_INSUFFICIENT_BUFFER;
8878 if (!rpcbuf_alloc_size(buffer, *needed)) {
8879 result = WERR_NOMEM;
8883 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8888 if ( !W_ERROR_IS_OK(result) )
8894 /****************************************************************************
8895 ****************************************************************************/
8897 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8899 uint32 level = q_u->level;
8900 RPC_BUFFER *buffer = NULL;
8901 uint32 offered = q_u->offered;
8902 uint32 *needed = &r_u->needed;
8903 uint32 *returned = &r_u->returned;
8905 /* that's an [in out] buffer */
8907 if (!q_u->buffer && (offered!=0)) {
8908 return WERR_INVALID_PARAM;
8911 if (offered > MAX_RPC_DATA_SIZE) {
8912 return WERR_INVALID_PARAM;
8915 rpcbuf_move(q_u->buffer, &r_u->buffer);
8916 buffer = r_u->buffer;
8918 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8925 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8927 return WERR_UNKNOWN_LEVEL;
8931 /****************************************************************************
8932 enumprintmonitors level 1.
8933 ****************************************************************************/
8935 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8937 PRINTMONITOR_1 *info_1;
8938 WERROR result = WERR_OK;
8941 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8946 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8947 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8949 for ( i=0; i<*returned; i++ ) {
8950 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8953 if (*needed > offered) {
8954 result = WERR_INSUFFICIENT_BUFFER;
8958 if (!rpcbuf_alloc_size(buffer, *needed)) {
8959 result = WERR_NOMEM;
8963 for ( i=0; i<*returned; i++ ) {
8964 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8970 if ( !W_ERROR_IS_OK(result) )
8976 /****************************************************************************
8977 enumprintmonitors level 2.
8978 ****************************************************************************/
8980 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8982 PRINTMONITOR_2 *info_2;
8983 WERROR result = WERR_OK;
8986 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8991 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8992 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8993 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8995 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8996 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8997 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8999 for ( i=0; i<*returned; i++ ) {
9000 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
9003 if (*needed > offered) {
9004 result = WERR_INSUFFICIENT_BUFFER;
9008 if (!rpcbuf_alloc_size(buffer, *needed)) {
9009 result = WERR_NOMEM;
9013 for ( i=0; i<*returned; i++ ) {
9014 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
9020 if ( !W_ERROR_IS_OK(result) )
9026 /****************************************************************************
9027 ****************************************************************************/
9029 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
9031 uint32 level = q_u->level;
9032 RPC_BUFFER *buffer = NULL;
9033 uint32 offered = q_u->offered;
9034 uint32 *needed = &r_u->needed;
9035 uint32 *returned = &r_u->returned;
9037 /* that's an [in out] buffer */
9039 if (!q_u->buffer && (offered!=0)) {
9040 return WERR_INVALID_PARAM;
9043 if (offered > MAX_RPC_DATA_SIZE) {
9044 return WERR_INVALID_PARAM;
9047 rpcbuf_move(q_u->buffer, &r_u->buffer);
9048 buffer = r_u->buffer;
9050 DEBUG(5,("spoolss_enumprintmonitors\n"));
9053 * Enumerate the print monitors ...
9055 * Just reply with "Local Port", to keep NT happy
9056 * and I can use my nice printer checker.
9064 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9066 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9068 return WERR_UNKNOWN_LEVEL;
9072 /****************************************************************************
9073 ****************************************************************************/
9075 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9076 NT_PRINTER_INFO_LEVEL *ntprinter,
9077 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9082 JOB_INFO_1 *info_1=NULL;
9083 WERROR result = WERR_OK;
9085 info_1=SMB_MALLOC_P(JOB_INFO_1);
9087 if (info_1 == NULL) {
9091 for (i=0; i<count && found==False; i++) {
9092 if ((*queue)[i].job==(int)jobid)
9098 /* NT treats not found as bad param... yet another bad choice */
9099 return WERR_INVALID_PARAM;
9102 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9104 *needed += spoolss_size_job_info_1(info_1);
9106 if (*needed > offered) {
9107 result = WERR_INSUFFICIENT_BUFFER;
9111 if (!rpcbuf_alloc_size(buffer, *needed)) {
9112 result = WERR_NOMEM;
9116 smb_io_job_info_1("", buffer, info_1, 0);
9124 /****************************************************************************
9125 ****************************************************************************/
9127 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9128 NT_PRINTER_INFO_LEVEL *ntprinter,
9129 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9136 DEVICEMODE *devmode = NULL;
9137 NT_DEVICEMODE *nt_devmode = NULL;
9139 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9142 ZERO_STRUCTP(info_2);
9144 for ( i=0; i<count && found==False; i++ )
9146 if ((*queue)[i].job == (int)jobid)
9151 /* NT treats not found as bad param... yet another bad
9153 result = WERR_INVALID_PARAM;
9158 * if the print job does not have a DEVMODE associated with it,
9159 * just use the one for the printer. A NULL devicemode is not
9160 * a failure condition
9163 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9164 devmode = construct_dev_mode(lp_const_servicename(snum));
9166 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9167 ZERO_STRUCTP( devmode );
9168 convert_nt_devicemode( devmode, nt_devmode );
9172 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9174 *needed += spoolss_size_job_info_2(info_2);
9176 if (*needed > offered) {
9177 result = WERR_INSUFFICIENT_BUFFER;
9181 if (!rpcbuf_alloc_size(buffer, *needed)) {
9182 result = WERR_NOMEM;
9186 smb_io_job_info_2("", buffer, info_2, 0);
9191 /* Cleanup allocated memory */
9193 free_job_info_2(info_2); /* Also frees devmode */
9199 /****************************************************************************
9200 ****************************************************************************/
9202 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9204 POLICY_HND *handle = &q_u->handle;
9205 uint32 jobid = q_u->jobid;
9206 uint32 level = q_u->level;
9207 RPC_BUFFER *buffer = NULL;
9208 uint32 offered = q_u->offered;
9209 uint32 *needed = &r_u->needed;
9210 WERROR wstatus = WERR_OK;
9211 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9214 print_queue_struct *queue = NULL;
9215 print_status_struct prt_status;
9217 /* that's an [in out] buffer */
9219 if (!q_u->buffer && (offered!=0)) {
9220 return WERR_INVALID_PARAM;
9223 if (offered > MAX_RPC_DATA_SIZE) {
9224 return WERR_INVALID_PARAM;
9227 rpcbuf_move(q_u->buffer, &r_u->buffer);
9228 buffer = r_u->buffer;
9230 DEBUG(5,("spoolss_getjob\n"));
9234 if (!get_printer_snum(p, handle, &snum, NULL))
9237 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9238 if ( !W_ERROR_IS_OK(wstatus) )
9241 count = print_queue_status(snum, &queue, &prt_status);
9243 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9244 count, prt_status.status, prt_status.message));
9248 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9249 buffer, offered, needed);
9252 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9253 buffer, offered, needed);
9256 wstatus = WERR_UNKNOWN_LEVEL;
9261 free_a_printer( &ntprinter, 2 );
9266 /****************************************************************
9267 _spoolss_GetPrinterDataEx
9269 From MSDN documentation of GetPrinterDataEx: pass request
9270 to GetPrinterData if key is "PrinterDriverData".
9271 ****************************************************************/
9273 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9274 struct spoolss_GetPrinterDataEx *r)
9276 POLICY_HND *handle = r->in.handle;
9278 const char *keyname = r->in.key_name;
9279 const char *valuename = r->in.value_name;
9281 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9283 NT_PRINTER_INFO_LEVEL *printer = NULL;
9285 WERROR status = WERR_OK;
9287 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9289 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9290 keyname, valuename));
9292 /* in case of problem, return some default values */
9298 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9299 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9300 status = WERR_BADFID;
9304 /* Is the handle to a printer or to the server? */
9306 if (Printer->printer_type == SPLHND_SERVER) {
9307 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9308 "Not implemented for server handles yet\n"));
9309 status = WERR_INVALID_PARAM;
9313 if ( !get_printer_snum(p,handle, &snum, NULL) )
9316 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9317 if ( !W_ERROR_IS_OK(status) )
9320 /* check to see if the keyname is valid */
9321 if ( !strlen(keyname) ) {
9322 status = WERR_INVALID_PARAM;
9326 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9327 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9328 "Invalid keyname [%s]\n", keyname ));
9329 free_a_printer( &printer, 2 );
9330 status = WERR_BADFILE;
9334 /* When given a new keyname, we should just create it */
9336 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9337 r->out.type, &data, r->out.needed,
9340 if (*r->out.needed > r->in.offered) {
9341 status = WERR_MORE_DATA;
9344 if (W_ERROR_IS_OK(status)) {
9345 memcpy(r->out.buffer, data, r->in.offered);
9350 free_a_printer( &printer, 2 );
9355 /****************************************************************
9356 _spoolss_SetPrinterDataEx
9357 ****************************************************************/
9359 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9360 struct spoolss_SetPrinterDataEx *r)
9362 POLICY_HND *handle = r->in.handle;
9363 NT_PRINTER_INFO_LEVEL *printer = NULL;
9365 WERROR status = WERR_OK;
9366 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9369 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9371 /* From MSDN documentation of SetPrinterDataEx: pass request to
9372 SetPrinterData if key is "PrinterDriverData" */
9375 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9376 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9380 if ( Printer->printer_type == SPLHND_SERVER ) {
9381 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9382 "Not implemented for server handles yet\n"));
9383 return WERR_INVALID_PARAM;
9386 if ( !get_printer_snum(p,handle, &snum, NULL) )
9390 * Access check : NT returns "access denied" if you make a
9391 * SetPrinterData call without the necessary privildge.
9392 * we were originally returning OK if nothing changed
9393 * which made Win2k issue **a lot** of SetPrinterData
9394 * when connecting to a printer --jerry
9397 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9399 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9400 "change denied by handle access permissions\n"));
9401 return WERR_ACCESS_DENIED;
9404 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9405 if (!W_ERROR_IS_OK(status))
9408 /* check for OID in valuename */
9410 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9416 /* save the registry data */
9418 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9419 r->in.type, r->in.buffer, r->in.offered );
9421 if ( W_ERROR_IS_OK(status) )
9423 /* save the OID if one was specified */
9425 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9426 r->in.key_name, SPOOL_OID_KEY);
9432 * I'm not checking the status here on purpose. Don't know
9433 * if this is right, but I'm returning the status from the
9434 * previous set_printer_dataex() call. I have no idea if
9435 * this is right. --jerry
9438 set_printer_dataex( printer, str, r->in.value_name,
9439 REG_SZ, (uint8 *)oid_string,
9440 strlen(oid_string)+1 );
9443 status = mod_a_printer(printer, 2);
9446 free_a_printer(&printer, 2);
9451 /****************************************************************
9452 _spoolss_DeletePrinterDataEx
9453 ****************************************************************/
9455 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9456 struct spoolss_DeletePrinterDataEx *r)
9458 POLICY_HND *handle = r->in.handle;
9459 NT_PRINTER_INFO_LEVEL *printer = NULL;
9461 WERROR status = WERR_OK;
9462 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9464 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9467 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9468 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9472 if (!get_printer_snum(p, handle, &snum, NULL))
9475 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9476 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9477 "printer properties change denied by handle\n"));
9478 return WERR_ACCESS_DENIED;
9481 if (!r->in.value_name || !r->in.key_name) {
9485 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9486 if (!W_ERROR_IS_OK(status))
9489 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9491 if ( W_ERROR_IS_OK(status) )
9492 mod_a_printer( printer, 2 );
9494 free_a_printer(&printer, 2);
9499 /********************************************************************
9500 * spoolss_enumprinterkey
9501 ********************************************************************/
9504 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9507 fstring *keynames = NULL;
9508 uint16 *enumkeys = NULL;
9511 POLICY_HND *handle = &q_u->handle;
9512 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9513 NT_PRINTER_DATA *data;
9514 NT_PRINTER_INFO_LEVEL *printer = NULL;
9516 WERROR status = WERR_BADFILE;
9519 DEBUG(4,("_spoolss_enumprinterkey\n"));
9522 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9526 if ( !get_printer_snum(p,handle, &snum, NULL) )
9529 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9530 if (!W_ERROR_IS_OK(status))
9533 /* get the list of subkey names */
9535 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9536 data = printer->info_2->data;
9538 num_keys = get_printer_subkeys( data, key, &keynames );
9540 if ( num_keys == -1 ) {
9541 status = WERR_BADFILE;
9545 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9547 r_u->needed = printerkey_len*2;
9549 if ( q_u->size < r_u->needed ) {
9550 status = WERR_MORE_DATA;
9554 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9555 status = WERR_NOMEM;
9561 if ( q_u->size < r_u->needed )
9562 status = WERR_MORE_DATA;
9565 free_a_printer( &printer, 2 );
9566 SAFE_FREE( keynames );
9571 /****************************************************************
9572 _spoolss_DeletePrinterKey
9573 ****************************************************************/
9575 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9576 struct spoolss_DeletePrinterKey *r)
9578 POLICY_HND *handle = r->in.handle;
9579 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9580 NT_PRINTER_INFO_LEVEL *printer = NULL;
9584 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9587 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9588 OUR_HANDLE(handle)));
9592 /* if keyname == NULL, return error */
9594 if ( !r->in.key_name )
9595 return WERR_INVALID_PARAM;
9597 if (!get_printer_snum(p, handle, &snum, NULL))
9600 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9601 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9602 "printer properties change denied by handle\n"));
9603 return WERR_ACCESS_DENIED;
9606 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9607 if (!W_ERROR_IS_OK(status))
9610 /* delete the key and all subneys */
9612 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9614 if ( W_ERROR_IS_OK(status) )
9615 status = mod_a_printer(printer, 2);
9617 free_a_printer( &printer, 2 );
9623 /********************************************************************
9624 * spoolss_enumprinterdataex
9625 ********************************************************************/
9627 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9629 POLICY_HND *handle = &q_u->handle;
9630 uint32 in_size = q_u->size;
9633 NT_PRINTER_INFO_LEVEL *printer = NULL;
9634 PRINTER_ENUM_VALUES *enum_values = NULL;
9635 NT_PRINTER_DATA *p_data;
9637 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9642 REGISTRY_VALUE *val;
9647 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9650 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9655 * first check for a keyname of NULL or "". Win2k seems to send
9656 * this a lot and we should send back WERR_INVALID_PARAM
9657 * no need to spend time looking up the printer in this case.
9661 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9662 if ( !strlen(key) ) {
9663 result = WERR_INVALID_PARAM;
9667 /* get the printer off of disk */
9669 if (!get_printer_snum(p,handle, &snum, NULL))
9672 ZERO_STRUCT(printer);
9673 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9674 if (!W_ERROR_IS_OK(result))
9677 /* now look for a match on the key name */
9679 p_data = printer->info_2->data;
9681 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9682 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9684 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9685 result = WERR_INVALID_PARAM;
9692 /* allocate the memory for the array of pointers -- if necessary */
9694 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9697 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9699 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9700 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9701 result = WERR_NOMEM;
9705 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9709 * loop through all params and build the array to pass
9710 * back to the client
9713 for ( i=0; i<num_entries; i++ )
9715 /* lookup the registry value */
9717 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9718 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9722 value_name = regval_name( val );
9723 init_unistr( &enum_values[i].valuename, value_name );
9724 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9725 enum_values[i].type = regval_type( val );
9727 data_len = regval_size( val );
9729 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9731 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9733 result = WERR_NOMEM;
9737 enum_values[i].data_len = data_len;
9739 /* keep track of the size of the array in bytes */
9741 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9744 /* housekeeping information in the reply */
9746 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9747 * the hand marshalled container size is a multiple
9748 * of 4 bytes for RPC alignment.
9752 needed += 4-(needed % 4);
9755 r_u->needed = needed;
9756 r_u->returned = num_entries;
9758 if (needed > in_size) {
9759 result = WERR_MORE_DATA;
9763 /* copy data into the reply */
9765 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9766 response buffer size is != the offered buffer size
9768 r_u->ctr.size = r_u->needed;
9770 r_u->ctr.size = in_size;
9772 r_u->ctr.size_of_array = r_u->returned;
9773 r_u->ctr.values = enum_values;
9777 free_a_printer(&printer, 2);
9782 /****************************************************************************
9783 ****************************************************************************/
9785 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9786 const char *servername,
9787 const char *environment,
9788 struct spoolss_PrintProcessorDirectoryInfo1 *r,
9795 werr = compose_spoolss_server_path(mem_ctx,
9798 SPOOLSS_PRTPROCS_PATH,
9800 if (!W_ERROR_IS_OK(werr)) {
9804 DEBUG(4,("print processor directory: [%s]\n", path));
9806 r->directory_name = path;
9808 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
9810 if (*needed > offered) {
9812 return WERR_INSUFFICIENT_BUFFER;
9818 /****************************************************************
9819 _spoolss_GetPrintProcessorDirectory
9820 ****************************************************************/
9822 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9823 struct spoolss_GetPrintProcessorDirectory *r)
9827 /* that's an [in out] buffer */
9829 if (!r->in.buffer && (r->in.offered != 0)) {
9830 return WERR_INVALID_PARAM;
9833 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9838 /* r->in.level is ignored */
9840 result = getprintprocessordirectory_level_1(p->mem_ctx,
9843 &r->out.info->info1,
9846 if (!W_ERROR_IS_OK(result)) {
9847 TALLOC_FREE(r->out.info);
9853 /*******************************************************************
9854 ********************************************************************/
9856 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9857 const char *dllname)
9859 enum ndr_err_code ndr_err;
9860 struct spoolss_MonitorUi ui;
9862 ui.dll_name = dllname;
9864 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9865 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9866 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9867 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9869 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9872 /*******************************************************************
9873 Streams the monitor UI DLL name in UNICODE
9874 *******************************************************************/
9876 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9877 NT_USER_TOKEN *token, DATA_BLOB *in,
9878 DATA_BLOB *out, uint32_t *needed)
9880 const char *dllname = "tcpmonui.dll";
9882 *needed = (strlen(dllname)+1) * 2;
9884 if (out->length < *needed) {
9885 return WERR_INSUFFICIENT_BUFFER;
9888 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9895 /*******************************************************************
9896 ********************************************************************/
9898 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9899 struct spoolss_PortData1 *port1,
9900 const DATA_BLOB *buf)
9902 enum ndr_err_code ndr_err;
9903 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9904 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9905 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9906 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9908 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9911 /*******************************************************************
9912 ********************************************************************/
9914 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9915 struct spoolss_PortData2 *port2,
9916 const DATA_BLOB *buf)
9918 enum ndr_err_code ndr_err;
9919 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9920 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9921 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9922 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9924 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9927 /*******************************************************************
9928 Create a new TCP/IP port
9929 *******************************************************************/
9931 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9932 NT_USER_TOKEN *token, DATA_BLOB *in,
9933 DATA_BLOB *out, uint32_t *needed)
9935 struct spoolss_PortData1 port1;
9936 struct spoolss_PortData2 port2;
9937 char *device_uri = NULL;
9940 const char *portname;
9941 const char *hostaddress;
9943 uint32_t port_number;
9946 /* peek for spoolss_PortData version */
9948 if (!in || (in->length < (128 + 4))) {
9949 return WERR_GENERAL_FAILURE;
9952 version = IVAL(in->data, 128);
9958 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9962 portname = port1.portname;
9963 hostaddress = port1.hostaddress;
9964 queue = port1.queue;
9965 protocol = port1.protocol;
9966 port_number = port1.port_number;
9972 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9976 portname = port2.portname;
9977 hostaddress = port2.hostaddress;
9978 queue = port2.queue;
9979 protocol = port2.protocol;
9980 port_number = port2.port_number;
9984 DEBUG(1,("xcvtcp_addport: "
9985 "unknown version of port_data: %d\n", version));
9986 return WERR_UNKNOWN_PORT;
9989 /* create the device URI and call the add_port_hook() */
9992 case PROTOCOL_RAWTCP_TYPE:
9993 device_uri = talloc_asprintf(mem_ctx,
9994 "socket://%s:%d/", hostaddress,
9998 case PROTOCOL_LPR_TYPE:
9999 device_uri = talloc_asprintf(mem_ctx,
10000 "lpr://%s/%s", hostaddress, queue );
10004 return WERR_UNKNOWN_PORT;
10011 return add_port_hook(mem_ctx, token, portname, device_uri);
10014 /*******************************************************************
10015 *******************************************************************/
10017 struct xcv_api_table xcvtcp_cmds[] = {
10018 { "MonitorUI", xcvtcp_monitorui },
10019 { "AddPort", xcvtcp_addport},
10023 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
10024 NT_USER_TOKEN *token, const char *command,
10031 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
10033 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
10034 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
10035 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10038 return WERR_BADFUNC;
10041 /*******************************************************************
10042 *******************************************************************/
10043 #if 0 /* don't support management using the "Local Port" monitor */
10045 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10046 NT_USER_TOKEN *token, DATA_BLOB *in,
10047 DATA_BLOB *out, uint32_t *needed)
10049 const char *dllname = "localui.dll";
10051 *needed = (strlen(dllname)+1) * 2;
10053 if (out->length < *needed) {
10054 return WERR_INSUFFICIENT_BUFFER;
10057 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10064 /*******************************************************************
10065 *******************************************************************/
10067 struct xcv_api_table xcvlocal_cmds[] = {
10068 { "MonitorUI", xcvlocal_monitorui },
10072 struct xcv_api_table xcvlocal_cmds[] = {
10079 /*******************************************************************
10080 *******************************************************************/
10082 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10083 NT_USER_TOKEN *token, const char *command,
10084 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10089 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10091 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10092 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10093 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10095 return WERR_BADFUNC;
10098 /****************************************************************
10100 ****************************************************************/
10102 WERROR _spoolss_XcvData(pipes_struct *p,
10103 struct spoolss_XcvData *r)
10105 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10106 DATA_BLOB out_data;
10110 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10111 OUR_HANDLE(r->in.handle)));
10112 return WERR_BADFID;
10115 /* Has to be a handle to the TCP/IP port monitor */
10117 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10118 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10119 return WERR_BADFID;
10122 /* requires administrative access to the server */
10124 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10125 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10126 return WERR_ACCESS_DENIED;
10129 /* Allocate the outgoing buffer */
10131 if (r->in.out_data_size) {
10132 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10133 if (out_data.data == NULL) {
10138 switch ( Printer->printer_type ) {
10139 case SPLHND_PORTMON_TCP:
10140 werror = process_xcvtcp_command(p->mem_ctx,
10141 p->server_info->ptok,
10142 r->in.function_name,
10143 &r->in.in_data, &out_data,
10146 case SPLHND_PORTMON_LOCAL:
10147 werror = process_xcvlocal_command(p->mem_ctx,
10148 p->server_info->ptok,
10149 r->in.function_name,
10150 &r->in.in_data, &out_data,
10154 werror = WERR_INVALID_PRINT_MONITOR;
10157 if (!W_ERROR_IS_OK(werror)) {
10161 *r->out.status_code = 0;
10163 memcpy(r->out.out_data, out_data.data, out_data.length);
10168 /****************************************************************
10169 _spoolss_AddPrintProcessor
10170 ****************************************************************/
10172 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10173 struct spoolss_AddPrintProcessor *r)
10175 /* for now, just indicate success and ignore the add. We'll
10176 automatically set the winprint processor for printer
10177 entries later. Used to debug the LexMark Optra S 1855 PCL
10183 /****************************************************************
10184 _spoolss_EnumPrinters
10185 ****************************************************************/
10187 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10188 struct spoolss_EnumPrinters *r)
10190 p->rng_fault_state = true;
10191 return WERR_NOT_SUPPORTED;
10194 /****************************************************************
10196 ****************************************************************/
10198 WERROR _spoolss_GetJob(pipes_struct *p,
10199 struct spoolss_GetJob *r)
10201 p->rng_fault_state = true;
10202 return WERR_NOT_SUPPORTED;
10205 /****************************************************************
10207 ****************************************************************/
10209 WERROR _spoolss_EnumJobs(pipes_struct *p,
10210 struct spoolss_EnumJobs *r)
10212 p->rng_fault_state = true;
10213 return WERR_NOT_SUPPORTED;
10216 /****************************************************************
10217 _spoolss_AddPrinter
10218 ****************************************************************/
10220 WERROR _spoolss_AddPrinter(pipes_struct *p,
10221 struct spoolss_AddPrinter *r)
10223 p->rng_fault_state = true;
10224 return WERR_NOT_SUPPORTED;
10227 /****************************************************************
10228 _spoolss_GetPrinter
10229 ****************************************************************/
10231 WERROR _spoolss_GetPrinter(pipes_struct *p,
10232 struct spoolss_GetPrinter *r)
10234 p->rng_fault_state = true;
10235 return WERR_NOT_SUPPORTED;
10238 /****************************************************************
10239 _spoolss_EnumPrinterDrivers
10240 ****************************************************************/
10242 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10243 struct spoolss_EnumPrinterDrivers *r)
10245 p->rng_fault_state = true;
10246 return WERR_NOT_SUPPORTED;
10249 /****************************************************************
10250 _spoolss_GetPrinterDriver
10251 ****************************************************************/
10253 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10254 struct spoolss_GetPrinterDriver *r)
10256 p->rng_fault_state = true;
10257 return WERR_NOT_SUPPORTED;
10260 /****************************************************************
10261 _spoolss_EnumPrintProcessors
10262 ****************************************************************/
10264 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10265 struct spoolss_EnumPrintProcessors *r)
10267 p->rng_fault_state = true;
10268 return WERR_NOT_SUPPORTED;
10271 /****************************************************************
10272 _spoolss_ReadPrinter
10273 ****************************************************************/
10275 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10276 struct spoolss_ReadPrinter *r)
10278 p->rng_fault_state = true;
10279 return WERR_NOT_SUPPORTED;
10282 /****************************************************************
10283 _spoolss_GetPrinterData
10284 ****************************************************************/
10286 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10287 struct spoolss_GetPrinterData *r)
10289 p->rng_fault_state = true;
10290 return WERR_NOT_SUPPORTED;
10293 /****************************************************************
10294 _spoolss_SetPrinterData
10295 ****************************************************************/
10297 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10298 struct spoolss_SetPrinterData *r)
10300 p->rng_fault_state = true;
10301 return WERR_NOT_SUPPORTED;
10304 /****************************************************************
10305 _spoolss_WaitForPrinterChange
10306 ****************************************************************/
10308 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10309 struct spoolss_WaitForPrinterChange *r)
10311 p->rng_fault_state = true;
10312 return WERR_NOT_SUPPORTED;
10315 /****************************************************************
10317 ****************************************************************/
10319 WERROR _spoolss_EnumForms(pipes_struct *p,
10320 struct spoolss_EnumForms *r)
10322 p->rng_fault_state = true;
10323 return WERR_NOT_SUPPORTED;
10326 /****************************************************************
10328 ****************************************************************/
10330 WERROR _spoolss_EnumPorts(pipes_struct *p,
10331 struct spoolss_EnumPorts *r)
10333 p->rng_fault_state = true;
10334 return WERR_NOT_SUPPORTED;
10337 /****************************************************************
10338 _spoolss_EnumMonitors
10339 ****************************************************************/
10341 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10342 struct spoolss_EnumMonitors *r)
10344 p->rng_fault_state = true;
10345 return WERR_NOT_SUPPORTED;
10348 /****************************************************************
10350 ****************************************************************/
10352 WERROR _spoolss_AddPort(pipes_struct *p,
10353 struct spoolss_AddPort *r)
10355 p->rng_fault_state = true;
10356 return WERR_NOT_SUPPORTED;
10359 /****************************************************************
10360 _spoolss_ConfigurePort
10361 ****************************************************************/
10363 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10364 struct spoolss_ConfigurePort *r)
10366 p->rng_fault_state = true;
10367 return WERR_NOT_SUPPORTED;
10370 /****************************************************************
10371 _spoolss_DeletePort
10372 ****************************************************************/
10374 WERROR _spoolss_DeletePort(pipes_struct *p,
10375 struct spoolss_DeletePort *r)
10377 p->rng_fault_state = true;
10378 return WERR_NOT_SUPPORTED;
10381 /****************************************************************
10382 _spoolss_CreatePrinterIC
10383 ****************************************************************/
10385 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10386 struct spoolss_CreatePrinterIC *r)
10388 p->rng_fault_state = true;
10389 return WERR_NOT_SUPPORTED;
10392 /****************************************************************
10393 _spoolss_PlayGDIScriptOnPrinterIC
10394 ****************************************************************/
10396 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10397 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10399 p->rng_fault_state = true;
10400 return WERR_NOT_SUPPORTED;
10403 /****************************************************************
10404 _spoolss_DeletePrinterIC
10405 ****************************************************************/
10407 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10408 struct spoolss_DeletePrinterIC *r)
10410 p->rng_fault_state = true;
10411 return WERR_NOT_SUPPORTED;
10414 /****************************************************************
10415 _spoolss_AddPrinterConnection
10416 ****************************************************************/
10418 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10419 struct spoolss_AddPrinterConnection *r)
10421 p->rng_fault_state = true;
10422 return WERR_NOT_SUPPORTED;
10425 /****************************************************************
10426 _spoolss_DeletePrinterConnection
10427 ****************************************************************/
10429 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10430 struct spoolss_DeletePrinterConnection *r)
10432 p->rng_fault_state = true;
10433 return WERR_NOT_SUPPORTED;
10436 /****************************************************************
10437 _spoolss_PrinterMessageBox
10438 ****************************************************************/
10440 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10441 struct spoolss_PrinterMessageBox *r)
10443 p->rng_fault_state = true;
10444 return WERR_NOT_SUPPORTED;
10447 /****************************************************************
10448 _spoolss_AddMonitor
10449 ****************************************************************/
10451 WERROR _spoolss_AddMonitor(pipes_struct *p,
10452 struct spoolss_AddMonitor *r)
10454 p->rng_fault_state = true;
10455 return WERR_NOT_SUPPORTED;
10458 /****************************************************************
10459 _spoolss_DeleteMonitor
10460 ****************************************************************/
10462 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10463 struct spoolss_DeleteMonitor *r)
10465 p->rng_fault_state = true;
10466 return WERR_NOT_SUPPORTED;
10469 /****************************************************************
10470 _spoolss_DeletePrintProcessor
10471 ****************************************************************/
10473 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10474 struct spoolss_DeletePrintProcessor *r)
10476 p->rng_fault_state = true;
10477 return WERR_NOT_SUPPORTED;
10480 /****************************************************************
10481 _spoolss_AddPrintProvidor
10482 ****************************************************************/
10484 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10485 struct spoolss_AddPrintProvidor *r)
10487 p->rng_fault_state = true;
10488 return WERR_NOT_SUPPORTED;
10491 /****************************************************************
10492 _spoolss_DeletePrintProvidor
10493 ****************************************************************/
10495 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10496 struct spoolss_DeletePrintProvidor *r)
10498 p->rng_fault_state = true;
10499 return WERR_NOT_SUPPORTED;
10502 /****************************************************************
10503 _spoolss_EnumPrintProcDataTypes
10504 ****************************************************************/
10506 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10507 struct spoolss_EnumPrintProcDataTypes *r)
10509 p->rng_fault_state = true;
10510 return WERR_NOT_SUPPORTED;
10513 /****************************************************************
10514 _spoolss_GetPrinterDriver2
10515 ****************************************************************/
10517 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10518 struct spoolss_GetPrinterDriver2 *r)
10520 p->rng_fault_state = true;
10521 return WERR_NOT_SUPPORTED;
10524 /****************************************************************
10525 _spoolss_FindFirstPrinterChangeNotification
10526 ****************************************************************/
10528 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10529 struct spoolss_FindFirstPrinterChangeNotification *r)
10531 p->rng_fault_state = true;
10532 return WERR_NOT_SUPPORTED;
10535 /****************************************************************
10536 _spoolss_FindNextPrinterChangeNotification
10537 ****************************************************************/
10539 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10540 struct spoolss_FindNextPrinterChangeNotification *r)
10542 p->rng_fault_state = true;
10543 return WERR_NOT_SUPPORTED;
10546 /****************************************************************
10547 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10548 ****************************************************************/
10550 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10551 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10553 p->rng_fault_state = true;
10554 return WERR_NOT_SUPPORTED;
10557 /****************************************************************
10558 _spoolss_ReplyOpenPrinter
10559 ****************************************************************/
10561 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10562 struct spoolss_ReplyOpenPrinter *r)
10564 p->rng_fault_state = true;
10565 return WERR_NOT_SUPPORTED;
10568 /****************************************************************
10569 _spoolss_RouterReplyPrinter
10570 ****************************************************************/
10572 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10573 struct spoolss_RouterReplyPrinter *r)
10575 p->rng_fault_state = true;
10576 return WERR_NOT_SUPPORTED;
10579 /****************************************************************
10580 _spoolss_ReplyClosePrinter
10581 ****************************************************************/
10583 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10584 struct spoolss_ReplyClosePrinter *r)
10586 p->rng_fault_state = true;
10587 return WERR_NOT_SUPPORTED;
10590 /****************************************************************
10592 ****************************************************************/
10594 WERROR _spoolss_AddPortEx(pipes_struct *p,
10595 struct spoolss_AddPortEx *r)
10597 p->rng_fault_state = true;
10598 return WERR_NOT_SUPPORTED;
10601 /****************************************************************
10602 _spoolss_RouterFindFirstPrinterChangeNotification
10603 ****************************************************************/
10605 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10606 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10608 p->rng_fault_state = true;
10609 return WERR_NOT_SUPPORTED;
10612 /****************************************************************
10613 _spoolss_SpoolerInit
10614 ****************************************************************/
10616 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10617 struct spoolss_SpoolerInit *r)
10619 p->rng_fault_state = true;
10620 return WERR_NOT_SUPPORTED;
10623 /****************************************************************
10624 _spoolss_ResetPrinterEx
10625 ****************************************************************/
10627 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10628 struct spoolss_ResetPrinterEx *r)
10630 p->rng_fault_state = true;
10631 return WERR_NOT_SUPPORTED;
10634 /****************************************************************
10635 _spoolss_RouterReplyPrinterEx
10636 ****************************************************************/
10638 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10639 struct spoolss_RouterReplyPrinterEx *r)
10641 p->rng_fault_state = true;
10642 return WERR_NOT_SUPPORTED;
10645 /****************************************************************
10647 ****************************************************************/
10649 WERROR _spoolss_44(pipes_struct *p,
10650 struct spoolss_44 *r)
10652 p->rng_fault_state = true;
10653 return WERR_NOT_SUPPORTED;
10656 /****************************************************************
10658 ****************************************************************/
10660 WERROR _spoolss_47(pipes_struct *p,
10661 struct spoolss_47 *r)
10663 p->rng_fault_state = true;
10664 return WERR_NOT_SUPPORTED;
10667 /****************************************************************
10668 _spoolss_EnumPrinterData
10669 ****************************************************************/
10671 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10672 struct spoolss_EnumPrinterData *r)
10674 p->rng_fault_state = true;
10675 return WERR_NOT_SUPPORTED;
10678 /****************************************************************
10680 ****************************************************************/
10682 WERROR _spoolss_4a(pipes_struct *p,
10683 struct spoolss_4a *r)
10685 p->rng_fault_state = true;
10686 return WERR_NOT_SUPPORTED;
10689 /****************************************************************
10691 ****************************************************************/
10693 WERROR _spoolss_4b(pipes_struct *p,
10694 struct spoolss_4b *r)
10696 p->rng_fault_state = true;
10697 return WERR_NOT_SUPPORTED;
10700 /****************************************************************
10702 ****************************************************************/
10704 WERROR _spoolss_4c(pipes_struct *p,
10705 struct spoolss_4c *r)
10707 p->rng_fault_state = true;
10708 return WERR_NOT_SUPPORTED;
10711 /****************************************************************
10712 _spoolss_EnumPrinterDataEx
10713 ****************************************************************/
10715 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10716 struct spoolss_EnumPrinterDataEx *r)
10718 p->rng_fault_state = true;
10719 return WERR_NOT_SUPPORTED;
10722 /****************************************************************
10723 _spoolss_EnumPrinterKey
10724 ****************************************************************/
10726 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10727 struct spoolss_EnumPrinterKey *r)
10729 p->rng_fault_state = true;
10730 return WERR_NOT_SUPPORTED;
10733 /****************************************************************
10735 ****************************************************************/
10737 WERROR _spoolss_53(pipes_struct *p,
10738 struct spoolss_53 *r)
10740 p->rng_fault_state = true;
10741 return WERR_NOT_SUPPORTED;
10744 /****************************************************************
10746 ****************************************************************/
10748 WERROR _spoolss_55(pipes_struct *p,
10749 struct spoolss_55 *r)
10751 p->rng_fault_state = true;
10752 return WERR_NOT_SUPPORTED;
10755 /****************************************************************
10757 ****************************************************************/
10759 WERROR _spoolss_56(pipes_struct *p,
10760 struct spoolss_56 *r)
10762 p->rng_fault_state = true;
10763 return WERR_NOT_SUPPORTED;
10766 /****************************************************************
10768 ****************************************************************/
10770 WERROR _spoolss_57(pipes_struct *p,
10771 struct spoolss_57 *r)
10773 p->rng_fault_state = true;
10774 return WERR_NOT_SUPPORTED;
10777 /****************************************************************
10779 ****************************************************************/
10781 WERROR _spoolss_5a(pipes_struct *p,
10782 struct spoolss_5a *r)
10784 p->rng_fault_state = true;
10785 return WERR_NOT_SUPPORTED;
10788 /****************************************************************
10790 ****************************************************************/
10792 WERROR _spoolss_5b(pipes_struct *p,
10793 struct spoolss_5b *r)
10795 p->rng_fault_state = true;
10796 return WERR_NOT_SUPPORTED;
10799 /****************************************************************
10801 ****************************************************************/
10803 WERROR _spoolss_5c(pipes_struct *p,
10804 struct spoolss_5c *r)
10806 p->rng_fault_state = true;
10807 return WERR_NOT_SUPPORTED;
10810 /****************************************************************
10812 ****************************************************************/
10814 WERROR _spoolss_5d(pipes_struct *p,
10815 struct spoolss_5d *r)
10817 p->rng_fault_state = true;
10818 return WERR_NOT_SUPPORTED;
10821 /****************************************************************
10823 ****************************************************************/
10825 WERROR _spoolss_5e(pipes_struct *p,
10826 struct spoolss_5e *r)
10828 p->rng_fault_state = true;
10829 return WERR_NOT_SUPPORTED;
10832 /****************************************************************
10834 ****************************************************************/
10836 WERROR _spoolss_5f(pipes_struct *p,
10837 struct spoolss_5f *r)
10839 p->rng_fault_state = true;
10840 return WERR_NOT_SUPPORTED;