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 },
3489 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3492 /*******************************************************************
3493 Return the variable_type of info_data structure.
3494 ********************************************************************/
3496 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3497 enum spoolss_Field field)
3501 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3502 if ( (notify_info_data_table[i].type == type) &&
3503 (notify_info_data_table[i].field == field) ) {
3504 return notify_info_data_table[i].variable_type;
3508 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3513 /****************************************************************************
3514 ****************************************************************************/
3516 static bool search_notify(enum spoolss_NotifyType type,
3517 enum spoolss_Field field,
3522 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3523 if (notify_info_data_table[i].type == type &&
3524 notify_info_data_table[i].field == field &&
3525 notify_info_data_table[i].fn != NULL) {
3534 /****************************************************************************
3535 ****************************************************************************/
3537 void construct_info_data(struct spoolss_Notify *info_data,
3538 enum spoolss_NotifyType type,
3539 enum spoolss_Field field,
3542 info_data->type = type;
3543 info_data->field = field;
3544 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3545 info_data->job_id = id;
3548 /*******************************************************************
3550 * fill a notify_info struct with info asked
3552 ********************************************************************/
3554 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3555 struct spoolss_NotifyInfo *info,
3557 const struct spoolss_NotifyOptionType *option_type,
3559 TALLOC_CTX *mem_ctx)
3562 enum spoolss_NotifyType type;
3563 enum spoolss_Field field;
3565 struct spoolss_Notify *current_data;
3566 NT_PRINTER_INFO_LEVEL *printer = NULL;
3567 print_queue_struct *queue=NULL;
3569 type = option_type->type;
3571 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3572 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3573 option_type->count, lp_servicename(snum)));
3575 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3578 for(field_num=0; field_num < option_type->count; field_num++) {
3579 field = option_type->fields[field_num];
3581 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3583 if (!search_notify(type, field, &j) )
3586 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3587 struct spoolss_Notify,
3589 if (info->notifies == NULL) {
3590 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3591 free_a_printer(&printer, 2);
3595 current_data = &info->notifies[info->count];
3597 construct_info_data(current_data, type, field, id);
3599 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3600 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3602 notify_info_data_table[j].fn(snum, current_data, queue,
3608 free_a_printer(&printer, 2);
3612 /*******************************************************************
3614 * fill a notify_info struct with info asked
3616 ********************************************************************/
3618 static bool construct_notify_jobs_info(print_queue_struct *queue,
3619 struct spoolss_NotifyInfo *info,
3620 NT_PRINTER_INFO_LEVEL *printer,
3622 const struct spoolss_NotifyOptionType *option_type,
3624 TALLOC_CTX *mem_ctx)
3627 enum spoolss_NotifyType type;
3628 enum spoolss_Field field;
3629 struct spoolss_Notify *current_data;
3631 DEBUG(4,("construct_notify_jobs_info\n"));
3633 type = option_type->type;
3635 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3636 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3637 option_type->count));
3639 for(field_num=0; field_num<option_type->count; field_num++) {
3640 field = option_type->fields[field_num];
3642 if (!search_notify(type, field, &j) )
3645 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3646 struct spoolss_Notify,
3648 if (info->notifies == NULL) {
3649 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3653 current_data=&(info->notifies[info->count]);
3655 construct_info_data(current_data, type, field, id);
3656 notify_info_data_table[j].fn(snum, current_data, queue,
3665 * JFM: The enumeration is not that simple, it's even non obvious.
3667 * let's take an example: I want to monitor the PRINTER SERVER for
3668 * the printer's name and the number of jobs currently queued.
3669 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3670 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3672 * I have 3 printers on the back of my server.
3674 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3677 * 1 printer 1 name 1
3678 * 2 printer 1 cjob 1
3679 * 3 printer 2 name 2
3680 * 4 printer 2 cjob 2
3681 * 5 printer 3 name 3
3682 * 6 printer 3 name 3
3684 * that's the print server case, the printer case is even worse.
3687 /*******************************************************************
3689 * enumerate all printers on the printserver
3690 * fill a notify_info struct with info asked
3692 ********************************************************************/
3694 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3695 struct spoolss_NotifyInfo *info,
3696 TALLOC_CTX *mem_ctx)
3699 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3700 int n_services=lp_numservices();
3702 struct spoolss_NotifyOption *option;
3703 struct spoolss_NotifyOptionType option_type;
3705 DEBUG(4,("printserver_notify_info\n"));
3710 option = Printer->notify.option;
3713 info->notifies = NULL;
3716 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3717 sending a ffpcn() request first */
3722 for (i=0; i<option->count; i++) {
3723 option_type = option->types[i];
3725 if (option_type.type != PRINTER_NOTIFY_TYPE)
3728 for (snum=0; snum<n_services; snum++)
3730 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3731 construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3737 * Debugging information, don't delete.
3740 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3741 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3742 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3744 for (i=0; i<info->count; i++) {
3745 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3746 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3747 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3754 /*******************************************************************
3756 * fill a notify_info struct with info asked
3758 ********************************************************************/
3760 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
3761 TALLOC_CTX *mem_ctx)
3764 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3767 struct spoolss_NotifyOption *option;
3768 struct spoolss_NotifyOptionType option_type;
3770 print_queue_struct *queue=NULL;
3771 print_status_struct status;
3773 DEBUG(4,("printer_notify_info\n"));
3778 option = Printer->notify.option;
3782 info->notifies = NULL;
3785 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3786 sending a ffpcn() request first */
3791 get_printer_snum(p, hnd, &snum, NULL);
3793 for (i=0; i<option->count; i++) {
3794 option_type = option->types[i];
3796 switch (option_type.type) {
3797 case PRINTER_NOTIFY_TYPE:
3798 if(construct_notify_printer_info(Printer, info, snum,
3804 case JOB_NOTIFY_TYPE: {
3805 NT_PRINTER_INFO_LEVEL *printer = NULL;
3807 count = print_queue_status(snum, &queue, &status);
3809 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3812 for (j=0; j<count; j++) {
3813 construct_notify_jobs_info(&queue[j], info,
3820 free_a_printer(&printer, 2);
3830 * Debugging information, don't delete.
3833 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3834 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3835 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3837 for (i=0; i<info->count; i++) {
3838 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3839 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3840 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3846 /****************************************************************
3847 _spoolss_RouterRefreshPrinterChangeNotify
3848 ****************************************************************/
3850 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3851 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3853 POLICY_HND *handle = r->in.handle;
3854 struct spoolss_NotifyInfo *info;
3856 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3857 WERROR result = WERR_BADFID;
3859 /* we always have a spoolss_NotifyInfo struct */
3860 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3862 result = WERR_NOMEM;
3866 *r->out.info = info;
3869 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3870 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
3874 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3877 * We are now using the change value, and
3878 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3879 * I don't have a global notification system, I'm sending back all the
3880 * informations even when _NOTHING_ has changed.
3883 /* We need to keep track of the change value to send back in
3884 RRPCN replies otherwise our updates are ignored. */
3886 Printer->notify.fnpcn = True;
3888 if (Printer->notify.client_connected) {
3889 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3890 "Saving change value in request [%x]\n",
3892 Printer->notify.change = r->in.change_low;
3895 /* just ignore the spoolss_NotifyOption */
3897 switch (Printer->printer_type) {
3899 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3902 case SPLHND_PRINTER:
3903 result = printer_notify_info(p, handle, info, p->mem_ctx);
3907 Printer->notify.fnpcn = False;
3913 /********************************************************************
3914 * construct_printer_info_0
3915 * fill a printer_info_0 struct
3916 ********************************************************************/
3918 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3920 char *chaine = NULL;
3922 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3923 counter_printer_0 *session_counter;
3924 uint32 global_counter;
3927 print_status_struct status;
3928 TALLOC_CTX *ctx = talloc_tos();
3930 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3933 init_unistr(&printer->printername, ntprinter->info_2->printername);
3935 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3937 free_a_printer(&ntprinter,2);
3941 count = print_queue_length(snum, &status);
3943 /* check if we already have a counter for this printer */
3944 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3945 if (session_counter->snum == snum)
3949 init_unistr(&printer->servername, chaine);
3951 /* it's the first time, add it to the list */
3952 if (session_counter==NULL) {
3953 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3954 free_a_printer(&ntprinter, 2);
3957 ZERO_STRUCTP(session_counter);
3958 session_counter->snum=snum;
3959 session_counter->counter=0;
3960 DLIST_ADD(counter_list, session_counter);
3964 session_counter->counter++;
3967 * the global_counter should be stored in a TDB as it's common to all the clients
3968 * and should be zeroed on samba startup
3970 global_counter=session_counter->counter;
3971 printer->cjobs = count;
3972 printer->total_jobs = 0;
3973 printer->total_bytes = 0;
3975 setuptime = (time_t)ntprinter->info_2->setuptime;
3976 t=gmtime(&setuptime);
3978 printer->year = t->tm_year+1900;
3979 printer->month = t->tm_mon+1;
3980 printer->dayofweek = t->tm_wday;
3981 printer->day = t->tm_mday;
3982 printer->hour = t->tm_hour;
3983 printer->minute = t->tm_min;
3984 printer->second = t->tm_sec;
3985 printer->milliseconds = 0;
3987 printer->global_counter = global_counter;
3988 printer->total_pages = 0;
3990 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3991 printer->major_version = 0x0005; /* NT 5 */
3992 printer->build_version = 0x0893; /* build 2195 */
3994 printer->unknown7 = 0x1;
3995 printer->unknown8 = 0x0;
3996 printer->unknown9 = 0x0;
3997 printer->session_counter = session_counter->counter;
3998 printer->unknown11 = 0x0;
3999 printer->printer_errors = 0x0; /* number of print failure */
4000 printer->unknown13 = 0x0;
4001 printer->unknown14 = 0x1;
4002 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4003 printer->unknown16 = 0x0;
4004 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4005 printer->unknown18 = 0x0;
4006 printer->status = nt_printq_status(status.status);
4007 printer->unknown20 = 0x0;
4008 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4009 printer->unknown22 = 0x0;
4010 printer->unknown23 = 0x6; /* 6 ???*/
4011 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4012 printer->unknown25 = 0;
4013 printer->unknown26 = 0;
4014 printer->unknown27 = 0;
4015 printer->unknown28 = 0;
4016 printer->unknown29 = 0;
4018 free_a_printer(&ntprinter,2);
4022 /********************************************************************
4023 * construct_printer_info_1
4024 * fill a printer_info_1 struct
4025 ********************************************************************/
4026 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4028 char *chaine = NULL;
4029 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4030 TALLOC_CTX *ctx = talloc_tos();
4032 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4035 printer->flags=flags;
4037 if (*ntprinter->info_2->comment == '\0') {
4038 init_unistr(&printer->comment, lp_comment(snum));
4039 chaine = talloc_asprintf(ctx,
4040 "%s,%s,%s", ntprinter->info_2->printername,
4041 ntprinter->info_2->drivername, lp_comment(snum));
4044 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4045 chaine = talloc_asprintf(ctx,
4046 "%s,%s,%s", ntprinter->info_2->printername,
4047 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4051 free_a_printer(&ntprinter,2);
4055 init_unistr(&printer->description, chaine);
4056 init_unistr(&printer->name, ntprinter->info_2->printername);
4058 free_a_printer(&ntprinter,2);
4063 /****************************************************************************
4064 Free a DEVMODE struct.
4065 ****************************************************************************/
4067 static void free_dev_mode(DEVICEMODE *dev)
4072 SAFE_FREE(dev->dev_private);
4077 /****************************************************************************
4078 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4079 should be valid upon entry
4080 ****************************************************************************/
4082 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4084 if ( !devmode || !ntdevmode )
4087 init_unistr(&devmode->devicename, ntdevmode->devicename);
4089 init_unistr(&devmode->formname, ntdevmode->formname);
4091 devmode->specversion = ntdevmode->specversion;
4092 devmode->driverversion = ntdevmode->driverversion;
4093 devmode->size = ntdevmode->size;
4094 devmode->driverextra = ntdevmode->driverextra;
4095 devmode->fields = ntdevmode->fields;
4097 devmode->orientation = ntdevmode->orientation;
4098 devmode->papersize = ntdevmode->papersize;
4099 devmode->paperlength = ntdevmode->paperlength;
4100 devmode->paperwidth = ntdevmode->paperwidth;
4101 devmode->scale = ntdevmode->scale;
4102 devmode->copies = ntdevmode->copies;
4103 devmode->defaultsource = ntdevmode->defaultsource;
4104 devmode->printquality = ntdevmode->printquality;
4105 devmode->color = ntdevmode->color;
4106 devmode->duplex = ntdevmode->duplex;
4107 devmode->yresolution = ntdevmode->yresolution;
4108 devmode->ttoption = ntdevmode->ttoption;
4109 devmode->collate = ntdevmode->collate;
4110 devmode->icmmethod = ntdevmode->icmmethod;
4111 devmode->icmintent = ntdevmode->icmintent;
4112 devmode->mediatype = ntdevmode->mediatype;
4113 devmode->dithertype = ntdevmode->dithertype;
4115 if (ntdevmode->nt_dev_private != NULL) {
4116 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4123 /****************************************************************************
4124 Create a DEVMODE struct. Returns malloced memory.
4125 ****************************************************************************/
4127 DEVICEMODE *construct_dev_mode(const char *servicename)
4129 NT_PRINTER_INFO_LEVEL *printer = NULL;
4130 DEVICEMODE *devmode = NULL;
4132 DEBUG(7,("construct_dev_mode\n"));
4134 DEBUGADD(8,("getting printer characteristics\n"));
4136 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4139 if ( !printer->info_2->devmode ) {
4140 DEBUG(5, ("BONG! There was no device mode!\n"));
4144 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4145 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4149 ZERO_STRUCTP(devmode);
4151 DEBUGADD(8,("loading DEVICEMODE\n"));
4153 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4154 free_dev_mode( devmode );
4159 free_a_printer(&printer,2);
4164 /********************************************************************
4165 * construct_printer_info_2
4166 * fill a printer_info_2 struct
4167 ********************************************************************/
4169 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4172 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4174 print_status_struct status;
4176 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4179 count = print_queue_length(snum, &status);
4181 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4182 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4183 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4184 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4185 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4187 if (*ntprinter->info_2->comment == '\0')
4188 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4190 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4192 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4193 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4194 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4195 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4196 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4198 printer->attributes = ntprinter->info_2->attributes;
4200 printer->priority = ntprinter->info_2->priority; /* priority */
4201 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4202 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4203 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4204 printer->status = nt_printq_status(status.status); /* status */
4205 printer->cjobs = count; /* jobs */
4206 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4208 if ( !(printer->devmode = construct_dev_mode(
4209 lp_const_servicename(snum))) )
4210 DEBUG(8, ("Returning NULL Devicemode!\n"));
4212 printer->secdesc = NULL;
4214 if ( ntprinter->info_2->secdesc_buf
4215 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4217 /* don't use talloc_steal() here unless you do a deep steal of all
4218 the SEC_DESC members */
4220 printer->secdesc = dup_sec_desc( talloc_tos(),
4221 ntprinter->info_2->secdesc_buf->sd );
4224 free_a_printer(&ntprinter, 2);
4229 /********************************************************************
4230 * construct_printer_info_3
4231 * fill a printer_info_3 struct
4232 ********************************************************************/
4234 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4236 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4237 PRINTER_INFO_3 *printer = NULL;
4239 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4243 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4244 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4245 free_a_printer(&ntprinter, 2);
4249 ZERO_STRUCTP(printer);
4251 /* These are the components of the SD we are returning. */
4253 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4254 /* don't use talloc_steal() here unless you do a deep steal of all
4255 the SEC_DESC members */
4257 printer->secdesc = dup_sec_desc( talloc_tos(),
4258 ntprinter->info_2->secdesc_buf->sd );
4261 free_a_printer(&ntprinter, 2);
4263 *pp_printer = printer;
4267 /********************************************************************
4268 * construct_printer_info_4
4269 * fill a printer_info_4 struct
4270 ********************************************************************/
4272 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4274 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4276 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4279 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4280 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4281 printer->attributes = ntprinter->info_2->attributes;
4283 free_a_printer(&ntprinter, 2);
4287 /********************************************************************
4288 * construct_printer_info_5
4289 * fill a printer_info_5 struct
4290 ********************************************************************/
4292 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4294 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4296 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4299 init_unistr(&printer->printername, ntprinter->info_2->printername);
4300 init_unistr(&printer->portname, ntprinter->info_2->portname);
4301 printer->attributes = ntprinter->info_2->attributes;
4303 /* these two are not used by NT+ according to MSDN */
4305 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4306 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4308 free_a_printer(&ntprinter, 2);
4313 /********************************************************************
4314 * construct_printer_info_6
4315 * fill a printer_info_6 struct
4316 ********************************************************************/
4318 static bool construct_printer_info_6(Printer_entry *print_hnd,
4319 PRINTER_INFO_6 *printer,
4322 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4324 print_status_struct status;
4326 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4327 lp_const_servicename(snum))))
4330 count = print_queue_length(snum, &status);
4332 printer->status = nt_printq_status(status.status);
4334 free_a_printer(&ntprinter, 2);
4339 /********************************************************************
4340 * construct_printer_info_7
4341 * fill a printer_info_7 struct
4342 ********************************************************************/
4344 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4346 char *guid_str = NULL;
4349 if (is_printer_published(print_hnd, snum, &guid)) {
4350 if (asprintf(&guid_str, "{%s}",
4351 GUID_string(talloc_tos(), &guid)) == -1) {
4354 strupper_m(guid_str);
4355 init_unistr(&printer->guid, guid_str);
4356 SAFE_FREE(guid_str);
4357 printer->action = SPOOL_DS_PUBLISH;
4359 init_unistr(&printer->guid, "");
4360 printer->action = SPOOL_DS_UNPUBLISH;
4366 /********************************************************************
4367 Spoolss_enumprinters.
4368 ********************************************************************/
4370 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4374 int n_services=lp_numservices();
4375 PRINTER_INFO_1 *printers=NULL;
4376 PRINTER_INFO_1 current_prt;
4377 WERROR result = WERR_OK;
4379 DEBUG(4,("enum_all_printers_info_1\n"));
4381 for (snum=0; snum<n_services; snum++) {
4382 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4383 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4385 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4386 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4387 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4391 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4393 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4399 /* check the required size. */
4400 for (i=0; i<*returned; i++)
4401 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4403 if (*needed > offered) {
4404 result = WERR_INSUFFICIENT_BUFFER;
4408 if (!rpcbuf_alloc_size(buffer, *needed)) {
4409 result = WERR_NOMEM;
4413 /* fill the buffer with the structures */
4414 for (i=0; i<*returned; i++)
4415 smb_io_printer_info_1("", buffer, &printers[i], 0);
4420 SAFE_FREE(printers);
4422 if ( !W_ERROR_IS_OK(result) )
4428 /********************************************************************
4429 enum_all_printers_info_1_local.
4430 *********************************************************************/
4432 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4434 DEBUG(4,("enum_all_printers_info_1_local\n"));
4436 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4439 /********************************************************************
4440 enum_all_printers_info_1_name.
4441 *********************************************************************/
4443 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4447 DEBUG(4,("enum_all_printers_info_1_name\n"));
4449 if ((name[0] == '\\') && (name[1] == '\\'))
4452 if (is_myname_or_ipaddr(s)) {
4453 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4456 return WERR_INVALID_NAME;
4459 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4460 /********************************************************************
4461 enum_all_printers_info_1_remote.
4462 *********************************************************************/
4464 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4466 PRINTER_INFO_1 *printer;
4467 fstring printername;
4470 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4471 WERROR result = WERR_OK;
4473 /* JFM: currently it's more a place holder than anything else.
4474 * In the spooler world there is a notion of server registration.
4475 * the print servers are registered on the PDC (in the same domain)
4477 * We should have a TDB here. The registration is done thru an
4478 * undocumented RPC call.
4481 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4486 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4487 slprintf(desc, sizeof(desc)-1,"%s", name);
4488 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4490 init_unistr(&printer->description, desc);
4491 init_unistr(&printer->name, printername);
4492 init_unistr(&printer->comment, comment);
4493 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4495 /* check the required size. */
4496 *needed += spoolss_size_printer_info_1(printer);
4498 if (*needed > offered) {
4499 result = WERR_INSUFFICIENT_BUFFER;
4503 if (!rpcbuf_alloc_size(buffer, *needed)) {
4504 result = WERR_NOMEM;
4508 /* fill the buffer with the structures */
4509 smb_io_printer_info_1("", buffer, printer, 0);
4515 if ( !W_ERROR_IS_OK(result) )
4523 /********************************************************************
4524 enum_all_printers_info_1_network.
4525 *********************************************************************/
4527 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4531 DEBUG(4,("enum_all_printers_info_1_network\n"));
4533 /* If we respond to a enum_printers level 1 on our name with flags
4534 set to PRINTER_ENUM_REMOTE with a list of printers then these
4535 printers incorrectly appear in the APW browse list.
4536 Specifically the printers for the server appear at the workgroup
4537 level where all the other servers in the domain are
4538 listed. Windows responds to this call with a
4539 WERR_CAN_NOT_COMPLETE so we should do the same. */
4541 if (name[0] == '\\' && name[1] == '\\')
4544 if (is_myname_or_ipaddr(s))
4545 return WERR_CAN_NOT_COMPLETE;
4547 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4550 /********************************************************************
4551 * api_spoolss_enumprinters
4553 * called from api_spoolss_enumprinters (see this to understand)
4554 ********************************************************************/
4556 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4560 int n_services=lp_numservices();
4561 PRINTER_INFO_2 *printers=NULL;
4562 PRINTER_INFO_2 current_prt;
4563 WERROR result = WERR_OK;
4567 for (snum=0; snum<n_services; snum++) {
4568 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4569 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4571 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4572 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4573 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4578 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4580 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4587 /* check the required size. */
4588 for (i=0; i<*returned; i++)
4589 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4591 if (*needed > offered) {
4592 result = WERR_INSUFFICIENT_BUFFER;
4596 if (!rpcbuf_alloc_size(buffer, *needed)) {
4597 result = WERR_NOMEM;
4601 /* fill the buffer with the structures */
4602 for (i=0; i<*returned; i++)
4603 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4608 for (i=0; i<*returned; i++)
4609 free_devmode(printers[i].devmode);
4611 SAFE_FREE(printers);
4613 if ( !W_ERROR_IS_OK(result) )
4619 /********************************************************************
4620 * handle enumeration of printers at level 1
4621 ********************************************************************/
4623 static WERROR enumprinters_level1( uint32 flags, fstring name,
4624 RPC_BUFFER *buffer, uint32 offered,
4625 uint32 *needed, uint32 *returned)
4627 /* Not all the flags are equals */
4629 if (flags & PRINTER_ENUM_LOCAL)
4630 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4632 if (flags & PRINTER_ENUM_NAME)
4633 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4635 #if 0 /* JERRY - disabled for now */
4636 if (flags & PRINTER_ENUM_REMOTE)
4637 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4640 if (flags & PRINTER_ENUM_NETWORK)
4641 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4643 return WERR_OK; /* NT4sp5 does that */
4646 /********************************************************************
4647 * handle enumeration of printers at level 2
4648 ********************************************************************/
4650 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4651 RPC_BUFFER *buffer, uint32 offered,
4652 uint32 *needed, uint32 *returned)
4654 if (flags & PRINTER_ENUM_LOCAL) {
4655 return enum_all_printers_info_2(buffer, offered, needed, returned);
4658 if (flags & PRINTER_ENUM_NAME) {
4659 if (is_myname_or_ipaddr(canon_servername(servername)))
4660 return enum_all_printers_info_2(buffer, offered, needed, returned);
4662 return WERR_INVALID_NAME;
4665 if (flags & PRINTER_ENUM_REMOTE)
4666 return WERR_UNKNOWN_LEVEL;
4671 /********************************************************************
4672 * handle enumeration of printers at level 5
4673 ********************************************************************/
4675 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4676 RPC_BUFFER *buffer, uint32 offered,
4677 uint32 *needed, uint32 *returned)
4679 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4683 /********************************************************************
4684 * api_spoolss_enumprinters
4686 * called from api_spoolss_enumprinters (see this to understand)
4687 ********************************************************************/
4689 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4691 uint32 flags = q_u->flags;
4692 UNISTR2 *servername = &q_u->servername;
4693 uint32 level = q_u->level;
4694 RPC_BUFFER *buffer = NULL;
4695 uint32 offered = q_u->offered;
4696 uint32 *needed = &r_u->needed;
4697 uint32 *returned = &r_u->returned;
4701 /* that's an [in out] buffer */
4703 if (!q_u->buffer && (offered!=0)) {
4704 return WERR_INVALID_PARAM;
4707 if (offered > MAX_RPC_DATA_SIZE) {
4708 return WERR_INVALID_PARAM;
4711 rpcbuf_move(q_u->buffer, &r_u->buffer);
4712 buffer = r_u->buffer;
4714 DEBUG(4,("_spoolss_enumprinters\n"));
4721 * flags==PRINTER_ENUM_NAME
4722 * if name=="" then enumerates all printers
4723 * if name!="" then enumerate the printer
4724 * flags==PRINTER_ENUM_REMOTE
4725 * name is NULL, enumerate printers
4726 * Level 2: name!="" enumerates printers, name can't be NULL
4727 * Level 3: doesn't exist
4728 * Level 4: does a local registry lookup
4729 * Level 5: same as Level 2
4732 unistr2_to_ascii(name, servername, sizeof(name));
4737 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4739 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4741 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4746 return WERR_UNKNOWN_LEVEL;
4749 /****************************************************************************
4750 ****************************************************************************/
4752 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4754 PRINTER_INFO_0 *printer=NULL;
4755 WERROR result = WERR_OK;
4757 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4760 construct_printer_info_0(print_hnd, printer, snum);
4762 /* check the required size. */
4763 *needed += spoolss_size_printer_info_0(printer);
4765 if (*needed > offered) {
4766 result = WERR_INSUFFICIENT_BUFFER;
4770 if (!rpcbuf_alloc_size(buffer, *needed)) {
4771 result = WERR_NOMEM;
4775 /* fill the buffer with the structures */
4776 smb_io_printer_info_0("", buffer, printer, 0);
4786 /****************************************************************************
4787 ****************************************************************************/
4789 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4791 PRINTER_INFO_1 *printer=NULL;
4792 WERROR result = WERR_OK;
4794 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4797 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4799 /* check the required size. */
4800 *needed += spoolss_size_printer_info_1(printer);
4802 if (*needed > offered) {
4803 result = WERR_INSUFFICIENT_BUFFER;
4807 if (!rpcbuf_alloc_size(buffer, *needed)) {
4808 result = WERR_NOMEM;
4812 /* fill the buffer with the structures */
4813 smb_io_printer_info_1("", buffer, printer, 0);
4822 /****************************************************************************
4823 ****************************************************************************/
4825 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4827 PRINTER_INFO_2 *printer=NULL;
4828 WERROR result = WERR_OK;
4830 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4833 construct_printer_info_2(print_hnd, printer, snum);
4835 /* check the required size. */
4836 *needed += spoolss_size_printer_info_2(printer);
4838 if (*needed > offered) {
4839 result = WERR_INSUFFICIENT_BUFFER;
4843 if (!rpcbuf_alloc_size(buffer, *needed)) {
4844 result = WERR_NOMEM;
4848 /* fill the buffer with the structures */
4849 if (!smb_io_printer_info_2("", buffer, printer, 0))
4850 result = WERR_NOMEM;
4854 free_printer_info_2(printer);
4859 /****************************************************************************
4860 ****************************************************************************/
4862 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4864 PRINTER_INFO_3 *printer=NULL;
4865 WERROR result = WERR_OK;
4867 if (!construct_printer_info_3(print_hnd, &printer, snum))
4870 /* check the required size. */
4871 *needed += spoolss_size_printer_info_3(printer);
4873 if (*needed > offered) {
4874 result = WERR_INSUFFICIENT_BUFFER;
4878 if (!rpcbuf_alloc_size(buffer, *needed)) {
4879 result = WERR_NOMEM;
4883 /* fill the buffer with the structures */
4884 smb_io_printer_info_3("", buffer, printer, 0);
4888 free_printer_info_3(printer);
4893 /****************************************************************************
4894 ****************************************************************************/
4896 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4898 PRINTER_INFO_4 *printer=NULL;
4899 WERROR result = WERR_OK;
4901 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4904 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4909 /* check the required size. */
4910 *needed += spoolss_size_printer_info_4(printer);
4912 if (*needed > offered) {
4913 result = WERR_INSUFFICIENT_BUFFER;
4917 if (!rpcbuf_alloc_size(buffer, *needed)) {
4918 result = WERR_NOMEM;
4922 /* fill the buffer with the structures */
4923 smb_io_printer_info_4("", buffer, printer, 0);
4927 free_printer_info_4(printer);
4932 /****************************************************************************
4933 ****************************************************************************/
4935 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4937 PRINTER_INFO_5 *printer=NULL;
4938 WERROR result = WERR_OK;
4940 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4943 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4944 free_printer_info_5(printer);
4948 /* check the required size. */
4949 *needed += spoolss_size_printer_info_5(printer);
4951 if (*needed > offered) {
4952 result = WERR_INSUFFICIENT_BUFFER;
4956 if (!rpcbuf_alloc_size(buffer, *needed)) {
4957 result = WERR_NOMEM;
4961 /* fill the buffer with the structures */
4962 smb_io_printer_info_5("", buffer, printer, 0);
4966 free_printer_info_5(printer);
4971 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4973 RPC_BUFFER *buffer, uint32 offered,
4976 PRINTER_INFO_6 *printer;
4977 WERROR result = WERR_OK;
4979 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4983 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4984 free_printer_info_6(printer);
4988 /* check the required size. */
4989 *needed += spoolss_size_printer_info_6(printer);
4991 if (*needed > offered) {
4992 result = WERR_INSUFFICIENT_BUFFER;
4996 if (!rpcbuf_alloc_size(buffer, *needed)) {
4997 result = WERR_NOMEM;
5001 /* fill the buffer with the structures */
5002 smb_io_printer_info_6("", buffer, printer, 0);
5006 free_printer_info_6(printer);
5011 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5013 PRINTER_INFO_7 *printer=NULL;
5014 WERROR result = WERR_OK;
5016 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5019 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5020 result = WERR_NOMEM;
5024 /* check the required size. */
5025 *needed += spoolss_size_printer_info_7(printer);
5027 if (*needed > offered) {
5028 result = WERR_INSUFFICIENT_BUFFER;
5032 if (!rpcbuf_alloc_size(buffer, *needed)) {
5033 result = WERR_NOMEM;
5038 /* fill the buffer with the structures */
5039 smb_io_printer_info_7("", buffer, printer, 0);
5043 free_printer_info_7(printer);
5048 /****************************************************************************
5049 ****************************************************************************/
5051 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5053 POLICY_HND *handle = &q_u->handle;
5054 uint32 level = q_u->level;
5055 RPC_BUFFER *buffer = NULL;
5056 uint32 offered = q_u->offered;
5057 uint32 *needed = &r_u->needed;
5058 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5062 /* that's an [in out] buffer */
5064 if (!q_u->buffer && (offered!=0)) {
5065 return WERR_INVALID_PARAM;
5068 if (offered > MAX_RPC_DATA_SIZE) {
5069 return WERR_INVALID_PARAM;
5072 rpcbuf_move(q_u->buffer, &r_u->buffer);
5073 buffer = r_u->buffer;
5077 if (!get_printer_snum(p, handle, &snum, NULL))
5082 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5084 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5086 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5088 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5090 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5092 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5094 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5096 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5098 return WERR_UNKNOWN_LEVEL;
5101 /********************************************************************
5102 * fill a DRIVER_INFO_1 struct
5103 ********************************************************************/
5105 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5107 init_unistr( &info->name, driver.info_3->name);
5110 /********************************************************************
5111 * construct_printer_driver_info_1
5112 ********************************************************************/
5114 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5116 NT_PRINTER_INFO_LEVEL *printer = NULL;
5117 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5119 ZERO_STRUCT(driver);
5121 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5122 return WERR_INVALID_PRINTER_NAME;
5124 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5125 free_a_printer(&printer, 2);
5126 return WERR_UNKNOWN_PRINTER_DRIVER;
5129 fill_printer_driver_info_1(info, driver, servername, architecture);
5131 free_a_printer(&printer,2);
5136 /********************************************************************
5137 * construct_printer_driver_info_2
5138 * fill a printer_info_2 struct
5139 ********************************************************************/
5141 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5143 TALLOC_CTX *ctx = talloc_tos();
5145 const char *cservername = canon_servername(servername);
5147 info->version=driver.info_3->cversion;
5149 init_unistr( &info->name, driver.info_3->name );
5150 init_unistr( &info->architecture, driver.info_3->environment );
5152 if (strlen(driver.info_3->driverpath)) {
5153 temp = talloc_asprintf(ctx,
5156 driver.info_3->driverpath);
5157 init_unistr( &info->driverpath, temp );
5159 init_unistr( &info->driverpath, "" );
5163 if (strlen(driver.info_3->datafile)) {
5164 temp = talloc_asprintf(ctx,
5167 driver.info_3->datafile);
5168 init_unistr( &info->datafile, temp );
5170 init_unistr( &info->datafile, "" );
5173 if (strlen(driver.info_3->configfile)) {
5174 temp = talloc_asprintf(ctx,
5177 driver.info_3->configfile);
5178 init_unistr( &info->configfile, temp );
5180 init_unistr( &info->configfile, "" );
5183 /********************************************************************
5184 * construct_printer_driver_info_2
5185 * fill a printer_info_2 struct
5186 ********************************************************************/
5188 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5190 NT_PRINTER_INFO_LEVEL *printer = NULL;
5191 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5193 ZERO_STRUCT(printer);
5194 ZERO_STRUCT(driver);
5196 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5197 return WERR_INVALID_PRINTER_NAME;
5199 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5200 free_a_printer(&printer, 2);
5201 return WERR_UNKNOWN_PRINTER_DRIVER;
5204 fill_printer_driver_info_2(info, driver, servername);
5206 free_a_printer(&printer,2);
5211 /********************************************************************
5212 * copy a strings array and convert to UNICODE
5214 * convert an array of ascii string to a UNICODE string
5215 ********************************************************************/
5217 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5223 TALLOC_CTX *ctx = talloc_tos();
5225 DEBUG(6,("init_unistr_array\n"));
5229 if ( !char_array ) {
5234 v = ""; /* hack to handle null lists */
5237 /* hack to allow this to be used in places other than when generating
5238 the list of dependent files */
5242 line = talloc_asprintf(ctx,
5244 canon_servername(servername),
5247 line = talloc_strdup(ctx, v);
5251 SAFE_FREE(*uni_array);
5254 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5256 /* add one extra unit16 for the second terminating NULL */
5258 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5259 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5266 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5271 /* special case for ""; we need to add both NULL's here */
5273 (*uni_array)[j++]=0x0000;
5274 (*uni_array)[j]=0x0000;
5277 DEBUGADD(6,("last one:done\n"));
5279 /* return size of array in uint16's */
5284 /********************************************************************
5285 * construct_printer_info_3
5286 * fill a printer_info_3 struct
5287 ********************************************************************/
5289 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5292 TALLOC_CTX *ctx = talloc_tos();
5293 const char *cservername = canon_servername(servername);
5297 info->version=driver.info_3->cversion;
5299 init_unistr( &info->name, driver.info_3->name );
5300 init_unistr( &info->architecture, driver.info_3->environment );
5302 if (strlen(driver.info_3->driverpath)) {
5303 temp = talloc_asprintf(ctx,
5306 driver.info_3->driverpath);
5307 init_unistr( &info->driverpath, temp );
5309 init_unistr( &info->driverpath, "" );
5312 if (strlen(driver.info_3->datafile)) {
5313 temp = talloc_asprintf(ctx,
5316 driver.info_3->datafile);
5317 init_unistr( &info->datafile, temp );
5319 init_unistr( &info->datafile, "" );
5322 if (strlen(driver.info_3->configfile)) {
5323 temp = talloc_asprintf(ctx,
5326 driver.info_3->configfile);
5327 init_unistr( &info->configfile, temp );
5329 init_unistr( &info->configfile, "" );
5332 if (strlen(driver.info_3->helpfile)) {
5333 temp = talloc_asprintf(ctx,
5336 driver.info_3->helpfile);
5337 init_unistr( &info->helpfile, temp );
5339 init_unistr( &info->helpfile, "" );
5342 init_unistr( &info->monitorname, driver.info_3->monitorname );
5343 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5345 info->dependentfiles=NULL;
5346 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5349 /********************************************************************
5350 * construct_printer_info_3
5351 * fill a printer_info_3 struct
5352 ********************************************************************/
5354 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5356 NT_PRINTER_INFO_LEVEL *printer = NULL;
5357 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5359 ZERO_STRUCT(driver);
5361 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5362 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5363 if (!W_ERROR_IS_OK(status))
5364 return WERR_INVALID_PRINTER_NAME;
5366 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5367 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5372 * I put this code in during testing. Helpful when commenting out the
5373 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5374 * as win2k always queries the driver using an infor level of 6.
5375 * I've left it in (but ifdef'd out) because I'll probably
5376 * use it in experimentation again in the future. --jerry 22/01/2002
5379 if (!W_ERROR_IS_OK(status)) {
5381 * Is this a W2k client ?
5384 /* Yes - try again with a WinNT driver. */
5386 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5387 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5391 if (!W_ERROR_IS_OK(status)) {
5392 free_a_printer(&printer,2);
5393 return WERR_UNKNOWN_PRINTER_DRIVER;
5401 fill_printer_driver_info_3(info, driver, servername);
5403 free_a_printer(&printer,2);
5408 /********************************************************************
5409 * construct_printer_info_6
5410 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5411 ********************************************************************/
5413 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5417 TALLOC_CTX *ctx = talloc_tos();
5418 const char *cservername = canon_servername(servername);
5421 memset(&nullstr, '\0', sizeof(fstring));
5423 info->version=driver.info_3->cversion;
5425 init_unistr( &info->name, driver.info_3->name );
5426 init_unistr( &info->architecture, driver.info_3->environment );
5428 if (strlen(driver.info_3->driverpath)) {
5429 temp = talloc_asprintf(ctx,
5432 driver.info_3->driverpath);
5433 init_unistr( &info->driverpath, temp );
5435 init_unistr( &info->driverpath, "" );
5438 if (strlen(driver.info_3->datafile)) {
5439 temp = talloc_asprintf(ctx,
5442 driver.info_3->datafile);
5443 init_unistr( &info->datafile, temp );
5445 init_unistr( &info->datafile, "" );
5448 if (strlen(driver.info_3->configfile)) {
5449 temp = talloc_asprintf(ctx,
5452 driver.info_3->configfile);
5453 init_unistr( &info->configfile, temp );
5455 init_unistr( &info->configfile, "" );
5458 if (strlen(driver.info_3->helpfile)) {
5459 temp = talloc_asprintf(ctx,
5462 driver.info_3->helpfile);
5463 init_unistr( &info->helpfile, temp );
5465 init_unistr( &info->helpfile, "" );
5468 init_unistr( &info->monitorname, driver.info_3->monitorname );
5469 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5471 info->dependentfiles = NULL;
5472 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5474 info->previousdrivernames=NULL;
5475 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5477 info->driver_date=0;
5480 info->driver_version_low=0;
5481 info->driver_version_high=0;
5483 init_unistr( &info->mfgname, "");
5484 init_unistr( &info->oem_url, "");
5485 init_unistr( &info->hardware_id, "");
5486 init_unistr( &info->provider, "");
5489 /********************************************************************
5490 * construct_printer_info_6
5491 * fill a printer_info_6 struct
5492 ********************************************************************/
5494 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5495 const char *servername, fstring architecture, uint32 version)
5497 NT_PRINTER_INFO_LEVEL *printer = NULL;
5498 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5501 ZERO_STRUCT(driver);
5503 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5505 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5507 if (!W_ERROR_IS_OK(status))
5508 return WERR_INVALID_PRINTER_NAME;
5510 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5512 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5514 if (!W_ERROR_IS_OK(status))
5517 * Is this a W2k client ?
5521 free_a_printer(&printer,2);
5522 return WERR_UNKNOWN_PRINTER_DRIVER;
5525 /* Yes - try again with a WinNT driver. */
5527 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5528 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5529 if (!W_ERROR_IS_OK(status)) {
5530 free_a_printer(&printer,2);
5531 return WERR_UNKNOWN_PRINTER_DRIVER;
5535 fill_printer_driver_info_6(info, driver, servername);
5537 free_a_printer(&printer,2);
5538 free_a_printer_driver(driver, 3);
5543 /****************************************************************************
5544 ****************************************************************************/
5546 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5548 SAFE_FREE(info->dependentfiles);
5551 /****************************************************************************
5552 ****************************************************************************/
5554 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5556 SAFE_FREE(info->dependentfiles);
5559 /****************************************************************************
5560 ****************************************************************************/
5562 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5564 DRIVER_INFO_1 *info=NULL;
5567 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5570 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5571 if (!W_ERROR_IS_OK(result))
5574 /* check the required size. */
5575 *needed += spoolss_size_printer_driver_info_1(info);
5577 if (*needed > offered) {
5578 result = WERR_INSUFFICIENT_BUFFER;
5582 if (!rpcbuf_alloc_size(buffer, *needed)) {
5583 result = WERR_NOMEM;
5587 /* fill the buffer with the structures */
5588 smb_io_printer_driver_info_1("", buffer, info, 0);
5597 /****************************************************************************
5598 ****************************************************************************/
5600 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5602 DRIVER_INFO_2 *info=NULL;
5605 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5608 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5609 if (!W_ERROR_IS_OK(result))
5612 /* check the required size. */
5613 *needed += spoolss_size_printer_driver_info_2(info);
5615 if (*needed > offered) {
5616 result = WERR_INSUFFICIENT_BUFFER;
5620 if (!rpcbuf_alloc_size(buffer, *needed)) {
5621 result = WERR_NOMEM;
5625 /* fill the buffer with the structures */
5626 smb_io_printer_driver_info_2("", buffer, info, 0);
5635 /****************************************************************************
5636 ****************************************************************************/
5638 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5645 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5646 if (!W_ERROR_IS_OK(result))
5649 /* check the required size. */
5650 *needed += spoolss_size_printer_driver_info_3(&info);
5652 if (*needed > offered) {
5653 result = WERR_INSUFFICIENT_BUFFER;
5657 if (!rpcbuf_alloc_size(buffer, *needed)) {
5658 result = WERR_NOMEM;
5662 /* fill the buffer with the structures */
5663 smb_io_printer_driver_info_3("", buffer, &info, 0);
5666 free_printer_driver_info_3(&info);
5671 /****************************************************************************
5672 ****************************************************************************/
5674 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5681 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5682 if (!W_ERROR_IS_OK(result))
5685 /* check the required size. */
5686 *needed += spoolss_size_printer_driver_info_6(&info);
5688 if (*needed > offered) {
5689 result = WERR_INSUFFICIENT_BUFFER;
5693 if (!rpcbuf_alloc_size(buffer, *needed)) {
5694 result = WERR_NOMEM;
5698 /* fill the buffer with the structures */
5699 smb_io_printer_driver_info_6("", buffer, &info, 0);
5702 free_printer_driver_info_6(&info);
5707 /****************************************************************************
5708 ****************************************************************************/
5710 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5712 POLICY_HND *handle = &q_u->handle;
5713 UNISTR2 *uni_arch = &q_u->architecture;
5714 uint32 level = q_u->level;
5715 uint32 clientmajorversion = q_u->clientmajorversion;
5716 RPC_BUFFER *buffer = NULL;
5717 uint32 offered = q_u->offered;
5718 uint32 *needed = &r_u->needed;
5719 uint32 *servermajorversion = &r_u->servermajorversion;
5720 uint32 *serverminorversion = &r_u->serverminorversion;
5721 Printer_entry *printer;
5724 fstring architecture;
5727 /* that's an [in out] buffer */
5729 if (!q_u->buffer && (offered!=0)) {
5730 return WERR_INVALID_PARAM;
5733 if (offered > MAX_RPC_DATA_SIZE) {
5734 return WERR_INVALID_PARAM;
5737 rpcbuf_move(q_u->buffer, &r_u->buffer);
5738 buffer = r_u->buffer;
5740 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5742 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5743 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5744 return WERR_INVALID_PRINTER_NAME;
5748 *servermajorversion = 0;
5749 *serverminorversion = 0;
5751 fstrcpy(servername, get_server_name( printer ));
5752 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5754 if (!get_printer_snum(p, handle, &snum, NULL))
5759 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5761 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5763 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5765 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5768 /* apparently this call is the equivalent of
5769 EnumPrinterDataEx() for the DsDriver key */
5774 return WERR_UNKNOWN_LEVEL;
5778 /****************************************************************
5779 _spoolss_StartPagePrinter
5780 ****************************************************************/
5782 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5783 struct spoolss_StartPagePrinter *r)
5785 POLICY_HND *handle = r->in.handle;
5787 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5790 DEBUG(3,("_spoolss_StartPagePrinter: "
5791 "Error in startpageprinter printer handle\n"));
5795 Printer->page_started=True;
5799 /****************************************************************
5800 _spoolss_EndPagePrinter
5801 ****************************************************************/
5803 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5804 struct spoolss_EndPagePrinter *r)
5806 POLICY_HND *handle = r->in.handle;
5809 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5812 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5813 OUR_HANDLE(handle)));
5817 if (!get_printer_snum(p, handle, &snum, NULL))
5820 Printer->page_started=False;
5821 print_job_endpage(snum, Printer->jobid);
5826 /****************************************************************
5827 _spoolss_StartDocPrinter
5828 ****************************************************************/
5830 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5831 struct spoolss_StartDocPrinter *r)
5833 POLICY_HND *handle = r->in.handle;
5834 uint32_t *jobid = r->out.job_id;
5835 struct spoolss_DocumentInfo1 *info_1;
5837 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5840 DEBUG(2,("_spoolss_StartDocPrinter: "
5841 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5845 if (r->in.level != 1) {
5846 return WERR_UNKNOWN_LEVEL;
5849 info_1 = r->in.info.info1;
5852 * a nice thing with NT is it doesn't listen to what you tell it.
5853 * when asked to send _only_ RAW datas, it tries to send datas
5856 * So I add checks like in NT Server ...
5859 if (info_1->datatype) {
5860 if (strcmp(info_1->datatype, "RAW") != 0) {
5862 return WERR_INVALID_DATATYPE;
5866 /* get the share number of the printer */
5867 if (!get_printer_snum(p, handle, &snum, NULL)) {
5871 Printer->jobid = print_job_start(p->server_info, snum,
5872 CONST_DISCARD(char *,info_1->document_name),
5873 Printer->nt_devmode);
5875 /* An error occured in print_job_start() so return an appropriate
5878 if (Printer->jobid == -1) {
5879 return map_werror_from_unix(errno);
5882 Printer->document_started=True;
5883 (*jobid) = Printer->jobid;
5888 /****************************************************************
5889 _spoolss_EndDocPrinter
5890 ****************************************************************/
5892 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5893 struct spoolss_EndDocPrinter *r)
5895 POLICY_HND *handle = r->in.handle;
5897 return _spoolss_enddocprinter_internal(p, handle);
5900 /****************************************************************
5901 _spoolss_WritePrinter
5902 ****************************************************************/
5904 WERROR _spoolss_WritePrinter(pipes_struct *p,
5905 struct spoolss_WritePrinter *r)
5907 POLICY_HND *handle = r->in.handle;
5908 uint32 buffer_size = r->in._data_size;
5909 uint8 *buffer = r->in.data.data;
5910 uint32 *buffer_written = &r->in._data_size;
5912 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5915 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5916 OUR_HANDLE(handle)));
5917 *r->out.num_written = r->in._data_size;
5921 if (!get_printer_snum(p, handle, &snum, NULL))
5924 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5925 (SMB_OFF_T)-1, (size_t)buffer_size);
5926 if (*buffer_written == (uint32)-1) {
5927 *r->out.num_written = 0;
5928 if (errno == ENOSPC)
5929 return WERR_NO_SPOOL_SPACE;
5931 return WERR_ACCESS_DENIED;
5934 *r->out.num_written = r->in._data_size;
5939 /********************************************************************
5940 * api_spoolss_getprinter
5941 * called from the spoolss dispatcher
5943 ********************************************************************/
5945 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5949 WERROR errcode = WERR_BADFUNC;
5950 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5953 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5957 if (!get_printer_snum(p, handle, &snum, NULL))
5961 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5962 if (print_queue_pause(p->server_info, snum, &errcode)) {
5966 case SPOOLSS_PRINTER_CONTROL_RESUME:
5967 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5968 if (print_queue_resume(p->server_info, snum, &errcode)) {
5972 case SPOOLSS_PRINTER_CONTROL_PURGE:
5973 if (print_queue_purge(p->server_info, snum, &errcode)) {
5978 return WERR_UNKNOWN_LEVEL;
5985 /****************************************************************
5986 _spoolss_AbortPrinter
5987 * From MSDN: "Deletes printer's spool file if printer is configured
5989 ****************************************************************/
5991 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5992 struct spoolss_AbortPrinter *r)
5994 POLICY_HND *handle = r->in.handle;
5995 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5997 WERROR errcode = WERR_OK;
6000 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6001 OUR_HANDLE(handle)));
6005 if (!get_printer_snum(p, handle, &snum, NULL))
6008 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6013 /********************************************************************
6014 * called by spoolss_api_setprinter
6015 * when updating a printer description
6016 ********************************************************************/
6018 static WERROR update_printer_sec(POLICY_HND *handle,
6019 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6021 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6025 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6027 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6028 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6029 OUR_HANDLE(handle)));
6031 result = WERR_BADFID;
6036 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6037 result = WERR_INVALID_PARAM;
6041 /* Check the user has permissions to change the security
6042 descriptor. By experimentation with two NT machines, the user
6043 requires Full Access to the printer to change security
6046 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6047 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6048 result = WERR_ACCESS_DENIED;
6052 /* NT seems to like setting the security descriptor even though
6053 nothing may have actually changed. */
6055 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6056 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6057 result = WERR_BADFID;
6061 if (DEBUGLEVEL >= 10) {
6065 the_acl = old_secdesc_ctr->sd->dacl;
6066 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6067 PRINTERNAME(snum), the_acl->num_aces));
6069 for (i = 0; i < the_acl->num_aces; i++) {
6070 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6071 &the_acl->aces[i].trustee),
6072 the_acl->aces[i].access_mask));
6075 the_acl = secdesc_ctr->sd->dacl;
6078 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6079 PRINTERNAME(snum), the_acl->num_aces));
6081 for (i = 0; i < the_acl->num_aces; i++) {
6082 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6083 &the_acl->aces[i].trustee),
6084 the_acl->aces[i].access_mask));
6087 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6091 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6092 if (!new_secdesc_ctr) {
6093 result = WERR_NOMEM;
6097 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6102 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6109 /********************************************************************
6110 Canonicalize printer info from a client
6112 ATTN: It does not matter what we set the servername to hear
6113 since we do the necessary work in get_a_printer() to set it to
6114 the correct value based on what the client sent in the
6115 _spoolss_open_printer_ex().
6116 ********************************************************************/
6118 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6120 fstring printername;
6123 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6124 "portname=%s drivername=%s comment=%s location=%s\n",
6125 info->servername, info->printername, info->sharename,
6126 info->portname, info->drivername, info->comment, info->location));
6128 /* we force some elements to "correct" values */
6129 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6130 fstrcpy(info->sharename, lp_servicename(snum));
6132 /* check to see if we allow printername != sharename */
6134 if ( lp_force_printername(snum) ) {
6135 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6136 global_myname(), info->sharename );
6139 /* make sure printername is in \\server\printername format */
6141 fstrcpy( printername, info->printername );
6143 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6144 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6148 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6149 global_myname(), p );
6152 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6153 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6160 /****************************************************************************
6161 ****************************************************************************/
6163 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6165 char *cmd = lp_addport_cmd();
6166 char *command = NULL;
6168 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6169 bool is_print_op = False;
6172 return WERR_ACCESS_DENIED;
6175 command = talloc_asprintf(ctx,
6176 "%s \"%s\" \"%s\"", cmd, portname, uri );
6182 is_print_op = user_has_privileges( token, &se_printop );
6184 DEBUG(10,("Running [%s]\n", command));
6186 /********* BEGIN SePrintOperatorPrivilege **********/
6191 ret = smbrun(command, NULL);
6196 /********* END SePrintOperatorPrivilege **********/
6198 DEBUGADD(10,("returned [%d]\n", ret));
6200 TALLOC_FREE(command);
6203 return WERR_ACCESS_DENIED;
6209 /****************************************************************************
6210 ****************************************************************************/
6212 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6214 char *cmd = lp_addprinter_cmd();
6216 char *command = NULL;
6220 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6221 bool is_print_op = False;
6222 char *remote_machine = talloc_strdup(ctx, "%m");
6224 if (!remote_machine) {
6227 remote_machine = talloc_sub_basic(ctx,
6228 current_user_info.smb_name,
6229 current_user_info.domain,
6231 if (!remote_machine) {
6235 command = talloc_asprintf(ctx,
6236 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6237 cmd, printer->info_2->printername, printer->info_2->sharename,
6238 printer->info_2->portname, printer->info_2->drivername,
6239 printer->info_2->location, printer->info_2->comment, remote_machine);
6245 is_print_op = user_has_privileges( token, &se_printop );
6247 DEBUG(10,("Running [%s]\n", command));
6249 /********* BEGIN SePrintOperatorPrivilege **********/
6254 if ( (ret = smbrun(command, &fd)) == 0 ) {
6255 /* Tell everyone we updated smb.conf. */
6256 message_send_all(smbd_messaging_context(),
6257 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6263 /********* END SePrintOperatorPrivilege **********/
6265 DEBUGADD(10,("returned [%d]\n", ret));
6267 TALLOC_FREE(command);
6268 TALLOC_FREE(remote_machine);
6276 /* reload our services immediately */
6277 reload_services( False );
6280 /* Get lines and convert them back to dos-codepage */
6281 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6282 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6285 /* Set the portname to what the script says the portname should be. */
6286 /* but don't require anything to be return from the script exit a good error code */
6289 /* Set the portname to what the script says the portname should be. */
6290 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6291 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6294 TALLOC_FREE(qlines);
6299 /********************************************************************
6300 * Called by spoolss_api_setprinter
6301 * when updating a printer description.
6302 ********************************************************************/
6304 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6305 struct spoolss_SetPrinterInfoCtr *info_ctr,
6306 struct spoolss_DeviceMode *devmode)
6309 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6310 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6315 DEBUG(8,("update_printer\n"));
6320 result = WERR_BADFID;
6324 if (!get_printer_snum(p, handle, &snum, NULL)) {
6325 result = WERR_BADFID;
6329 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6330 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6331 result = WERR_BADFID;
6335 DEBUGADD(8,("Converting info_2 struct\n"));
6338 * convert_printer_info converts the incoming
6339 * info from the client and overwrites the info
6340 * just read from the tdb in the pointer 'printer'.
6343 if (!convert_printer_info_new(info_ctr, printer)) {
6344 result = WERR_NOMEM;
6349 /* we have a valid devmode
6350 convert it and link it*/
6352 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6353 if (!convert_devicemode_new(printer->info_2->printername,
6355 &printer->info_2->devmode)) {
6356 result = WERR_NOMEM;
6361 /* Do sanity check on the requested changes for Samba */
6363 if (!check_printer_ok(printer->info_2, snum)) {
6364 result = WERR_INVALID_PARAM;
6368 /* FIXME!!! If the driver has changed we really should verify that
6369 it is installed before doing much else --jerry */
6371 /* Check calling user has permission to update printer description */
6373 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6374 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6375 result = WERR_ACCESS_DENIED;
6379 /* Call addprinter hook */
6380 /* Check changes to see if this is really needed */
6382 if ( *lp_addprinter_cmd()
6383 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6384 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6385 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6386 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6388 /* add_printer_hook() will call reload_services() */
6390 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6392 result = WERR_ACCESS_DENIED;
6398 * When a *new* driver is bound to a printer, the drivername is used to
6399 * lookup previously saved driver initialization info, which is then
6400 * bound to the printer, simulating what happens in the Windows arch.
6402 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6404 if (!set_driver_init(printer, 2))
6406 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6407 printer->info_2->drivername));
6410 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6411 printer->info_2->drivername));
6413 notify_printer_driver(snum, printer->info_2->drivername);
6417 * flag which changes actually occured. This is a small subset of
6418 * all the possible changes. We also have to update things in the
6422 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6423 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6424 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6425 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6427 notify_printer_comment(snum, printer->info_2->comment);
6430 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6431 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6432 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6433 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6435 notify_printer_sharename(snum, printer->info_2->sharename);
6438 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6441 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6444 pname = printer->info_2->printername;
6447 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6448 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6449 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6451 notify_printer_printername( snum, pname );
6454 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6455 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6456 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6457 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6459 notify_printer_port(snum, printer->info_2->portname);
6462 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6463 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6464 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6465 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6467 notify_printer_location(snum, printer->info_2->location);
6470 /* here we need to update some more DsSpooler keys */
6471 /* uNCName, serverName, shortServerName */
6473 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6474 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6475 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6476 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6477 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6479 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6480 global_myname(), printer->info_2->sharename );
6481 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6482 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6483 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6485 /* Update printer info */
6486 result = mod_a_printer(printer, 2);
6489 free_a_printer(&printer, 2);
6490 free_a_printer(&old_printer, 2);
6496 /****************************************************************************
6497 ****************************************************************************/
6498 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6499 struct spoolss_SetPrinterInfo7 *info7)
6503 Printer_entry *Printer;
6505 if ( lp_security() != SEC_ADS ) {
6506 return WERR_UNKNOWN_LEVEL;
6509 Printer = find_printer_index_by_hnd(p, handle);
6511 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6516 if (!get_printer_snum(p, handle, &snum, NULL))
6519 nt_printer_publish(Printer, snum, info7->action);
6523 return WERR_UNKNOWN_LEVEL;
6527 /****************************************************************
6529 ****************************************************************/
6531 WERROR _spoolss_SetPrinter(pipes_struct *p,
6532 struct spoolss_SetPrinter *r)
6534 POLICY_HND *handle = r->in.handle;
6537 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6540 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6541 OUR_HANDLE(handle)));
6545 /* check the level */
6546 switch (r->in.info_ctr->level) {
6548 return control_printer(handle, r->in.command, p);
6550 result = update_printer(p, handle,
6552 r->in.devmode_ctr->devmode);
6553 if (!W_ERROR_IS_OK(result))
6555 if (r->in.secdesc_ctr->sd)
6556 result = update_printer_sec(handle, p,
6560 return update_printer_sec(handle, p,
6563 return publish_or_unpublish_printer(p, handle,
6564 r->in.info_ctr->info.info7);
6566 return WERR_UNKNOWN_LEVEL;
6570 /****************************************************************
6571 _spoolss_FindClosePrinterNotify
6572 ****************************************************************/
6574 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6575 struct spoolss_FindClosePrinterNotify *r)
6577 POLICY_HND *handle = r->in.handle;
6578 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6581 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6582 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6586 if (Printer->notify.client_connected==True) {
6589 if ( Printer->printer_type == SPLHND_SERVER)
6591 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6592 !get_printer_snum(p, handle, &snum, NULL) )
6595 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6598 Printer->notify.flags=0;
6599 Printer->notify.options=0;
6600 Printer->notify.localmachine[0]='\0';
6601 Printer->notify.printerlocal=0;
6602 TALLOC_FREE(Printer->notify.option);
6603 Printer->notify.client_connected=False;
6608 /****************************************************************
6610 ****************************************************************/
6612 WERROR _spoolss_AddJob(pipes_struct *p,
6613 struct spoolss_AddJob *r)
6615 if (!r->in.buffer && (r->in.offered != 0)) {
6616 return WERR_INVALID_PARAM;
6619 /* this is what a NT server returns for AddJob. AddJob must fail on
6620 * non-local printers */
6622 return WERR_INVALID_PARAM;
6625 /****************************************************************************
6626 ****************************************************************************/
6628 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6629 int position, int snum,
6630 const NT_PRINTER_INFO_LEVEL *ntprinter)
6634 t=gmtime(&queue->time);
6636 job_info->jobid=queue->job;
6637 init_unistr(&job_info->printername, lp_servicename(snum));
6638 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6639 init_unistr(&job_info->username, queue->fs_user);
6640 init_unistr(&job_info->document, queue->fs_file);
6641 init_unistr(&job_info->datatype, "RAW");
6642 init_unistr(&job_info->text_status, "");
6643 job_info->status=nt_printj_status(queue->status);
6644 job_info->priority=queue->priority;
6645 job_info->position=position;
6646 job_info->totalpages=queue->page_count;
6647 job_info->pagesprinted=0;
6649 make_systemtime(&job_info->submitted, t);
6652 /****************************************************************************
6653 ****************************************************************************/
6655 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6656 int position, int snum,
6657 const NT_PRINTER_INFO_LEVEL *ntprinter,
6658 DEVICEMODE *devmode)
6662 t=gmtime(&queue->time);
6664 job_info->jobid=queue->job;
6666 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6668 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6669 init_unistr(&job_info->username, queue->fs_user);
6670 init_unistr(&job_info->document, queue->fs_file);
6671 init_unistr(&job_info->notifyname, queue->fs_user);
6672 init_unistr(&job_info->datatype, "RAW");
6673 init_unistr(&job_info->printprocessor, "winprint");
6674 init_unistr(&job_info->parameters, "");
6675 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6676 init_unistr(&job_info->text_status, "");
6678 /* and here the security descriptor */
6680 job_info->status=nt_printj_status(queue->status);
6681 job_info->priority=queue->priority;
6682 job_info->position=position;
6683 job_info->starttime=0;
6684 job_info->untiltime=0;
6685 job_info->totalpages=queue->page_count;
6686 job_info->size=queue->size;
6687 make_systemtime(&(job_info->submitted), t);
6688 job_info->timeelapsed=0;
6689 job_info->pagesprinted=0;
6691 job_info->devmode = devmode;
6696 /****************************************************************************
6697 Enumjobs at level 1.
6698 ****************************************************************************/
6700 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6701 const NT_PRINTER_INFO_LEVEL *ntprinter,
6702 RPC_BUFFER *buffer, uint32 offered,
6703 uint32 *needed, uint32 *returned)
6707 WERROR result = WERR_OK;
6709 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6715 for (i=0; i<*returned; i++)
6716 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6718 /* check the required size. */
6719 for (i=0; i<*returned; i++)
6720 (*needed) += spoolss_size_job_info_1(&info[i]);
6722 if (*needed > offered) {
6723 result = WERR_INSUFFICIENT_BUFFER;
6727 if (!rpcbuf_alloc_size(buffer, *needed)) {
6728 result = WERR_NOMEM;
6732 /* fill the buffer with the structures */
6733 for (i=0; i<*returned; i++)
6734 smb_io_job_info_1("", buffer, &info[i], 0);
6740 if ( !W_ERROR_IS_OK(result) )
6746 /****************************************************************************
6747 Enumjobs at level 2.
6748 ****************************************************************************/
6750 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6751 const NT_PRINTER_INFO_LEVEL *ntprinter,
6752 RPC_BUFFER *buffer, uint32 offered,
6753 uint32 *needed, uint32 *returned)
6755 JOB_INFO_2 *info = NULL;
6757 WERROR result = WERR_OK;
6758 DEVICEMODE *devmode = NULL;
6760 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6765 /* this should not be a failure condition if the devmode is NULL */
6767 devmode = construct_dev_mode(lp_const_servicename(snum));
6769 for (i=0; i<*returned; i++)
6770 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6772 /* check the required size. */
6773 for (i=0; i<*returned; i++)
6774 (*needed) += spoolss_size_job_info_2(&info[i]);
6776 if (*needed > offered) {
6777 result = WERR_INSUFFICIENT_BUFFER;
6781 if (!rpcbuf_alloc_size(buffer, *needed)) {
6782 result = WERR_NOMEM;
6786 /* fill the buffer with the structures */
6787 for (i=0; i<*returned; i++)
6788 smb_io_job_info_2("", buffer, &info[i], 0);
6791 free_devmode(devmode);
6794 if ( !W_ERROR_IS_OK(result) )
6801 /****************************************************************************
6803 ****************************************************************************/
6805 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6807 POLICY_HND *handle = &q_u->handle;
6808 uint32 level = q_u->level;
6809 RPC_BUFFER *buffer = NULL;
6810 uint32 offered = q_u->offered;
6811 uint32 *needed = &r_u->needed;
6812 uint32 *returned = &r_u->returned;
6814 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6816 print_status_struct prt_status;
6817 print_queue_struct *queue=NULL;
6819 /* that's an [in out] buffer */
6821 if (!q_u->buffer && (offered!=0)) {
6822 return WERR_INVALID_PARAM;
6825 if (offered > MAX_RPC_DATA_SIZE) {
6826 return WERR_INVALID_PARAM;
6829 rpcbuf_move(q_u->buffer, &r_u->buffer);
6830 buffer = r_u->buffer;
6832 DEBUG(4,("_spoolss_enumjobs\n"));
6837 /* lookup the printer snum and tdb entry */
6839 if (!get_printer_snum(p, handle, &snum, NULL))
6842 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6843 if ( !W_ERROR_IS_OK(wret) )
6846 *returned = print_queue_status(snum, &queue, &prt_status);
6847 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6849 if (*returned == 0) {
6851 free_a_printer(&ntprinter, 2);
6857 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6860 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6864 wret = WERR_UNKNOWN_LEVEL;
6869 free_a_printer( &ntprinter, 2 );
6873 /****************************************************************
6874 _spoolss_ScheduleJob
6875 ****************************************************************/
6877 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6878 struct spoolss_ScheduleJob *r)
6883 /****************************************************************
6885 ****************************************************************/
6887 WERROR _spoolss_SetJob(pipes_struct *p,
6888 struct spoolss_SetJob *r)
6890 POLICY_HND *handle = r->in.handle;
6891 uint32 jobid = r->in.job_id;
6892 uint32 command = r->in.command;
6895 WERROR errcode = WERR_BADFUNC;
6897 if (!get_printer_snum(p, handle, &snum, NULL)) {
6901 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6902 return WERR_INVALID_PRINTER_NAME;
6906 case SPOOLSS_JOB_CONTROL_CANCEL:
6907 case SPOOLSS_JOB_CONTROL_DELETE:
6908 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6912 case SPOOLSS_JOB_CONTROL_PAUSE:
6913 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6917 case SPOOLSS_JOB_CONTROL_RESTART:
6918 case SPOOLSS_JOB_CONTROL_RESUME:
6919 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6924 return WERR_UNKNOWN_LEVEL;
6930 /****************************************************************************
6931 Enumerates all printer drivers at level 1.
6932 ****************************************************************************/
6934 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6939 fstring *list = NULL;
6940 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6941 DRIVER_INFO_1 *driver_info_1=NULL;
6942 WERROR result = WERR_OK;
6946 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6948 ndrivers=get_ntdrivers(&list, architecture, version);
6949 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6951 if(ndrivers == -1) {
6952 SAFE_FREE(driver_info_1);
6957 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6958 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6964 for (i=0; i<ndrivers; i++) {
6966 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6967 ZERO_STRUCT(driver);
6968 status = get_a_printer_driver(&driver, 3, list[i],
6969 architecture, version);
6970 if (!W_ERROR_IS_OK(status)) {
6972 SAFE_FREE(driver_info_1);
6975 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6976 free_a_printer_driver(driver, 3);
6979 *returned+=ndrivers;
6983 /* check the required size. */
6984 for (i=0; i<*returned; i++) {
6985 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6986 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6989 if (*needed > offered) {
6990 result = WERR_INSUFFICIENT_BUFFER;
6994 if (!rpcbuf_alloc_size(buffer, *needed)) {
6995 result = WERR_NOMEM;
6999 /* fill the buffer with the driver structures */
7000 for (i=0; i<*returned; i++) {
7001 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7002 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7006 SAFE_FREE(driver_info_1);
7008 if ( !W_ERROR_IS_OK(result) )
7014 /****************************************************************************
7015 Enumerates all printer drivers at level 2.
7016 ****************************************************************************/
7018 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7023 fstring *list = NULL;
7024 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7025 DRIVER_INFO_2 *driver_info_2=NULL;
7026 WERROR result = WERR_OK;
7030 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7032 ndrivers=get_ntdrivers(&list, architecture, version);
7033 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7035 if(ndrivers == -1) {
7036 SAFE_FREE(driver_info_2);
7041 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7042 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7048 for (i=0; i<ndrivers; i++) {
7051 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7052 ZERO_STRUCT(driver);
7053 status = get_a_printer_driver(&driver, 3, list[i],
7054 architecture, version);
7055 if (!W_ERROR_IS_OK(status)) {
7057 SAFE_FREE(driver_info_2);
7060 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7061 free_a_printer_driver(driver, 3);
7064 *returned+=ndrivers;
7068 /* check the required size. */
7069 for (i=0; i<*returned; i++) {
7070 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7071 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7074 if (*needed > offered) {
7075 result = WERR_INSUFFICIENT_BUFFER;
7079 if (!rpcbuf_alloc_size(buffer, *needed)) {
7080 result = WERR_NOMEM;
7084 /* fill the buffer with the form structures */
7085 for (i=0; i<*returned; i++) {
7086 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7087 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7091 SAFE_FREE(driver_info_2);
7093 if ( !W_ERROR_IS_OK(result) )
7099 /****************************************************************************
7100 Enumerates all printer drivers at level 3.
7101 ****************************************************************************/
7103 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7108 fstring *list = NULL;
7109 DRIVER_INFO_3 *driver_info_3=NULL;
7110 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7111 WERROR result = WERR_OK;
7115 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7117 ndrivers=get_ntdrivers(&list, architecture, version);
7118 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7120 if(ndrivers == -1) {
7121 SAFE_FREE(driver_info_3);
7126 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7127 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7133 for (i=0; i<ndrivers; i++) {
7136 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7137 ZERO_STRUCT(driver);
7138 status = get_a_printer_driver(&driver, 3, list[i],
7139 architecture, version);
7140 if (!W_ERROR_IS_OK(status)) {
7142 SAFE_FREE(driver_info_3);
7145 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7146 free_a_printer_driver(driver, 3);
7149 *returned+=ndrivers;
7153 /* check the required size. */
7154 for (i=0; i<*returned; i++) {
7155 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7156 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7159 if (*needed > offered) {
7160 result = WERR_INSUFFICIENT_BUFFER;
7164 if (!rpcbuf_alloc_size(buffer, *needed)) {
7165 result = WERR_NOMEM;
7169 /* fill the buffer with the driver structures */
7170 for (i=0; i<*returned; i++) {
7171 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7172 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7176 for (i=0; i<*returned; i++) {
7177 SAFE_FREE(driver_info_3[i].dependentfiles);
7180 SAFE_FREE(driver_info_3);
7182 if ( !W_ERROR_IS_OK(result) )
7188 /****************************************************************************
7189 Enumerates all printer drivers.
7190 ****************************************************************************/
7192 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7194 uint32 level = q_u->level;
7195 RPC_BUFFER *buffer = NULL;
7196 uint32 offered = q_u->offered;
7197 uint32 *needed = &r_u->needed;
7198 uint32 *returned = &r_u->returned;
7199 const char *cservername;
7201 fstring architecture;
7203 /* that's an [in out] buffer */
7205 if (!q_u->buffer && (offered!=0)) {
7206 return WERR_INVALID_PARAM;
7209 if (offered > MAX_RPC_DATA_SIZE) {
7210 return WERR_INVALID_PARAM;
7213 rpcbuf_move(q_u->buffer, &r_u->buffer);
7214 buffer = r_u->buffer;
7216 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7221 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7222 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7224 cservername = canon_servername(servername);
7226 if (!is_myname_or_ipaddr(cservername))
7227 return WERR_UNKNOWN_PRINTER_DRIVER;
7231 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7233 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7235 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7237 return WERR_UNKNOWN_LEVEL;
7241 /****************************************************************************
7242 ****************************************************************************/
7244 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7246 form->flag=list->flag;
7247 init_unistr(&form->name, list->name);
7248 form->width=list->width;
7249 form->length=list->length;
7250 form->left=list->left;
7251 form->top=list->top;
7252 form->right=list->right;
7253 form->bottom=list->bottom;
7256 /****************************************************************************
7257 ****************************************************************************/
7259 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7260 struct spoolss_FormInfo1 *form,
7261 nt_forms_struct *list)
7263 form->form_name = talloc_strdup(mem_ctx, list->name);
7264 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7266 form->flags = list->flag;
7267 form->size.width = list->width;
7268 form->size.height = list->length;
7269 form->area.left = list->left;
7270 form->area.top = list->top;
7271 form->area.right = list->right;
7272 form->area.bottom = list->bottom;
7277 /****************************************************************************
7278 ****************************************************************************/
7280 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7282 uint32 level = q_u->level;
7283 RPC_BUFFER *buffer = NULL;
7284 uint32 offered = q_u->offered;
7285 uint32 *needed = &r_u->needed;
7286 uint32 *numofforms = &r_u->numofforms;
7287 uint32 numbuiltinforms;
7289 nt_forms_struct *list=NULL;
7290 nt_forms_struct *builtinlist=NULL;
7295 /* that's an [in out] buffer */
7297 if (!q_u->buffer && (offered!=0) ) {
7298 return WERR_INVALID_PARAM;
7301 if (offered > MAX_RPC_DATA_SIZE) {
7302 return WERR_INVALID_PARAM;
7305 rpcbuf_move(q_u->buffer, &r_u->buffer);
7306 buffer = r_u->buffer;
7308 DEBUG(4,("_spoolss_enumforms\n"));
7309 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7310 DEBUGADD(5,("Info level [%d]\n", level));
7312 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7313 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7314 *numofforms = get_ntforms(&list);
7315 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7316 *numofforms += numbuiltinforms;
7318 if (*numofforms == 0) {
7319 SAFE_FREE(builtinlist);
7321 return WERR_NO_MORE_ITEMS;
7326 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7327 SAFE_FREE(builtinlist);
7333 /* construct the list of form structures */
7334 for (i=0; i<numbuiltinforms; i++) {
7335 DEBUGADD(6,("Filling form number [%d]\n",i));
7336 fill_form_1(&forms_1[i], &builtinlist[i]);
7339 SAFE_FREE(builtinlist);
7341 for (; i<*numofforms; i++) {
7342 DEBUGADD(6,("Filling form number [%d]\n",i));
7343 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7348 /* check the required size. */
7349 for (i=0; i<numbuiltinforms; i++) {
7350 DEBUGADD(6,("adding form [%d]'s size\n",i));
7351 buffer_size += spoolss_size_form_1(&forms_1[i]);
7353 for (; i<*numofforms; i++) {
7354 DEBUGADD(6,("adding form [%d]'s size\n",i));
7355 buffer_size += spoolss_size_form_1(&forms_1[i]);
7358 *needed=buffer_size;
7360 if (*needed > offered) {
7363 return WERR_INSUFFICIENT_BUFFER;
7366 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7372 /* fill the buffer with the form structures */
7373 for (i=0; i<numbuiltinforms; i++) {
7374 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7375 smb_io_form_1("", buffer, &forms_1[i], 0);
7377 for (; i<*numofforms; i++) {
7378 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7379 smb_io_form_1("", buffer, &forms_1[i], 0);
7388 SAFE_FREE(builtinlist);
7389 return WERR_UNKNOWN_LEVEL;
7393 /****************************************************************
7395 ****************************************************************/
7397 WERROR _spoolss_GetForm(pipes_struct *p,
7398 struct spoolss_GetForm *r)
7400 uint32 level = r->in.level;
7401 uint32 offered = r->in.offered;
7402 uint32 *needed = r->out.needed;
7404 nt_forms_struct *list=NULL;
7405 nt_forms_struct builtin_form;
7407 union spoolss_FormInfo info;
7408 struct spoolss_FormInfo1 form_1;
7409 int numofforms=0, i=0;
7411 /* that's an [in out] buffer */
7413 if (!r->in.buffer && (offered!=0)) {
7414 return WERR_INVALID_PARAM;
7417 DEBUG(4,("_spoolss_GetForm\n"));
7418 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7419 DEBUGADD(5,("Info level [%d]\n", level));
7421 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7422 if (!foundBuiltin) {
7423 numofforms = get_ntforms(&list);
7424 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7426 if (numofforms == 0)
7430 ZERO_STRUCT(form_1);
7435 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7438 /* Check if the requested name is in the list of form structures */
7439 for (i=0; i<numofforms; i++) {
7441 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7442 list[i].name, r->in.form_name));
7444 if (strequal(r->in.form_name, list[i].name)) {
7445 DEBUGADD(6,("Found form %s number [%d]\n",
7446 r->in.form_name, i));
7447 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7453 if (i == numofforms) {
7457 /* check the required size. */
7459 info.info1 = form_1;
7461 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7463 if (*needed > offered) {
7465 return WERR_INSUFFICIENT_BUFFER;
7468 r->out.info->info1 = form_1;
7470 /* fill the buffer with the form structures */
7471 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7472 r->in.form_name, i));
7478 return WERR_UNKNOWN_LEVEL;
7482 /****************************************************************************
7483 ****************************************************************************/
7485 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7487 init_unistr(&port->port_name, name);
7490 /****************************************************************************
7491 TODO: This probably needs distinguish between TCP/IP and Local ports
7493 ****************************************************************************/
7495 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7497 init_unistr(&port->port_name, name);
7498 init_unistr(&port->monitor_name, "Local Monitor");
7499 init_unistr(&port->description, SPL_LOCAL_PORT );
7500 port->port_type=PORT_TYPE_WRITE;
7505 /****************************************************************************
7506 wrapper around the enumer ports command
7507 ****************************************************************************/
7509 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7511 char *cmd = lp_enumports_cmd();
7512 char **qlines = NULL;
7513 char *command = NULL;
7521 /* if no hook then just fill in the default port */
7524 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7527 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7528 TALLOC_FREE(qlines);
7535 /* we have a valid enumport command */
7537 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7542 DEBUG(10,("Running [%s]\n", command));
7543 ret = smbrun(command, &fd);
7544 DEBUG(10,("Returned [%d]\n", ret));
7545 TALLOC_FREE(command);
7550 return WERR_ACCESS_DENIED;
7554 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7555 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7565 /****************************************************************************
7567 ****************************************************************************/
7569 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7571 PORT_INFO_1 *ports=NULL;
7573 WERROR result = WERR_OK;
7574 char **qlines = NULL;
7577 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7578 if (!W_ERROR_IS_OK(result)) {
7579 TALLOC_FREE(qlines);
7584 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7585 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7586 win_errstr(WERR_NOMEM)));
7587 TALLOC_FREE(qlines);
7591 for (i=0; i<numlines; i++) {
7592 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7593 fill_port_1(&ports[i], qlines[i]);
7596 TALLOC_FREE(qlines);
7598 *returned = numlines;
7600 /* check the required size. */
7601 for (i=0; i<*returned; i++) {
7602 DEBUGADD(6,("adding port [%d]'s size\n", i));
7603 *needed += spoolss_size_port_info_1(&ports[i]);
7606 if (*needed > offered) {
7607 result = WERR_INSUFFICIENT_BUFFER;
7611 if (!rpcbuf_alloc_size(buffer, *needed)) {
7612 result = WERR_NOMEM;
7616 /* fill the buffer with the ports structures */
7617 for (i=0; i<*returned; i++) {
7618 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7619 smb_io_port_1("", buffer, &ports[i], 0);
7625 if ( !W_ERROR_IS_OK(result) )
7631 /****************************************************************************
7633 ****************************************************************************/
7635 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7637 PORT_INFO_2 *ports=NULL;
7639 WERROR result = WERR_OK;
7640 char **qlines = NULL;
7643 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7644 if ( !W_ERROR_IS_OK(result)) {
7645 TALLOC_FREE(qlines);
7650 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7651 TALLOC_FREE(qlines);
7655 for (i=0; i<numlines; i++) {
7656 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7657 fill_port_2(&(ports[i]), qlines[i]);
7661 TALLOC_FREE(qlines);
7663 *returned = numlines;
7665 /* check the required size. */
7666 for (i=0; i<*returned; i++) {
7667 DEBUGADD(6,("adding port [%d]'s size\n", i));
7668 *needed += spoolss_size_port_info_2(&ports[i]);
7671 if (*needed > offered) {
7672 result = WERR_INSUFFICIENT_BUFFER;
7676 if (!rpcbuf_alloc_size(buffer, *needed)) {
7677 result = WERR_NOMEM;
7681 /* fill the buffer with the ports structures */
7682 for (i=0; i<*returned; i++) {
7683 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7684 smb_io_port_2("", buffer, &ports[i], 0);
7690 if ( !W_ERROR_IS_OK(result) )
7696 /****************************************************************************
7698 ****************************************************************************/
7700 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7702 uint32 level = q_u->level;
7703 RPC_BUFFER *buffer = NULL;
7704 uint32 offered = q_u->offered;
7705 uint32 *needed = &r_u->needed;
7706 uint32 *returned = &r_u->returned;
7708 /* that's an [in out] buffer */
7710 if (!q_u->buffer && (offered!=0)) {
7711 return WERR_INVALID_PARAM;
7714 if (offered > MAX_RPC_DATA_SIZE) {
7715 return WERR_INVALID_PARAM;
7718 rpcbuf_move(q_u->buffer, &r_u->buffer);
7719 buffer = r_u->buffer;
7721 DEBUG(4,("_spoolss_enumports\n"));
7728 return enumports_level_1(buffer, offered, needed, returned);
7730 return enumports_level_2(buffer, offered, needed, returned);
7732 return WERR_UNKNOWN_LEVEL;
7736 /****************************************************************************
7737 ****************************************************************************/
7739 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7741 struct spoolss_SetPrinterInfoCtr *info_ctr,
7742 struct spoolss_DeviceMode *devmode,
7743 struct security_descriptor *sec_desc,
7744 struct spoolss_UserLevelCtr *user_ctr,
7747 NT_PRINTER_INFO_LEVEL *printer = NULL;
7750 WERROR err = WERR_OK;
7752 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7753 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7757 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7758 if (!convert_printer_info_new(info_ctr, printer)) {
7759 free_a_printer(&printer, 2);
7763 /* check to see if the printer already exists */
7765 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7766 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7767 printer->info_2->sharename));
7768 free_a_printer(&printer, 2);
7769 return WERR_PRINTER_ALREADY_EXISTS;
7772 /* FIXME!!! smbd should check to see if the driver is installed before
7773 trying to add a printer like this --jerry */
7775 if (*lp_addprinter_cmd() ) {
7776 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7778 free_a_printer(&printer,2);
7779 return WERR_ACCESS_DENIED;
7782 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7783 "smb.conf parameter \"addprinter command\" is defined. This"
7784 "parameter must exist for this call to succeed\n",
7785 printer->info_2->sharename ));
7788 /* use our primary netbios name since get_a_printer() will convert
7789 it to what the client expects on a case by case basis */
7791 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7792 printer->info_2->sharename);
7795 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7796 free_a_printer(&printer,2);
7797 return WERR_ACCESS_DENIED;
7800 /* you must be a printer admin to add a new printer */
7801 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7802 free_a_printer(&printer,2);
7803 return WERR_ACCESS_DENIED;
7807 * Do sanity check on the requested changes for Samba.
7810 if (!check_printer_ok(printer->info_2, snum)) {
7811 free_a_printer(&printer,2);
7812 return WERR_INVALID_PARAM;
7816 * When a printer is created, the drivername bound to the printer is used
7817 * to lookup previously saved driver initialization info, which is then
7818 * bound to the new printer, simulating what happens in the Windows arch.
7823 set_driver_init(printer, 2);
7827 /* A valid devmode was included, convert and link it
7829 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7831 if (!convert_devicemode_new(printer->info_2->printername,
7833 &printer->info_2->devmode))
7837 /* write the ASCII on disk */
7838 err = mod_a_printer(printer, 2);
7839 if (!W_ERROR_IS_OK(err)) {
7840 free_a_printer(&printer,2);
7844 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7845 /* Handle open failed - remove addition. */
7846 del_a_printer(printer->info_2->sharename);
7847 free_a_printer(&printer,2);
7848 ZERO_STRUCTP(handle);
7849 return WERR_ACCESS_DENIED;
7852 update_c_setprinter(False);
7853 free_a_printer(&printer,2);
7858 /****************************************************************
7859 _spoolss_AddPrinterEx
7860 ****************************************************************/
7862 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7863 struct spoolss_AddPrinterEx *r)
7865 switch (r->in.info_ctr->level) {
7867 /* we don't handle yet */
7868 /* but I know what to do ... */
7869 return WERR_UNKNOWN_LEVEL;
7871 return spoolss_addprinterex_level_2(p, r->in.server,
7873 r->in.devmode_ctr->devmode,
7874 r->in.secdesc_ctr->sd,
7875 r->in.userlevel_ctr,
7878 return WERR_UNKNOWN_LEVEL;
7882 /****************************************************************
7883 _spoolss_AddPrinterDriver
7884 ****************************************************************/
7886 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7887 struct spoolss_AddPrinterDriver *r)
7889 uint32_t level = r->in.info_ctr->level;
7890 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7891 WERROR err = WERR_OK;
7892 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7893 fstring driver_name;
7897 switch (p->hdr_req.opnum) {
7898 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7899 fn = "_spoolss_AddPrinterDriver";
7901 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7902 fn = "_spoolss_AddPrinterDriverEx";
7905 return WERR_INVALID_PARAM;
7910 if (level != 3 && level != 6) {
7911 /* Clever hack from Martin Zielinski <mz@seh.de>
7912 * to allow downgrade from level 8 (Vista).
7914 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7915 return WERR_UNKNOWN_LEVEL;
7918 ZERO_STRUCT(driver);
7920 if (!convert_printer_driver_info(info, &driver, level)) {
7925 DEBUG(5,("Cleaning driver's information\n"));
7926 err = clean_up_driver_struct(p, driver, level);
7927 if (!W_ERROR_IS_OK(err))
7930 DEBUG(5,("Moving driver to final destination\n"));
7931 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7936 if (add_a_printer_driver(driver, level)!=0) {
7937 err = WERR_ACCESS_DENIED;
7943 fstrcpy(driver_name,
7944 driver.info_3->name ? driver.info_3->name : "");
7947 fstrcpy(driver_name,
7948 driver.info_6->name ? driver.info_6->name : "");
7953 * I think this is where he DrvUpgradePrinter() hook would be
7954 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7955 * server. Right now, we just need to send ourselves a message
7956 * to update each printer bound to this driver. --jerry
7959 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7960 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7965 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7966 * decide if the driver init data should be deleted. The rules are:
7967 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7968 * 2) delete init data only if there is no 2k/Xp driver
7969 * 3) always delete init data
7970 * The generalized rule is always use init data from the highest order driver.
7971 * It is necessary to follow the driver install by an initialization step to
7972 * finish off this process.
7975 version = driver.info_3->cversion;
7976 else if (level == 6)
7977 version = driver.info_6->version;
7982 * 9x printer driver - never delete init data
7985 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7990 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7991 * there is no 2k/Xp driver init data for this driver name.
7995 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7997 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7999 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
8001 if (!del_driver_init(driver_name))
8002 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
8006 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
8008 free_a_printer_driver(driver1,3);
8009 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
8016 * 2k or Xp printer driver - always delete init data
8019 if (!del_driver_init(driver_name))
8020 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
8025 DEBUG(0,("%s: invalid level=%d\n", fn, level));
8031 free_a_printer_driver(driver, level);
8035 /****************************************************************
8036 _spoolss_AddPrinterDriverEx
8037 ****************************************************************/
8039 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8040 struct spoolss_AddPrinterDriverEx *r)
8042 struct spoolss_AddPrinterDriver a;
8045 * we only support the semantics of AddPrinterDriver()
8046 * i.e. only copy files that are newer than existing ones
8049 if (r->in.flags != APD_COPY_NEW_FILES) {
8050 return WERR_ACCESS_DENIED;
8053 a.in.servername = r->in.servername;
8054 a.in.info_ctr = r->in.info_ctr;
8056 return _spoolss_AddPrinterDriver(p, &a);
8059 /****************************************************************************
8060 ****************************************************************************/
8062 struct _spoolss_paths {
8068 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
8070 static const struct _spoolss_paths spoolss_paths[]= {
8071 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
8072 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
8075 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
8076 const char *servername,
8077 const char *environment,
8081 const char *pservername = NULL;
8082 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8083 const char *short_archi;
8087 /* environment may be empty */
8088 if (environment && strlen(environment)) {
8089 long_archi = environment;
8092 /* servername may be empty */
8093 if (servername && strlen(servername)) {
8094 pservername = canon_servername(servername);
8096 if (!is_myname_or_ipaddr(pservername)) {
8097 return WERR_INVALID_PARAM;
8101 if (!(short_archi = get_short_archi(long_archi))) {
8102 return WERR_INVALID_ENVIRONMENT;
8105 switch (component) {
8106 case SPOOLSS_PRTPROCS_PATH:
8107 case SPOOLSS_DRIVER_PATH:
8109 *path = talloc_asprintf(mem_ctx,
8112 spoolss_paths[component].share,
8115 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
8116 SPOOLSS_DEFAULT_SERVER_PATH,
8117 spoolss_paths[component].dir,
8122 return WERR_INVALID_PARAM;
8132 /****************************************************************************
8133 ****************************************************************************/
8135 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8136 const char *servername,
8137 const char *environment,
8138 struct spoolss_DriverDirectoryInfo1 *r,
8145 werr = compose_spoolss_server_path(mem_ctx,
8148 SPOOLSS_DRIVER_PATH,
8150 if (!W_ERROR_IS_OK(werr)) {
8154 DEBUG(4,("printer driver directory: [%s]\n", path));
8156 r->directory_name = path;
8158 *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
8160 if (*needed > offered) {
8162 return WERR_INSUFFICIENT_BUFFER;
8168 /****************************************************************
8169 _spoolss_GetPrinterDriverDirectory
8170 ****************************************************************/
8172 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8173 struct spoolss_GetPrinterDriverDirectory *r)
8177 /* that's an [in out] buffer */
8179 if (!r->in.buffer && (r->in.offered != 0)) {
8180 return WERR_INVALID_PARAM;
8183 if (r->in.offered > MAX_RPC_DATA_SIZE) {
8184 return WERR_INVALID_PARAM;
8187 DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
8191 switch (r->in.level) {
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);
8204 return WERR_UNKNOWN_LEVEL;
8210 /****************************************************************************
8211 ****************************************************************************/
8213 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8215 POLICY_HND *handle = &q_u->handle;
8216 uint32 idx = q_u->index;
8217 uint32 in_value_len = q_u->valuesize;
8218 uint32 in_data_len = q_u->datasize;
8219 uint32 *out_max_value_len = &r_u->valuesize;
8220 uint16 **out_value = &r_u->value;
8221 uint32 *out_value_len = &r_u->realvaluesize;
8222 uint32 *out_type = &r_u->type;
8223 uint32 *out_max_data_len = &r_u->datasize;
8224 uint8 **data_out = &r_u->data;
8225 uint32 *out_data_len = &r_u->realdatasize;
8227 NT_PRINTER_INFO_LEVEL *printer = NULL;
8229 uint32 biggest_valuesize;
8230 uint32 biggest_datasize;
8232 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8235 REGISTRY_VALUE *val = NULL;
8236 NT_PRINTER_DATA *p_data;
8237 int i, key_index, num_values;
8242 *out_max_data_len = 0;
8246 DEBUG(5,("spoolss_enumprinterdata\n"));
8249 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8253 if (!get_printer_snum(p,handle, &snum, NULL))
8256 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8257 if (!W_ERROR_IS_OK(result))
8260 p_data = printer->info_2->data;
8261 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8266 * The NT machine wants to know the biggest size of value and data
8268 * cf: MSDN EnumPrinterData remark section
8271 if ( !in_value_len && !in_data_len && (key_index != -1) )
8273 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8275 biggest_valuesize = 0;
8276 biggest_datasize = 0;
8278 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8280 for ( i=0; i<num_values; i++ )
8282 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8284 name_length = strlen(val->valuename);
8285 if ( strlen(val->valuename) > biggest_valuesize )
8286 biggest_valuesize = name_length;
8288 if ( val->size > biggest_datasize )
8289 biggest_datasize = val->size;
8291 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8295 /* the value is an UNICODE string but real_value_size is the length
8296 in bytes including the trailing 0 */
8298 *out_value_len = 2 * (1+biggest_valuesize);
8299 *out_data_len = biggest_datasize;
8301 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8307 * the value len is wrong in NT sp3
8308 * that's the number of bytes not the number of unicode chars
8311 if ( key_index != -1 )
8312 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8317 /* out_value should default to "" or else NT4 has
8318 problems unmarshalling the response */
8320 *out_max_value_len=(in_value_len/sizeof(uint16));
8323 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8325 result = WERR_NOMEM;
8328 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8334 /* the data is counted in bytes */
8336 *out_max_data_len = in_data_len;
8337 *out_data_len = in_data_len;
8339 /* only allocate when given a non-zero data_len */
8341 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8343 result = WERR_NOMEM;
8347 result = WERR_NO_MORE_ITEMS;
8353 * - counted in bytes in the request
8354 * - counted in UNICODE chars in the max reply
8355 * - counted in bytes in the real size
8357 * take a pause *before* coding not *during* coding
8361 *out_max_value_len=(in_value_len/sizeof(uint16));
8363 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8365 result = WERR_NOMEM;
8369 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8377 *out_type = regval_type( val );
8379 /* data - counted in bytes */
8381 *out_max_data_len = in_data_len;
8382 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8384 result = WERR_NOMEM;
8387 data_len = regval_size(val);
8388 if ( *data_out && data_len )
8389 memcpy( *data_out, regval_data_p(val), data_len );
8390 *out_data_len = data_len;
8394 free_a_printer(&printer, 2);
8398 /****************************************************************************
8399 ****************************************************************************/
8401 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8403 POLICY_HND *handle = &q_u->handle;
8404 UNISTR2 *value = &q_u->value;
8405 uint32 type = q_u->type;
8406 uint8 *data = q_u->data;
8407 uint32 real_len = q_u->real_len;
8409 NT_PRINTER_INFO_LEVEL *printer = NULL;
8411 WERROR status = WERR_OK;
8412 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8415 DEBUG(5,("spoolss_setprinterdata\n"));
8418 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8422 if ( Printer->printer_type == SPLHND_SERVER ) {
8423 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8424 return WERR_INVALID_PARAM;
8427 if (!get_printer_snum(p,handle, &snum, NULL))
8431 * Access check : NT returns "access denied" if you make a
8432 * SetPrinterData call without the necessary privildge.
8433 * we were originally returning OK if nothing changed
8434 * which made Win2k issue **a lot** of SetPrinterData
8435 * when connecting to a printer --jerry
8438 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8440 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8441 status = WERR_ACCESS_DENIED;
8445 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8446 if (!W_ERROR_IS_OK(status))
8449 unistr2_to_ascii(valuename, value, sizeof(valuename));
8452 * When client side code sets a magic printer data key, detect it and save
8453 * the current printer data and the magic key's data (its the DEVMODE) for
8454 * future printer/driver initializations.
8456 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8458 /* Set devmode and printer initialization info */
8459 status = save_driver_init( printer, 2, data, real_len );
8461 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8465 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8466 type, data, real_len );
8467 if ( W_ERROR_IS_OK(status) )
8468 status = mod_a_printer(printer, 2);
8472 free_a_printer(&printer, 2);
8477 /****************************************************************
8478 _spoolss_ResetPrinter
8479 ****************************************************************/
8481 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8482 struct spoolss_ResetPrinter *r)
8484 POLICY_HND *handle = r->in.handle;
8485 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8488 DEBUG(5,("_spoolss_ResetPrinter\n"));
8491 * All we do is to check to see if the handle and queue is valid.
8492 * This call really doesn't mean anything to us because we only
8493 * support RAW printing. --jerry
8497 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8498 OUR_HANDLE(handle)));
8502 if (!get_printer_snum(p,handle, &snum, NULL))
8506 /* blindly return success */
8510 /****************************************************************
8511 _spoolss_DeletePrinterData
8512 ****************************************************************/
8514 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8515 struct spoolss_DeletePrinterData *r)
8517 POLICY_HND *handle = r->in.handle;
8518 NT_PRINTER_INFO_LEVEL *printer = NULL;
8520 WERROR status = WERR_OK;
8521 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8523 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8526 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8527 OUR_HANDLE(handle)));
8531 if (!get_printer_snum(p, handle, &snum, NULL))
8534 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8535 DEBUG(3, ("_spoolss_DeletePrinterData: "
8536 "printer properties change denied by handle\n"));
8537 return WERR_ACCESS_DENIED;
8540 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8541 if (!W_ERROR_IS_OK(status))
8544 if (!r->in.value_name) {
8545 free_a_printer(&printer, 2);
8549 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8552 if ( W_ERROR_IS_OK(status) )
8553 mod_a_printer( printer, 2 );
8555 free_a_printer(&printer, 2);
8560 /****************************************************************
8562 ****************************************************************/
8564 WERROR _spoolss_AddForm(pipes_struct *p,
8565 struct spoolss_AddForm *r)
8567 POLICY_HND *handle = r->in.handle;
8568 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8569 nt_forms_struct tmpForm;
8571 WERROR status = WERR_OK;
8572 NT_PRINTER_INFO_LEVEL *printer = NULL;
8575 nt_forms_struct *list=NULL;
8576 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8578 DEBUG(5,("_spoolss_AddForm\n"));
8581 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8582 OUR_HANDLE(handle)));
8587 /* forms can be added on printer of on the print server handle */
8589 if ( Printer->printer_type == SPLHND_PRINTER )
8591 if (!get_printer_snum(p,handle, &snum, NULL))
8594 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8595 if (!W_ERROR_IS_OK(status))
8599 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8600 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8601 status = WERR_ACCESS_DENIED;
8605 /* can't add if builtin */
8607 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8608 status = WERR_FILE_EXISTS;
8612 count = get_ntforms(&list);
8614 if(!add_a_form(&list, form, &count)) {
8615 status = WERR_NOMEM;
8619 write_ntforms(&list, count);
8622 * ChangeID must always be set if this is a printer
8625 if ( Printer->printer_type == SPLHND_PRINTER )
8626 status = mod_a_printer(printer, 2);
8630 free_a_printer(&printer, 2);
8636 /****************************************************************
8638 ****************************************************************/
8640 WERROR _spoolss_DeleteForm(pipes_struct *p,
8641 struct spoolss_DeleteForm *r)
8643 POLICY_HND *handle = r->in.handle;
8644 const char *form_name = r->in.form_name;
8645 nt_forms_struct tmpForm;
8647 nt_forms_struct *list=NULL;
8648 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8650 WERROR status = WERR_OK;
8651 NT_PRINTER_INFO_LEVEL *printer = NULL;
8653 DEBUG(5,("_spoolss_DeleteForm\n"));
8656 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8657 OUR_HANDLE(handle)));
8661 /* forms can be deleted on printer of on the print server handle */
8663 if ( Printer->printer_type == SPLHND_PRINTER )
8665 if (!get_printer_snum(p,handle, &snum, NULL))
8668 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8669 if (!W_ERROR_IS_OK(status))
8673 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8674 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8675 status = WERR_ACCESS_DENIED;
8679 /* can't delete if builtin */
8681 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8682 status = WERR_INVALID_PARAM;
8686 count = get_ntforms(&list);
8688 if ( !delete_a_form(&list, form_name, &count, &status ))
8692 * ChangeID must always be set if this is a printer
8695 if ( Printer->printer_type == SPLHND_PRINTER )
8696 status = mod_a_printer(printer, 2);
8700 free_a_printer(&printer, 2);
8706 /****************************************************************
8708 ****************************************************************/
8710 WERROR _spoolss_SetForm(pipes_struct *p,
8711 struct spoolss_SetForm *r)
8713 POLICY_HND *handle = r->in.handle;
8714 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8715 nt_forms_struct tmpForm;
8717 WERROR status = WERR_OK;
8718 NT_PRINTER_INFO_LEVEL *printer = NULL;
8721 nt_forms_struct *list=NULL;
8722 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8724 DEBUG(5,("_spoolss_SetForm\n"));
8727 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8728 OUR_HANDLE(handle)));
8732 /* forms can be modified on printer of on the print server handle */
8734 if ( Printer->printer_type == SPLHND_PRINTER )
8736 if (!get_printer_snum(p,handle, &snum, NULL))
8739 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8740 if (!W_ERROR_IS_OK(status))
8744 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8745 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8746 status = WERR_ACCESS_DENIED;
8750 /* can't set if builtin */
8751 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8752 status = WERR_INVALID_PARAM;
8756 count = get_ntforms(&list);
8757 update_a_form(&list, form, count);
8758 write_ntforms(&list, count);
8761 * ChangeID must always be set if this is a printer
8764 if ( Printer->printer_type == SPLHND_PRINTER )
8765 status = mod_a_printer(printer, 2);
8770 free_a_printer(&printer, 2);
8776 /****************************************************************************
8777 enumprintprocessors level 1.
8778 ****************************************************************************/
8780 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8782 PRINTPROCESSOR_1 *info_1=NULL;
8783 WERROR result = WERR_OK;
8785 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8790 init_unistr(&info_1->name, "winprint");
8792 *needed += spoolss_size_printprocessor_info_1(info_1);
8794 if (*needed > offered) {
8795 result = WERR_INSUFFICIENT_BUFFER;
8799 if (!rpcbuf_alloc_size(buffer, *needed)) {
8800 result = WERR_NOMEM;
8804 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8809 if ( !W_ERROR_IS_OK(result) )
8815 /****************************************************************************
8816 ****************************************************************************/
8818 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8820 uint32 level = q_u->level;
8821 RPC_BUFFER *buffer = NULL;
8822 uint32 offered = q_u->offered;
8823 uint32 *needed = &r_u->needed;
8824 uint32 *returned = &r_u->returned;
8826 /* that's an [in out] buffer */
8828 if (!q_u->buffer && (offered!=0)) {
8829 return WERR_INVALID_PARAM;
8832 if (offered > MAX_RPC_DATA_SIZE) {
8833 return WERR_INVALID_PARAM;
8836 rpcbuf_move(q_u->buffer, &r_u->buffer);
8837 buffer = r_u->buffer;
8839 DEBUG(5,("spoolss_enumprintprocessors\n"));
8842 * Enumerate the print processors ...
8844 * Just reply with "winprint", to keep NT happy
8845 * and I can use my nice printer checker.
8853 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8855 return WERR_UNKNOWN_LEVEL;
8859 /****************************************************************************
8860 enumprintprocdatatypes level 1.
8861 ****************************************************************************/
8863 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8865 PRINTPROCDATATYPE_1 *info_1=NULL;
8866 WERROR result = WERR_OK;
8868 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8873 init_unistr(&info_1->name, "RAW");
8875 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8877 if (*needed > offered) {
8878 result = WERR_INSUFFICIENT_BUFFER;
8882 if (!rpcbuf_alloc_size(buffer, *needed)) {
8883 result = WERR_NOMEM;
8887 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8892 if ( !W_ERROR_IS_OK(result) )
8898 /****************************************************************************
8899 ****************************************************************************/
8901 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8903 uint32 level = q_u->level;
8904 RPC_BUFFER *buffer = NULL;
8905 uint32 offered = q_u->offered;
8906 uint32 *needed = &r_u->needed;
8907 uint32 *returned = &r_u->returned;
8909 /* that's an [in out] buffer */
8911 if (!q_u->buffer && (offered!=0)) {
8912 return WERR_INVALID_PARAM;
8915 if (offered > MAX_RPC_DATA_SIZE) {
8916 return WERR_INVALID_PARAM;
8919 rpcbuf_move(q_u->buffer, &r_u->buffer);
8920 buffer = r_u->buffer;
8922 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8929 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8931 return WERR_UNKNOWN_LEVEL;
8935 /****************************************************************************
8936 enumprintmonitors level 1.
8937 ****************************************************************************/
8939 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8941 PRINTMONITOR_1 *info_1;
8942 WERROR result = WERR_OK;
8945 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8950 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8951 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8953 for ( i=0; i<*returned; i++ ) {
8954 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8957 if (*needed > offered) {
8958 result = WERR_INSUFFICIENT_BUFFER;
8962 if (!rpcbuf_alloc_size(buffer, *needed)) {
8963 result = WERR_NOMEM;
8967 for ( i=0; i<*returned; i++ ) {
8968 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8974 if ( !W_ERROR_IS_OK(result) )
8980 /****************************************************************************
8981 enumprintmonitors level 2.
8982 ****************************************************************************/
8984 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8986 PRINTMONITOR_2 *info_2;
8987 WERROR result = WERR_OK;
8990 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8995 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8996 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8997 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8999 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
9000 init_unistr( &(info_2[1].environment), "Windows NT X86" );
9001 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
9003 for ( i=0; i<*returned; i++ ) {
9004 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
9007 if (*needed > offered) {
9008 result = WERR_INSUFFICIENT_BUFFER;
9012 if (!rpcbuf_alloc_size(buffer, *needed)) {
9013 result = WERR_NOMEM;
9017 for ( i=0; i<*returned; i++ ) {
9018 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
9024 if ( !W_ERROR_IS_OK(result) )
9030 /****************************************************************************
9031 ****************************************************************************/
9033 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
9035 uint32 level = q_u->level;
9036 RPC_BUFFER *buffer = NULL;
9037 uint32 offered = q_u->offered;
9038 uint32 *needed = &r_u->needed;
9039 uint32 *returned = &r_u->returned;
9041 /* that's an [in out] buffer */
9043 if (!q_u->buffer && (offered!=0)) {
9044 return WERR_INVALID_PARAM;
9047 if (offered > MAX_RPC_DATA_SIZE) {
9048 return WERR_INVALID_PARAM;
9051 rpcbuf_move(q_u->buffer, &r_u->buffer);
9052 buffer = r_u->buffer;
9054 DEBUG(5,("spoolss_enumprintmonitors\n"));
9057 * Enumerate the print monitors ...
9059 * Just reply with "Local Port", to keep NT happy
9060 * and I can use my nice printer checker.
9068 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9070 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9072 return WERR_UNKNOWN_LEVEL;
9076 /****************************************************************************
9077 ****************************************************************************/
9079 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9080 NT_PRINTER_INFO_LEVEL *ntprinter,
9081 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9086 JOB_INFO_1 *info_1=NULL;
9087 WERROR result = WERR_OK;
9089 info_1=SMB_MALLOC_P(JOB_INFO_1);
9091 if (info_1 == NULL) {
9095 for (i=0; i<count && found==False; i++) {
9096 if ((*queue)[i].job==(int)jobid)
9102 /* NT treats not found as bad param... yet another bad choice */
9103 return WERR_INVALID_PARAM;
9106 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9108 *needed += spoolss_size_job_info_1(info_1);
9110 if (*needed > offered) {
9111 result = WERR_INSUFFICIENT_BUFFER;
9115 if (!rpcbuf_alloc_size(buffer, *needed)) {
9116 result = WERR_NOMEM;
9120 smb_io_job_info_1("", buffer, info_1, 0);
9128 /****************************************************************************
9129 ****************************************************************************/
9131 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9132 NT_PRINTER_INFO_LEVEL *ntprinter,
9133 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9140 DEVICEMODE *devmode = NULL;
9141 NT_DEVICEMODE *nt_devmode = NULL;
9143 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9146 ZERO_STRUCTP(info_2);
9148 for ( i=0; i<count && found==False; i++ )
9150 if ((*queue)[i].job == (int)jobid)
9155 /* NT treats not found as bad param... yet another bad
9157 result = WERR_INVALID_PARAM;
9162 * if the print job does not have a DEVMODE associated with it,
9163 * just use the one for the printer. A NULL devicemode is not
9164 * a failure condition
9167 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9168 devmode = construct_dev_mode(lp_const_servicename(snum));
9170 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9171 ZERO_STRUCTP( devmode );
9172 convert_nt_devicemode( devmode, nt_devmode );
9176 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9178 *needed += spoolss_size_job_info_2(info_2);
9180 if (*needed > offered) {
9181 result = WERR_INSUFFICIENT_BUFFER;
9185 if (!rpcbuf_alloc_size(buffer, *needed)) {
9186 result = WERR_NOMEM;
9190 smb_io_job_info_2("", buffer, info_2, 0);
9195 /* Cleanup allocated memory */
9197 free_job_info_2(info_2); /* Also frees devmode */
9203 /****************************************************************************
9204 ****************************************************************************/
9206 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9208 POLICY_HND *handle = &q_u->handle;
9209 uint32 jobid = q_u->jobid;
9210 uint32 level = q_u->level;
9211 RPC_BUFFER *buffer = NULL;
9212 uint32 offered = q_u->offered;
9213 uint32 *needed = &r_u->needed;
9214 WERROR wstatus = WERR_OK;
9215 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9218 print_queue_struct *queue = NULL;
9219 print_status_struct prt_status;
9221 /* that's an [in out] buffer */
9223 if (!q_u->buffer && (offered!=0)) {
9224 return WERR_INVALID_PARAM;
9227 if (offered > MAX_RPC_DATA_SIZE) {
9228 return WERR_INVALID_PARAM;
9231 rpcbuf_move(q_u->buffer, &r_u->buffer);
9232 buffer = r_u->buffer;
9234 DEBUG(5,("spoolss_getjob\n"));
9238 if (!get_printer_snum(p, handle, &snum, NULL))
9241 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9242 if ( !W_ERROR_IS_OK(wstatus) )
9245 count = print_queue_status(snum, &queue, &prt_status);
9247 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9248 count, prt_status.status, prt_status.message));
9252 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9253 buffer, offered, needed);
9256 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9257 buffer, offered, needed);
9260 wstatus = WERR_UNKNOWN_LEVEL;
9265 free_a_printer( &ntprinter, 2 );
9270 /****************************************************************
9271 _spoolss_GetPrinterDataEx
9273 From MSDN documentation of GetPrinterDataEx: pass request
9274 to GetPrinterData if key is "PrinterDriverData".
9275 ****************************************************************/
9277 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9278 struct spoolss_GetPrinterDataEx *r)
9280 POLICY_HND *handle = r->in.handle;
9282 const char *keyname = r->in.key_name;
9283 const char *valuename = r->in.value_name;
9285 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9287 NT_PRINTER_INFO_LEVEL *printer = NULL;
9289 WERROR status = WERR_OK;
9291 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9293 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9294 keyname, valuename));
9296 /* in case of problem, return some default values */
9302 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9303 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9304 status = WERR_BADFID;
9308 /* Is the handle to a printer or to the server? */
9310 if (Printer->printer_type == SPLHND_SERVER) {
9311 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9312 "Not implemented for server handles yet\n"));
9313 status = WERR_INVALID_PARAM;
9317 if ( !get_printer_snum(p,handle, &snum, NULL) )
9320 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9321 if ( !W_ERROR_IS_OK(status) )
9324 /* check to see if the keyname is valid */
9325 if ( !strlen(keyname) ) {
9326 status = WERR_INVALID_PARAM;
9330 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9331 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9332 "Invalid keyname [%s]\n", keyname ));
9333 free_a_printer( &printer, 2 );
9334 status = WERR_BADFILE;
9338 /* When given a new keyname, we should just create it */
9340 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9341 r->out.type, &data, r->out.needed,
9344 if (*r->out.needed > r->in.offered) {
9345 status = WERR_MORE_DATA;
9348 if (W_ERROR_IS_OK(status)) {
9349 memcpy(r->out.buffer, data, r->in.offered);
9354 free_a_printer( &printer, 2 );
9359 /****************************************************************
9360 _spoolss_SetPrinterDataEx
9361 ****************************************************************/
9363 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9364 struct spoolss_SetPrinterDataEx *r)
9366 POLICY_HND *handle = r->in.handle;
9367 NT_PRINTER_INFO_LEVEL *printer = NULL;
9369 WERROR status = WERR_OK;
9370 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9373 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9375 /* From MSDN documentation of SetPrinterDataEx: pass request to
9376 SetPrinterData if key is "PrinterDriverData" */
9379 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9380 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9384 if ( Printer->printer_type == SPLHND_SERVER ) {
9385 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9386 "Not implemented for server handles yet\n"));
9387 return WERR_INVALID_PARAM;
9390 if ( !get_printer_snum(p,handle, &snum, NULL) )
9394 * Access check : NT returns "access denied" if you make a
9395 * SetPrinterData call without the necessary privildge.
9396 * we were originally returning OK if nothing changed
9397 * which made Win2k issue **a lot** of SetPrinterData
9398 * when connecting to a printer --jerry
9401 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9403 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9404 "change denied by handle access permissions\n"));
9405 return WERR_ACCESS_DENIED;
9408 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9409 if (!W_ERROR_IS_OK(status))
9412 /* check for OID in valuename */
9414 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9420 /* save the registry data */
9422 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9423 r->in.type, r->in.buffer, r->in.offered );
9425 if ( W_ERROR_IS_OK(status) )
9427 /* save the OID if one was specified */
9429 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9430 r->in.key_name, SPOOL_OID_KEY);
9436 * I'm not checking the status here on purpose. Don't know
9437 * if this is right, but I'm returning the status from the
9438 * previous set_printer_dataex() call. I have no idea if
9439 * this is right. --jerry
9442 set_printer_dataex( printer, str, r->in.value_name,
9443 REG_SZ, (uint8 *)oid_string,
9444 strlen(oid_string)+1 );
9447 status = mod_a_printer(printer, 2);
9450 free_a_printer(&printer, 2);
9455 /****************************************************************
9456 _spoolss_DeletePrinterDataEx
9457 ****************************************************************/
9459 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9460 struct spoolss_DeletePrinterDataEx *r)
9462 POLICY_HND *handle = r->in.handle;
9463 NT_PRINTER_INFO_LEVEL *printer = NULL;
9465 WERROR status = WERR_OK;
9466 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9468 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9471 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9472 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9476 if (!get_printer_snum(p, handle, &snum, NULL))
9479 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9480 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9481 "printer properties change denied by handle\n"));
9482 return WERR_ACCESS_DENIED;
9485 if (!r->in.value_name || !r->in.key_name) {
9489 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9490 if (!W_ERROR_IS_OK(status))
9493 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9495 if ( W_ERROR_IS_OK(status) )
9496 mod_a_printer( printer, 2 );
9498 free_a_printer(&printer, 2);
9503 /********************************************************************
9504 * spoolss_enumprinterkey
9505 ********************************************************************/
9508 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9511 fstring *keynames = NULL;
9512 uint16 *enumkeys = NULL;
9515 POLICY_HND *handle = &q_u->handle;
9516 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9517 NT_PRINTER_DATA *data;
9518 NT_PRINTER_INFO_LEVEL *printer = NULL;
9520 WERROR status = WERR_BADFILE;
9523 DEBUG(4,("_spoolss_enumprinterkey\n"));
9526 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9530 if ( !get_printer_snum(p,handle, &snum, NULL) )
9533 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9534 if (!W_ERROR_IS_OK(status))
9537 /* get the list of subkey names */
9539 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9540 data = printer->info_2->data;
9542 num_keys = get_printer_subkeys( data, key, &keynames );
9544 if ( num_keys == -1 ) {
9545 status = WERR_BADFILE;
9549 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9551 r_u->needed = printerkey_len*2;
9553 if ( q_u->size < r_u->needed ) {
9554 status = WERR_MORE_DATA;
9558 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9559 status = WERR_NOMEM;
9565 if ( q_u->size < r_u->needed )
9566 status = WERR_MORE_DATA;
9569 free_a_printer( &printer, 2 );
9570 SAFE_FREE( keynames );
9575 /****************************************************************
9576 _spoolss_DeletePrinterKey
9577 ****************************************************************/
9579 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9580 struct spoolss_DeletePrinterKey *r)
9582 POLICY_HND *handle = r->in.handle;
9583 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9584 NT_PRINTER_INFO_LEVEL *printer = NULL;
9588 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9591 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9592 OUR_HANDLE(handle)));
9596 /* if keyname == NULL, return error */
9598 if ( !r->in.key_name )
9599 return WERR_INVALID_PARAM;
9601 if (!get_printer_snum(p, handle, &snum, NULL))
9604 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9605 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9606 "printer properties change denied by handle\n"));
9607 return WERR_ACCESS_DENIED;
9610 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9611 if (!W_ERROR_IS_OK(status))
9614 /* delete the key and all subneys */
9616 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9618 if ( W_ERROR_IS_OK(status) )
9619 status = mod_a_printer(printer, 2);
9621 free_a_printer( &printer, 2 );
9627 /********************************************************************
9628 * spoolss_enumprinterdataex
9629 ********************************************************************/
9631 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9633 POLICY_HND *handle = &q_u->handle;
9634 uint32 in_size = q_u->size;
9637 NT_PRINTER_INFO_LEVEL *printer = NULL;
9638 PRINTER_ENUM_VALUES *enum_values = NULL;
9639 NT_PRINTER_DATA *p_data;
9641 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9646 REGISTRY_VALUE *val;
9651 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9654 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9659 * first check for a keyname of NULL or "". Win2k seems to send
9660 * this a lot and we should send back WERR_INVALID_PARAM
9661 * no need to spend time looking up the printer in this case.
9665 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9666 if ( !strlen(key) ) {
9667 result = WERR_INVALID_PARAM;
9671 /* get the printer off of disk */
9673 if (!get_printer_snum(p,handle, &snum, NULL))
9676 ZERO_STRUCT(printer);
9677 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9678 if (!W_ERROR_IS_OK(result))
9681 /* now look for a match on the key name */
9683 p_data = printer->info_2->data;
9685 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9686 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9688 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9689 result = WERR_INVALID_PARAM;
9696 /* allocate the memory for the array of pointers -- if necessary */
9698 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9701 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9703 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9704 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9705 result = WERR_NOMEM;
9709 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9713 * loop through all params and build the array to pass
9714 * back to the client
9717 for ( i=0; i<num_entries; i++ )
9719 /* lookup the registry value */
9721 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9722 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9726 value_name = regval_name( val );
9727 init_unistr( &enum_values[i].valuename, value_name );
9728 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9729 enum_values[i].type = regval_type( val );
9731 data_len = regval_size( val );
9733 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9735 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9737 result = WERR_NOMEM;
9741 enum_values[i].data_len = data_len;
9743 /* keep track of the size of the array in bytes */
9745 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9748 /* housekeeping information in the reply */
9750 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9751 * the hand marshalled container size is a multiple
9752 * of 4 bytes for RPC alignment.
9756 needed += 4-(needed % 4);
9759 r_u->needed = needed;
9760 r_u->returned = num_entries;
9762 if (needed > in_size) {
9763 result = WERR_MORE_DATA;
9767 /* copy data into the reply */
9769 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9770 response buffer size is != the offered buffer size
9772 r_u->ctr.size = r_u->needed;
9774 r_u->ctr.size = in_size;
9776 r_u->ctr.size_of_array = r_u->returned;
9777 r_u->ctr.values = enum_values;
9781 free_a_printer(&printer, 2);
9786 /****************************************************************************
9787 ****************************************************************************/
9789 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9790 const char *servername,
9791 const char *environment,
9792 struct spoolss_PrintProcessorDirectoryInfo1 *r,
9799 werr = compose_spoolss_server_path(mem_ctx,
9802 SPOOLSS_PRTPROCS_PATH,
9804 if (!W_ERROR_IS_OK(werr)) {
9808 DEBUG(4,("print processor directory: [%s]\n", path));
9810 r->directory_name = path;
9812 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
9814 if (*needed > offered) {
9816 return WERR_INSUFFICIENT_BUFFER;
9822 /****************************************************************
9823 _spoolss_GetPrintProcessorDirectory
9824 ****************************************************************/
9826 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9827 struct spoolss_GetPrintProcessorDirectory *r)
9831 /* that's an [in out] buffer */
9833 if (!r->in.buffer && (r->in.offered != 0)) {
9834 return WERR_INVALID_PARAM;
9837 if (r->in.offered > MAX_RPC_DATA_SIZE) {
9838 return WERR_INVALID_PARAM;
9841 DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
9845 switch (r->in.level) {
9847 result = getprintprocessordirectory_level_1(p->mem_ctx,
9850 &r->out.info->info1,
9853 if (!W_ERROR_IS_OK(result)) {
9854 TALLOC_FREE(r->out.info);
9858 result = WERR_UNKNOWN_LEVEL;
9864 /*******************************************************************
9865 ********************************************************************/
9867 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9868 const char *dllname)
9870 enum ndr_err_code ndr_err;
9871 struct spoolss_MonitorUi ui;
9873 ui.dll_name = dllname;
9875 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9876 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9877 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9878 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9880 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9883 /*******************************************************************
9884 Streams the monitor UI DLL name in UNICODE
9885 *******************************************************************/
9887 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9888 NT_USER_TOKEN *token, DATA_BLOB *in,
9889 DATA_BLOB *out, uint32_t *needed)
9891 const char *dllname = "tcpmonui.dll";
9893 *needed = (strlen(dllname)+1) * 2;
9895 if (out->length < *needed) {
9896 return WERR_INSUFFICIENT_BUFFER;
9899 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9906 /*******************************************************************
9907 ********************************************************************/
9909 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9910 struct spoolss_PortData1 *port1,
9911 const DATA_BLOB *buf)
9913 enum ndr_err_code ndr_err;
9914 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9915 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9916 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9917 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9919 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9922 /*******************************************************************
9923 ********************************************************************/
9925 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9926 struct spoolss_PortData2 *port2,
9927 const DATA_BLOB *buf)
9929 enum ndr_err_code ndr_err;
9930 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9931 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9932 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9933 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9935 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9938 /*******************************************************************
9939 Create a new TCP/IP port
9940 *******************************************************************/
9942 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9943 NT_USER_TOKEN *token, DATA_BLOB *in,
9944 DATA_BLOB *out, uint32_t *needed)
9946 struct spoolss_PortData1 port1;
9947 struct spoolss_PortData2 port2;
9948 char *device_uri = NULL;
9951 const char *portname;
9952 const char *hostaddress;
9954 uint32_t port_number;
9957 /* peek for spoolss_PortData version */
9959 if (!in || (in->length < (128 + 4))) {
9960 return WERR_GENERAL_FAILURE;
9963 version = IVAL(in->data, 128);
9969 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9973 portname = port1.portname;
9974 hostaddress = port1.hostaddress;
9975 queue = port1.queue;
9976 protocol = port1.protocol;
9977 port_number = port1.port_number;
9983 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9987 portname = port2.portname;
9988 hostaddress = port2.hostaddress;
9989 queue = port2.queue;
9990 protocol = port2.protocol;
9991 port_number = port2.port_number;
9995 DEBUG(1,("xcvtcp_addport: "
9996 "unknown version of port_data: %d\n", version));
9997 return WERR_UNKNOWN_PORT;
10000 /* create the device URI and call the add_port_hook() */
10002 switch (protocol) {
10003 case PROTOCOL_RAWTCP_TYPE:
10004 device_uri = talloc_asprintf(mem_ctx,
10005 "socket://%s:%d/", hostaddress,
10009 case PROTOCOL_LPR_TYPE:
10010 device_uri = talloc_asprintf(mem_ctx,
10011 "lpr://%s/%s", hostaddress, queue );
10015 return WERR_UNKNOWN_PORT;
10022 return add_port_hook(mem_ctx, token, portname, device_uri);
10025 /*******************************************************************
10026 *******************************************************************/
10028 struct xcv_api_table xcvtcp_cmds[] = {
10029 { "MonitorUI", xcvtcp_monitorui },
10030 { "AddPort", xcvtcp_addport},
10034 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
10035 NT_USER_TOKEN *token, const char *command,
10042 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
10044 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
10045 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
10046 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10049 return WERR_BADFUNC;
10052 /*******************************************************************
10053 *******************************************************************/
10054 #if 0 /* don't support management using the "Local Port" monitor */
10056 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10057 NT_USER_TOKEN *token, DATA_BLOB *in,
10058 DATA_BLOB *out, uint32_t *needed)
10060 const char *dllname = "localui.dll";
10062 *needed = (strlen(dllname)+1) * 2;
10064 if (out->length < *needed) {
10065 return WERR_INSUFFICIENT_BUFFER;
10068 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10075 /*******************************************************************
10076 *******************************************************************/
10078 struct xcv_api_table xcvlocal_cmds[] = {
10079 { "MonitorUI", xcvlocal_monitorui },
10083 struct xcv_api_table xcvlocal_cmds[] = {
10090 /*******************************************************************
10091 *******************************************************************/
10093 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10094 NT_USER_TOKEN *token, const char *command,
10095 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10100 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10102 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10103 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10104 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10106 return WERR_BADFUNC;
10109 /****************************************************************
10111 ****************************************************************/
10113 WERROR _spoolss_XcvData(pipes_struct *p,
10114 struct spoolss_XcvData *r)
10116 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10117 DATA_BLOB out_data;
10121 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10122 OUR_HANDLE(r->in.handle)));
10123 return WERR_BADFID;
10126 /* Has to be a handle to the TCP/IP port monitor */
10128 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10129 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10130 return WERR_BADFID;
10133 /* requires administrative access to the server */
10135 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10136 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10137 return WERR_ACCESS_DENIED;
10140 /* Allocate the outgoing buffer */
10142 if (r->in.out_data_size) {
10143 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10144 if (out_data.data == NULL) {
10149 switch ( Printer->printer_type ) {
10150 case SPLHND_PORTMON_TCP:
10151 werror = process_xcvtcp_command(p->mem_ctx,
10152 p->server_info->ptok,
10153 r->in.function_name,
10154 &r->in.in_data, &out_data,
10157 case SPLHND_PORTMON_LOCAL:
10158 werror = process_xcvlocal_command(p->mem_ctx,
10159 p->server_info->ptok,
10160 r->in.function_name,
10161 &r->in.in_data, &out_data,
10165 werror = WERR_INVALID_PRINT_MONITOR;
10168 if (!W_ERROR_IS_OK(werror)) {
10172 *r->out.status_code = 0;
10174 memcpy(r->out.out_data, out_data.data, out_data.length);
10179 /****************************************************************
10180 _spoolss_AddPrintProcessor
10181 ****************************************************************/
10183 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10184 struct spoolss_AddPrintProcessor *r)
10186 /* for now, just indicate success and ignore the add. We'll
10187 automatically set the winprint processor for printer
10188 entries later. Used to debug the LexMark Optra S 1855 PCL
10194 /****************************************************************
10195 _spoolss_EnumPrinters
10196 ****************************************************************/
10198 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10199 struct spoolss_EnumPrinters *r)
10201 p->rng_fault_state = true;
10202 return WERR_NOT_SUPPORTED;
10205 /****************************************************************
10207 ****************************************************************/
10209 WERROR _spoolss_GetJob(pipes_struct *p,
10210 struct spoolss_GetJob *r)
10212 p->rng_fault_state = true;
10213 return WERR_NOT_SUPPORTED;
10216 /****************************************************************
10218 ****************************************************************/
10220 WERROR _spoolss_EnumJobs(pipes_struct *p,
10221 struct spoolss_EnumJobs *r)
10223 p->rng_fault_state = true;
10224 return WERR_NOT_SUPPORTED;
10227 /****************************************************************
10228 _spoolss_AddPrinter
10229 ****************************************************************/
10231 WERROR _spoolss_AddPrinter(pipes_struct *p,
10232 struct spoolss_AddPrinter *r)
10234 p->rng_fault_state = true;
10235 return WERR_NOT_SUPPORTED;
10238 /****************************************************************
10239 _spoolss_GetPrinter
10240 ****************************************************************/
10242 WERROR _spoolss_GetPrinter(pipes_struct *p,
10243 struct spoolss_GetPrinter *r)
10245 p->rng_fault_state = true;
10246 return WERR_NOT_SUPPORTED;
10249 /****************************************************************
10250 _spoolss_EnumPrinterDrivers
10251 ****************************************************************/
10253 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10254 struct spoolss_EnumPrinterDrivers *r)
10256 p->rng_fault_state = true;
10257 return WERR_NOT_SUPPORTED;
10260 /****************************************************************
10261 _spoolss_GetPrinterDriver
10262 ****************************************************************/
10264 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10265 struct spoolss_GetPrinterDriver *r)
10267 p->rng_fault_state = true;
10268 return WERR_NOT_SUPPORTED;
10271 /****************************************************************
10272 _spoolss_EnumPrintProcessors
10273 ****************************************************************/
10275 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10276 struct spoolss_EnumPrintProcessors *r)
10278 p->rng_fault_state = true;
10279 return WERR_NOT_SUPPORTED;
10282 /****************************************************************
10283 _spoolss_ReadPrinter
10284 ****************************************************************/
10286 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10287 struct spoolss_ReadPrinter *r)
10289 p->rng_fault_state = true;
10290 return WERR_NOT_SUPPORTED;
10293 /****************************************************************
10294 _spoolss_GetPrinterData
10295 ****************************************************************/
10297 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10298 struct spoolss_GetPrinterData *r)
10300 p->rng_fault_state = true;
10301 return WERR_NOT_SUPPORTED;
10304 /****************************************************************
10305 _spoolss_SetPrinterData
10306 ****************************************************************/
10308 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10309 struct spoolss_SetPrinterData *r)
10311 p->rng_fault_state = true;
10312 return WERR_NOT_SUPPORTED;
10315 /****************************************************************
10316 _spoolss_WaitForPrinterChange
10317 ****************************************************************/
10319 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10320 struct spoolss_WaitForPrinterChange *r)
10322 p->rng_fault_state = true;
10323 return WERR_NOT_SUPPORTED;
10326 /****************************************************************
10328 ****************************************************************/
10330 WERROR _spoolss_EnumForms(pipes_struct *p,
10331 struct spoolss_EnumForms *r)
10333 p->rng_fault_state = true;
10334 return WERR_NOT_SUPPORTED;
10337 /****************************************************************
10339 ****************************************************************/
10341 WERROR _spoolss_EnumPorts(pipes_struct *p,
10342 struct spoolss_EnumPorts *r)
10344 p->rng_fault_state = true;
10345 return WERR_NOT_SUPPORTED;
10348 /****************************************************************
10349 _spoolss_EnumMonitors
10350 ****************************************************************/
10352 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10353 struct spoolss_EnumMonitors *r)
10355 p->rng_fault_state = true;
10356 return WERR_NOT_SUPPORTED;
10359 /****************************************************************
10361 ****************************************************************/
10363 WERROR _spoolss_AddPort(pipes_struct *p,
10364 struct spoolss_AddPort *r)
10366 p->rng_fault_state = true;
10367 return WERR_NOT_SUPPORTED;
10370 /****************************************************************
10371 _spoolss_ConfigurePort
10372 ****************************************************************/
10374 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10375 struct spoolss_ConfigurePort *r)
10377 p->rng_fault_state = true;
10378 return WERR_NOT_SUPPORTED;
10381 /****************************************************************
10382 _spoolss_DeletePort
10383 ****************************************************************/
10385 WERROR _spoolss_DeletePort(pipes_struct *p,
10386 struct spoolss_DeletePort *r)
10388 p->rng_fault_state = true;
10389 return WERR_NOT_SUPPORTED;
10392 /****************************************************************
10393 _spoolss_CreatePrinterIC
10394 ****************************************************************/
10396 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10397 struct spoolss_CreatePrinterIC *r)
10399 p->rng_fault_state = true;
10400 return WERR_NOT_SUPPORTED;
10403 /****************************************************************
10404 _spoolss_PlayGDIScriptOnPrinterIC
10405 ****************************************************************/
10407 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10408 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10410 p->rng_fault_state = true;
10411 return WERR_NOT_SUPPORTED;
10414 /****************************************************************
10415 _spoolss_DeletePrinterIC
10416 ****************************************************************/
10418 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10419 struct spoolss_DeletePrinterIC *r)
10421 p->rng_fault_state = true;
10422 return WERR_NOT_SUPPORTED;
10425 /****************************************************************
10426 _spoolss_AddPrinterConnection
10427 ****************************************************************/
10429 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10430 struct spoolss_AddPrinterConnection *r)
10432 p->rng_fault_state = true;
10433 return WERR_NOT_SUPPORTED;
10436 /****************************************************************
10437 _spoolss_DeletePrinterConnection
10438 ****************************************************************/
10440 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10441 struct spoolss_DeletePrinterConnection *r)
10443 p->rng_fault_state = true;
10444 return WERR_NOT_SUPPORTED;
10447 /****************************************************************
10448 _spoolss_PrinterMessageBox
10449 ****************************************************************/
10451 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10452 struct spoolss_PrinterMessageBox *r)
10454 p->rng_fault_state = true;
10455 return WERR_NOT_SUPPORTED;
10458 /****************************************************************
10459 _spoolss_AddMonitor
10460 ****************************************************************/
10462 WERROR _spoolss_AddMonitor(pipes_struct *p,
10463 struct spoolss_AddMonitor *r)
10465 p->rng_fault_state = true;
10466 return WERR_NOT_SUPPORTED;
10469 /****************************************************************
10470 _spoolss_DeleteMonitor
10471 ****************************************************************/
10473 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10474 struct spoolss_DeleteMonitor *r)
10476 p->rng_fault_state = true;
10477 return WERR_NOT_SUPPORTED;
10480 /****************************************************************
10481 _spoolss_DeletePrintProcessor
10482 ****************************************************************/
10484 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10485 struct spoolss_DeletePrintProcessor *r)
10487 p->rng_fault_state = true;
10488 return WERR_NOT_SUPPORTED;
10491 /****************************************************************
10492 _spoolss_AddPrintProvidor
10493 ****************************************************************/
10495 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10496 struct spoolss_AddPrintProvidor *r)
10498 p->rng_fault_state = true;
10499 return WERR_NOT_SUPPORTED;
10502 /****************************************************************
10503 _spoolss_DeletePrintProvidor
10504 ****************************************************************/
10506 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10507 struct spoolss_DeletePrintProvidor *r)
10509 p->rng_fault_state = true;
10510 return WERR_NOT_SUPPORTED;
10513 /****************************************************************
10514 _spoolss_EnumPrintProcDataTypes
10515 ****************************************************************/
10517 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10518 struct spoolss_EnumPrintProcDataTypes *r)
10520 p->rng_fault_state = true;
10521 return WERR_NOT_SUPPORTED;
10524 /****************************************************************
10525 _spoolss_GetPrinterDriver2
10526 ****************************************************************/
10528 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10529 struct spoolss_GetPrinterDriver2 *r)
10531 p->rng_fault_state = true;
10532 return WERR_NOT_SUPPORTED;
10535 /****************************************************************
10536 _spoolss_FindFirstPrinterChangeNotification
10537 ****************************************************************/
10539 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10540 struct spoolss_FindFirstPrinterChangeNotification *r)
10542 p->rng_fault_state = true;
10543 return WERR_NOT_SUPPORTED;
10546 /****************************************************************
10547 _spoolss_FindNextPrinterChangeNotification
10548 ****************************************************************/
10550 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10551 struct spoolss_FindNextPrinterChangeNotification *r)
10553 p->rng_fault_state = true;
10554 return WERR_NOT_SUPPORTED;
10557 /****************************************************************
10558 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10559 ****************************************************************/
10561 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10562 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10564 p->rng_fault_state = true;
10565 return WERR_NOT_SUPPORTED;
10568 /****************************************************************
10569 _spoolss_ReplyOpenPrinter
10570 ****************************************************************/
10572 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10573 struct spoolss_ReplyOpenPrinter *r)
10575 p->rng_fault_state = true;
10576 return WERR_NOT_SUPPORTED;
10579 /****************************************************************
10580 _spoolss_RouterReplyPrinter
10581 ****************************************************************/
10583 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10584 struct spoolss_RouterReplyPrinter *r)
10586 p->rng_fault_state = true;
10587 return WERR_NOT_SUPPORTED;
10590 /****************************************************************
10591 _spoolss_ReplyClosePrinter
10592 ****************************************************************/
10594 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10595 struct spoolss_ReplyClosePrinter *r)
10597 p->rng_fault_state = true;
10598 return WERR_NOT_SUPPORTED;
10601 /****************************************************************
10603 ****************************************************************/
10605 WERROR _spoolss_AddPortEx(pipes_struct *p,
10606 struct spoolss_AddPortEx *r)
10608 p->rng_fault_state = true;
10609 return WERR_NOT_SUPPORTED;
10612 /****************************************************************
10613 _spoolss_RouterFindFirstPrinterChangeNotification
10614 ****************************************************************/
10616 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10617 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10619 p->rng_fault_state = true;
10620 return WERR_NOT_SUPPORTED;
10623 /****************************************************************
10624 _spoolss_SpoolerInit
10625 ****************************************************************/
10627 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10628 struct spoolss_SpoolerInit *r)
10630 p->rng_fault_state = true;
10631 return WERR_NOT_SUPPORTED;
10634 /****************************************************************
10635 _spoolss_ResetPrinterEx
10636 ****************************************************************/
10638 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10639 struct spoolss_ResetPrinterEx *r)
10641 p->rng_fault_state = true;
10642 return WERR_NOT_SUPPORTED;
10645 /****************************************************************
10646 _spoolss_RouterReplyPrinterEx
10647 ****************************************************************/
10649 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10650 struct spoolss_RouterReplyPrinterEx *r)
10652 p->rng_fault_state = true;
10653 return WERR_NOT_SUPPORTED;
10656 /****************************************************************
10658 ****************************************************************/
10660 WERROR _spoolss_44(pipes_struct *p,
10661 struct spoolss_44 *r)
10663 p->rng_fault_state = true;
10664 return WERR_NOT_SUPPORTED;
10667 /****************************************************************
10669 ****************************************************************/
10671 WERROR _spoolss_47(pipes_struct *p,
10672 struct spoolss_47 *r)
10674 p->rng_fault_state = true;
10675 return WERR_NOT_SUPPORTED;
10678 /****************************************************************
10679 _spoolss_EnumPrinterData
10680 ****************************************************************/
10682 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10683 struct spoolss_EnumPrinterData *r)
10685 p->rng_fault_state = true;
10686 return WERR_NOT_SUPPORTED;
10689 /****************************************************************
10691 ****************************************************************/
10693 WERROR _spoolss_4a(pipes_struct *p,
10694 struct spoolss_4a *r)
10696 p->rng_fault_state = true;
10697 return WERR_NOT_SUPPORTED;
10700 /****************************************************************
10702 ****************************************************************/
10704 WERROR _spoolss_4b(pipes_struct *p,
10705 struct spoolss_4b *r)
10707 p->rng_fault_state = true;
10708 return WERR_NOT_SUPPORTED;
10711 /****************************************************************
10713 ****************************************************************/
10715 WERROR _spoolss_4c(pipes_struct *p,
10716 struct spoolss_4c *r)
10718 p->rng_fault_state = true;
10719 return WERR_NOT_SUPPORTED;
10722 /****************************************************************
10723 _spoolss_EnumPrinterDataEx
10724 ****************************************************************/
10726 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10727 struct spoolss_EnumPrinterDataEx *r)
10729 p->rng_fault_state = true;
10730 return WERR_NOT_SUPPORTED;
10733 /****************************************************************
10734 _spoolss_EnumPrinterKey
10735 ****************************************************************/
10737 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10738 struct spoolss_EnumPrinterKey *r)
10740 p->rng_fault_state = true;
10741 return WERR_NOT_SUPPORTED;
10744 /****************************************************************
10746 ****************************************************************/
10748 WERROR _spoolss_53(pipes_struct *p,
10749 struct spoolss_53 *r)
10751 p->rng_fault_state = true;
10752 return WERR_NOT_SUPPORTED;
10755 /****************************************************************
10757 ****************************************************************/
10759 WERROR _spoolss_55(pipes_struct *p,
10760 struct spoolss_55 *r)
10762 p->rng_fault_state = true;
10763 return WERR_NOT_SUPPORTED;
10766 /****************************************************************
10768 ****************************************************************/
10770 WERROR _spoolss_56(pipes_struct *p,
10771 struct spoolss_56 *r)
10773 p->rng_fault_state = true;
10774 return WERR_NOT_SUPPORTED;
10777 /****************************************************************
10779 ****************************************************************/
10781 WERROR _spoolss_57(pipes_struct *p,
10782 struct spoolss_57 *r)
10784 p->rng_fault_state = true;
10785 return WERR_NOT_SUPPORTED;
10788 /****************************************************************
10790 ****************************************************************/
10792 WERROR _spoolss_5a(pipes_struct *p,
10793 struct spoolss_5a *r)
10795 p->rng_fault_state = true;
10796 return WERR_NOT_SUPPORTED;
10799 /****************************************************************
10801 ****************************************************************/
10803 WERROR _spoolss_5b(pipes_struct *p,
10804 struct spoolss_5b *r)
10806 p->rng_fault_state = true;
10807 return WERR_NOT_SUPPORTED;
10810 /****************************************************************
10812 ****************************************************************/
10814 WERROR _spoolss_5c(pipes_struct *p,
10815 struct spoolss_5c *r)
10817 p->rng_fault_state = true;
10818 return WERR_NOT_SUPPORTED;
10821 /****************************************************************
10823 ****************************************************************/
10825 WERROR _spoolss_5d(pipes_struct *p,
10826 struct spoolss_5d *r)
10828 p->rng_fault_state = true;
10829 return WERR_NOT_SUPPORTED;
10832 /****************************************************************
10834 ****************************************************************/
10836 WERROR _spoolss_5e(pipes_struct *p,
10837 struct spoolss_5e *r)
10839 p->rng_fault_state = true;
10840 return WERR_NOT_SUPPORTED;
10843 /****************************************************************
10845 ****************************************************************/
10847 WERROR _spoolss_5f(pipes_struct *p,
10848 struct spoolss_5f *r)
10850 p->rng_fault_state = true;
10851 return WERR_NOT_SUPPORTED;