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
) (NT_USER_TOKEN
*token
, RPC_BUFFER
*in
, RPC_BUFFER
*out
, uint32
*needed
);
76 /* translate between internal status numbers and NT status numbers */
77 static int nt_printj_status(int v
)
83 return JOB_STATUS_PAUSED
;
85 return JOB_STATUS_SPOOLING
;
87 return JOB_STATUS_PRINTING
;
89 return JOB_STATUS_ERROR
;
91 return JOB_STATUS_DELETING
;
93 return JOB_STATUS_OFFLINE
;
95 return JOB_STATUS_PAPEROUT
;
97 return JOB_STATUS_PRINTED
;
99 return JOB_STATUS_DELETED
;
101 return JOB_STATUS_BLOCKED
;
102 case LPQ_USER_INTERVENTION
:
103 return JOB_STATUS_USER_INTERVENTION
;
108 static int nt_printq_status(int v
)
112 return PRINTER_STATUS_PAUSED
;
121 /****************************************************************************
122 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
123 ****************************************************************************/
125 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
130 SAFE_FREE((*pp
)->ctr
.type
);
134 /***************************************************************************
135 Disconnect from the client
136 ****************************************************************************/
138 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 result
= rpccli_spoolss_reply_close_printer(notify_cli_pipe
,
160 if (!W_ERROR_IS_OK(result
))
161 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
162 dos_errstr(result
)));
164 /* if it's the last connection, deconnect the IPC$ share */
165 if (smb_connections
==1) {
167 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe
) );
168 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
170 messaging_deregister(smbd_messaging_context(),
171 MSG_PRINTER_NOTIFY2
, NULL
);
173 /* Tell the connections db we're no longer interested in
174 * printer notify messages. */
176 register_message_flags( False
, FLAG_MSG_PRINT_NOTIFY
);
182 /****************************************************************************
183 Functions to free a printer entry datastruct.
184 ****************************************************************************/
186 static void free_printer_entry(void *ptr
)
188 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
190 if (Printer
->notify
.client_connected
==True
) {
193 if ( Printer
->printer_type
== SPLHND_SERVER
) {
195 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
196 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
197 snum
= print_queue_snum(Printer
->sharename
);
199 srv_spoolss_replycloseprinter(snum
,
200 &Printer
->notify
.client_hnd
);
204 Printer
->notify
.flags
=0;
205 Printer
->notify
.options
=0;
206 Printer
->notify
.localmachine
[0]='\0';
207 Printer
->notify
.printerlocal
=0;
208 free_spool_notify_option(&Printer
->notify
.option
);
209 Printer
->notify
.option
=NULL
;
210 Printer
->notify
.client_connected
=False
;
212 free_nt_devicemode( &Printer
->nt_devmode
);
213 free_a_printer( &Printer
->printer_info
, 2 );
215 talloc_destroy( Printer
->ctx
);
217 /* Remove from the internal list. */
218 DLIST_REMOVE(printers_list
, Printer
);
223 /****************************************************************************
224 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
225 ****************************************************************************/
227 static SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
229 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
234 new_sp
= SMB_MALLOC_P(SPOOL_NOTIFY_OPTION
);
241 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
243 if (!new_sp
->ctr
.type
) {
252 /****************************************************************************
253 find printer index by handle
254 ****************************************************************************/
256 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
258 Printer_entry
*find_printer
= NULL
;
260 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
261 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
268 /****************************************************************************
269 Close printer index by handle.
270 ****************************************************************************/
272 static bool close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
274 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
277 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
281 close_policy_hnd(p
, hnd
);
286 /****************************************************************************
287 Delete a printer given a handle.
288 ****************************************************************************/
290 WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
292 char *cmd
= lp_deleteprinter_cmd();
293 char *command
= NULL
;
295 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
296 bool is_print_op
= False
;
298 /* can't fail if we don't try */
303 command
= talloc_asprintf(ctx
,
310 is_print_op
= user_has_privileges( token
, &se_printop
);
312 DEBUG(10,("Running [%s]\n", command
));
314 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
319 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
320 /* Tell everyone we updated smb.conf. */
321 message_send_all(smbd_messaging_context(),
322 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
328 /********** END SePrintOperatorPrivlege BLOCK **********/
330 DEBUGADD(10,("returned [%d]\n", ret
));
332 TALLOC_FREE(command
);
335 return WERR_BADFID
; /* What to return here? */
337 /* go ahead and re-read the services immediately */
338 reload_services( False
);
340 if ( lp_servicenumber( sharename
) < 0 )
341 return WERR_ACCESS_DENIED
;
346 /****************************************************************************
347 Delete a printer given a handle.
348 ****************************************************************************/
350 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
352 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
355 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
360 * It turns out that Windows allows delete printer on a handle
361 * opened by an admin user, then used on a pipe handle created
362 * by an anonymous user..... but they're working on security.... riiight !
366 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
367 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
368 return WERR_ACCESS_DENIED
;
371 /* this does not need a become root since the access check has been
372 done on the handle already */
374 if (del_a_printer( Printer
->sharename
) != 0) {
375 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
379 return delete_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, Printer
->sharename
);
382 /****************************************************************************
383 Return the snum of a printer corresponding to an handle.
384 ****************************************************************************/
386 static bool get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
,
387 struct share_params
**params
)
389 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
392 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
396 switch (Printer
->printer_type
) {
398 DEBUG(4,("short name:%s\n", Printer
->sharename
));
399 *number
= print_queue_snum(Printer
->sharename
);
400 return (*number
!= -1);
408 /****************************************************************************
409 Set printer handle type.
410 Check if it's \\server or \\server\printer
411 ****************************************************************************/
413 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
415 DEBUG(3,("Setting printer type=%s\n", handlename
));
417 if ( strlen(handlename
) < 3 ) {
418 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
422 /* it's a print server */
423 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
424 DEBUGADD(4,("Printer is a print server\n"));
425 Printer
->printer_type
= SPLHND_SERVER
;
427 /* it's a printer (set_printer_hnd_name() will handle port monitors */
429 DEBUGADD(4,("Printer is a printer\n"));
430 Printer
->printer_type
= SPLHND_PRINTER
;
436 /****************************************************************************
437 Set printer handle name.. Accept names like \\server, \\server\printer,
438 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
439 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
440 XcvDataPort() interface.
441 ****************************************************************************/
443 static bool set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
446 int n_services
=lp_numservices();
447 char *aprinter
, *printername
;
448 const char *servername
;
451 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
454 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
, (unsigned long)strlen(handlename
)));
456 aprinter
= handlename
;
457 if ( *handlename
== '\\' ) {
458 servername
= handlename
+ 2;
459 if ( (aprinter
= strchr_m( handlename
+2, '\\' )) != NULL
) {
468 /* save the servername to fill in replies on this handle */
470 if ( !is_myname_or_ipaddr( servername
) )
473 fstrcpy( Printer
->servername
, servername
);
475 if ( Printer
->printer_type
== SPLHND_SERVER
)
478 if ( Printer
->printer_type
!= SPLHND_PRINTER
)
481 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
483 /* check for the Port Monitor Interface */
485 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
486 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
487 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
490 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
491 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
492 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
496 /* Search all sharenames first as this is easier than pulling
497 the printer_info_2 off of disk. Don't use find_service() since
498 that calls out to map_username() */
500 /* do another loop to look for printernames */
502 for (snum
=0; !found
&& snum
<n_services
; snum
++) {
504 /* no point going on if this is not a printer */
506 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
)) )
509 fstrcpy(sname
, lp_servicename(snum
));
510 if ( strequal( aprinter
, sname
) ) {
515 /* no point looking up the printer object if
516 we aren't allowing printername != sharename */
518 if ( lp_force_printername(snum
) )
521 fstrcpy(sname
, lp_servicename(snum
));
525 /* This call doesn't fill in the location or comment from
526 * a CUPS server for efficiency with large numbers of printers.
530 result
= get_a_printer_search( NULL
, &printer
, 2, sname
);
531 if ( !W_ERROR_IS_OK(result
) ) {
532 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
533 sname
, dos_errstr(result
)));
537 /* printername is always returned as \\server\printername */
538 if ( !(printername
= strchr_m(&printer
->info_2
->printername
[2], '\\')) ) {
539 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
540 printer
->info_2
->printername
));
541 free_a_printer( &printer
, 2);
547 if ( strequal(printername
, aprinter
) ) {
548 free_a_printer( &printer
, 2);
553 DEBUGADD(10, ("printername: %s\n", printername
));
555 free_a_printer( &printer
, 2);
558 free_a_printer( &printer
, 2);
561 DEBUGADD(4,("Printer not found\n"));
565 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
567 fstrcpy(Printer
->sharename
, sname
);
572 /****************************************************************************
573 Find first available printer slot. creates a printer handle for you.
574 ****************************************************************************/
576 static bool open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
, uint32 access_granted
)
578 Printer_entry
*new_printer
;
580 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
582 if((new_printer
=SMB_MALLOC_P(Printer_entry
)) == NULL
)
585 ZERO_STRUCTP(new_printer
);
587 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
588 SAFE_FREE(new_printer
);
592 /* Add to the internal list. */
593 DLIST_ADD(printers_list
, new_printer
);
595 new_printer
->notify
.option
=NULL
;
597 if ( !(new_printer
->ctx
= talloc_init("Printer Entry [%p]", hnd
)) ) {
598 DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
599 close_printer_handle(p
, hnd
);
603 if (!set_printer_hnd_printertype(new_printer
, name
)) {
604 close_printer_handle(p
, hnd
);
608 if (!set_printer_hnd_name(new_printer
, name
)) {
609 close_printer_handle(p
, hnd
);
613 new_printer
->access_granted
= access_granted
;
615 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
620 /***************************************************************************
621 check to see if the client motify handle is monitoring the notification
622 given by (notify_type, notify_field).
623 **************************************************************************/
625 static bool is_monitoring_event_flags(uint32 flags
, uint16 notify_type
,
631 static bool is_monitoring_event(Printer_entry
*p
, uint16 notify_type
,
634 SPOOL_NOTIFY_OPTION
*option
= p
->notify
.option
;
638 * Flags should always be zero when the change notify
639 * is registered by the client's spooler. A user Win32 app
640 * might use the flags though instead of the NOTIFY_OPTION_INFO
649 return is_monitoring_event_flags(
650 p
->notify
.flags
, notify_type
, notify_field
);
652 for (i
= 0; i
< option
->count
; i
++) {
654 /* Check match for notify_type */
656 if (option
->ctr
.type
[i
].type
!= notify_type
)
659 /* Check match for field */
661 for (j
= 0; j
< option
->ctr
.type
[i
].count
; j
++) {
662 if (option
->ctr
.type
[i
].fields
[j
] == notify_field
) {
668 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
669 p
->servername
, p
->sharename
, notify_type
, notify_field
));
674 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
676 static void notify_one_value(struct spoolss_notify_msg
*msg
,
677 SPOOL_NOTIFY_INFO_DATA
*data
,
680 data
->notify_data
.value
[0] = msg
->notify
.value
[0];
681 data
->notify_data
.value
[1] = 0;
684 static void notify_string(struct spoolss_notify_msg
*msg
,
685 SPOOL_NOTIFY_INFO_DATA
*data
,
690 /* The length of the message includes the trailing \0 */
692 init_unistr2(&unistr
, msg
->notify
.data
, UNI_STR_TERMINATE
);
694 data
->notify_data
.data
.length
= msg
->len
* 2;
695 data
->notify_data
.data
.string
= TALLOC_ARRAY(mem_ctx
, uint16
, msg
->len
);
697 if (!data
->notify_data
.data
.string
) {
698 data
->notify_data
.data
.length
= 0;
702 memcpy(data
->notify_data
.data
.string
, unistr
.buffer
, msg
->len
* 2);
705 static void notify_system_time(struct spoolss_notify_msg
*msg
,
706 SPOOL_NOTIFY_INFO_DATA
*data
,
712 if (msg
->len
!= sizeof(time_t)) {
713 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
718 if (!prs_init(&ps
, RPC_MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
)) {
719 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
723 if (!make_systemtime(&systime
, gmtime((time_t *)msg
->notify
.data
))) {
724 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
729 if (!spoolss_io_system_time("", &ps
, 0, &systime
)) {
734 data
->notify_data
.data
.length
= prs_offset(&ps
);
735 if (prs_offset(&ps
)) {
736 data
->notify_data
.data
.string
= (uint16
*)
737 TALLOC(mem_ctx
, prs_offset(&ps
));
738 if (!data
->notify_data
.data
.string
) {
742 prs_copy_all_data_out((char *)data
->notify_data
.data
.string
, &ps
);
744 data
->notify_data
.data
.string
= NULL
;
750 struct notify2_message_table
{
752 void (*fn
)(struct spoolss_notify_msg
*msg
,
753 SPOOL_NOTIFY_INFO_DATA
*data
, TALLOC_CTX
*mem_ctx
);
756 static struct notify2_message_table printer_notify_table
[] = {
757 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string
},
758 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string
},
759 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string
},
760 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string
},
761 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string
},
762 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string
},
763 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string
},
764 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL
},
765 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string
},
766 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string
},
767 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL
},
768 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string
},
769 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
770 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value
},
771 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value
},
772 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL
},
773 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL
},
774 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL
},
775 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value
},
778 static struct notify2_message_table job_notify_table
[] = {
779 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL
},
780 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL
},
781 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL
},
782 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string
},
783 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL
},
784 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL
},
785 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL
},
786 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL
},
787 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL
},
788 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL
},
789 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value
},
790 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL
},
791 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
792 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string
},
793 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL
},
794 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL
},
795 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time
},
796 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL
},
797 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL
},
798 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL
},
799 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value
},
800 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL
},
801 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value
},
802 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL
},
806 /***********************************************************************
807 Allocate talloc context for container object
808 **********************************************************************/
810 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
815 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
820 /***********************************************************************
821 release all allocated memory and zero out structure
822 **********************************************************************/
824 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
830 talloc_destroy(ctr
->ctx
);
837 /***********************************************************************
838 **********************************************************************/
840 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
848 /***********************************************************************
849 **********************************************************************/
851 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
853 if ( !ctr
|| !ctr
->msg_groups
)
856 if ( idx
>= ctr
->num_groups
)
859 return &ctr
->msg_groups
[idx
];
863 /***********************************************************************
864 How many groups of change messages do we have ?
865 **********************************************************************/
867 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
872 return ctr
->num_groups
;
875 /***********************************************************************
876 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
877 **********************************************************************/
879 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
881 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
882 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
883 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
889 /* loop over all groups looking for a matching printer name */
891 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
892 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
896 /* add a new group? */
898 if ( i
== ctr
->num_groups
) {
901 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
902 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
905 ctr
->msg_groups
= groups
;
907 /* clear the new entry and set the printer name */
909 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
910 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
913 /* add the change messages; 'i' is the correct index now regardless */
915 msg_grp
= &ctr
->msg_groups
[i
];
919 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
920 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
923 msg_grp
->msgs
= msg_list
;
925 new_slot
= msg_grp
->num_msgs
-1;
926 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
928 /* need to allocate own copy of data */
931 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
932 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
934 return ctr
->num_groups
;
937 /***********************************************************************
938 Send a change notication message on all handles which have a call
940 **********************************************************************/
942 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
945 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
946 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
947 SPOOLSS_NOTIFY_MSG
*messages
;
948 int sending_msg_count
;
951 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
955 messages
= msg_group
->msgs
;
958 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
962 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
964 /* loop over all printers */
966 for (p
= printers_list
; p
; p
= p
->next
) {
967 SPOOL_NOTIFY_INFO_DATA
*data
;
972 /* Is there notification on this handle? */
974 if ( !p
->notify
.client_connected
)
977 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
979 /* For this printer? Print servers always receive
982 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
983 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
986 DEBUG(10,("Our printer\n"));
988 /* allocate the max entries possible */
990 data
= TALLOC_ARRAY( mem_ctx
, SPOOL_NOTIFY_INFO_DATA
, msg_group
->num_msgs
);
997 /* build the array of change notifications */
999 sending_msg_count
= 0;
1001 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
1002 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
1004 /* Are we monitoring this event? */
1006 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1009 sending_msg_count
++;
1012 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1013 msg
->type
, msg
->field
, p
->sharename
));
1016 * if the is a printer notification handle and not a job notification
1017 * type, then set the id to 0. Other wise just use what was specified
1020 * When registering change notification on a print server handle
1021 * we always need to send back the id (snum) matching the printer
1022 * for which the change took place. For change notify registered
1023 * on a printer handle, this does not matter and the id should be 0.
1028 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1034 /* Convert unix jobid to smb jobid */
1036 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1037 id
= sysjob_to_jobid(msg
->id
);
1040 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1045 construct_info_data( &data
[data_len
], msg
->type
, msg
->field
, id
);
1048 case PRINTER_NOTIFY_TYPE
:
1049 if ( printer_notify_table
[msg
->field
].fn
)
1050 printer_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1053 case JOB_NOTIFY_TYPE
:
1054 if ( job_notify_table
[msg
->field
].fn
)
1055 job_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1059 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1066 if ( sending_msg_count
) {
1067 rpccli_spoolss_rrpcn( notify_cli_pipe
, mem_ctx
, &p
->notify
.client_hnd
,
1068 data_len
, data
, p
->notify
.change
, 0 );
1073 DEBUG(8,("send_notify2_changes: Exit...\n"));
1077 /***********************************************************************
1078 **********************************************************************/
1080 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1083 uint32 tv_sec
, tv_usec
;
1086 /* Unpack message */
1088 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "f",
1091 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "ddddddd",
1093 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1096 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "dd",
1097 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1099 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "B",
1100 &msg
->len
, &msg
->notify
.data
);
1102 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1103 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1105 tv
->tv_sec
= tv_sec
;
1106 tv
->tv_usec
= tv_usec
;
1109 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1110 msg
->notify
.value
[1]));
1112 dump_data(3, (uint8
*)msg
->notify
.data
, msg
->len
);
1117 /********************************************************************
1118 Receive a notify2 message list
1119 ********************************************************************/
1121 static void receive_notify2_message_list(struct messaging_context
*msg
,
1124 struct server_id server_id
,
1127 size_t msg_count
, i
;
1128 char *buf
= (char *)data
->data
;
1131 SPOOLSS_NOTIFY_MSG notify
;
1132 SPOOLSS_NOTIFY_MSG_CTR messages
;
1135 if (data
->length
< 4) {
1136 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1140 msg_count
= IVAL(buf
, 0);
1143 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1145 if (msg_count
== 0) {
1146 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1150 /* initialize the container */
1152 ZERO_STRUCT( messages
);
1153 notify_msg_ctr_init( &messages
);
1156 * build message groups for each printer identified
1157 * in a change_notify msg. Remember that a PCN message
1158 * includes the handle returned for the srv_spoolss_replyopenprinter()
1159 * call. Therefore messages are grouped according to printer handle.
1162 for ( i
=0; i
<msg_count
; i
++ ) {
1163 struct timeval msg_tv
;
1165 if (msg_ptr
+ 4 - buf
> data
->length
) {
1166 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1170 msg_len
= IVAL(msg_ptr
,0);
1173 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1174 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1178 /* unpack messages */
1180 ZERO_STRUCT( notify
);
1181 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1184 /* add to correct list in container */
1186 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1188 /* free memory that might have been allocated by notify2_unpack_msg() */
1190 if ( notify
.len
!= 0 )
1191 SAFE_FREE( notify
.notify
.data
);
1194 /* process each group of messages */
1196 num_groups
= notify_msg_ctr_numgroups( &messages
);
1197 for ( i
=0; i
<num_groups
; i
++ )
1198 send_notify2_changes( &messages
, i
);
1203 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32
)msg_count
));
1205 notify_msg_ctr_destroy( &messages
);
1210 /********************************************************************
1211 Send a message to ourself about new driver being installed
1212 so we can upgrade the information for each printer bound to this
1214 ********************************************************************/
1216 static bool srv_spoolss_drv_upgrade_printer(char* drivername
)
1218 int len
= strlen(drivername
);
1223 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1226 messaging_send_buf(smbd_messaging_context(), procid_self(),
1227 MSG_PRINTER_DRVUPGRADE
,
1228 (uint8
*)drivername
, len
+1);
1233 /**********************************************************************
1234 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1235 over all printers, upgrading ones as necessary
1236 **********************************************************************/
1238 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1241 struct server_id server_id
,
1246 int n_services
= lp_numservices();
1249 len
= MIN(data
->length
,sizeof(drivername
)-1);
1250 strncpy(drivername
, (const char *)data
->data
, len
);
1252 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1254 /* Iterate the printer list */
1256 for (snum
=0; snum
<n_services
; snum
++)
1258 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1261 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1263 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1264 if (!W_ERROR_IS_OK(result
))
1267 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1269 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1271 /* all we care about currently is the change_id */
1273 result
= mod_a_printer(printer
, 2);
1274 if (!W_ERROR_IS_OK(result
)) {
1275 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1276 dos_errstr(result
)));
1280 free_a_printer(&printer
, 2);
1287 /********************************************************************
1288 Update the cache for all printq's with a registered client
1290 ********************************************************************/
1292 void update_monitored_printq_cache( void )
1294 Printer_entry
*printer
= printers_list
;
1297 /* loop through all printers and update the cache where
1298 client_connected == True */
1301 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1302 && printer
->notify
.client_connected
)
1304 snum
= print_queue_snum(printer
->sharename
);
1305 print_queue_status( snum
, NULL
, NULL
);
1308 printer
= printer
->next
;
1313 /********************************************************************
1314 Send a message to ourself about new driver being installed
1315 so we can upgrade the information for each printer bound to this
1317 ********************************************************************/
1319 static bool srv_spoolss_reset_printerdata(char* drivername
)
1321 int len
= strlen(drivername
);
1326 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1329 messaging_send_buf(smbd_messaging_context(), procid_self(),
1330 MSG_PRINTERDATA_INIT_RESET
,
1331 (uint8
*)drivername
, len
+1);
1336 /**********************************************************************
1337 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1338 over all printers, resetting printer data as neessary
1339 **********************************************************************/
1341 void reset_all_printerdata(struct messaging_context
*msg
,
1344 struct server_id server_id
,
1349 int n_services
= lp_numservices();
1352 len
= MIN( data
->length
, sizeof(drivername
)-1 );
1353 strncpy( drivername
, (const char *)data
->data
, len
);
1355 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1357 /* Iterate the printer list */
1359 for ( snum
=0; snum
<n_services
; snum
++ )
1361 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1364 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1366 result
= get_a_printer( NULL
, &printer
, 2, lp_const_servicename(snum
) );
1367 if ( !W_ERROR_IS_OK(result
) )
1371 * if the printer is bound to the driver,
1372 * then reset to the new driver initdata
1375 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1377 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1379 if ( !set_driver_init(printer
, 2) ) {
1380 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1381 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1384 result
= mod_a_printer( printer
, 2 );
1385 if ( !W_ERROR_IS_OK(result
) ) {
1386 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1387 get_dos_error_msg(result
)));
1391 free_a_printer( &printer
, 2 );
1400 /********************************************************************
1401 Copy routines used by convert_to_openprinterex()
1402 *******************************************************************/
1404 static DEVICEMODE
* dup_devicemode(TALLOC_CTX
*ctx
, DEVICEMODE
*devmode
)
1412 DEBUG (8,("dup_devmode\n"));
1414 /* bulk copy first */
1416 d
= (DEVICEMODE
*)TALLOC_MEMDUP(ctx
, devmode
, sizeof(DEVICEMODE
));
1420 /* dup the pointer members separately */
1422 len
= unistrlen(devmode
->devicename
.buffer
);
1424 d
->devicename
.buffer
= TALLOC_ARRAY(ctx
, uint16
, len
);
1425 if (!d
->devicename
.buffer
) {
1428 if (unistrcpy(d
->devicename
.buffer
, devmode
->devicename
.buffer
) != len
)
1433 len
= unistrlen(devmode
->formname
.buffer
);
1435 d
->formname
.buffer
= TALLOC_ARRAY(ctx
, uint16
, len
);
1436 if (!d
->formname
.buffer
) {
1439 if (unistrcpy(d
->formname
.buffer
, devmode
->formname
.buffer
) != len
)
1443 if (devmode
->driverextra
) {
1444 d
->dev_private
= (uint8
*)TALLOC_MEMDUP(ctx
, devmode
->dev_private
,
1445 devmode
->driverextra
);
1446 if (!d
->dev_private
) {
1450 d
->dev_private
= NULL
;
1455 static void copy_devmode_ctr(TALLOC_CTX
*ctx
, DEVMODE_CTR
*new_ctr
, DEVMODE_CTR
*ctr
)
1457 if (!new_ctr
|| !ctr
)
1460 DEBUG(8,("copy_devmode_ctr\n"));
1462 new_ctr
->size
= ctr
->size
;
1463 new_ctr
->devmode_ptr
= ctr
->devmode_ptr
;
1465 if(ctr
->devmode_ptr
)
1466 new_ctr
->devmode
= dup_devicemode(ctx
, ctr
->devmode
);
1469 static void copy_printer_default(TALLOC_CTX
*ctx
, PRINTER_DEFAULT
*new_def
, PRINTER_DEFAULT
*def
)
1471 if (!new_def
|| !def
)
1474 DEBUG(8,("copy_printer_defaults\n"));
1476 new_def
->datatype_ptr
= def
->datatype_ptr
;
1478 if (def
->datatype_ptr
)
1479 copy_unistr2(&new_def
->datatype
, &def
->datatype
);
1481 copy_devmode_ctr(ctx
, &new_def
->devmode_cont
, &def
->devmode_cont
);
1483 new_def
->access_required
= def
->access_required
;
1486 /********************************************************************
1487 * Convert a SPOOL_Q_OPEN_PRINTER structure to a
1488 * SPOOL_Q_OPEN_PRINTER_EX structure
1489 ********************************************************************/
1491 static WERROR
convert_to_openprinterex(TALLOC_CTX
*ctx
, SPOOL_Q_OPEN_PRINTER_EX
*q_u_ex
, SPOOL_Q_OPEN_PRINTER
*q_u
)
1493 if (!q_u_ex
|| !q_u
)
1496 DEBUG(8,("convert_to_openprinterex\n"));
1498 if ( q_u
->printername
) {
1499 q_u_ex
->printername
= TALLOC_ZERO_P( ctx
, UNISTR2
);
1500 if (q_u_ex
->printername
== NULL
)
1502 copy_unistr2(q_u_ex
->printername
, q_u
->printername
);
1505 copy_printer_default(ctx
, &q_u_ex
->printer_default
, &q_u
->printer_default
);
1510 /********************************************************************
1511 * spoolss_open_printer
1513 * called from the spoolss dispatcher
1514 ********************************************************************/
1516 WERROR
_spoolss_open_printer(pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER
*q_u
, SPOOL_R_OPEN_PRINTER
*r_u
)
1518 SPOOL_Q_OPEN_PRINTER_EX q_u_ex
;
1519 SPOOL_R_OPEN_PRINTER_EX r_u_ex
;
1524 ZERO_STRUCT(q_u_ex
);
1525 ZERO_STRUCT(r_u_ex
);
1527 /* convert the OpenPrinter() call to OpenPrinterEx() */
1529 r_u_ex
.status
= convert_to_openprinterex(p
->mem_ctx
, &q_u_ex
, q_u
);
1530 if (!W_ERROR_IS_OK(r_u_ex
.status
))
1531 return r_u_ex
.status
;
1533 r_u_ex
.status
= _spoolss_open_printer_ex(p
, &q_u_ex
, &r_u_ex
);
1535 /* convert back to OpenPrinter() */
1537 memcpy(r_u
, &r_u_ex
, sizeof(*r_u
));
1539 if (W_ERROR_EQUAL(r_u
->status
, WERR_INVALID_PARAM
)) {
1540 /* OpenPrinterEx returns this for a bad
1541 * printer name. We must return WERR_INVALID_PRINTER_NAME
1544 r_u
->status
= WERR_INVALID_PRINTER_NAME
;
1549 /********************************************************************
1550 ********************************************************************/
1552 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
1554 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
1555 POLICY_HND
*handle
= &r_u
->handle
;
1559 Printer_entry
*Printer
=NULL
;
1561 if (!q_u
->printername
) {
1562 return WERR_INVALID_PARAM
;
1565 /* some sanity check because you can open a printer or a print server */
1566 /* aka: \\server\printer or \\server */
1568 unistr2_to_ascii(name
, q_u
->printername
, sizeof(name
));
1570 DEBUGADD(3,("checking name: %s\n",name
));
1572 if (!open_printer_hnd(p
, handle
, name
, 0)) {
1573 return WERR_INVALID_PARAM
;
1576 Printer
=find_printer_index_by_hnd(p
, handle
);
1578 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
1579 "handle we created for printer %s\n", name
));
1580 close_printer_handle(p
,handle
);
1581 return WERR_INVALID_PARAM
;
1585 * First case: the user is opening the print server:
1587 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1588 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1590 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1591 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1592 * or if the user is listed in the smb.conf printer admin parameter.
1594 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1595 * client view printer folder, but does not show the MSAPW.
1597 * Note: this test needs code to check access rights here too. Jeremy
1598 * could you look at this?
1600 * Second case: the user is opening a printer:
1601 * NT doesn't let us connect to a printer if the connecting user
1602 * doesn't have print permission.
1604 * Third case: user is opening a Port Monitor
1605 * access checks same as opening a handle to the print server.
1608 switch (Printer
->printer_type
)
1611 case SPLHND_PORTMON_TCP
:
1612 case SPLHND_PORTMON_LOCAL
:
1613 /* Printserver handles use global struct... */
1617 /* Map standard access rights to object specific access rights */
1619 se_map_standard(&printer_default
->access_required
,
1620 &printserver_std_mapping
);
1622 /* Deny any object specific bits that don't apply to print
1623 servers (i.e printer and job specific bits) */
1625 printer_default
->access_required
&= SPECIFIC_RIGHTS_MASK
;
1627 if (printer_default
->access_required
&
1628 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1629 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1630 close_printer_handle(p
, handle
);
1631 return WERR_ACCESS_DENIED
;
1634 /* Allow admin access */
1636 if ( printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
)
1638 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1640 if (!lp_ms_add_printer_wizard()) {
1641 close_printer_handle(p
, handle
);
1642 return WERR_ACCESS_DENIED
;
1645 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1646 and not a printer admin, then fail */
1648 if ((p
->pipe_user
.ut
.uid
!= 0) &&
1649 !user_has_privileges(p
->pipe_user
.nt_user_token
,
1651 !token_contains_name_in_list(
1652 uidtoname(p
->pipe_user
.ut
.uid
),
1654 p
->pipe_user
.nt_user_token
,
1655 lp_printer_admin(snum
))) {
1656 close_printer_handle(p
, handle
);
1657 return WERR_ACCESS_DENIED
;
1660 printer_default
->access_required
= SERVER_ACCESS_ADMINISTER
;
1664 printer_default
->access_required
= SERVER_ACCESS_ENUMERATE
;
1667 DEBUG(4,("Setting print server access = %s\n", (printer_default
->access_required
== SERVER_ACCESS_ADMINISTER
)
1668 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1670 /* We fall through to return WERR_OK */
1673 case SPLHND_PRINTER
:
1674 /* NT doesn't let us connect to a printer if the connecting user
1675 doesn't have print permission. */
1677 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
1678 close_printer_handle(p
, handle
);
1682 se_map_standard(&printer_default
->access_required
, &printer_std_mapping
);
1684 /* map an empty access mask to the minimum access mask */
1685 if (printer_default
->access_required
== 0x0)
1686 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1689 * If we are not serving the printer driver for this printer,
1690 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1691 * will keep NT clients happy --jerry
1694 if (lp_use_client_driver(snum
)
1695 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
1697 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1700 /* check smb.conf parameters and the the sec_desc */
1702 if ( !check_access(smbd_server_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1703 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1704 return WERR_ACCESS_DENIED
;
1707 if (!user_ok_token(uidtoname(p
->pipe_user
.ut
.uid
), NULL
,
1708 p
->pipe_user
.nt_user_token
, snum
) ||
1709 !print_access_check(&p
->pipe_user
, snum
,
1710 printer_default
->access_required
)) {
1711 DEBUG(3, ("access DENIED for printer open\n"));
1712 close_printer_handle(p
, handle
);
1713 return WERR_ACCESS_DENIED
;
1716 if ((printer_default
->access_required
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1717 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1718 close_printer_handle(p
, handle
);
1719 return WERR_ACCESS_DENIED
;
1722 if (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
)
1723 printer_default
->access_required
= PRINTER_ACCESS_ADMINISTER
;
1725 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1727 DEBUG(4,("Setting printer access = %s\n", (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1728 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1733 /* sanity check to prevent programmer error */
1737 Printer
->access_granted
= printer_default
->access_required
;
1740 * If the client sent a devmode in the OpenPrinter() call, then
1741 * save it here in case we get a job submission on this handle
1744 if ( (Printer
->printer_type
!= SPLHND_SERVER
)
1745 && q_u
->printer_default
.devmode_cont
.devmode_ptr
)
1747 convert_devicemode( Printer
->sharename
, q_u
->printer_default
.devmode_cont
.devmode
,
1748 &Printer
->nt_devmode
);
1751 #if 0 /* JERRY -- I'm doubtful this is really effective */
1752 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1753 optimization in Windows 2000 clients --jerry */
1755 if ( (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1756 && (RA_WIN2K
== get_remote_arch()) )
1758 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1759 sys_usleep( 500000 );
1766 /****************************************************************************
1767 ****************************************************************************/
1769 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
1770 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
1776 /* allocate memory if needed. Messy because
1777 convert_printer_info is used to update an existing
1778 printer or build a new one */
1780 if ( !printer
->info_2
) {
1781 printer
->info_2
= TALLOC_ZERO_P( printer
, NT_PRINTER_INFO_LEVEL_2
);
1782 if ( !printer
->info_2
) {
1783 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1788 ret
= uni_2_asc_printer_info_2(uni
->info_2
, printer
->info_2
);
1789 printer
->info_2
->setuptime
= time(NULL
);
1797 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
1798 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
1804 printer
->info_3
=NULL
;
1805 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
1809 printer
->info_6
=NULL
;
1810 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
1820 bool convert_devicemode(const char *printername
, const DEVICEMODE
*devmode
,
1821 NT_DEVICEMODE
**pp_nt_devmode
)
1823 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1826 * Ensure nt_devmode is a valid pointer
1827 * as we will be overwriting it.
1830 if (nt_devmode
== NULL
) {
1831 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1832 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1836 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
1837 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
1839 nt_devmode
->specversion
=devmode
->specversion
;
1840 nt_devmode
->driverversion
=devmode
->driverversion
;
1841 nt_devmode
->size
=devmode
->size
;
1842 nt_devmode
->fields
=devmode
->fields
;
1843 nt_devmode
->orientation
=devmode
->orientation
;
1844 nt_devmode
->papersize
=devmode
->papersize
;
1845 nt_devmode
->paperlength
=devmode
->paperlength
;
1846 nt_devmode
->paperwidth
=devmode
->paperwidth
;
1847 nt_devmode
->scale
=devmode
->scale
;
1848 nt_devmode
->copies
=devmode
->copies
;
1849 nt_devmode
->defaultsource
=devmode
->defaultsource
;
1850 nt_devmode
->printquality
=devmode
->printquality
;
1851 nt_devmode
->color
=devmode
->color
;
1852 nt_devmode
->duplex
=devmode
->duplex
;
1853 nt_devmode
->yresolution
=devmode
->yresolution
;
1854 nt_devmode
->ttoption
=devmode
->ttoption
;
1855 nt_devmode
->collate
=devmode
->collate
;
1857 nt_devmode
->logpixels
=devmode
->logpixels
;
1858 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
1859 nt_devmode
->pelswidth
=devmode
->pelswidth
;
1860 nt_devmode
->pelsheight
=devmode
->pelsheight
;
1861 nt_devmode
->displayflags
=devmode
->displayflags
;
1862 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
1863 nt_devmode
->icmmethod
=devmode
->icmmethod
;
1864 nt_devmode
->icmintent
=devmode
->icmintent
;
1865 nt_devmode
->mediatype
=devmode
->mediatype
;
1866 nt_devmode
->dithertype
=devmode
->dithertype
;
1867 nt_devmode
->reserved1
=devmode
->reserved1
;
1868 nt_devmode
->reserved2
=devmode
->reserved2
;
1869 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1870 nt_devmode
->panningheight
=devmode
->panningheight
;
1873 * Only change private and driverextra if the incoming devmode
1874 * has a new one. JRA.
1877 if ((devmode
->driverextra
!= 0) && (devmode
->dev_private
!= NULL
)) {
1878 SAFE_FREE(nt_devmode
->nt_dev_private
);
1879 nt_devmode
->driverextra
=devmode
->driverextra
;
1880 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1882 memcpy(nt_devmode
->nt_dev_private
, devmode
->dev_private
, nt_devmode
->driverextra
);
1885 *pp_nt_devmode
= nt_devmode
;
1890 /********************************************************************
1891 * _spoolss_enddocprinter_internal.
1892 ********************************************************************/
1894 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1896 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1900 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
1904 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
1907 Printer
->document_started
=False
;
1908 print_job_end(snum
, Printer
->jobid
,NORMAL_CLOSE
);
1909 /* error codes unhandled so far ... */
1914 /********************************************************************
1915 * api_spoolss_closeprinter
1916 ********************************************************************/
1918 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1920 POLICY_HND
*handle
= &q_u
->handle
;
1922 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1924 if (Printer
&& Printer
->document_started
)
1925 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1927 if (!close_printer_handle(p
, handle
))
1930 /* clear the returned printer handle. Observed behavior
1931 from Win2k server. Don't think this really matters.
1932 Previous code just copied the value of the closed
1935 memset(&r_u
->handle
, '\0', sizeof(r_u
->handle
));
1940 /********************************************************************
1941 * api_spoolss_deleteprinter
1943 ********************************************************************/
1945 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1947 POLICY_HND
*handle
= &q_u
->handle
;
1948 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1951 if (Printer
&& Printer
->document_started
)
1952 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1954 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1956 result
= delete_printer_handle(p
, handle
);
1958 update_c_setprinter(False
);
1963 /*******************************************************************
1964 * static function to lookup the version id corresponding to an
1965 * long architecture string
1966 ******************************************************************/
1968 static int get_version_id (char * arch
)
1971 struct table_node archi_table
[]= {
1973 {"Windows 4.0", "WIN40", 0 },
1974 {"Windows NT x86", "W32X86", 2 },
1975 {"Windows NT R4000", "W32MIPS", 2 },
1976 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1977 {"Windows NT PowerPC", "W32PPC", 2 },
1978 {"Windows IA64", "IA64", 3 },
1979 {"Windows x64", "x64", 3 },
1983 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1985 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1986 return (archi_table
[i
].version
);
1992 /********************************************************************
1993 * _spoolss_deleteprinterdriver
1994 ********************************************************************/
1996 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
, SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
2000 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2001 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2004 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2005 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2007 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2008 and not a printer admin, then fail */
2010 if ( (p
->pipe_user
.ut
.uid
!= 0)
2011 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2012 && !token_contains_name_in_list(
2013 uidtoname(p
->pipe_user
.ut
.uid
), NULL
,
2014 NULL
, p
->pipe_user
.nt_user_token
,
2015 lp_printer_admin(-1)) )
2017 return WERR_ACCESS_DENIED
;
2020 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2021 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2023 /* check that we have a valid driver name first */
2025 if ((version
=get_version_id(arch
)) == -1)
2026 return WERR_INVALID_ENVIRONMENT
;
2029 ZERO_STRUCT(info_win2k
);
2031 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
2033 /* try for Win2k driver if "Windows NT x86" */
2035 if ( version
== 2 ) {
2037 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2038 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2042 /* otherwise it was a failure */
2044 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2050 if (printer_driver_in_use(info
.info_3
)) {
2051 status
= WERR_PRINTER_DRIVER_IN_USE
;
2057 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2059 /* if we get to here, we now have 2 driver info structures to remove */
2060 /* remove the Win2k driver first*/
2062 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, False
);
2063 free_a_printer_driver( info_win2k
, 3 );
2065 /* this should not have failed---if it did, report to client */
2066 if ( !W_ERROR_IS_OK(status_win2k
) )
2068 status
= status_win2k
;
2074 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, False
);
2076 /* if at least one of the deletes succeeded return OK */
2078 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2082 free_a_printer_driver( info
, 3 );
2087 /********************************************************************
2088 * spoolss_deleteprinterdriverex
2089 ********************************************************************/
2091 WERROR
_spoolss_deleteprinterdriverex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVEREX
*q_u
, SPOOL_R_DELETEPRINTERDRIVEREX
*r_u
)
2095 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2096 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2098 uint32 flags
= q_u
->delete_flags
;
2101 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2102 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2104 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2105 and not a printer admin, then fail */
2107 if ( (p
->pipe_user
.ut
.uid
!= 0)
2108 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2109 && !token_contains_name_in_list(
2110 uidtoname(p
->pipe_user
.ut
.uid
), NULL
, NULL
,
2111 p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2113 return WERR_ACCESS_DENIED
;
2116 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2117 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2119 /* check that we have a valid driver name first */
2120 if ((version
=get_version_id(arch
)) == -1) {
2121 /* this is what NT returns */
2122 return WERR_INVALID_ENVIRONMENT
;
2125 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
2126 version
= q_u
->version
;
2129 ZERO_STRUCT(info_win2k
);
2131 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
2133 if ( !W_ERROR_IS_OK(status
) )
2136 * if the client asked for a specific version,
2137 * or this is something other than Windows NT x86,
2141 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2144 /* try for Win2k driver if "Windows NT x86" */
2147 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2148 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2153 if ( printer_driver_in_use(info
.info_3
) ) {
2154 status
= WERR_PRINTER_DRIVER_IN_USE
;
2159 * we have a couple of cases to consider.
2160 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2161 * then the delete should fail if **any** files overlap with
2163 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2164 * non-overlapping files
2165 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2166 * is set, the do not delete any files
2167 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2170 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2172 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2174 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2175 /* no idea of the correct error here */
2176 status
= WERR_ACCESS_DENIED
;
2181 /* also check for W32X86/3 if necessary; maybe we already have? */
2183 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2184 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2187 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2188 /* no idea of the correct error here */
2189 free_a_printer_driver( info_win2k
, 3 );
2190 status
= WERR_ACCESS_DENIED
;
2194 /* if we get to here, we now have 2 driver info structures to remove */
2195 /* remove the Win2k driver first*/
2197 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, delete_files
);
2198 free_a_printer_driver( info_win2k
, 3 );
2200 /* this should not have failed---if it did, report to client */
2202 if ( !W_ERROR_IS_OK(status_win2k
) )
2207 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, delete_files
);
2209 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2212 free_a_printer_driver( info
, 3 );
2218 /****************************************************************************
2219 Internal routine for retreiving printerdata
2220 ***************************************************************************/
2222 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2223 const char *key
, const char *value
, uint32
*type
, uint8
**data
,
2224 uint32
*needed
, uint32 in_size
)
2226 REGISTRY_VALUE
*val
;
2230 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2231 return WERR_BADFILE
;
2233 *type
= regval_type( val
);
2235 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2237 size
= regval_size( val
);
2239 /* copy the min(in_size, len) */
2242 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2244 /* special case for 0 length values */
2246 if ( (*data
= (uint8
*)TALLOC_MEMDUP(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2250 if ( (*data
= (uint8
*)TALLOC_ZERO(ctx
, in_size
)) == NULL
)
2259 DEBUG(5,("get_printer_dataex: copy done\n"));
2264 /****************************************************************************
2265 Internal routine for removing printerdata
2266 ***************************************************************************/
2268 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2270 return delete_printer_data( printer
->info_2
, key
, value
);
2273 /****************************************************************************
2274 Internal routine for storing printerdata
2275 ***************************************************************************/
2277 WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
,
2278 uint32 type
, uint8
*data
, int real_len
)
2280 /* the registry objects enforce uniqueness based on value name */
2282 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2285 /********************************************************************
2286 GetPrinterData on a printer server Handle.
2287 ********************************************************************/
2289 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2293 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2295 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2297 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2299 SIVAL(*data
, 0, 0x00);
2304 if (!StrCaseCmp(value
, "BeepEnabled")) {
2306 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2308 SIVAL(*data
, 0, 0x00);
2313 if (!StrCaseCmp(value
, "EventLog")) {
2315 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2317 /* formally was 0x1b */
2318 SIVAL(*data
, 0, 0x0);
2323 if (!StrCaseCmp(value
, "NetPopup")) {
2325 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2327 SIVAL(*data
, 0, 0x00);
2332 if (!StrCaseCmp(value
, "MajorVersion")) {
2334 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2337 /* Windows NT 4.0 seems to not allow uploading of drivers
2338 to a server that reports 0x3 as the MajorVersion.
2339 need to investigate more how Win2k gets around this .
2342 if ( RA_WINNT
== get_remote_arch() )
2351 if (!StrCaseCmp(value
, "MinorVersion")) {
2353 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2361 * uint32 size = 0x114
2363 * uint32 minor = [0|1]
2364 * uint32 build = [2195|2600]
2365 * extra unicode string = e.g. "Service Pack 3"
2367 if (!StrCaseCmp(value
, "OSVersion")) {
2371 if ( !(*data
= TALLOC_ZERO_ARRAY(ctx
, uint8
, (*needed
> in_size
) ? *needed
:in_size
)) )
2374 SIVAL(*data
, 0, *needed
); /* size */
2375 SIVAL(*data
, 4, 5); /* Windows 2000 == 5.0 */
2377 SIVAL(*data
, 12, 2195); /* build */
2379 /* leave extra string empty */
2385 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2386 const char *string
="C:\\PRINTERS";
2388 *needed
= 2*(strlen(string
)+1);
2389 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2391 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2393 /* it's done by hand ready to go on the wire */
2394 for (i
=0; i
<strlen(string
); i
++) {
2395 (*data
)[2*i
]=string
[i
];
2396 (*data
)[2*i
+1]='\0';
2401 if (!StrCaseCmp(value
, "Architecture")) {
2402 const char *string
="Windows NT x86";
2404 *needed
= 2*(strlen(string
)+1);
2405 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2407 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2408 for (i
=0; i
<strlen(string
); i
++) {
2409 (*data
)[2*i
]=string
[i
];
2410 (*data
)[2*i
+1]='\0';
2415 if (!StrCaseCmp(value
, "DsPresent")) {
2417 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2420 /* only show the publish check box if we are a
2421 memeber of a AD domain */
2423 if ( lp_security() == SEC_ADS
)
2424 SIVAL(*data
, 0, 0x01);
2426 SIVAL(*data
, 0, 0x00);
2432 if (!StrCaseCmp(value
, "DNSMachineName")) {
2433 const char *hostname
= get_mydnsfullname();
2436 return WERR_BADFILE
;
2438 *needed
= 2*(strlen(hostname
)+1);
2439 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2441 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2442 for (i
=0; i
<strlen(hostname
); i
++) {
2443 (*data
)[2*i
]=hostname
[i
];
2444 (*data
)[2*i
+1]='\0';
2450 return WERR_BADFILE
;
2453 /********************************************************************
2454 * spoolss_getprinterdata
2455 ********************************************************************/
2457 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2459 POLICY_HND
*handle
= &q_u
->handle
;
2460 UNISTR2
*valuename
= &q_u
->valuename
;
2461 uint32 in_size
= q_u
->size
;
2462 uint32
*type
= &r_u
->type
;
2463 uint32
*out_size
= &r_u
->size
;
2464 uint8
**data
= &r_u
->data
;
2465 uint32
*needed
= &r_u
->needed
;
2468 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2469 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2473 * Reminder: when it's a string, the length is in BYTES
2474 * even if UNICODE is negociated.
2479 *out_size
= in_size
;
2481 /* in case of problem, return some default values */
2486 DEBUG(4,("_spoolss_getprinterdata\n"));
2489 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2490 status
= WERR_BADFID
;
2494 unistr2_to_ascii(value
, valuename
, sizeof(value
));
2496 if ( Printer
->printer_type
== SPLHND_SERVER
)
2497 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2500 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) ) {
2501 status
= WERR_BADFID
;
2505 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2506 if ( !W_ERROR_IS_OK(status
) )
2509 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2511 if ( strequal(value
, "ChangeId") ) {
2513 *needed
= sizeof(uint32
);
2514 if ( (*data
= (uint8
*)TALLOC(p
->mem_ctx
, sizeof(uint32
))) == NULL
) {
2515 status
= WERR_NOMEM
;
2518 SIVAL( *data
, 0, printer
->info_2
->changeid
);
2522 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2525 if (*needed
> *out_size
)
2526 status
= WERR_MORE_DATA
;
2529 if ( !W_ERROR_IS_OK(status
) )
2531 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status
),*out_size
));
2533 /* reply this param doesn't exist */
2536 if((*data
=(uint8
*)TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint8
, *out_size
)) == NULL
) {
2538 free_a_printer( &printer
, 2 );
2546 /* cleanup & exit */
2549 free_a_printer( &printer
, 2 );
2554 /*********************************************************
2555 Connect to the client machine.
2556 **********************************************************/
2558 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2559 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2562 struct cli_state
*the_cli
;
2563 struct sockaddr_storage rm_addr
;
2565 if ( is_zero_addr(client_ss
) ) {
2566 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20) ) {
2567 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2571 if (ismyaddr(&rm_addr
)) {
2572 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2576 char addr
[INET6_ADDRSTRLEN
];
2577 rm_addr
= *client_ss
;
2578 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2579 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2583 /* setup the connection */
2585 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2586 &rm_addr
, 0, "IPC$", "IPC",
2590 0, lp_client_signing(), NULL
);
2592 if ( !NT_STATUS_IS_OK( ret
) ) {
2593 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2598 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2599 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2600 cli_shutdown(the_cli
);
2605 * Ok - we have an anonymous connection to the IPC$ share.
2606 * Now start the NT Domain stuff :-).
2609 if ( !(*pp_pipe
= cli_rpc_pipe_open_noauth(the_cli
, PI_SPOOLSS
, &ret
)) ) {
2610 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2611 remote_machine
, nt_errstr(ret
)));
2612 cli_shutdown(the_cli
);
2619 /***************************************************************************
2620 Connect to the client.
2621 ****************************************************************************/
2623 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2624 uint32 localprinter
, uint32 type
,
2625 POLICY_HND
*handle
, struct sockaddr_storage
*client_ss
)
2630 * If it's the first connection, contact the client
2631 * and connect to the IPC$ share anonymously
2633 if (smb_connections
==0) {
2634 fstring unix_printer
;
2636 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2638 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2641 messaging_register(smbd_messaging_context(), NULL
,
2642 MSG_PRINTER_NOTIFY2
,
2643 receive_notify2_message_list
);
2644 /* Tell the connections db we're now interested in printer
2645 * notify messages. */
2646 register_message_flags( True
, FLAG_MSG_PRINT_NOTIFY
);
2650 * Tell the specific printing tdb we want messages for this printer
2651 * by registering our PID.
2654 if (!print_notify_register_pid(snum
))
2655 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2659 result
= rpccli_spoolss_reply_open_printer(notify_cli_pipe
,
2666 if (!W_ERROR_IS_OK(result
))
2667 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2668 dos_errstr(result
)));
2670 return (W_ERROR_IS_OK(result
));
2673 /********************************************************************
2675 * ReplyFindFirstPrinterChangeNotifyEx
2677 * before replying OK: status=0 a rpc call is made to the workstation
2678 * asking ReplyOpenPrinter
2680 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2681 * called from api_spoolss_rffpcnex
2682 ********************************************************************/
2684 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
2686 POLICY_HND
*handle
= &q_u
->handle
;
2687 uint32 flags
= q_u
->flags
;
2688 uint32 options
= q_u
->options
;
2689 UNISTR2
*localmachine
= &q_u
->localmachine
;
2690 uint32 printerlocal
= q_u
->printerlocal
;
2692 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
2693 struct sockaddr_storage client_ss
;
2695 /* store the notify value in the printer struct */
2697 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2700 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2704 Printer
->notify
.flags
=flags
;
2705 Printer
->notify
.options
=options
;
2706 Printer
->notify
.printerlocal
=printerlocal
;
2708 if (Printer
->notify
.option
)
2709 free_spool_notify_option(&Printer
->notify
.option
);
2711 Printer
->notify
.option
=dup_spool_notify_option(option
);
2713 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
,
2714 sizeof(Printer
->notify
.localmachine
));
2716 /* Connect to the client machine and send a ReplyOpenPrinter */
2718 if ( Printer
->printer_type
== SPLHND_SERVER
)
2720 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2721 !get_printer_snum(p
, handle
, &snum
, NULL
) )
2724 if (!interpret_string_addr(&client_ss
,
2725 p
->conn
->client_address
,
2727 return WERR_SERVER_UNAVAILABLE
;
2730 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2731 Printer
->notify
.printerlocal
, 1,
2732 &Printer
->notify
.client_hnd
, &client_ss
))
2733 return WERR_SERVER_UNAVAILABLE
;
2735 Printer
->notify
.client_connected
=True
;
2740 /*******************************************************************
2741 * fill a notify_info_data with the servername
2742 ********************************************************************/
2744 void spoolss_notify_server_name(int snum
,
2745 SPOOL_NOTIFY_INFO_DATA
*data
,
2746 print_queue_struct
*queue
,
2747 NT_PRINTER_INFO_LEVEL
*printer
,
2748 TALLOC_CTX
*mem_ctx
)
2750 smb_ucs2_t
*temp
= NULL
;
2753 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->servername
);
2754 if (len
== (uint32
)-1) {
2758 data
->notify_data
.data
.length
= len
;
2760 data
->notify_data
.data
.string
= (uint16
*)temp
;
2762 data
->notify_data
.data
.string
= NULL
;
2766 /*******************************************************************
2767 * fill a notify_info_data with the printername (not including the servername).
2768 ********************************************************************/
2770 void spoolss_notify_printer_name(int snum
,
2771 SPOOL_NOTIFY_INFO_DATA
*data
,
2772 print_queue_struct
*queue
,
2773 NT_PRINTER_INFO_LEVEL
*printer
,
2774 TALLOC_CTX
*mem_ctx
)
2776 smb_ucs2_t
*temp
= NULL
;
2779 /* the notify name should not contain the \\server\ part */
2780 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2783 p
= printer
->info_2
->printername
;
2788 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
2789 if (len
== (uint32
)-1) {
2793 data
->notify_data
.data
.length
= len
;
2795 data
->notify_data
.data
.string
= (uint16
*)temp
;
2797 data
->notify_data
.data
.string
= NULL
;
2801 /*******************************************************************
2802 * fill a notify_info_data with the servicename
2803 ********************************************************************/
2805 void spoolss_notify_share_name(int snum
,
2806 SPOOL_NOTIFY_INFO_DATA
*data
,
2807 print_queue_struct
*queue
,
2808 NT_PRINTER_INFO_LEVEL
*printer
,
2809 TALLOC_CTX
*mem_ctx
)
2811 smb_ucs2_t
*temp
= NULL
;
2814 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_servicename(snum
));
2815 if (len
== (uint32
)-1) {
2819 data
->notify_data
.data
.length
= len
;
2821 data
->notify_data
.data
.string
= (uint16
*)temp
;
2823 data
->notify_data
.data
.string
= NULL
;
2828 /*******************************************************************
2829 * fill a notify_info_data with the port name
2830 ********************************************************************/
2832 void spoolss_notify_port_name(int snum
,
2833 SPOOL_NOTIFY_INFO_DATA
*data
,
2834 print_queue_struct
*queue
,
2835 NT_PRINTER_INFO_LEVEL
*printer
,
2836 TALLOC_CTX
*mem_ctx
)
2838 smb_ucs2_t
*temp
= NULL
;
2841 /* even if it's strange, that's consistant in all the code */
2843 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->portname
);
2844 if (len
== (uint32
)-1) {
2848 data
->notify_data
.data
.length
= len
;
2850 data
->notify_data
.data
.string
= (uint16
*)temp
;
2852 data
->notify_data
.data
.string
= NULL
;
2856 /*******************************************************************
2857 * fill a notify_info_data with the printername
2858 * but it doesn't exist, have to see what to do
2859 ********************************************************************/
2861 void spoolss_notify_driver_name(int snum
,
2862 SPOOL_NOTIFY_INFO_DATA
*data
,
2863 print_queue_struct
*queue
,
2864 NT_PRINTER_INFO_LEVEL
*printer
,
2865 TALLOC_CTX
*mem_ctx
)
2867 smb_ucs2_t
*temp
= NULL
;
2870 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->drivername
);
2871 if (len
== (uint32
)-1) {
2875 data
->notify_data
.data
.length
= len
;
2877 data
->notify_data
.data
.string
= (uint16
*)temp
;
2879 data
->notify_data
.data
.string
= NULL
;
2883 /*******************************************************************
2884 * fill a notify_info_data with the comment
2885 ********************************************************************/
2887 void spoolss_notify_comment(int snum
,
2888 SPOOL_NOTIFY_INFO_DATA
*data
,
2889 print_queue_struct
*queue
,
2890 NT_PRINTER_INFO_LEVEL
*printer
,
2891 TALLOC_CTX
*mem_ctx
)
2893 smb_ucs2_t
*temp
= NULL
;
2896 if (*printer
->info_2
->comment
== '\0')
2897 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_comment(snum
));
2899 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->comment
);
2901 if (len
== (uint32
)-1) {
2904 data
->notify_data
.data
.length
= len
;
2906 data
->notify_data
.data
.string
= (uint16
*)temp
;
2908 data
->notify_data
.data
.string
= NULL
;
2912 /*******************************************************************
2913 * fill a notify_info_data with the comment
2914 * location = "Room 1, floor 2, building 3"
2915 ********************************************************************/
2917 void spoolss_notify_location(int snum
,
2918 SPOOL_NOTIFY_INFO_DATA
*data
,
2919 print_queue_struct
*queue
,
2920 NT_PRINTER_INFO_LEVEL
*printer
,
2921 TALLOC_CTX
*mem_ctx
)
2923 smb_ucs2_t
*temp
= NULL
;
2926 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->location
);
2927 if (len
== (uint32
)-1) {
2931 data
->notify_data
.data
.length
= len
;
2933 data
->notify_data
.data
.string
= (uint16
*)temp
;
2935 data
->notify_data
.data
.string
= NULL
;
2939 /*******************************************************************
2940 * fill a notify_info_data with the device mode
2941 * jfm:xxxx don't to it for know but that's a real problem !!!
2942 ********************************************************************/
2944 static void spoolss_notify_devmode(int snum
,
2945 SPOOL_NOTIFY_INFO_DATA
*data
,
2946 print_queue_struct
*queue
,
2947 NT_PRINTER_INFO_LEVEL
*printer
,
2948 TALLOC_CTX
*mem_ctx
)
2950 /* for a dummy implementation we have to zero the fields */
2951 data
->notify_data
.data
.length
= 0;
2952 data
->notify_data
.data
.string
= NULL
;
2955 /*******************************************************************
2956 * fill a notify_info_data with the separator file name
2957 ********************************************************************/
2959 void spoolss_notify_sepfile(int snum
,
2960 SPOOL_NOTIFY_INFO_DATA
*data
,
2961 print_queue_struct
*queue
,
2962 NT_PRINTER_INFO_LEVEL
*printer
,
2963 TALLOC_CTX
*mem_ctx
)
2965 smb_ucs2_t
*temp
= NULL
;
2968 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->sepfile
);
2969 if (len
== (uint32
)-1) {
2973 data
->notify_data
.data
.length
= len
;
2975 data
->notify_data
.data
.string
= (uint16
*)temp
;
2977 data
->notify_data
.data
.string
= NULL
;
2981 /*******************************************************************
2982 * fill a notify_info_data with the print processor
2983 * jfm:xxxx return always winprint to indicate we don't do anything to it
2984 ********************************************************************/
2986 void spoolss_notify_print_processor(int snum
,
2987 SPOOL_NOTIFY_INFO_DATA
*data
,
2988 print_queue_struct
*queue
,
2989 NT_PRINTER_INFO_LEVEL
*printer
,
2990 TALLOC_CTX
*mem_ctx
)
2992 smb_ucs2_t
*temp
= NULL
;
2995 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->printprocessor
);
2996 if (len
== (uint32
)-1) {
3000 data
->notify_data
.data
.length
= len
;
3002 data
->notify_data
.data
.string
= (uint16
*)temp
;
3004 data
->notify_data
.data
.string
= NULL
;
3008 /*******************************************************************
3009 * fill a notify_info_data with the print processor options
3010 * jfm:xxxx send an empty string
3011 ********************************************************************/
3013 void spoolss_notify_parameters(int snum
,
3014 SPOOL_NOTIFY_INFO_DATA
*data
,
3015 print_queue_struct
*queue
,
3016 NT_PRINTER_INFO_LEVEL
*printer
,
3017 TALLOC_CTX
*mem_ctx
)
3019 smb_ucs2_t
*temp
= NULL
;
3022 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->parameters
);
3023 if (len
== (uint32
)-1) {
3027 data
->notify_data
.data
.length
= len
;
3029 data
->notify_data
.data
.string
= (uint16
*)temp
;
3031 data
->notify_data
.data
.string
= NULL
;
3035 /*******************************************************************
3036 * fill a notify_info_data with the data type
3037 * jfm:xxxx always send RAW as data type
3038 ********************************************************************/
3040 void spoolss_notify_datatype(int snum
,
3041 SPOOL_NOTIFY_INFO_DATA
*data
,
3042 print_queue_struct
*queue
,
3043 NT_PRINTER_INFO_LEVEL
*printer
,
3044 TALLOC_CTX
*mem_ctx
)
3046 smb_ucs2_t
*temp
= NULL
;
3049 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->datatype
);
3050 if (len
== (uint32
)-1) {
3054 data
->notify_data
.data
.length
= len
;
3056 data
->notify_data
.data
.string
= (uint16
*)temp
;
3058 data
->notify_data
.data
.string
= NULL
;
3062 /*******************************************************************
3063 * fill a notify_info_data with the security descriptor
3064 * jfm:xxxx send an null pointer to say no security desc
3065 * have to implement security before !
3066 ********************************************************************/
3068 static void spoolss_notify_security_desc(int snum
,
3069 SPOOL_NOTIFY_INFO_DATA
*data
,
3070 print_queue_struct
*queue
,
3071 NT_PRINTER_INFO_LEVEL
*printer
,
3072 TALLOC_CTX
*mem_ctx
)
3074 data
->notify_data
.sd
.size
= printer
->info_2
->secdesc_buf
->sd_size
;
3075 data
->notify_data
.sd
.desc
= dup_sec_desc( mem_ctx
, printer
->info_2
->secdesc_buf
->sd
) ;
3078 /*******************************************************************
3079 * fill a notify_info_data with the attributes
3080 * jfm:xxxx a samba printer is always shared
3081 ********************************************************************/
3083 void spoolss_notify_attributes(int snum
,
3084 SPOOL_NOTIFY_INFO_DATA
*data
,
3085 print_queue_struct
*queue
,
3086 NT_PRINTER_INFO_LEVEL
*printer
,
3087 TALLOC_CTX
*mem_ctx
)
3089 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
3090 data
->notify_data
.value
[1] = 0;
3093 /*******************************************************************
3094 * fill a notify_info_data with the priority
3095 ********************************************************************/
3097 static void spoolss_notify_priority(int snum
,
3098 SPOOL_NOTIFY_INFO_DATA
*data
,
3099 print_queue_struct
*queue
,
3100 NT_PRINTER_INFO_LEVEL
*printer
,
3101 TALLOC_CTX
*mem_ctx
)
3103 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
3104 data
->notify_data
.value
[1] = 0;
3107 /*******************************************************************
3108 * fill a notify_info_data with the default priority
3109 ********************************************************************/
3111 static void spoolss_notify_default_priority(int snum
,
3112 SPOOL_NOTIFY_INFO_DATA
*data
,
3113 print_queue_struct
*queue
,
3114 NT_PRINTER_INFO_LEVEL
*printer
,
3115 TALLOC_CTX
*mem_ctx
)
3117 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
3118 data
->notify_data
.value
[1] = 0;
3121 /*******************************************************************
3122 * fill a notify_info_data with the start time
3123 ********************************************************************/
3125 static void spoolss_notify_start_time(int snum
,
3126 SPOOL_NOTIFY_INFO_DATA
*data
,
3127 print_queue_struct
*queue
,
3128 NT_PRINTER_INFO_LEVEL
*printer
,
3129 TALLOC_CTX
*mem_ctx
)
3131 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
3132 data
->notify_data
.value
[1] = 0;
3135 /*******************************************************************
3136 * fill a notify_info_data with the until time
3137 ********************************************************************/
3139 static void spoolss_notify_until_time(int snum
,
3140 SPOOL_NOTIFY_INFO_DATA
*data
,
3141 print_queue_struct
*queue
,
3142 NT_PRINTER_INFO_LEVEL
*printer
,
3143 TALLOC_CTX
*mem_ctx
)
3145 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
3146 data
->notify_data
.value
[1] = 0;
3149 /*******************************************************************
3150 * fill a notify_info_data with the status
3151 ********************************************************************/
3153 static void spoolss_notify_status(int snum
,
3154 SPOOL_NOTIFY_INFO_DATA
*data
,
3155 print_queue_struct
*queue
,
3156 NT_PRINTER_INFO_LEVEL
*printer
,
3157 TALLOC_CTX
*mem_ctx
)
3159 print_status_struct status
;
3161 print_queue_length(snum
, &status
);
3162 data
->notify_data
.value
[0]=(uint32
) status
.status
;
3163 data
->notify_data
.value
[1] = 0;
3166 /*******************************************************************
3167 * fill a notify_info_data with the number of jobs queued
3168 ********************************************************************/
3170 void spoolss_notify_cjobs(int snum
,
3171 SPOOL_NOTIFY_INFO_DATA
*data
,
3172 print_queue_struct
*queue
,
3173 NT_PRINTER_INFO_LEVEL
*printer
,
3174 TALLOC_CTX
*mem_ctx
)
3176 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
3177 data
->notify_data
.value
[1] = 0;
3180 /*******************************************************************
3181 * fill a notify_info_data with the average ppm
3182 ********************************************************************/
3184 static void spoolss_notify_average_ppm(int snum
,
3185 SPOOL_NOTIFY_INFO_DATA
*data
,
3186 print_queue_struct
*queue
,
3187 NT_PRINTER_INFO_LEVEL
*printer
,
3188 TALLOC_CTX
*mem_ctx
)
3190 /* always respond 8 pages per minutes */
3191 /* a little hard ! */
3192 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
3193 data
->notify_data
.value
[1] = 0;
3196 /*******************************************************************
3197 * fill a notify_info_data with username
3198 ********************************************************************/
3200 static void spoolss_notify_username(int snum
,
3201 SPOOL_NOTIFY_INFO_DATA
*data
,
3202 print_queue_struct
*queue
,
3203 NT_PRINTER_INFO_LEVEL
*printer
,
3204 TALLOC_CTX
*mem_ctx
)
3206 smb_ucs2_t
*temp
= NULL
;
3209 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_user
);
3210 if (len
== (uint32
)-1) {
3214 data
->notify_data
.data
.length
= len
;
3216 data
->notify_data
.data
.string
= (uint16
*)temp
;
3218 data
->notify_data
.data
.string
= NULL
;
3222 /*******************************************************************
3223 * fill a notify_info_data with job status
3224 ********************************************************************/
3226 static void spoolss_notify_job_status(int snum
,
3227 SPOOL_NOTIFY_INFO_DATA
*data
,
3228 print_queue_struct
*queue
,
3229 NT_PRINTER_INFO_LEVEL
*printer
,
3230 TALLOC_CTX
*mem_ctx
)
3232 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
3233 data
->notify_data
.value
[1] = 0;
3236 /*******************************************************************
3237 * fill a notify_info_data with job name
3238 ********************************************************************/
3240 static void spoolss_notify_job_name(int snum
,
3241 SPOOL_NOTIFY_INFO_DATA
*data
,
3242 print_queue_struct
*queue
,
3243 NT_PRINTER_INFO_LEVEL
*printer
,
3244 TALLOC_CTX
*mem_ctx
)
3246 smb_ucs2_t
*temp
= NULL
;
3249 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_file
);
3250 if (len
== (uint32
)-1) {
3254 data
->notify_data
.data
.length
= len
;
3256 data
->notify_data
.data
.string
= (uint16
*)temp
;
3258 data
->notify_data
.data
.string
= NULL
;
3262 /*******************************************************************
3263 * fill a notify_info_data with job status
3264 ********************************************************************/
3266 static void spoolss_notify_job_status_string(int snum
,
3267 SPOOL_NOTIFY_INFO_DATA
*data
,
3268 print_queue_struct
*queue
,
3269 NT_PRINTER_INFO_LEVEL
*printer
,
3270 TALLOC_CTX
*mem_ctx
)
3273 * Now we're returning job status codes we just return a "" here. JRA.
3277 smb_ucs2_t
*temp
= NULL
;
3280 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3283 switch (queue
->status
) {
3288 p
= ""; /* NT provides the paused string */
3297 #endif /* NO LONGER NEEDED. */
3299 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
3300 if (len
== (uint32
)-1) {
3304 data
->notify_data
.data
.length
= len
;
3306 data
->notify_data
.data
.string
= (uint16
*)temp
;
3308 data
->notify_data
.data
.string
= NULL
;
3312 /*******************************************************************
3313 * fill a notify_info_data with job time
3314 ********************************************************************/
3316 static void spoolss_notify_job_time(int snum
,
3317 SPOOL_NOTIFY_INFO_DATA
*data
,
3318 print_queue_struct
*queue
,
3319 NT_PRINTER_INFO_LEVEL
*printer
,
3320 TALLOC_CTX
*mem_ctx
)
3322 data
->notify_data
.value
[0]=0x0;
3323 data
->notify_data
.value
[1]=0;
3326 /*******************************************************************
3327 * fill a notify_info_data with job size
3328 ********************************************************************/
3330 static void spoolss_notify_job_size(int snum
,
3331 SPOOL_NOTIFY_INFO_DATA
*data
,
3332 print_queue_struct
*queue
,
3333 NT_PRINTER_INFO_LEVEL
*printer
,
3334 TALLOC_CTX
*mem_ctx
)
3336 data
->notify_data
.value
[0]=queue
->size
;
3337 data
->notify_data
.value
[1]=0;
3340 /*******************************************************************
3341 * fill a notify_info_data with page info
3342 ********************************************************************/
3343 static void spoolss_notify_total_pages(int snum
,
3344 SPOOL_NOTIFY_INFO_DATA
*data
,
3345 print_queue_struct
*queue
,
3346 NT_PRINTER_INFO_LEVEL
*printer
,
3347 TALLOC_CTX
*mem_ctx
)
3349 data
->notify_data
.value
[0]=queue
->page_count
;
3350 data
->notify_data
.value
[1]=0;
3353 /*******************************************************************
3354 * fill a notify_info_data with pages printed info.
3355 ********************************************************************/
3356 static void spoolss_notify_pages_printed(int snum
,
3357 SPOOL_NOTIFY_INFO_DATA
*data
,
3358 print_queue_struct
*queue
,
3359 NT_PRINTER_INFO_LEVEL
*printer
,
3360 TALLOC_CTX
*mem_ctx
)
3362 data
->notify_data
.value
[0]=0; /* Add code when back-end tracks this */
3363 data
->notify_data
.value
[1]=0;
3366 /*******************************************************************
3367 Fill a notify_info_data with job position.
3368 ********************************************************************/
3370 static void spoolss_notify_job_position(int snum
,
3371 SPOOL_NOTIFY_INFO_DATA
*data
,
3372 print_queue_struct
*queue
,
3373 NT_PRINTER_INFO_LEVEL
*printer
,
3374 TALLOC_CTX
*mem_ctx
)
3376 data
->notify_data
.value
[0]=queue
->job
;
3377 data
->notify_data
.value
[1]=0;
3380 /*******************************************************************
3381 Fill a notify_info_data with submitted time.
3382 ********************************************************************/
3384 static void spoolss_notify_submitted_time(int snum
,
3385 SPOOL_NOTIFY_INFO_DATA
*data
,
3386 print_queue_struct
*queue
,
3387 NT_PRINTER_INFO_LEVEL
*printer
,
3388 TALLOC_CTX
*mem_ctx
)
3395 t
=gmtime(&queue
->time
);
3397 len
= sizeof(SYSTEMTIME
);
3399 data
->notify_data
.data
.length
= len
;
3400 data
->notify_data
.data
.string
= (uint16
*)TALLOC(mem_ctx
, len
);
3402 if (!data
->notify_data
.data
.string
) {
3403 data
->notify_data
.data
.length
= 0;
3407 make_systemtime(&st
, t
);
3410 * Systemtime must be linearized as a set of UINT16's.
3411 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3414 p
= (char *)data
->notify_data
.data
.string
;
3415 SSVAL(p
, 0, st
.year
);
3416 SSVAL(p
, 2, st
.month
);
3417 SSVAL(p
, 4, st
.dayofweek
);
3418 SSVAL(p
, 6, st
.day
);
3419 SSVAL(p
, 8, st
.hour
);
3420 SSVAL(p
, 10, st
.minute
);
3421 SSVAL(p
, 12, st
.second
);
3422 SSVAL(p
, 14, st
.milliseconds
);
3425 struct s_notify_info_data_table
3431 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
3432 print_queue_struct
*queue
,
3433 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3436 /* A table describing the various print notification constants and
3437 whether the notification data is a pointer to a variable sized
3438 buffer, a one value uint32 or a two value uint32. */
3440 static const struct s_notify_info_data_table notify_info_data_table
[] =
3442 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3443 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3444 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING
, spoolss_notify_share_name
},
3445 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3446 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3447 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING
, spoolss_notify_comment
},
3448 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING
, spoolss_notify_location
},
3449 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3450 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING
, spoolss_notify_sepfile
},
3451 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3452 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3453 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3454 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC
, spoolss_notify_security_desc
},
3455 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE
, spoolss_notify_attributes
},
3456 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3457 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_default_priority
},
3458 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3459 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3460 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_status
},
3461 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER
, NULL
},
3462 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE
, spoolss_notify_cjobs
},
3463 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE
, spoolss_notify_average_ppm
},
3464 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER
, NULL
},
3465 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER
, NULL
},
3466 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER
, NULL
},
3467 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER
, NULL
},
3468 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3469 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3470 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3471 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3472 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3473 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3474 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3475 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3476 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3477 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3478 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_job_status
},
3479 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING
, spoolss_notify_job_status_string
},
3480 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER
, NULL
},
3481 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING
, spoolss_notify_job_name
},
3482 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3483 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE
, spoolss_notify_job_position
},
3484 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER
, spoolss_notify_submitted_time
},
3485 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3486 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3487 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_job_time
},
3488 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE
, spoolss_notify_total_pages
},
3489 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE
, spoolss_notify_pages_printed
},
3490 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE
, spoolss_notify_job_size
},
3491 { PRINT_TABLE_END
, 0x0, NULL
, 0x0, NULL
},
3494 /*******************************************************************
3495 Return the size of info_data structure.
3496 ********************************************************************/
3498 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
3502 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3503 if ( (notify_info_data_table
[i
].type
== type
)
3504 && (notify_info_data_table
[i
].field
== field
) ) {
3505 switch(notify_info_data_table
[i
].size
) {
3506 case NOTIFY_ONE_VALUE
:
3507 case NOTIFY_TWO_VALUE
:
3512 /* The only pointer notify data I have seen on
3513 the wire is the submitted time and this has
3514 the notify size set to 4. -tpot */
3516 case NOTIFY_POINTER
:
3519 case NOTIFY_SECDESC
:
3525 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3530 /*******************************************************************
3531 Return the type of notify_info_data.
3532 ********************************************************************/
3534 static uint32
type_of_notify_info_data(uint16 type
, uint16 field
)
3538 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3539 if (notify_info_data_table
[i
].type
== type
&&
3540 notify_info_data_table
[i
].field
== field
)
3541 return notify_info_data_table
[i
].size
;
3547 /****************************************************************************
3548 ****************************************************************************/
3550 static bool search_notify(uint16 type
, uint16 field
, int *value
)
3554 for (i
= 0; notify_info_data_table
[i
].type
!= PRINT_TABLE_END
; i
++) {
3555 if (notify_info_data_table
[i
].type
== type
&&
3556 notify_info_data_table
[i
].field
== field
&&
3557 notify_info_data_table
[i
].fn
!= NULL
) {
3566 /****************************************************************************
3567 ****************************************************************************/
3569 void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
3571 info_data
->type
= type
;
3572 info_data
->field
= field
;
3573 info_data
->reserved
= 0;
3575 info_data
->size
= size_of_notify_info_data(type
, field
);
3576 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
3581 /*******************************************************************
3583 * fill a notify_info struct with info asked
3585 ********************************************************************/
3587 static bool construct_notify_printer_info(Printer_entry
*print_hnd
, SPOOL_NOTIFY_INFO
*info
, int
3588 snum
, SPOOL_NOTIFY_OPTION_TYPE
3589 *option_type
, uint32 id
,
3590 TALLOC_CTX
*mem_ctx
)
3596 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3597 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3598 print_queue_struct
*queue
=NULL
;
3600 type
=option_type
->type
;
3602 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3603 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3604 option_type
->count
, lp_servicename(snum
)));
3606 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3609 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3610 field
= option_type
->fields
[field_num
];
3612 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3614 if (!search_notify(type
, field
, &j
) )
3617 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3618 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3619 free_a_printer(&printer
, 2);
3623 current_data
= &info
->data
[info
->count
];
3625 construct_info_data(current_data
, type
, field
, id
);
3627 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3628 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3630 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3636 free_a_printer(&printer
, 2);
3640 /*******************************************************************
3642 * fill a notify_info struct with info asked
3644 ********************************************************************/
3646 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3647 SPOOL_NOTIFY_INFO
*info
,
3648 NT_PRINTER_INFO_LEVEL
*printer
,
3649 int snum
, SPOOL_NOTIFY_OPTION_TYPE
3650 *option_type
, uint32 id
,
3651 TALLOC_CTX
*mem_ctx
)
3657 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3659 DEBUG(4,("construct_notify_jobs_info\n"));
3661 type
= option_type
->type
;
3663 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3664 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3665 option_type
->count
));
3667 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3668 field
= option_type
->fields
[field_num
];
3670 if (!search_notify(type
, field
, &j
) )
3673 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3674 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3678 current_data
=&(info
->data
[info
->count
]);
3680 construct_info_data(current_data
, type
, field
, id
);
3681 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3690 * JFM: The enumeration is not that simple, it's even non obvious.
3692 * let's take an example: I want to monitor the PRINTER SERVER for
3693 * the printer's name and the number of jobs currently queued.
3694 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3695 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3697 * I have 3 printers on the back of my server.
3699 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3702 * 1 printer 1 name 1
3703 * 2 printer 1 cjob 1
3704 * 3 printer 2 name 2
3705 * 4 printer 2 cjob 2
3706 * 5 printer 3 name 3
3707 * 6 printer 3 name 3
3709 * that's the print server case, the printer case is even worse.
3712 /*******************************************************************
3714 * enumerate all printers on the printserver
3715 * fill a notify_info struct with info asked
3717 ********************************************************************/
3719 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
3720 SPOOL_NOTIFY_INFO
*info
,
3721 TALLOC_CTX
*mem_ctx
)
3724 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3725 int n_services
=lp_numservices();
3727 SPOOL_NOTIFY_OPTION
*option
;
3728 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3730 DEBUG(4,("printserver_notify_info\n"));
3735 option
=Printer
->notify
.option
;
3740 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3741 sending a ffpcn() request first */
3746 for (i
=0; i
<option
->count
; i
++) {
3747 option_type
=&(option
->ctr
.type
[i
]);
3749 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
3752 for (snum
=0; snum
<n_services
; snum
++)
3754 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3755 construct_notify_printer_info ( Printer
, info
, snum
, option_type
, snum
, mem_ctx
);
3761 * Debugging information, don't delete.
3764 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3765 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3766 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3768 for (i
=0; i
<info
->count
; i
++) {
3769 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3770 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3771 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3778 /*******************************************************************
3780 * fill a notify_info struct with info asked
3782 ********************************************************************/
3784 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
3785 TALLOC_CTX
*mem_ctx
)
3788 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3791 SPOOL_NOTIFY_OPTION
*option
;
3792 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3794 print_queue_struct
*queue
=NULL
;
3795 print_status_struct status
;
3797 DEBUG(4,("printer_notify_info\n"));
3802 option
=Printer
->notify
.option
;
3808 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3809 sending a ffpcn() request first */
3814 get_printer_snum(p
, hnd
, &snum
, NULL
);
3816 for (i
=0; i
<option
->count
; i
++) {
3817 option_type
=&option
->ctr
.type
[i
];
3819 switch ( option_type
->type
) {
3820 case PRINTER_NOTIFY_TYPE
:
3821 if(construct_notify_printer_info(Printer
, info
, snum
,
3827 case JOB_NOTIFY_TYPE
: {
3828 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3830 count
= print_queue_status(snum
, &queue
, &status
);
3832 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3835 for (j
=0; j
<count
; j
++) {
3836 construct_notify_jobs_info(&queue
[j
], info
,
3843 free_a_printer(&printer
, 2);
3853 * Debugging information, don't delete.
3856 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3857 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3858 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3860 for (i=0; i<info->count; i++) {
3861 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3862 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3863 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3869 /********************************************************************
3871 ********************************************************************/
3873 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
3875 POLICY_HND
*handle
= &q_u
->handle
;
3876 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
3878 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
3879 WERROR result
= WERR_BADFID
;
3881 /* we always have a NOTIFY_INFO struct */
3885 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3886 OUR_HANDLE(handle
)));
3890 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3893 * We are now using the change value, and
3894 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3895 * I don't have a global notification system, I'm sending back all the
3896 * informations even when _NOTHING_ has changed.
3899 /* We need to keep track of the change value to send back in
3900 RRPCN replies otherwise our updates are ignored. */
3902 Printer
->notify
.fnpcn
= True
;
3904 if (Printer
->notify
.client_connected
) {
3905 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u
->change
));
3906 Printer
->notify
.change
= q_u
->change
;
3909 /* just ignore the SPOOL_NOTIFY_OPTION */
3911 switch (Printer
->printer_type
) {
3913 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
3916 case SPLHND_PRINTER
:
3917 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
3921 Printer
->notify
.fnpcn
= False
;
3927 /********************************************************************
3928 * construct_printer_info_0
3929 * fill a printer_info_0 struct
3930 ********************************************************************/
3932 static bool construct_printer_info_0(Printer_entry
*print_hnd
, PRINTER_INFO_0
*printer
, int snum
)
3934 char *chaine
= NULL
;
3936 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3937 counter_printer_0
*session_counter
;
3938 uint32 global_counter
;
3941 print_status_struct status
;
3942 TALLOC_CTX
*ctx
= talloc_tos();
3944 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
3947 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
3949 chaine
= talloc_asprintf(ctx
, "\\\\%s", get_server_name(print_hnd
));
3951 free_a_printer(&ntprinter
,2);
3955 count
= print_queue_length(snum
, &status
);
3957 /* check if we already have a counter for this printer */
3958 for(session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3959 if (session_counter
->snum
== snum
)
3963 init_unistr(&printer
->servername
, chaine
);
3965 /* it's the first time, add it to the list */
3966 if (session_counter
==NULL
) {
3967 if((session_counter
=SMB_MALLOC_P(counter_printer_0
)) == NULL
) {
3968 free_a_printer(&ntprinter
, 2);
3971 ZERO_STRUCTP(session_counter
);
3972 session_counter
->snum
=snum
;
3973 session_counter
->counter
=0;
3974 DLIST_ADD(counter_list
, session_counter
);
3978 session_counter
->counter
++;
3981 * the global_counter should be stored in a TDB as it's common to all the clients
3982 * and should be zeroed on samba startup
3984 global_counter
=session_counter
->counter
;
3985 printer
->cjobs
= count
;
3986 printer
->total_jobs
= 0;
3987 printer
->total_bytes
= 0;
3989 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
3990 t
=gmtime(&setuptime
);
3992 printer
->year
= t
->tm_year
+1900;
3993 printer
->month
= t
->tm_mon
+1;
3994 printer
->dayofweek
= t
->tm_wday
;
3995 printer
->day
= t
->tm_mday
;
3996 printer
->hour
= t
->tm_hour
;
3997 printer
->minute
= t
->tm_min
;
3998 printer
->second
= t
->tm_sec
;
3999 printer
->milliseconds
= 0;
4001 printer
->global_counter
= global_counter
;
4002 printer
->total_pages
= 0;
4004 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4005 printer
->major_version
= 0x0005; /* NT 5 */
4006 printer
->build_version
= 0x0893; /* build 2195 */
4008 printer
->unknown7
= 0x1;
4009 printer
->unknown8
= 0x0;
4010 printer
->unknown9
= 0x0;
4011 printer
->session_counter
= session_counter
->counter
;
4012 printer
->unknown11
= 0x0;
4013 printer
->printer_errors
= 0x0; /* number of print failure */
4014 printer
->unknown13
= 0x0;
4015 printer
->unknown14
= 0x1;
4016 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
4017 printer
->unknown16
= 0x0;
4018 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
4019 printer
->unknown18
= 0x0;
4020 printer
->status
= nt_printq_status(status
.status
);
4021 printer
->unknown20
= 0x0;
4022 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4023 printer
->unknown22
= 0x0;
4024 printer
->unknown23
= 0x6; /* 6 ???*/
4025 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
4026 printer
->unknown25
= 0;
4027 printer
->unknown26
= 0;
4028 printer
->unknown27
= 0;
4029 printer
->unknown28
= 0;
4030 printer
->unknown29
= 0;
4032 free_a_printer(&ntprinter
,2);
4036 /********************************************************************
4037 * construct_printer_info_1
4038 * fill a printer_info_1 struct
4039 ********************************************************************/
4040 static bool construct_printer_info_1(Printer_entry
*print_hnd
, uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
4042 char *chaine
= NULL
;
4043 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4044 TALLOC_CTX
*ctx
= talloc_tos();
4046 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4049 printer
->flags
=flags
;
4051 if (*ntprinter
->info_2
->comment
== '\0') {
4052 init_unistr(&printer
->comment
, lp_comment(snum
));
4053 chaine
= talloc_asprintf(ctx
,
4054 "%s,%s,%s", ntprinter
->info_2
->printername
,
4055 ntprinter
->info_2
->drivername
, lp_comment(snum
));
4058 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4059 chaine
= talloc_asprintf(ctx
,
4060 "%s,%s,%s", ntprinter
->info_2
->printername
,
4061 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
4065 free_a_printer(&ntprinter
,2);
4069 init_unistr(&printer
->description
, chaine
);
4070 init_unistr(&printer
->name
, ntprinter
->info_2
->printername
);
4072 free_a_printer(&ntprinter
,2);
4077 /****************************************************************************
4078 Free a DEVMODE struct.
4079 ****************************************************************************/
4081 static void free_dev_mode(DEVICEMODE
*dev
)
4086 SAFE_FREE(dev
->dev_private
);
4091 /****************************************************************************
4092 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4093 should be valid upon entry
4094 ****************************************************************************/
4096 static bool convert_nt_devicemode( DEVICEMODE
*devmode
, NT_DEVICEMODE
*ntdevmode
)
4098 if ( !devmode
|| !ntdevmode
)
4101 init_unistr(&devmode
->devicename
, ntdevmode
->devicename
);
4103 init_unistr(&devmode
->formname
, ntdevmode
->formname
);
4105 devmode
->specversion
= ntdevmode
->specversion
;
4106 devmode
->driverversion
= ntdevmode
->driverversion
;
4107 devmode
->size
= ntdevmode
->size
;
4108 devmode
->driverextra
= ntdevmode
->driverextra
;
4109 devmode
->fields
= ntdevmode
->fields
;
4111 devmode
->orientation
= ntdevmode
->orientation
;
4112 devmode
->papersize
= ntdevmode
->papersize
;
4113 devmode
->paperlength
= ntdevmode
->paperlength
;
4114 devmode
->paperwidth
= ntdevmode
->paperwidth
;
4115 devmode
->scale
= ntdevmode
->scale
;
4116 devmode
->copies
= ntdevmode
->copies
;
4117 devmode
->defaultsource
= ntdevmode
->defaultsource
;
4118 devmode
->printquality
= ntdevmode
->printquality
;
4119 devmode
->color
= ntdevmode
->color
;
4120 devmode
->duplex
= ntdevmode
->duplex
;
4121 devmode
->yresolution
= ntdevmode
->yresolution
;
4122 devmode
->ttoption
= ntdevmode
->ttoption
;
4123 devmode
->collate
= ntdevmode
->collate
;
4124 devmode
->icmmethod
= ntdevmode
->icmmethod
;
4125 devmode
->icmintent
= ntdevmode
->icmintent
;
4126 devmode
->mediatype
= ntdevmode
->mediatype
;
4127 devmode
->dithertype
= ntdevmode
->dithertype
;
4129 if (ntdevmode
->nt_dev_private
!= NULL
) {
4130 if ((devmode
->dev_private
=(uint8
*)memdup(ntdevmode
->nt_dev_private
, ntdevmode
->driverextra
)) == NULL
)
4137 /****************************************************************************
4138 Create a DEVMODE struct. Returns malloced memory.
4139 ****************************************************************************/
4141 DEVICEMODE
*construct_dev_mode(const char *servicename
)
4143 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4144 DEVICEMODE
*devmode
= NULL
;
4146 DEBUG(7,("construct_dev_mode\n"));
4148 DEBUGADD(8,("getting printer characteristics\n"));
4150 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
4153 if ( !printer
->info_2
->devmode
) {
4154 DEBUG(5, ("BONG! There was no device mode!\n"));
4158 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) == NULL
) {
4159 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4163 ZERO_STRUCTP(devmode
);
4165 DEBUGADD(8,("loading DEVICEMODE\n"));
4167 if ( !convert_nt_devicemode( devmode
, printer
->info_2
->devmode
) ) {
4168 free_dev_mode( devmode
);
4173 free_a_printer(&printer
,2);
4178 /********************************************************************
4179 * construct_printer_info_2
4180 * fill a printer_info_2 struct
4181 ********************************************************************/
4183 static bool construct_printer_info_2(Printer_entry
*print_hnd
, PRINTER_INFO_2
*printer
, int snum
)
4186 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4188 print_status_struct status
;
4190 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4193 count
= print_queue_length(snum
, &status
);
4195 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4196 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4197 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
4198 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
4199 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
4201 if (*ntprinter
->info_2
->comment
== '\0')
4202 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
4204 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4206 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
4207 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
4208 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
4209 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
4210 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
4212 printer
->attributes
= ntprinter
->info_2
->attributes
;
4214 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
4215 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
4216 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
4217 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
4218 printer
->status
= nt_printq_status(status
.status
); /* status */
4219 printer
->cjobs
= count
; /* jobs */
4220 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
4222 if ( !(printer
->devmode
= construct_dev_mode(
4223 lp_const_servicename(snum
))) )
4224 DEBUG(8, ("Returning NULL Devicemode!\n"));
4226 printer
->secdesc
= NULL
;
4228 if ( ntprinter
->info_2
->secdesc_buf
4229 && ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0 )
4231 /* don't use talloc_steal() here unless you do a deep steal of all
4232 the SEC_DESC members */
4234 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4235 ntprinter
->info_2
->secdesc_buf
->sd
);
4238 free_a_printer(&ntprinter
, 2);
4243 /********************************************************************
4244 * construct_printer_info_3
4245 * fill a printer_info_3 struct
4246 ********************************************************************/
4248 static bool construct_printer_info_3(Printer_entry
*print_hnd
, PRINTER_INFO_3
**pp_printer
, int snum
)
4250 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4251 PRINTER_INFO_3
*printer
= NULL
;
4253 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4257 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_3
)) == NULL
) {
4258 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4259 free_a_printer(&ntprinter
, 2);
4263 ZERO_STRUCTP(printer
);
4265 /* These are the components of the SD we are returning. */
4267 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
4268 /* don't use talloc_steal() here unless you do a deep steal of all
4269 the SEC_DESC members */
4271 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4272 ntprinter
->info_2
->secdesc_buf
->sd
);
4275 free_a_printer(&ntprinter
, 2);
4277 *pp_printer
= printer
;
4281 /********************************************************************
4282 * construct_printer_info_4
4283 * fill a printer_info_4 struct
4284 ********************************************************************/
4286 static bool construct_printer_info_4(Printer_entry
*print_hnd
, PRINTER_INFO_4
*printer
, int snum
)
4288 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4290 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4293 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4294 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4295 printer
->attributes
= ntprinter
->info_2
->attributes
;
4297 free_a_printer(&ntprinter
, 2);
4301 /********************************************************************
4302 * construct_printer_info_5
4303 * fill a printer_info_5 struct
4304 ********************************************************************/
4306 static bool construct_printer_info_5(Printer_entry
*print_hnd
, PRINTER_INFO_5
*printer
, int snum
)
4308 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4310 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4313 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
4314 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
);
4315 printer
->attributes
= ntprinter
->info_2
->attributes
;
4317 /* these two are not used by NT+ according to MSDN */
4319 printer
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
4320 printer
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
4322 free_a_printer(&ntprinter
, 2);
4327 /********************************************************************
4328 * construct_printer_info_6
4329 * fill a printer_info_6 struct
4330 ********************************************************************/
4332 static bool construct_printer_info_6(Printer_entry
*print_hnd
,
4333 PRINTER_INFO_6
*printer
,
4336 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4338 print_status_struct status
;
4340 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2,
4341 lp_const_servicename(snum
))))
4344 count
= print_queue_length(snum
, &status
);
4346 printer
->status
= nt_printq_status(status
.status
);
4348 free_a_printer(&ntprinter
, 2);
4353 /********************************************************************
4354 * construct_printer_info_7
4355 * fill a printer_info_7 struct
4356 ********************************************************************/
4358 static bool construct_printer_info_7(Printer_entry
*print_hnd
, PRINTER_INFO_7
*printer
, int snum
)
4360 char *guid_str
= NULL
;
4363 if (is_printer_published(print_hnd
, snum
, &guid
)) {
4364 if (asprintf(&guid_str
, "{%s}",
4365 smb_uuid_string(talloc_tos(), guid
)) == -1) {
4368 strupper_m(guid_str
);
4369 init_unistr(&printer
->guid
, guid_str
);
4370 SAFE_FREE(guid_str
);
4371 printer
->action
= SPOOL_DS_PUBLISH
;
4373 init_unistr(&printer
->guid
, "");
4374 printer
->action
= SPOOL_DS_UNPUBLISH
;
4380 /********************************************************************
4381 Spoolss_enumprinters.
4382 ********************************************************************/
4384 static WERROR
enum_all_printers_info_1(uint32 flags
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4388 int n_services
=lp_numservices();
4389 PRINTER_INFO_1
*printers
=NULL
;
4390 PRINTER_INFO_1 current_prt
;
4391 WERROR result
= WERR_OK
;
4393 DEBUG(4,("enum_all_printers_info_1\n"));
4395 for (snum
=0; snum
<n_services
; snum
++) {
4396 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4397 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4399 if (construct_printer_info_1(NULL
, flags
, ¤t_prt
, snum
)) {
4400 if((printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_1
, *returned
+1)) == NULL
) {
4401 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4405 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4407 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4413 /* check the required size. */
4414 for (i
=0; i
<*returned
; i
++)
4415 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4417 if (*needed
> offered
) {
4418 result
= WERR_INSUFFICIENT_BUFFER
;
4422 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4423 result
= WERR_NOMEM
;
4427 /* fill the buffer with the structures */
4428 for (i
=0; i
<*returned
; i
++)
4429 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4434 SAFE_FREE(printers
);
4436 if ( !W_ERROR_IS_OK(result
) )
4442 /********************************************************************
4443 enum_all_printers_info_1_local.
4444 *********************************************************************/
4446 static WERROR
enum_all_printers_info_1_local(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4448 DEBUG(4,("enum_all_printers_info_1_local\n"));
4450 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4453 /********************************************************************
4454 enum_all_printers_info_1_name.
4455 *********************************************************************/
4457 static WERROR
enum_all_printers_info_1_name(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4461 DEBUG(4,("enum_all_printers_info_1_name\n"));
4463 if ((name
[0] == '\\') && (name
[1] == '\\'))
4466 if (is_myname_or_ipaddr(s
)) {
4467 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4470 return WERR_INVALID_NAME
;
4473 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4474 /********************************************************************
4475 enum_all_printers_info_1_remote.
4476 *********************************************************************/
4478 static WERROR
enum_all_printers_info_1_remote(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4480 PRINTER_INFO_1
*printer
;
4481 fstring printername
;
4484 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4485 WERROR result
= WERR_OK
;
4487 /* JFM: currently it's more a place holder than anything else.
4488 * In the spooler world there is a notion of server registration.
4489 * the print servers are registered on the PDC (in the same domain)
4491 * We should have a TDB here. The registration is done thru an
4492 * undocumented RPC call.
4495 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4500 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", name
);
4501 slprintf(desc
, sizeof(desc
)-1,"%s", name
);
4502 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4504 init_unistr(&printer
->description
, desc
);
4505 init_unistr(&printer
->name
, printername
);
4506 init_unistr(&printer
->comment
, comment
);
4507 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4509 /* check the required size. */
4510 *needed
+= spoolss_size_printer_info_1(printer
);
4512 if (*needed
> offered
) {
4513 result
= WERR_INSUFFICIENT_BUFFER
;
4517 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4518 result
= WERR_NOMEM
;
4522 /* fill the buffer with the structures */
4523 smb_io_printer_info_1("", buffer
, printer
, 0);
4529 if ( !W_ERROR_IS_OK(result
) )
4537 /********************************************************************
4538 enum_all_printers_info_1_network.
4539 *********************************************************************/
4541 static WERROR
enum_all_printers_info_1_network(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4545 DEBUG(4,("enum_all_printers_info_1_network\n"));
4547 /* If we respond to a enum_printers level 1 on our name with flags
4548 set to PRINTER_ENUM_REMOTE with a list of printers then these
4549 printers incorrectly appear in the APW browse list.
4550 Specifically the printers for the server appear at the workgroup
4551 level where all the other servers in the domain are
4552 listed. Windows responds to this call with a
4553 WERR_CAN_NOT_COMPLETE so we should do the same. */
4555 if (name
[0] == '\\' && name
[1] == '\\')
4558 if (is_myname_or_ipaddr(s
))
4559 return WERR_CAN_NOT_COMPLETE
;
4561 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
4564 /********************************************************************
4565 * api_spoolss_enumprinters
4567 * called from api_spoolss_enumprinters (see this to understand)
4568 ********************************************************************/
4570 static WERROR
enum_all_printers_info_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4574 int n_services
=lp_numservices();
4575 PRINTER_INFO_2
*printers
=NULL
;
4576 PRINTER_INFO_2 current_prt
;
4577 WERROR result
= WERR_OK
;
4581 for (snum
=0; snum
<n_services
; snum
++) {
4582 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4583 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4585 if (construct_printer_info_2(NULL
, ¤t_prt
, snum
)) {
4586 if ( !(printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_2
, *returned
+1)) ) {
4587 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4592 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
+ 1));
4594 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4601 /* check the required size. */
4602 for (i
=0; i
<*returned
; i
++)
4603 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4605 if (*needed
> offered
) {
4606 result
= WERR_INSUFFICIENT_BUFFER
;
4610 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4611 result
= WERR_NOMEM
;
4615 /* fill the buffer with the structures */
4616 for (i
=0; i
<*returned
; i
++)
4617 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4622 for (i
=0; i
<*returned
; i
++)
4623 free_devmode(printers
[i
].devmode
);
4625 SAFE_FREE(printers
);
4627 if ( !W_ERROR_IS_OK(result
) )
4633 /********************************************************************
4634 * handle enumeration of printers at level 1
4635 ********************************************************************/
4637 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4638 RPC_BUFFER
*buffer
, uint32 offered
,
4639 uint32
*needed
, uint32
*returned
)
4641 /* Not all the flags are equals */
4643 if (flags
& PRINTER_ENUM_LOCAL
)
4644 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4646 if (flags
& PRINTER_ENUM_NAME
)
4647 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4649 #if 0 /* JERRY - disabled for now */
4650 if (flags
& PRINTER_ENUM_REMOTE
)
4651 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4654 if (flags
& PRINTER_ENUM_NETWORK
)
4655 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4657 return WERR_OK
; /* NT4sp5 does that */
4660 /********************************************************************
4661 * handle enumeration of printers at level 2
4662 ********************************************************************/
4664 static WERROR
enumprinters_level2( uint32 flags
, fstring servername
,
4665 RPC_BUFFER
*buffer
, uint32 offered
,
4666 uint32
*needed
, uint32
*returned
)
4668 char *s
= servername
;
4670 if (flags
& PRINTER_ENUM_LOCAL
) {
4671 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4674 if (flags
& PRINTER_ENUM_NAME
) {
4675 if ((servername
[0] == '\\') && (servername
[1] == '\\'))
4677 if (is_myname_or_ipaddr(s
))
4678 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4680 return WERR_INVALID_NAME
;
4683 if (flags
& PRINTER_ENUM_REMOTE
)
4684 return WERR_UNKNOWN_LEVEL
;
4689 /********************************************************************
4690 * handle enumeration of printers at level 5
4691 ********************************************************************/
4693 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
4694 RPC_BUFFER
*buffer
, uint32 offered
,
4695 uint32
*needed
, uint32
*returned
)
4697 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4701 /********************************************************************
4702 * api_spoolss_enumprinters
4704 * called from api_spoolss_enumprinters (see this to understand)
4705 ********************************************************************/
4707 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4709 uint32 flags
= q_u
->flags
;
4710 UNISTR2
*servername
= &q_u
->servername
;
4711 uint32 level
= q_u
->level
;
4712 RPC_BUFFER
*buffer
= NULL
;
4713 uint32 offered
= q_u
->offered
;
4714 uint32
*needed
= &r_u
->needed
;
4715 uint32
*returned
= &r_u
->returned
;
4719 /* that's an [in out] buffer */
4721 if (!q_u
->buffer
&& (offered
!=0)) {
4722 return WERR_INVALID_PARAM
;
4725 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
4726 buffer
= r_u
->buffer
;
4728 DEBUG(4,("_spoolss_enumprinters\n"));
4735 * flags==PRINTER_ENUM_NAME
4736 * if name=="" then enumerates all printers
4737 * if name!="" then enumerate the printer
4738 * flags==PRINTER_ENUM_REMOTE
4739 * name is NULL, enumerate printers
4740 * Level 2: name!="" enumerates printers, name can't be NULL
4741 * Level 3: doesn't exist
4742 * Level 4: does a local registry lookup
4743 * Level 5: same as Level 2
4746 unistr2_to_ascii(name
, servername
, sizeof(name
));
4751 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4753 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4755 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4760 return WERR_UNKNOWN_LEVEL
;
4763 /****************************************************************************
4764 ****************************************************************************/
4766 static WERROR
getprinter_level_0(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4768 PRINTER_INFO_0
*printer
=NULL
;
4769 WERROR result
= WERR_OK
;
4771 if((printer
=SMB_MALLOC_P(PRINTER_INFO_0
)) == NULL
)
4774 construct_printer_info_0(print_hnd
, printer
, snum
);
4776 /* check the required size. */
4777 *needed
+= spoolss_size_printer_info_0(printer
);
4779 if (*needed
> offered
) {
4780 result
= WERR_INSUFFICIENT_BUFFER
;
4784 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4785 result
= WERR_NOMEM
;
4789 /* fill the buffer with the structures */
4790 smb_io_printer_info_0("", buffer
, printer
, 0);
4800 /****************************************************************************
4801 ****************************************************************************/
4803 static WERROR
getprinter_level_1(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4805 PRINTER_INFO_1
*printer
=NULL
;
4806 WERROR result
= WERR_OK
;
4808 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4811 construct_printer_info_1(print_hnd
, PRINTER_ENUM_ICON8
, printer
, snum
);
4813 /* check the required size. */
4814 *needed
+= spoolss_size_printer_info_1(printer
);
4816 if (*needed
> offered
) {
4817 result
= WERR_INSUFFICIENT_BUFFER
;
4821 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4822 result
= WERR_NOMEM
;
4826 /* fill the buffer with the structures */
4827 smb_io_printer_info_1("", buffer
, printer
, 0);
4836 /****************************************************************************
4837 ****************************************************************************/
4839 static WERROR
getprinter_level_2(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4841 PRINTER_INFO_2
*printer
=NULL
;
4842 WERROR result
= WERR_OK
;
4844 if((printer
=SMB_MALLOC_P(PRINTER_INFO_2
))==NULL
)
4847 construct_printer_info_2(print_hnd
, printer
, snum
);
4849 /* check the required size. */
4850 *needed
+= spoolss_size_printer_info_2(printer
);
4852 if (*needed
> offered
) {
4853 result
= WERR_INSUFFICIENT_BUFFER
;
4857 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4858 result
= WERR_NOMEM
;
4862 /* fill the buffer with the structures */
4863 if (!smb_io_printer_info_2("", buffer
, printer
, 0))
4864 result
= WERR_NOMEM
;
4868 free_printer_info_2(printer
);
4873 /****************************************************************************
4874 ****************************************************************************/
4876 static WERROR
getprinter_level_3(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4878 PRINTER_INFO_3
*printer
=NULL
;
4879 WERROR result
= WERR_OK
;
4881 if (!construct_printer_info_3(print_hnd
, &printer
, snum
))
4884 /* check the required size. */
4885 *needed
+= spoolss_size_printer_info_3(printer
);
4887 if (*needed
> offered
) {
4888 result
= WERR_INSUFFICIENT_BUFFER
;
4892 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4893 result
= WERR_NOMEM
;
4897 /* fill the buffer with the structures */
4898 smb_io_printer_info_3("", buffer
, printer
, 0);
4902 free_printer_info_3(printer
);
4907 /****************************************************************************
4908 ****************************************************************************/
4910 static WERROR
getprinter_level_4(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4912 PRINTER_INFO_4
*printer
=NULL
;
4913 WERROR result
= WERR_OK
;
4915 if((printer
=SMB_MALLOC_P(PRINTER_INFO_4
))==NULL
)
4918 if (!construct_printer_info_4(print_hnd
, printer
, snum
)) {
4923 /* check the required size. */
4924 *needed
+= spoolss_size_printer_info_4(printer
);
4926 if (*needed
> offered
) {
4927 result
= WERR_INSUFFICIENT_BUFFER
;
4931 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4932 result
= WERR_NOMEM
;
4936 /* fill the buffer with the structures */
4937 smb_io_printer_info_4("", buffer
, printer
, 0);
4941 free_printer_info_4(printer
);
4946 /****************************************************************************
4947 ****************************************************************************/
4949 static WERROR
getprinter_level_5(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4951 PRINTER_INFO_5
*printer
=NULL
;
4952 WERROR result
= WERR_OK
;
4954 if((printer
=SMB_MALLOC_P(PRINTER_INFO_5
))==NULL
)
4957 if (!construct_printer_info_5(print_hnd
, printer
, snum
)) {
4958 free_printer_info_5(printer
);
4962 /* check the required size. */
4963 *needed
+= spoolss_size_printer_info_5(printer
);
4965 if (*needed
> offered
) {
4966 result
= WERR_INSUFFICIENT_BUFFER
;
4970 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4971 result
= WERR_NOMEM
;
4975 /* fill the buffer with the structures */
4976 smb_io_printer_info_5("", buffer
, printer
, 0);
4980 free_printer_info_5(printer
);
4985 static WERROR
getprinter_level_6(Printer_entry
*print_hnd
,
4987 RPC_BUFFER
*buffer
, uint32 offered
,
4990 PRINTER_INFO_6
*printer
;
4991 WERROR result
= WERR_OK
;
4993 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_6
)) == NULL
) {
4997 if (!construct_printer_info_6(print_hnd
, printer
, snum
)) {
4998 free_printer_info_6(printer
);
5002 /* check the required size. */
5003 *needed
+= spoolss_size_printer_info_6(printer
);
5005 if (*needed
> offered
) {
5006 result
= WERR_INSUFFICIENT_BUFFER
;
5010 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5011 result
= WERR_NOMEM
;
5015 /* fill the buffer with the structures */
5016 smb_io_printer_info_6("", buffer
, printer
, 0);
5020 free_printer_info_6(printer
);
5025 static WERROR
getprinter_level_7(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5027 PRINTER_INFO_7
*printer
=NULL
;
5028 WERROR result
= WERR_OK
;
5030 if((printer
=SMB_MALLOC_P(PRINTER_INFO_7
))==NULL
)
5033 if (!construct_printer_info_7(print_hnd
, printer
, snum
))
5036 /* check the required size. */
5037 *needed
+= spoolss_size_printer_info_7(printer
);
5039 if (*needed
> offered
) {
5040 result
= WERR_INSUFFICIENT_BUFFER
;
5044 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5045 result
= WERR_NOMEM
;
5050 /* fill the buffer with the structures */
5051 smb_io_printer_info_7("", buffer
, printer
, 0);
5055 free_printer_info_7(printer
);
5060 /****************************************************************************
5061 ****************************************************************************/
5063 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
5065 POLICY_HND
*handle
= &q_u
->handle
;
5066 uint32 level
= q_u
->level
;
5067 RPC_BUFFER
*buffer
= NULL
;
5068 uint32 offered
= q_u
->offered
;
5069 uint32
*needed
= &r_u
->needed
;
5070 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
5074 /* that's an [in out] buffer */
5076 if (!q_u
->buffer
&& (offered
!=0)) {
5077 return WERR_INVALID_PARAM
;
5080 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5081 buffer
= r_u
->buffer
;
5085 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5090 return getprinter_level_0(Printer
, snum
, buffer
, offered
, needed
);
5092 return getprinter_level_1(Printer
, snum
, buffer
, offered
, needed
);
5094 return getprinter_level_2(Printer
, snum
, buffer
, offered
, needed
);
5096 return getprinter_level_3(Printer
, snum
, buffer
, offered
, needed
);
5098 return getprinter_level_4(Printer
, snum
, buffer
, offered
, needed
);
5100 return getprinter_level_5(Printer
, snum
, buffer
, offered
, needed
);
5102 return getprinter_level_6(Printer
, snum
, buffer
, offered
, needed
);
5104 return getprinter_level_7(Printer
, snum
, buffer
, offered
, needed
);
5106 return WERR_UNKNOWN_LEVEL
;
5109 /********************************************************************
5110 * fill a DRIVER_INFO_1 struct
5111 ********************************************************************/
5113 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
5115 init_unistr( &info
->name
, driver
.info_3
->name
);
5118 /********************************************************************
5119 * construct_printer_driver_info_1
5120 ********************************************************************/
5122 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5124 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5125 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5127 ZERO_STRUCT(driver
);
5129 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5130 return WERR_INVALID_PRINTER_NAME
;
5132 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5133 free_a_printer(&printer
, 2);
5134 return WERR_UNKNOWN_PRINTER_DRIVER
;
5137 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
5139 free_a_printer(&printer
,2);
5144 /********************************************************************
5145 * construct_printer_driver_info_2
5146 * fill a printer_info_2 struct
5147 ********************************************************************/
5149 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5151 TALLOC_CTX
*ctx
= talloc_tos();
5154 info
->version
=driver
.info_3
->cversion
;
5156 init_unistr( &info
->name
, driver
.info_3
->name
);
5157 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5160 if (strlen(driver
.info_3
->driverpath
)) {
5161 temp
= talloc_asprintf(ctx
,
5164 driver
.info_3
->driverpath
);
5165 init_unistr( &info
->driverpath
, temp
);
5167 init_unistr( &info
->driverpath
, "" );
5171 if (strlen(driver
.info_3
->datafile
)) {
5172 temp
= talloc_asprintf(ctx
,
5175 driver
.info_3
->datafile
);
5176 init_unistr( &info
->datafile
, temp
);
5178 init_unistr( &info
->datafile
, "" );
5181 if (strlen(driver
.info_3
->configfile
)) {
5182 temp
= talloc_asprintf(ctx
,
5185 driver
.info_3
->configfile
);
5186 init_unistr( &info
->configfile
, temp
);
5188 init_unistr( &info
->configfile
, "" );
5191 /********************************************************************
5192 * construct_printer_driver_info_2
5193 * fill a printer_info_2 struct
5194 ********************************************************************/
5196 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5198 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5199 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5201 ZERO_STRUCT(printer
);
5202 ZERO_STRUCT(driver
);
5204 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5205 return WERR_INVALID_PRINTER_NAME
;
5207 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5208 free_a_printer(&printer
, 2);
5209 return WERR_UNKNOWN_PRINTER_DRIVER
;
5212 fill_printer_driver_info_2(info
, driver
, servername
);
5214 free_a_printer(&printer
,2);
5219 /********************************************************************
5220 * copy a strings array and convert to UNICODE
5222 * convert an array of ascii string to a UNICODE string
5223 ********************************************************************/
5225 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, const char *servername
)
5231 TALLOC_CTX
*ctx
= talloc_tos();
5233 DEBUG(6,("init_unistr_array\n"));
5237 if ( !char_array
) {
5242 v
= ""; /* hack to handle null lists */
5245 /* hack to allow this to be used in places other than when generating
5246 the list of dependent files */
5250 line
= talloc_asprintf(ctx
,
5255 line
= talloc_strdup(ctx
, v
);
5259 SAFE_FREE(*uni_array
);
5262 DEBUGADD(6,("%d:%s:%lu\n", i
, line
, (unsigned long)strlen(line
)));
5264 /* add one extra unit16 for the second terminating NULL */
5266 if ( (*uni_array
=SMB_REALLOC_ARRAY(*uni_array
, uint16
, j
+1+strlen(line
)+2)) == NULL
) {
5267 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5274 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
5279 /* special case for ""; we need to add both NULL's here */
5281 (*uni_array
)[j
++]=0x0000;
5282 (*uni_array
)[j
]=0x0000;
5285 DEBUGADD(6,("last one:done\n"));
5287 /* return size of array in uint16's */
5292 /********************************************************************
5293 * construct_printer_info_3
5294 * fill a printer_info_3 struct
5295 ********************************************************************/
5297 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5300 TALLOC_CTX
*ctx
= talloc_tos();
5304 info
->version
=driver
.info_3
->cversion
;
5306 init_unistr( &info
->name
, driver
.info_3
->name
);
5307 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5309 if (strlen(driver
.info_3
->driverpath
)) {
5310 temp
= talloc_asprintf(ctx
,
5313 driver
.info_3
->driverpath
);
5314 init_unistr( &info
->driverpath
, temp
);
5316 init_unistr( &info
->driverpath
, "" );
5319 if (strlen(driver
.info_3
->datafile
)) {
5320 temp
= talloc_asprintf(ctx
,
5323 driver
.info_3
->datafile
);
5324 init_unistr( &info
->datafile
, temp
);
5326 init_unistr( &info
->datafile
, "" );
5329 if (strlen(driver
.info_3
->configfile
)) {
5330 temp
= talloc_asprintf(ctx
,
5333 driver
.info_3
->configfile
);
5334 init_unistr( &info
->configfile
, temp
);
5336 init_unistr( &info
->configfile
, "" );
5339 if (strlen(driver
.info_3
->helpfile
)) {
5340 temp
= talloc_asprintf(ctx
,
5343 driver
.info_3
->helpfile
);
5344 init_unistr( &info
->helpfile
, temp
);
5346 init_unistr( &info
->helpfile
, "" );
5349 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5350 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5352 info
->dependentfiles
=NULL
;
5353 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5356 /********************************************************************
5357 * construct_printer_info_3
5358 * fill a printer_info_3 struct
5359 ********************************************************************/
5361 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5363 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5364 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5366 ZERO_STRUCT(driver
);
5368 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5369 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5370 if (!W_ERROR_IS_OK(status
))
5371 return WERR_INVALID_PRINTER_NAME
;
5373 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5374 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5379 * I put this code in during testing. Helpful when commenting out the
5380 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5381 * as win2k always queries the driver using an infor level of 6.
5382 * I've left it in (but ifdef'd out) because I'll probably
5383 * use it in experimentation again in the future. --jerry 22/01/2002
5386 if (!W_ERROR_IS_OK(status
)) {
5388 * Is this a W2k client ?
5391 /* Yes - try again with a WinNT driver. */
5393 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5394 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5398 if (!W_ERROR_IS_OK(status
)) {
5399 free_a_printer(&printer
,2);
5400 return WERR_UNKNOWN_PRINTER_DRIVER
;
5408 fill_printer_driver_info_3(info
, driver
, servername
);
5410 free_a_printer(&printer
,2);
5415 /********************************************************************
5416 * construct_printer_info_6
5417 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5418 ********************************************************************/
5420 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5424 TALLOC_CTX
*ctx
= talloc_tos();
5427 memset(&nullstr
, '\0', sizeof(fstring
));
5429 info
->version
=driver
.info_3
->cversion
;
5431 init_unistr( &info
->name
, driver
.info_3
->name
);
5432 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5434 if (strlen(driver
.info_3
->driverpath
)) {
5435 temp
= talloc_asprintf(ctx
,
5438 driver
.info_3
->driverpath
);
5439 init_unistr( &info
->driverpath
, temp
);
5441 init_unistr( &info
->driverpath
, "" );
5444 if (strlen(driver
.info_3
->datafile
)) {
5445 temp
= talloc_asprintf(ctx
,
5448 driver
.info_3
->datafile
);
5449 init_unistr( &info
->datafile
, temp
);
5451 init_unistr( &info
->datafile
, "" );
5454 if (strlen(driver
.info_3
->configfile
)) {
5455 temp
= talloc_asprintf(ctx
,
5458 driver
.info_3
->configfile
);
5459 init_unistr( &info
->configfile
, temp
);
5461 init_unistr( &info
->configfile
, "" );
5464 if (strlen(driver
.info_3
->helpfile
)) {
5465 temp
= talloc_asprintf(ctx
,
5468 driver
.info_3
->helpfile
);
5469 init_unistr( &info
->helpfile
, temp
);
5471 init_unistr( &info
->helpfile
, "" );
5474 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5475 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5477 info
->dependentfiles
= NULL
;
5478 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5480 info
->previousdrivernames
=NULL
;
5481 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
5483 info
->driver_date
=0;
5486 info
->driver_version_low
=0;
5487 info
->driver_version_high
=0;
5489 init_unistr( &info
->mfgname
, "");
5490 init_unistr( &info
->oem_url
, "");
5491 init_unistr( &info
->hardware_id
, "");
5492 init_unistr( &info
->provider
, "");
5495 /********************************************************************
5496 * construct_printer_info_6
5497 * fill a printer_info_6 struct
5498 ********************************************************************/
5500 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
5501 fstring servername
, fstring architecture
, uint32 version
)
5503 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5504 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5507 ZERO_STRUCT(driver
);
5509 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5511 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5513 if (!W_ERROR_IS_OK(status
))
5514 return WERR_INVALID_PRINTER_NAME
;
5516 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5518 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5520 if (!W_ERROR_IS_OK(status
))
5523 * Is this a W2k client ?
5527 free_a_printer(&printer
,2);
5528 return WERR_UNKNOWN_PRINTER_DRIVER
;
5531 /* Yes - try again with a WinNT driver. */
5533 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5534 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5535 if (!W_ERROR_IS_OK(status
)) {
5536 free_a_printer(&printer
,2);
5537 return WERR_UNKNOWN_PRINTER_DRIVER
;
5541 fill_printer_driver_info_6(info
, driver
, servername
);
5543 free_a_printer(&printer
,2);
5544 free_a_printer_driver(driver
, 3);
5549 /****************************************************************************
5550 ****************************************************************************/
5552 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5554 SAFE_FREE(info
->dependentfiles
);
5557 /****************************************************************************
5558 ****************************************************************************/
5560 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5562 SAFE_FREE(info
->dependentfiles
);
5565 /****************************************************************************
5566 ****************************************************************************/
5568 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5570 DRIVER_INFO_1
*info
=NULL
;
5573 if((info
=SMB_MALLOC_P(DRIVER_INFO_1
)) == NULL
)
5576 result
= construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5577 if (!W_ERROR_IS_OK(result
))
5580 /* check the required size. */
5581 *needed
+= spoolss_size_printer_driver_info_1(info
);
5583 if (*needed
> offered
) {
5584 result
= WERR_INSUFFICIENT_BUFFER
;
5588 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5589 result
= WERR_NOMEM
;
5593 /* fill the buffer with the structures */
5594 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5603 /****************************************************************************
5604 ****************************************************************************/
5606 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5608 DRIVER_INFO_2
*info
=NULL
;
5611 if((info
=SMB_MALLOC_P(DRIVER_INFO_2
)) == NULL
)
5614 result
= construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5615 if (!W_ERROR_IS_OK(result
))
5618 /* check the required size. */
5619 *needed
+= spoolss_size_printer_driver_info_2(info
);
5621 if (*needed
> offered
) {
5622 result
= WERR_INSUFFICIENT_BUFFER
;
5626 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5627 result
= WERR_NOMEM
;
5631 /* fill the buffer with the structures */
5632 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5641 /****************************************************************************
5642 ****************************************************************************/
5644 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5651 result
= construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5652 if (!W_ERROR_IS_OK(result
))
5655 /* check the required size. */
5656 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5658 if (*needed
> offered
) {
5659 result
= WERR_INSUFFICIENT_BUFFER
;
5663 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5664 result
= WERR_NOMEM
;
5668 /* fill the buffer with the structures */
5669 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5672 free_printer_driver_info_3(&info
);
5677 /****************************************************************************
5678 ****************************************************************************/
5680 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5687 result
= construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5688 if (!W_ERROR_IS_OK(result
))
5691 /* check the required size. */
5692 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5694 if (*needed
> offered
) {
5695 result
= WERR_INSUFFICIENT_BUFFER
;
5699 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5700 result
= WERR_NOMEM
;
5704 /* fill the buffer with the structures */
5705 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5708 free_printer_driver_info_6(&info
);
5713 /****************************************************************************
5714 ****************************************************************************/
5716 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5718 POLICY_HND
*handle
= &q_u
->handle
;
5719 UNISTR2
*uni_arch
= &q_u
->architecture
;
5720 uint32 level
= q_u
->level
;
5721 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5722 RPC_BUFFER
*buffer
= NULL
;
5723 uint32 offered
= q_u
->offered
;
5724 uint32
*needed
= &r_u
->needed
;
5725 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5726 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5727 Printer_entry
*printer
;
5730 fstring architecture
;
5733 /* that's an [in out] buffer */
5735 if (!q_u
->buffer
&& (offered
!=0)) {
5736 return WERR_INVALID_PARAM
;
5739 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5740 buffer
= r_u
->buffer
;
5742 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5744 if ( !(printer
= find_printer_index_by_hnd( p
, handle
)) ) {
5745 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5746 return WERR_INVALID_PRINTER_NAME
;
5750 *servermajorversion
= 0;
5751 *serverminorversion
= 0;
5753 fstrcpy(servername
, get_server_name( printer
));
5754 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
));
5756 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5761 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5763 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5765 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5767 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5770 /* apparently this call is the equivalent of
5771 EnumPrinterDataEx() for the DsDriver key */
5776 return WERR_UNKNOWN_LEVEL
;
5779 /****************************************************************************
5780 ****************************************************************************/
5782 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
5784 POLICY_HND
*handle
= &q_u
->handle
;
5786 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5789 DEBUG(3,("Error in startpageprinter printer handle\n"));
5793 Printer
->page_started
=True
;
5797 /****************************************************************************
5798 ****************************************************************************/
5800 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
5802 POLICY_HND
*handle
= &q_u
->handle
;
5805 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5808 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle
)));
5812 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5815 Printer
->page_started
=False
;
5816 print_job_endpage(snum
, Printer
->jobid
);
5821 /********************************************************************
5822 * api_spoolss_getprinter
5823 * called from the spoolss dispatcher
5825 ********************************************************************/
5827 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
5829 POLICY_HND
*handle
= &q_u
->handle
;
5830 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
5831 uint32
*jobid
= &r_u
->jobid
;
5832 TALLOC_CTX
*ctx
= p
->mem_ctx
;
5833 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
5835 char *jobname
= NULL
;
5837 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5840 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5845 * a nice thing with NT is it doesn't listen to what you tell it.
5846 * when asked to send _only_ RAW datas, it tries to send datas
5849 * So I add checks like in NT Server ...
5852 if (info_1
->p_datatype
!= 0) {
5853 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
5854 if (strcmp(datatype
, "RAW") != 0) {
5856 return WERR_INVALID_DATATYPE
;
5860 /* get the share number of the printer */
5861 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5865 jobname
= unistr2_to_ascii_talloc(ctx
, &info_1
->docname
);
5867 Printer
->jobid
= print_job_start(&p
->pipe_user
, snum
, jobname
, Printer
->nt_devmode
);
5869 /* An error occured in print_job_start() so return an appropriate
5872 if (Printer
->jobid
== -1) {
5873 return map_werror_from_unix(errno
);
5876 Printer
->document_started
=True
;
5877 (*jobid
) = Printer
->jobid
;
5882 /********************************************************************
5883 * api_spoolss_getprinter
5884 * called from the spoolss dispatcher
5886 ********************************************************************/
5888 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
5890 POLICY_HND
*handle
= &q_u
->handle
;
5892 return _spoolss_enddocprinter_internal(p
, handle
);
5895 /****************************************************************************
5896 ****************************************************************************/
5898 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
5900 POLICY_HND
*handle
= &q_u
->handle
;
5901 uint32 buffer_size
= q_u
->buffer_size
;
5902 uint8
*buffer
= q_u
->buffer
;
5903 uint32
*buffer_written
= &q_u
->buffer_size2
;
5905 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5908 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5909 r_u
->buffer_written
= q_u
->buffer_size2
;
5913 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5916 (*buffer_written
) = (uint32
)print_job_write(snum
, Printer
->jobid
, (const char *)buffer
,
5917 (SMB_OFF_T
)-1, (size_t)buffer_size
);
5918 if (*buffer_written
== (uint32
)-1) {
5919 r_u
->buffer_written
= 0;
5920 if (errno
== ENOSPC
)
5921 return WERR_NO_SPOOL_SPACE
;
5923 return WERR_ACCESS_DENIED
;
5926 r_u
->buffer_written
= q_u
->buffer_size2
;
5931 /********************************************************************
5932 * api_spoolss_getprinter
5933 * called from the spoolss dispatcher
5935 ********************************************************************/
5937 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5941 WERROR errcode
= WERR_BADFUNC
;
5942 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5945 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5949 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5953 case PRINTER_CONTROL_PAUSE
:
5954 if (print_queue_pause(&p
->pipe_user
, snum
, &errcode
)) {
5958 case PRINTER_CONTROL_RESUME
:
5959 case PRINTER_CONTROL_UNPAUSE
:
5960 if (print_queue_resume(&p
->pipe_user
, snum
, &errcode
)) {
5964 case PRINTER_CONTROL_PURGE
:
5965 if (print_queue_purge(&p
->pipe_user
, snum
, &errcode
)) {
5970 return WERR_UNKNOWN_LEVEL
;
5976 /********************************************************************
5977 * api_spoolss_abortprinter
5978 * From MSDN: "Deletes printer's spool file if printer is configured
5980 ********************************************************************/
5982 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
5984 POLICY_HND
*handle
= &q_u
->handle
;
5985 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5987 WERROR errcode
= WERR_OK
;
5990 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5994 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5997 print_job_delete( &p
->pipe_user
, snum
, Printer
->jobid
, &errcode
);
6002 /********************************************************************
6003 * called by spoolss_api_setprinter
6004 * when updating a printer description
6005 ********************************************************************/
6007 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
6008 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6009 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
6011 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
6015 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6017 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
6018 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6019 OUR_HANDLE(handle
)));
6021 result
= WERR_BADFID
;
6026 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6027 result
= WERR_INVALID_PARAM
;
6031 /* Check the user has permissions to change the security
6032 descriptor. By experimentation with two NT machines, the user
6033 requires Full Access to the printer to change security
6036 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6037 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6038 result
= WERR_ACCESS_DENIED
;
6042 /* NT seems to like setting the security descriptor even though
6043 nothing may have actually changed. */
6045 if ( !nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
)) {
6046 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6047 result
= WERR_BADFID
;
6051 if (DEBUGLEVEL
>= 10) {
6055 the_acl
= old_secdesc_ctr
->sd
->dacl
;
6056 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6057 PRINTERNAME(snum
), the_acl
->num_aces
));
6059 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6060 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6061 &the_acl
->aces
[i
].trustee
),
6062 the_acl
->aces
[i
].access_mask
));
6065 the_acl
= secdesc_ctr
->sd
->dacl
;
6068 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6069 PRINTERNAME(snum
), the_acl
->num_aces
));
6071 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6072 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6073 &the_acl
->aces
[i
].trustee
),
6074 the_acl
->aces
[i
].access_mask
));
6077 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6081 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
6082 if (!new_secdesc_ctr
) {
6083 result
= WERR_NOMEM
;
6087 if (sec_desc_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
6092 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
6099 /********************************************************************
6100 Canonicalize printer info from a client
6102 ATTN: It does not matter what we set the servername to hear
6103 since we do the necessary work in get_a_printer() to set it to
6104 the correct value based on what the client sent in the
6105 _spoolss_open_printer_ex().
6106 ********************************************************************/
6108 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
6110 fstring printername
;
6113 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6114 "portname=%s drivername=%s comment=%s location=%s\n",
6115 info
->servername
, info
->printername
, info
->sharename
,
6116 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
6118 /* we force some elements to "correct" values */
6119 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
6120 fstrcpy(info
->sharename
, lp_servicename(snum
));
6122 /* check to see if we allow printername != sharename */
6124 if ( lp_force_printername(snum
) ) {
6125 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6126 global_myname(), info
->sharename
);
6129 /* make sure printername is in \\server\printername format */
6131 fstrcpy( printername
, info
->printername
);
6133 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
6134 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
6138 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6139 global_myname(), p
);
6142 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
6143 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
6150 /****************************************************************************
6151 ****************************************************************************/
6153 WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
6155 char *cmd
= lp_addport_cmd();
6156 char *command
= NULL
;
6159 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6160 bool is_print_op
= False
;
6163 return WERR_ACCESS_DENIED
;
6166 command
= talloc_asprintf(ctx
,
6167 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
6173 is_print_op
= user_has_privileges( token
, &se_printop
);
6175 DEBUG(10,("Running [%s]\n", command
));
6177 /********* BEGIN SePrintOperatorPrivilege **********/
6182 ret
= smbrun(command
, &fd
);
6187 /********* END SePrintOperatorPrivilege **********/
6189 DEBUGADD(10,("returned [%d]\n", ret
));
6191 TALLOC_FREE(command
);
6196 return WERR_ACCESS_DENIED
;
6202 /****************************************************************************
6203 ****************************************************************************/
6205 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
6207 char *cmd
= lp_addprinter_cmd();
6209 char *command
= NULL
;
6213 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6214 bool is_print_op
= False
;
6215 char *remote_machine
= talloc_strdup(ctx
, "%m");
6217 if (!remote_machine
) {
6220 remote_machine
= talloc_sub_basic(ctx
,
6221 current_user_info
.smb_name
,
6222 current_user_info
.domain
,
6224 if (!remote_machine
) {
6228 command
= talloc_asprintf(ctx
,
6229 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6230 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6231 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6232 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6238 is_print_op
= user_has_privileges( token
, &se_printop
);
6240 DEBUG(10,("Running [%s]\n", command
));
6242 /********* BEGIN SePrintOperatorPrivilege **********/
6247 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6248 /* Tell everyone we updated smb.conf. */
6249 message_send_all(smbd_messaging_context(),
6250 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6256 /********* END SePrintOperatorPrivilege **********/
6258 DEBUGADD(10,("returned [%d]\n", ret
));
6260 TALLOC_FREE(command
);
6261 TALLOC_FREE(remote_machine
);
6269 /* reload our services immediately */
6270 reload_services( False
);
6273 /* Get lines and convert them back to dos-codepage */
6274 qlines
= fd_lines_load(fd
, &numlines
, 0);
6275 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6278 /* Set the portname to what the script says the portname should be. */
6279 /* but don't require anything to be return from the script exit a good error code */
6282 /* Set the portname to what the script says the portname should be. */
6283 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6284 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6287 file_lines_free(qlines
);
6292 /********************************************************************
6293 * Called by spoolss_api_setprinter
6294 * when updating a printer description.
6295 ********************************************************************/
6297 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
6298 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6299 DEVICEMODE
*devmode
)
6302 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6303 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6308 DEBUG(8,("update_printer\n"));
6313 result
= WERR_BADFID
;
6317 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6318 result
= WERR_BADFID
;
6322 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6323 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6324 result
= WERR_BADFID
;
6328 DEBUGADD(8,("Converting info_2 struct\n"));
6331 * convert_printer_info converts the incoming
6332 * info from the client and overwrites the info
6333 * just read from the tdb in the pointer 'printer'.
6336 if (!convert_printer_info(info
, printer
, level
)) {
6337 result
= WERR_NOMEM
;
6342 /* we have a valid devmode
6343 convert it and link it*/
6345 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6346 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6347 &printer
->info_2
->devmode
)) {
6348 result
= WERR_NOMEM
;
6353 /* Do sanity check on the requested changes for Samba */
6355 if (!check_printer_ok(printer
->info_2
, snum
)) {
6356 result
= WERR_INVALID_PARAM
;
6360 /* FIXME!!! If the driver has changed we really should verify that
6361 it is installed before doing much else --jerry */
6363 /* Check calling user has permission to update printer description */
6365 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6366 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6367 result
= WERR_ACCESS_DENIED
;
6371 /* Call addprinter hook */
6372 /* Check changes to see if this is really needed */
6374 if ( *lp_addprinter_cmd()
6375 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6376 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6377 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6378 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6380 /* add_printer_hook() will call reload_services() */
6382 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
6383 result
= WERR_ACCESS_DENIED
;
6389 * When a *new* driver is bound to a printer, the drivername is used to
6390 * lookup previously saved driver initialization info, which is then
6391 * bound to the printer, simulating what happens in the Windows arch.
6393 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6395 if (!set_driver_init(printer
, 2))
6397 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6398 printer
->info_2
->drivername
));
6401 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6402 printer
->info_2
->drivername
));
6404 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6408 * flag which changes actually occured. This is a small subset of
6409 * all the possible changes. We also have to update things in the
6413 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6414 init_unistr2( &buffer
, printer
->info_2
->comment
, UNI_STR_TERMINATE
);
6415 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6416 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6418 notify_printer_comment(snum
, printer
->info_2
->comment
);
6421 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6422 init_unistr2( &buffer
, printer
->info_2
->sharename
, UNI_STR_TERMINATE
);
6423 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6424 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6426 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6429 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6432 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6435 pname
= printer
->info_2
->printername
;
6438 init_unistr2( &buffer
, pname
, UNI_STR_TERMINATE
);
6439 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6440 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6442 notify_printer_printername( snum
, pname
);
6445 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6446 init_unistr2( &buffer
, printer
->info_2
->portname
, UNI_STR_TERMINATE
);
6447 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6448 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6450 notify_printer_port(snum
, printer
->info_2
->portname
);
6453 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6454 init_unistr2( &buffer
, printer
->info_2
->location
, UNI_STR_TERMINATE
);
6455 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6456 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6458 notify_printer_location(snum
, printer
->info_2
->location
);
6461 /* here we need to update some more DsSpooler keys */
6462 /* uNCName, serverName, shortServerName */
6464 init_unistr2( &buffer
, global_myname(), UNI_STR_TERMINATE
);
6465 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6466 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6467 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6468 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6470 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6471 global_myname(), printer
->info_2
->sharename
);
6472 init_unistr2( &buffer
, asc_buffer
, UNI_STR_TERMINATE
);
6473 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6474 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6476 /* Update printer info */
6477 result
= mod_a_printer(printer
, 2);
6480 free_a_printer(&printer
, 2);
6481 free_a_printer(&old_printer
, 2);
6487 /****************************************************************************
6488 ****************************************************************************/
6489 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6490 const SPOOL_PRINTER_INFO_LEVEL
*info
)
6493 SPOOL_PRINTER_INFO_LEVEL_7
*info7
= info
->info_7
;
6495 Printer_entry
*Printer
;
6497 if ( lp_security() != SEC_ADS
) {
6498 return WERR_UNKNOWN_LEVEL
;
6501 Printer
= find_printer_index_by_hnd(p
, handle
);
6503 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6508 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6511 nt_printer_publish(Printer
, snum
, info7
->action
);
6515 return WERR_UNKNOWN_LEVEL
;
6518 /****************************************************************************
6519 ****************************************************************************/
6521 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
6523 POLICY_HND
*handle
= &q_u
->handle
;
6524 uint32 level
= q_u
->level
;
6525 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
6526 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
6527 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
6528 uint32 command
= q_u
->command
;
6531 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6534 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6538 /* check the level */
6541 return control_printer(handle
, command
, p
);
6543 result
= update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
6544 if (!W_ERROR_IS_OK(result
))
6547 result
= update_printer_sec(handle
, level
, info
, p
, secdesc_ctr
);
6550 return update_printer_sec(handle
, level
, info
, p
,
6553 return publish_or_unpublish_printer(p
, handle
, info
);
6555 return WERR_UNKNOWN_LEVEL
;
6559 /****************************************************************************
6560 ****************************************************************************/
6562 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
6564 POLICY_HND
*handle
= &q_u
->handle
;
6565 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6568 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6572 if (Printer
->notify
.client_connected
==True
) {
6575 if ( Printer
->printer_type
== SPLHND_SERVER
)
6577 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6578 !get_printer_snum(p
, handle
, &snum
, NULL
) )
6581 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6584 Printer
->notify
.flags
=0;
6585 Printer
->notify
.options
=0;
6586 Printer
->notify
.localmachine
[0]='\0';
6587 Printer
->notify
.printerlocal
=0;
6588 if (Printer
->notify
.option
)
6589 free_spool_notify_option(&Printer
->notify
.option
);
6590 Printer
->notify
.client_connected
=False
;
6595 /****************************************************************************
6596 ****************************************************************************/
6598 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
6600 /* that's an [in out] buffer */
6602 if (!q_u
->buffer
&& (q_u
->offered
!=0)) {
6603 return WERR_INVALID_PARAM
;
6606 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6609 return WERR_INVALID_PARAM
; /* this is what a NT server
6610 returns for AddJob. AddJob
6611 must fail on non-local
6615 /****************************************************************************
6616 ****************************************************************************/
6618 static void fill_job_info_1(JOB_INFO_1
*job_info
, const print_queue_struct
*queue
,
6619 int position
, int snum
,
6620 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6624 t
=gmtime(&queue
->time
);
6626 job_info
->jobid
=queue
->job
;
6627 init_unistr(&job_info
->printername
, lp_servicename(snum
));
6628 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6629 init_unistr(&job_info
->username
, queue
->fs_user
);
6630 init_unistr(&job_info
->document
, queue
->fs_file
);
6631 init_unistr(&job_info
->datatype
, "RAW");
6632 init_unistr(&job_info
->text_status
, "");
6633 job_info
->status
=nt_printj_status(queue
->status
);
6634 job_info
->priority
=queue
->priority
;
6635 job_info
->position
=position
;
6636 job_info
->totalpages
=queue
->page_count
;
6637 job_info
->pagesprinted
=0;
6639 make_systemtime(&job_info
->submitted
, t
);
6642 /****************************************************************************
6643 ****************************************************************************/
6645 static bool fill_job_info_2(JOB_INFO_2
*job_info
, const print_queue_struct
*queue
,
6646 int position
, int snum
,
6647 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6648 DEVICEMODE
*devmode
)
6652 t
=gmtime(&queue
->time
);
6654 job_info
->jobid
=queue
->job
;
6656 init_unistr(&job_info
->printername
, ntprinter
->info_2
->printername
);
6658 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6659 init_unistr(&job_info
->username
, queue
->fs_user
);
6660 init_unistr(&job_info
->document
, queue
->fs_file
);
6661 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
6662 init_unistr(&job_info
->datatype
, "RAW");
6663 init_unistr(&job_info
->printprocessor
, "winprint");
6664 init_unistr(&job_info
->parameters
, "");
6665 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
6666 init_unistr(&job_info
->text_status
, "");
6668 /* and here the security descriptor */
6670 job_info
->status
=nt_printj_status(queue
->status
);
6671 job_info
->priority
=queue
->priority
;
6672 job_info
->position
=position
;
6673 job_info
->starttime
=0;
6674 job_info
->untiltime
=0;
6675 job_info
->totalpages
=queue
->page_count
;
6676 job_info
->size
=queue
->size
;
6677 make_systemtime(&(job_info
->submitted
), t
);
6678 job_info
->timeelapsed
=0;
6679 job_info
->pagesprinted
=0;
6681 job_info
->devmode
= devmode
;
6686 /****************************************************************************
6687 Enumjobs at level 1.
6688 ****************************************************************************/
6690 static WERROR
enumjobs_level1(const print_queue_struct
*queue
, int snum
,
6691 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6692 RPC_BUFFER
*buffer
, uint32 offered
,
6693 uint32
*needed
, uint32
*returned
)
6697 WERROR result
= WERR_OK
;
6699 info
=SMB_MALLOC_ARRAY(JOB_INFO_1
,*returned
);
6705 for (i
=0; i
<*returned
; i
++)
6706 fill_job_info_1( &info
[i
], &queue
[i
], i
, snum
, ntprinter
);
6708 /* check the required size. */
6709 for (i
=0; i
<*returned
; i
++)
6710 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
6712 if (*needed
> offered
) {
6713 result
= WERR_INSUFFICIENT_BUFFER
;
6717 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6718 result
= WERR_NOMEM
;
6722 /* fill the buffer with the structures */
6723 for (i
=0; i
<*returned
; i
++)
6724 smb_io_job_info_1("", buffer
, &info
[i
], 0);
6730 if ( !W_ERROR_IS_OK(result
) )
6736 /****************************************************************************
6737 Enumjobs at level 2.
6738 ****************************************************************************/
6740 static WERROR
enumjobs_level2(const print_queue_struct
*queue
, int snum
,
6741 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6742 RPC_BUFFER
*buffer
, uint32 offered
,
6743 uint32
*needed
, uint32
*returned
)
6745 JOB_INFO_2
*info
= NULL
;
6747 WERROR result
= WERR_OK
;
6748 DEVICEMODE
*devmode
= NULL
;
6750 if ( !(info
= SMB_MALLOC_ARRAY(JOB_INFO_2
,*returned
)) ) {
6755 /* this should not be a failure condition if the devmode is NULL */
6757 devmode
= construct_dev_mode(lp_const_servicename(snum
));
6759 for (i
=0; i
<*returned
; i
++)
6760 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
, devmode
);
6762 /* check the required size. */
6763 for (i
=0; i
<*returned
; i
++)
6764 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6766 if (*needed
> offered
) {
6767 result
= WERR_INSUFFICIENT_BUFFER
;
6771 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6772 result
= WERR_NOMEM
;
6776 /* fill the buffer with the structures */
6777 for (i
=0; i
<*returned
; i
++)
6778 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6781 free_devmode(devmode
);
6784 if ( !W_ERROR_IS_OK(result
) )
6791 /****************************************************************************
6793 ****************************************************************************/
6795 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6797 POLICY_HND
*handle
= &q_u
->handle
;
6798 uint32 level
= q_u
->level
;
6799 RPC_BUFFER
*buffer
= NULL
;
6800 uint32 offered
= q_u
->offered
;
6801 uint32
*needed
= &r_u
->needed
;
6802 uint32
*returned
= &r_u
->returned
;
6804 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6806 print_status_struct prt_status
;
6807 print_queue_struct
*queue
=NULL
;
6809 /* that's an [in out] buffer */
6811 if (!q_u
->buffer
&& (offered
!=0)) {
6812 return WERR_INVALID_PARAM
;
6815 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6816 buffer
= r_u
->buffer
;
6818 DEBUG(4,("_spoolss_enumjobs\n"));
6823 /* lookup the printer snum and tdb entry */
6825 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6828 wret
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6829 if ( !W_ERROR_IS_OK(wret
) )
6832 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6833 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6835 if (*returned
== 0) {
6837 free_a_printer(&ntprinter
, 2);
6843 wret
= enumjobs_level1(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6846 wret
= enumjobs_level2(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6850 wret
= WERR_UNKNOWN_LEVEL
;
6855 free_a_printer( &ntprinter
, 2 );
6859 /****************************************************************************
6860 ****************************************************************************/
6862 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
6867 /****************************************************************************
6868 ****************************************************************************/
6870 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
6872 POLICY_HND
*handle
= &q_u
->handle
;
6873 uint32 jobid
= q_u
->jobid
;
6874 uint32 command
= q_u
->command
;
6877 WERROR errcode
= WERR_BADFUNC
;
6879 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6883 if (!print_job_exists(lp_const_servicename(snum
), jobid
)) {
6884 return WERR_INVALID_PRINTER_NAME
;
6888 case JOB_CONTROL_CANCEL
:
6889 case JOB_CONTROL_DELETE
:
6890 if (print_job_delete(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6894 case JOB_CONTROL_PAUSE
:
6895 if (print_job_pause(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6899 case JOB_CONTROL_RESTART
:
6900 case JOB_CONTROL_RESUME
:
6901 if (print_job_resume(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6906 return WERR_UNKNOWN_LEVEL
;
6912 /****************************************************************************
6913 Enumerates all printer drivers at level 1.
6914 ****************************************************************************/
6916 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6921 fstring
*list
= NULL
;
6922 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6923 DRIVER_INFO_1
*driver_info_1
=NULL
;
6924 WERROR result
= WERR_OK
;
6928 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6930 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6931 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6933 if(ndrivers
== -1) {
6934 SAFE_FREE(driver_info_1
);
6939 if((driver_info_1
=SMB_REALLOC_ARRAY(driver_info_1
, DRIVER_INFO_1
, *returned
+ndrivers
)) == NULL
) {
6940 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6946 for (i
=0; i
<ndrivers
; i
++) {
6948 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6949 ZERO_STRUCT(driver
);
6950 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6951 architecture
, version
);
6952 if (!W_ERROR_IS_OK(status
)) {
6954 SAFE_FREE(driver_info_1
);
6957 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6958 free_a_printer_driver(driver
, 3);
6961 *returned
+=ndrivers
;
6965 /* check the required size. */
6966 for (i
=0; i
<*returned
; i
++) {
6967 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6968 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6971 if (*needed
> offered
) {
6972 result
= WERR_INSUFFICIENT_BUFFER
;
6976 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6977 result
= WERR_NOMEM
;
6981 /* fill the buffer with the driver structures */
6982 for (i
=0; i
<*returned
; i
++) {
6983 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6984 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
6988 SAFE_FREE(driver_info_1
);
6990 if ( !W_ERROR_IS_OK(result
) )
6996 /****************************************************************************
6997 Enumerates all printer drivers at level 2.
6998 ****************************************************************************/
7000 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7005 fstring
*list
= NULL
;
7006 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7007 DRIVER_INFO_2
*driver_info_2
=NULL
;
7008 WERROR result
= WERR_OK
;
7012 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7014 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7015 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7017 if(ndrivers
== -1) {
7018 SAFE_FREE(driver_info_2
);
7023 if((driver_info_2
=SMB_REALLOC_ARRAY(driver_info_2
, DRIVER_INFO_2
, *returned
+ndrivers
)) == NULL
) {
7024 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7030 for (i
=0; i
<ndrivers
; i
++) {
7033 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7034 ZERO_STRUCT(driver
);
7035 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7036 architecture
, version
);
7037 if (!W_ERROR_IS_OK(status
)) {
7039 SAFE_FREE(driver_info_2
);
7042 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
7043 free_a_printer_driver(driver
, 3);
7046 *returned
+=ndrivers
;
7050 /* check the required size. */
7051 for (i
=0; i
<*returned
; i
++) {
7052 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7053 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
7056 if (*needed
> offered
) {
7057 result
= WERR_INSUFFICIENT_BUFFER
;
7061 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7062 result
= WERR_NOMEM
;
7066 /* fill the buffer with the form structures */
7067 for (i
=0; i
<*returned
; i
++) {
7068 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7069 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
7073 SAFE_FREE(driver_info_2
);
7075 if ( !W_ERROR_IS_OK(result
) )
7081 /****************************************************************************
7082 Enumerates all printer drivers at level 3.
7083 ****************************************************************************/
7085 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7090 fstring
*list
= NULL
;
7091 DRIVER_INFO_3
*driver_info_3
=NULL
;
7092 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7093 WERROR result
= WERR_OK
;
7097 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7099 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7100 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7102 if(ndrivers
== -1) {
7103 SAFE_FREE(driver_info_3
);
7108 if((driver_info_3
=SMB_REALLOC_ARRAY(driver_info_3
, DRIVER_INFO_3
, *returned
+ndrivers
)) == NULL
) {
7109 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7115 for (i
=0; i
<ndrivers
; i
++) {
7118 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7119 ZERO_STRUCT(driver
);
7120 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7121 architecture
, version
);
7122 if (!W_ERROR_IS_OK(status
)) {
7124 SAFE_FREE(driver_info_3
);
7127 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
7128 free_a_printer_driver(driver
, 3);
7131 *returned
+=ndrivers
;
7135 /* check the required size. */
7136 for (i
=0; i
<*returned
; i
++) {
7137 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7138 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
7141 if (*needed
> offered
) {
7142 result
= WERR_INSUFFICIENT_BUFFER
;
7146 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7147 result
= WERR_NOMEM
;
7151 /* fill the buffer with the driver structures */
7152 for (i
=0; i
<*returned
; i
++) {
7153 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7154 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
7158 for (i
=0; i
<*returned
; i
++) {
7159 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
7162 SAFE_FREE(driver_info_3
);
7164 if ( !W_ERROR_IS_OK(result
) )
7170 /****************************************************************************
7171 Enumerates all printer drivers.
7172 ****************************************************************************/
7174 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
7176 uint32 level
= q_u
->level
;
7177 RPC_BUFFER
*buffer
= NULL
;
7178 uint32 offered
= q_u
->offered
;
7179 uint32
*needed
= &r_u
->needed
;
7180 uint32
*returned
= &r_u
->returned
;
7183 fstring architecture
;
7185 /* that's an [in out] buffer */
7187 if (!q_u
->buffer
&& (offered
!=0)) {
7188 return WERR_INVALID_PARAM
;
7191 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7192 buffer
= r_u
->buffer
;
7194 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7199 unistr2_to_ascii(architecture
, &q_u
->environment
, sizeof(architecture
));
7200 unistr2_to_ascii(servername
, &q_u
->name
, sizeof(servername
));
7202 if ( !is_myname_or_ipaddr( servername
) )
7203 return WERR_UNKNOWN_PRINTER_DRIVER
;
7207 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
7209 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
7211 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
7213 return WERR_UNKNOWN_LEVEL
;
7217 /****************************************************************************
7218 ****************************************************************************/
7220 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
7222 form
->flag
=list
->flag
;
7223 init_unistr(&form
->name
, list
->name
);
7224 form
->width
=list
->width
;
7225 form
->length
=list
->length
;
7226 form
->left
=list
->left
;
7227 form
->top
=list
->top
;
7228 form
->right
=list
->right
;
7229 form
->bottom
=list
->bottom
;
7232 /****************************************************************************
7233 ****************************************************************************/
7235 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
7237 uint32 level
= q_u
->level
;
7238 RPC_BUFFER
*buffer
= NULL
;
7239 uint32 offered
= q_u
->offered
;
7240 uint32
*needed
= &r_u
->needed
;
7241 uint32
*numofforms
= &r_u
->numofforms
;
7242 uint32 numbuiltinforms
;
7244 nt_forms_struct
*list
=NULL
;
7245 nt_forms_struct
*builtinlist
=NULL
;
7250 /* that's an [in out] buffer */
7252 if (!q_u
->buffer
&& (offered
!=0) ) {
7253 return WERR_INVALID_PARAM
;
7256 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7257 buffer
= r_u
->buffer
;
7259 DEBUG(4,("_spoolss_enumforms\n"));
7260 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7261 DEBUGADD(5,("Info level [%d]\n", level
));
7263 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
7264 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
7265 *numofforms
= get_ntforms(&list
);
7266 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
7267 *numofforms
+= numbuiltinforms
;
7269 if (*numofforms
== 0) {
7270 SAFE_FREE(builtinlist
);
7272 return WERR_NO_MORE_ITEMS
;
7277 if ((forms_1
=SMB_MALLOC_ARRAY(FORM_1
, *numofforms
)) == NULL
) {
7278 SAFE_FREE(builtinlist
);
7284 /* construct the list of form structures */
7285 for (i
=0; i
<numbuiltinforms
; i
++) {
7286 DEBUGADD(6,("Filling form number [%d]\n",i
));
7287 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
7290 SAFE_FREE(builtinlist
);
7292 for (; i
<*numofforms
; i
++) {
7293 DEBUGADD(6,("Filling form number [%d]\n",i
));
7294 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
7299 /* check the required size. */
7300 for (i
=0; i
<numbuiltinforms
; i
++) {
7301 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7302 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7304 for (; i
<*numofforms
; i
++) {
7305 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7306 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7309 *needed
=buffer_size
;
7311 if (*needed
> offered
) {
7314 return WERR_INSUFFICIENT_BUFFER
;
7317 if (!rpcbuf_alloc_size(buffer
, buffer_size
)){
7323 /* fill the buffer with the form structures */
7324 for (i
=0; i
<numbuiltinforms
; i
++) {
7325 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7326 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7328 for (; i
<*numofforms
; i
++) {
7329 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7330 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7339 SAFE_FREE(builtinlist
);
7340 return WERR_UNKNOWN_LEVEL
;
7344 /****************************************************************************
7345 ****************************************************************************/
7347 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
7349 uint32 level
= q_u
->level
;
7350 UNISTR2
*uni_formname
= &q_u
->formname
;
7351 RPC_BUFFER
*buffer
= NULL
;
7352 uint32 offered
= q_u
->offered
;
7353 uint32
*needed
= &r_u
->needed
;
7355 nt_forms_struct
*list
=NULL
;
7356 nt_forms_struct builtin_form
;
7361 int numofforms
=0, i
=0;
7363 /* that's an [in out] buffer */
7365 if (!q_u
->buffer
&& (offered
!=0)) {
7366 return WERR_INVALID_PARAM
;
7369 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7370 buffer
= r_u
->buffer
;
7372 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
));
7374 DEBUG(4,("_spoolss_getform\n"));
7375 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7376 DEBUGADD(5,("Info level [%d]\n", level
));
7378 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
7379 if (!foundBuiltin
) {
7380 numofforms
= get_ntforms(&list
);
7381 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
7383 if (numofforms
== 0)
7390 fill_form_1(&form_1
, &builtin_form
);
7393 /* Check if the requested name is in the list of form structures */
7394 for (i
=0; i
<numofforms
; i
++) {
7396 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
7398 if (strequal(form_name
, list
[i
].name
)) {
7399 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
7400 fill_form_1(&form_1
, &list
[i
]);
7406 if (i
== numofforms
) {
7410 /* check the required size. */
7412 *needed
=spoolss_size_form_1(&form_1
);
7414 if (*needed
> offered
)
7415 return WERR_INSUFFICIENT_BUFFER
;
7417 if (!rpcbuf_alloc_size(buffer
, buffer_size
))
7420 /* fill the buffer with the form structures */
7421 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
7422 smb_io_form_1("", buffer
, &form_1
, 0);
7428 return WERR_UNKNOWN_LEVEL
;
7432 /****************************************************************************
7433 ****************************************************************************/
7435 static void fill_port_1(PORT_INFO_1
*port
, const char *name
)
7437 init_unistr(&port
->port_name
, name
);
7440 /****************************************************************************
7441 TODO: This probably needs distinguish between TCP/IP and Local ports
7443 ****************************************************************************/
7445 static void fill_port_2(PORT_INFO_2
*port
, const char *name
)
7447 init_unistr(&port
->port_name
, name
);
7448 init_unistr(&port
->monitor_name
, "Local Monitor");
7449 init_unistr(&port
->description
, SPL_LOCAL_PORT
);
7450 port
->port_type
=PORT_TYPE_WRITE
;
7455 /****************************************************************************
7456 wrapper around the enumer ports command
7457 ****************************************************************************/
7459 WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7461 char *cmd
= lp_enumports_cmd();
7462 char **qlines
= NULL
;
7463 char *command
= NULL
;
7471 /* if no hook then just fill in the default port */
7474 if (!(qlines
= SMB_MALLOC_ARRAY( char*, 2 ))) {
7477 if (!(qlines
[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME
))) {
7485 /* we have a valid enumport command */
7487 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7492 DEBUG(10,("Running [%s]\n", command
));
7493 ret
= smbrun(command
, &fd
);
7494 DEBUG(10,("Returned [%d]\n", ret
));
7495 TALLOC_FREE(command
);
7500 return WERR_ACCESS_DENIED
;
7504 qlines
= fd_lines_load(fd
, &numlines
, 0);
7505 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7515 /****************************************************************************
7517 ****************************************************************************/
7519 static WERROR
enumports_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7521 PORT_INFO_1
*ports
=NULL
;
7523 WERROR result
= WERR_OK
;
7524 char **qlines
= NULL
;
7527 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7528 if (!W_ERROR_IS_OK(result
)) {
7529 file_lines_free(qlines
);
7534 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_1
, numlines
)) == NULL
) {
7535 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7536 dos_errstr(WERR_NOMEM
)));
7537 file_lines_free(qlines
);
7541 for (i
=0; i
<numlines
; i
++) {
7542 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7543 fill_port_1(&ports
[i
], qlines
[i
]);
7546 file_lines_free(qlines
);
7548 *returned
= numlines
;
7550 /* check the required size. */
7551 for (i
=0; i
<*returned
; i
++) {
7552 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7553 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
7556 if (*needed
> offered
) {
7557 result
= WERR_INSUFFICIENT_BUFFER
;
7561 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7562 result
= WERR_NOMEM
;
7566 /* fill the buffer with the ports structures */
7567 for (i
=0; i
<*returned
; i
++) {
7568 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7569 smb_io_port_1("", buffer
, &ports
[i
], 0);
7575 if ( !W_ERROR_IS_OK(result
) )
7581 /****************************************************************************
7583 ****************************************************************************/
7585 static WERROR
enumports_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7587 PORT_INFO_2
*ports
=NULL
;
7589 WERROR result
= WERR_OK
;
7590 char **qlines
= NULL
;
7593 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7594 if ( !W_ERROR_IS_OK(result
)) {
7595 file_lines_free(qlines
);
7600 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_2
, numlines
)) == NULL
) {
7601 file_lines_free(qlines
);
7605 for (i
=0; i
<numlines
; i
++) {
7606 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7607 fill_port_2(&(ports
[i
]), qlines
[i
]);
7611 file_lines_free(qlines
);
7613 *returned
= numlines
;
7615 /* check the required size. */
7616 for (i
=0; i
<*returned
; i
++) {
7617 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7618 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
7621 if (*needed
> offered
) {
7622 result
= WERR_INSUFFICIENT_BUFFER
;
7626 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7627 result
= WERR_NOMEM
;
7631 /* fill the buffer with the ports structures */
7632 for (i
=0; i
<*returned
; i
++) {
7633 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7634 smb_io_port_2("", buffer
, &ports
[i
], 0);
7640 if ( !W_ERROR_IS_OK(result
) )
7646 /****************************************************************************
7648 ****************************************************************************/
7650 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
7652 uint32 level
= q_u
->level
;
7653 RPC_BUFFER
*buffer
= NULL
;
7654 uint32 offered
= q_u
->offered
;
7655 uint32
*needed
= &r_u
->needed
;
7656 uint32
*returned
= &r_u
->returned
;
7658 /* that's an [in out] buffer */
7660 if (!q_u
->buffer
&& (offered
!=0)) {
7661 return WERR_INVALID_PARAM
;
7664 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7665 buffer
= r_u
->buffer
;
7667 DEBUG(4,("_spoolss_enumports\n"));
7674 return enumports_level_1(buffer
, offered
, needed
, returned
);
7676 return enumports_level_2(buffer
, offered
, needed
, returned
);
7678 return WERR_UNKNOWN_LEVEL
;
7682 /****************************************************************************
7683 ****************************************************************************/
7685 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
7686 const SPOOL_PRINTER_INFO_LEVEL
*info
,
7687 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
7688 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
7691 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7694 WERROR err
= WERR_OK
;
7696 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7697 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7701 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7702 if (!convert_printer_info(info
, printer
, 2)) {
7703 free_a_printer(&printer
, 2);
7707 /* check to see if the printer already exists */
7709 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7710 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7711 printer
->info_2
->sharename
));
7712 free_a_printer(&printer
, 2);
7713 return WERR_PRINTER_ALREADY_EXISTS
;
7716 /* FIXME!!! smbd should check to see if the driver is installed before
7717 trying to add a printer like this --jerry */
7719 if (*lp_addprinter_cmd() ) {
7720 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
7721 free_a_printer(&printer
,2);
7722 return WERR_ACCESS_DENIED
;
7725 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7726 "smb.conf parameter \"addprinter command\" is defined. This"
7727 "parameter must exist for this call to succeed\n",
7728 printer
->info_2
->sharename
));
7731 /* use our primary netbios name since get_a_printer() will convert
7732 it to what the client expects on a case by case basis */
7734 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7735 printer
->info_2
->sharename
);
7738 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7739 free_a_printer(&printer
,2);
7740 return WERR_ACCESS_DENIED
;
7743 /* you must be a printer admin to add a new printer */
7744 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7745 free_a_printer(&printer
,2);
7746 return WERR_ACCESS_DENIED
;
7750 * Do sanity check on the requested changes for Samba.
7753 if (!check_printer_ok(printer
->info_2
, snum
)) {
7754 free_a_printer(&printer
,2);
7755 return WERR_INVALID_PARAM
;
7759 * When a printer is created, the drivername bound to the printer is used
7760 * to lookup previously saved driver initialization info, which is then
7761 * bound to the new printer, simulating what happens in the Windows arch.
7766 set_driver_init(printer
, 2);
7770 /* A valid devmode was included, convert and link it
7772 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7774 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
7775 &printer
->info_2
->devmode
))
7779 /* write the ASCII on disk */
7780 err
= mod_a_printer(printer
, 2);
7781 if (!W_ERROR_IS_OK(err
)) {
7782 free_a_printer(&printer
,2);
7786 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7787 /* Handle open failed - remove addition. */
7788 del_a_printer(printer
->info_2
->sharename
);
7789 free_a_printer(&printer
,2);
7790 return WERR_ACCESS_DENIED
;
7793 update_c_setprinter(False
);
7794 free_a_printer(&printer
,2);
7799 /****************************************************************************
7800 ****************************************************************************/
7802 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
7804 UNISTR2
*uni_srv_name
= q_u
->server_name
;
7805 uint32 level
= q_u
->level
;
7806 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
7807 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
7808 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
7809 uint32 user_switch
= q_u
->user_switch
;
7810 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
7811 POLICY_HND
*handle
= &r_u
->handle
;
7815 /* we don't handle yet */
7816 /* but I know what to do ... */
7817 return WERR_UNKNOWN_LEVEL
;
7819 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
7821 user_switch
, user
, handle
);
7823 return WERR_UNKNOWN_LEVEL
;
7827 /****************************************************************************
7828 ****************************************************************************/
7830 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
7832 uint32 level
= q_u
->level
;
7833 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
7834 WERROR err
= WERR_OK
;
7835 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7836 fstring driver_name
;
7839 ZERO_STRUCT(driver
);
7841 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7846 DEBUG(5,("Cleaning driver's information\n"));
7847 err
= clean_up_driver_struct(driver
, level
, &p
->pipe_user
);
7848 if (!W_ERROR_IS_OK(err
))
7851 DEBUG(5,("Moving driver to final destination\n"));
7852 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(driver
, level
, &p
->pipe_user
, &err
)) ) {
7856 if (add_a_printer_driver(driver
, level
)!=0) {
7857 err
= WERR_ACCESS_DENIED
;
7862 * I think this is where he DrvUpgradePrinter() hook would be
7863 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7864 * server. Right now, we just need to send ourselves a message
7865 * to update each printer bound to this driver. --jerry
7868 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7869 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7874 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7875 * decide if the driver init data should be deleted. The rules are:
7876 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7877 * 2) delete init data only if there is no 2k/Xp driver
7878 * 3) always delete init data
7879 * The generalized rule is always use init data from the highest order driver.
7880 * It is necessary to follow the driver install by an initialization step to
7881 * finish off this process.
7884 version
= driver
.info_3
->cversion
;
7885 else if (level
== 6)
7886 version
= driver
.info_6
->version
;
7891 * 9x printer driver - never delete init data
7894 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7899 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7900 * there is no 2k/Xp driver init data for this driver name.
7904 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7906 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7908 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7910 if (!del_driver_init(driver_name
))
7911 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name
));
7914 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7916 free_a_printer_driver(driver1
,3);
7917 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7924 * 2k or Xp printer driver - always delete init data
7927 if (!del_driver_init(driver_name
))
7928 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name
));
7932 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level
));
7938 free_a_printer_driver(driver
, level
);
7942 /********************************************************************
7943 * spoolss_addprinterdriverex
7944 ********************************************************************/
7946 WERROR
_spoolss_addprinterdriverex(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVEREX
*q_u
, SPOOL_R_ADDPRINTERDRIVEREX
*r_u
)
7948 SPOOL_Q_ADDPRINTERDRIVER q_u_local
;
7949 SPOOL_R_ADDPRINTERDRIVER r_u_local
;
7952 * we only support the semantics of AddPrinterDriver()
7953 * i.e. only copy files that are newer than existing ones
7956 if ( q_u
->copy_flags
!= APD_COPY_NEW_FILES
)
7957 return WERR_ACCESS_DENIED
;
7959 ZERO_STRUCT(q_u_local
);
7960 ZERO_STRUCT(r_u_local
);
7962 /* just pass the information off to _spoolss_addprinterdriver() */
7963 q_u_local
.server_name_ptr
= q_u
->server_name_ptr
;
7964 copy_unistr2(&q_u_local
.server_name
, &q_u
->server_name
);
7965 q_u_local
.level
= q_u
->level
;
7966 memcpy( &q_u_local
.info
, &q_u
->info
, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL
) );
7968 return _spoolss_addprinterdriver( p
, &q_u_local
, &r_u_local
);
7971 /****************************************************************************
7972 ****************************************************************************/
7974 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
7976 init_unistr(&info
->name
, name
);
7979 /****************************************************************************
7980 ****************************************************************************/
7982 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
7985 char *long_archi
= NULL
;
7986 char *servername
= NULL
;
7987 char *pservername
= NULL
;
7988 const char *short_archi
;
7989 DRIVER_DIRECTORY_1
*info
=NULL
;
7990 WERROR result
= WERR_OK
;
7991 TALLOC_CTX
*ctx
= talloc_tos();
7993 servername
= unistr2_to_ascii_talloc(ctx
, name
);
7997 long_archi
= unistr2_to_ascii_talloc(ctx
, uni_environment
);
8002 /* check for beginning double '\'s and that the server
8005 pservername
= servername
;
8006 if ( *pservername
== '\\' && strlen(servername
)>2 ) {
8010 if ( !is_myname_or_ipaddr( pservername
) )
8011 return WERR_INVALID_PARAM
;
8013 if (!(short_archi
= get_short_archi(long_archi
)))
8014 return WERR_INVALID_ENVIRONMENT
;
8016 if((info
=SMB_MALLOC_P(DRIVER_DIRECTORY_1
)) == NULL
)
8019 path
= talloc_asprintf(ctx
,
8020 "\\\\%s\\print$\\%s", pservername
, short_archi
);
8022 result
= WERR_NOMEM
;
8026 DEBUG(4,("printer driver directory: [%s]\n", path
));
8028 fill_driverdir_1(info
, path
);
8030 *needed
+= spoolss_size_driverdir_info_1(info
);
8032 if (*needed
> offered
) {
8033 result
= WERR_INSUFFICIENT_BUFFER
;
8037 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8038 result
= WERR_NOMEM
;
8042 smb_io_driverdir_1("", buffer
, info
, 0);
8050 /****************************************************************************
8051 ****************************************************************************/
8053 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
8055 UNISTR2
*name
= &q_u
->name
;
8056 UNISTR2
*uni_environment
= &q_u
->environment
;
8057 uint32 level
= q_u
->level
;
8058 RPC_BUFFER
*buffer
= NULL
;
8059 uint32 offered
= q_u
->offered
;
8060 uint32
*needed
= &r_u
->needed
;
8062 /* that's an [in out] buffer */
8064 if (!q_u
->buffer
&& (offered
!=0)) {
8065 return WERR_INVALID_PARAM
;
8068 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8069 buffer
= r_u
->buffer
;
8071 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8077 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
8079 return WERR_UNKNOWN_LEVEL
;
8083 /****************************************************************************
8084 ****************************************************************************/
8086 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
8088 POLICY_HND
*handle
= &q_u
->handle
;
8089 uint32 idx
= q_u
->index
;
8090 uint32 in_value_len
= q_u
->valuesize
;
8091 uint32 in_data_len
= q_u
->datasize
;
8092 uint32
*out_max_value_len
= &r_u
->valuesize
;
8093 uint16
**out_value
= &r_u
->value
;
8094 uint32
*out_value_len
= &r_u
->realvaluesize
;
8095 uint32
*out_type
= &r_u
->type
;
8096 uint32
*out_max_data_len
= &r_u
->datasize
;
8097 uint8
**data_out
= &r_u
->data
;
8098 uint32
*out_data_len
= &r_u
->realdatasize
;
8100 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8102 uint32 biggest_valuesize
;
8103 uint32 biggest_datasize
;
8105 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8108 REGISTRY_VALUE
*val
= NULL
;
8109 NT_PRINTER_DATA
*p_data
;
8110 int i
, key_index
, num_values
;
8115 *out_max_data_len
= 0;
8119 DEBUG(5,("spoolss_enumprinterdata\n"));
8122 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8126 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8129 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8130 if (!W_ERROR_IS_OK(result
))
8133 p_data
= printer
->info_2
->data
;
8134 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8139 * The NT machine wants to know the biggest size of value and data
8141 * cf: MSDN EnumPrinterData remark section
8144 if ( !in_value_len
&& !in_data_len
&& (key_index
!= -1) )
8146 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8148 biggest_valuesize
= 0;
8149 biggest_datasize
= 0;
8151 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8153 for ( i
=0; i
<num_values
; i
++ )
8155 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8157 name_length
= strlen(val
->valuename
);
8158 if ( strlen(val
->valuename
) > biggest_valuesize
)
8159 biggest_valuesize
= name_length
;
8161 if ( val
->size
> biggest_datasize
)
8162 biggest_datasize
= val
->size
;
8164 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8168 /* the value is an UNICODE string but real_value_size is the length
8169 in bytes including the trailing 0 */
8171 *out_value_len
= 2 * (1+biggest_valuesize
);
8172 *out_data_len
= biggest_datasize
;
8174 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
8180 * the value len is wrong in NT sp3
8181 * that's the number of bytes not the number of unicode chars
8184 if ( key_index
!= -1 )
8185 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, idx
);
8190 /* out_value should default to "" or else NT4 has
8191 problems unmarshalling the response */
8193 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8196 if((*out_value
=(uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8198 result
= WERR_NOMEM
;
8201 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
8207 /* the data is counted in bytes */
8209 *out_max_data_len
= in_data_len
;
8210 *out_data_len
= in_data_len
;
8212 /* only allocate when given a non-zero data_len */
8214 if ( in_data_len
&& ((*data_out
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
8216 result
= WERR_NOMEM
;
8220 result
= WERR_NO_MORE_ITEMS
;
8226 * - counted in bytes in the request
8227 * - counted in UNICODE chars in the max reply
8228 * - counted in bytes in the real size
8230 * take a pause *before* coding not *during* coding
8234 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8236 if ( (*out_value
= (uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8238 result
= WERR_NOMEM
;
8242 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), (size_t)in_value_len
, 0);
8250 *out_type
= regval_type( val
);
8252 /* data - counted in bytes */
8254 *out_max_data_len
= in_data_len
;
8255 if ( in_data_len
&& (*data_out
= (uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
8257 result
= WERR_NOMEM
;
8260 data_len
= regval_size(val
);
8261 if ( *data_out
&& data_len
)
8262 memcpy( *data_out
, regval_data_p(val
), data_len
);
8263 *out_data_len
= data_len
;
8267 free_a_printer(&printer
, 2);
8271 /****************************************************************************
8272 ****************************************************************************/
8274 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
8276 POLICY_HND
*handle
= &q_u
->handle
;
8277 UNISTR2
*value
= &q_u
->value
;
8278 uint32 type
= q_u
->type
;
8279 uint8
*data
= q_u
->data
;
8280 uint32 real_len
= q_u
->real_len
;
8282 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8284 WERROR status
= WERR_OK
;
8285 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8288 DEBUG(5,("spoolss_setprinterdata\n"));
8291 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8295 if ( Printer
->printer_type
== SPLHND_SERVER
) {
8296 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8297 return WERR_INVALID_PARAM
;
8300 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8304 * Access check : NT returns "access denied" if you make a
8305 * SetPrinterData call without the necessary privildge.
8306 * we were originally returning OK if nothing changed
8307 * which made Win2k issue **a lot** of SetPrinterData
8308 * when connecting to a printer --jerry
8311 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8313 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8314 status
= WERR_ACCESS_DENIED
;
8318 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8319 if (!W_ERROR_IS_OK(status
))
8322 unistr2_to_ascii(valuename
, value
, sizeof(valuename
));
8325 * When client side code sets a magic printer data key, detect it and save
8326 * the current printer data and the magic key's data (its the DEVMODE) for
8327 * future printer/driver initializations.
8329 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
8331 /* Set devmode and printer initialization info */
8332 status
= save_driver_init( printer
, 2, data
, real_len
);
8334 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
8338 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
8339 type
, data
, real_len
);
8340 if ( W_ERROR_IS_OK(status
) )
8341 status
= mod_a_printer(printer
, 2);
8345 free_a_printer(&printer
, 2);
8350 /****************************************************************************
8351 ****************************************************************************/
8353 WERROR
_spoolss_resetprinter(pipes_struct
*p
, SPOOL_Q_RESETPRINTER
*q_u
, SPOOL_R_RESETPRINTER
*r_u
)
8355 POLICY_HND
*handle
= &q_u
->handle
;
8356 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8359 DEBUG(5,("_spoolss_resetprinter\n"));
8362 * All we do is to check to see if the handle and queue is valid.
8363 * This call really doesn't mean anything to us because we only
8364 * support RAW printing. --jerry
8368 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8372 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8376 /* blindly return success */
8381 /****************************************************************************
8382 ****************************************************************************/
8384 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
8386 POLICY_HND
*handle
= &q_u
->handle
;
8387 UNISTR2
*value
= &q_u
->valuename
;
8389 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8391 WERROR status
= WERR_OK
;
8392 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8393 char *valuename
= NULL
;
8394 TALLOC_CTX
*ctx
= p
->mem_ctx
;
8396 DEBUG(5,("spoolss_deleteprinterdata\n"));
8399 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8403 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
8406 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8407 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
8408 return WERR_ACCESS_DENIED
;
8411 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8412 if (!W_ERROR_IS_OK(status
))
8415 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
8417 free_a_printer(&printer
, 2);
8421 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
);
8423 if ( W_ERROR_IS_OK(status
) )
8424 mod_a_printer( printer
, 2 );
8426 free_a_printer(&printer
, 2);
8427 TALLOC_FREE(valuename
);
8432 /****************************************************************************
8433 ****************************************************************************/
8435 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
8437 POLICY_HND
*handle
= &q_u
->handle
;
8438 FORM
*form
= &q_u
->form
;
8439 nt_forms_struct tmpForm
;
8441 WERROR status
= WERR_OK
;
8442 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8445 nt_forms_struct
*list
=NULL
;
8446 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8448 DEBUG(5,("spoolss_addform\n"));
8451 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8456 /* forms can be added on printer of on the print server handle */
8458 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8460 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8463 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8464 if (!W_ERROR_IS_OK(status
))
8468 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8469 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8470 status
= WERR_ACCESS_DENIED
;
8474 /* can't add if builtin */
8476 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8477 status
= WERR_ALREADY_EXISTS
;
8481 count
= get_ntforms(&list
);
8483 if(!add_a_form(&list
, form
, &count
)) {
8484 status
= WERR_NOMEM
;
8488 write_ntforms(&list
, count
);
8491 * ChangeID must always be set if this is a printer
8494 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8495 status
= mod_a_printer(printer
, 2);
8499 free_a_printer(&printer
, 2);
8505 /****************************************************************************
8506 ****************************************************************************/
8508 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
8510 POLICY_HND
*handle
= &q_u
->handle
;
8511 UNISTR2
*form_name
= &q_u
->name
;
8512 nt_forms_struct tmpForm
;
8514 nt_forms_struct
*list
=NULL
;
8515 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8517 WERROR status
= WERR_OK
;
8518 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8520 DEBUG(5,("spoolss_deleteform\n"));
8523 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8527 /* forms can be deleted on printer of on the print server handle */
8529 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8531 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8534 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8535 if (!W_ERROR_IS_OK(status
))
8539 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8540 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n"));
8541 status
= WERR_ACCESS_DENIED
;
8545 /* can't delete if builtin */
8547 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
8548 status
= WERR_INVALID_PARAM
;
8552 count
= get_ntforms(&list
);
8554 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
8558 * ChangeID must always be set if this is a printer
8561 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8562 status
= mod_a_printer(printer
, 2);
8566 free_a_printer(&printer
, 2);
8572 /****************************************************************************
8573 ****************************************************************************/
8575 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
8577 POLICY_HND
*handle
= &q_u
->handle
;
8578 FORM
*form
= &q_u
->form
;
8579 nt_forms_struct tmpForm
;
8581 WERROR status
= WERR_OK
;
8582 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8585 nt_forms_struct
*list
=NULL
;
8586 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8588 DEBUG(5,("spoolss_setform\n"));
8591 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8595 /* forms can be modified on printer of on the print server handle */
8597 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8599 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8602 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8603 if (!W_ERROR_IS_OK(status
))
8607 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8608 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
8609 status
= WERR_ACCESS_DENIED
;
8613 /* can't set if builtin */
8614 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8615 status
= WERR_INVALID_PARAM
;
8619 count
= get_ntforms(&list
);
8620 update_a_form(&list
, form
, count
);
8621 write_ntforms(&list
, count
);
8624 * ChangeID must always be set if this is a printer
8627 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8628 status
= mod_a_printer(printer
, 2);
8633 free_a_printer(&printer
, 2);
8639 /****************************************************************************
8640 enumprintprocessors level 1.
8641 ****************************************************************************/
8643 static WERROR
enumprintprocessors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8645 PRINTPROCESSOR_1
*info_1
=NULL
;
8646 WERROR result
= WERR_OK
;
8648 if((info_1
= SMB_MALLOC_P(PRINTPROCESSOR_1
)) == NULL
)
8653 init_unistr(&info_1
->name
, "winprint");
8655 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
8657 if (*needed
> offered
) {
8658 result
= WERR_INSUFFICIENT_BUFFER
;
8662 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8663 result
= WERR_NOMEM
;
8667 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
8672 if ( !W_ERROR_IS_OK(result
) )
8678 /****************************************************************************
8679 ****************************************************************************/
8681 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
8683 uint32 level
= q_u
->level
;
8684 RPC_BUFFER
*buffer
= NULL
;
8685 uint32 offered
= q_u
->offered
;
8686 uint32
*needed
= &r_u
->needed
;
8687 uint32
*returned
= &r_u
->returned
;
8689 /* that's an [in out] buffer */
8691 if (!q_u
->buffer
&& (offered
!=0)) {
8692 return WERR_INVALID_PARAM
;
8695 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8696 buffer
= r_u
->buffer
;
8698 DEBUG(5,("spoolss_enumprintprocessors\n"));
8701 * Enumerate the print processors ...
8703 * Just reply with "winprint", to keep NT happy
8704 * and I can use my nice printer checker.
8712 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
8714 return WERR_UNKNOWN_LEVEL
;
8718 /****************************************************************************
8719 enumprintprocdatatypes level 1.
8720 ****************************************************************************/
8722 static WERROR
enumprintprocdatatypes_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8724 PRINTPROCDATATYPE_1
*info_1
=NULL
;
8725 WERROR result
= WERR_OK
;
8727 if((info_1
= SMB_MALLOC_P(PRINTPROCDATATYPE_1
)) == NULL
)
8732 init_unistr(&info_1
->name
, "RAW");
8734 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
8736 if (*needed
> offered
) {
8737 result
= WERR_INSUFFICIENT_BUFFER
;
8741 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8742 result
= WERR_NOMEM
;
8746 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
8751 if ( !W_ERROR_IS_OK(result
) )
8757 /****************************************************************************
8758 ****************************************************************************/
8760 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
8762 uint32 level
= q_u
->level
;
8763 RPC_BUFFER
*buffer
= NULL
;
8764 uint32 offered
= q_u
->offered
;
8765 uint32
*needed
= &r_u
->needed
;
8766 uint32
*returned
= &r_u
->returned
;
8768 /* that's an [in out] buffer */
8770 if (!q_u
->buffer
&& (offered
!=0)) {
8771 return WERR_INVALID_PARAM
;
8774 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8775 buffer
= r_u
->buffer
;
8777 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8784 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
8786 return WERR_UNKNOWN_LEVEL
;
8790 /****************************************************************************
8791 enumprintmonitors level 1.
8792 ****************************************************************************/
8794 static WERROR
enumprintmonitors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8796 PRINTMONITOR_1
*info_1
;
8797 WERROR result
= WERR_OK
;
8800 if((info_1
= SMB_MALLOC_ARRAY(PRINTMONITOR_1
, 2)) == NULL
)
8805 init_unistr(&(info_1
[0].name
), SPL_LOCAL_PORT
);
8806 init_unistr(&(info_1
[1].name
), SPL_TCPIP_PORT
);
8808 for ( i
=0; i
<*returned
; i
++ ) {
8809 *needed
+= spoolss_size_printmonitor_info_1(&info_1
[i
]);
8812 if (*needed
> offered
) {
8813 result
= WERR_INSUFFICIENT_BUFFER
;
8817 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8818 result
= WERR_NOMEM
;
8822 for ( i
=0; i
<*returned
; i
++ ) {
8823 smb_io_printmonitor_info_1("", buffer
, &info_1
[i
], 0);
8829 if ( !W_ERROR_IS_OK(result
) )
8835 /****************************************************************************
8836 enumprintmonitors level 2.
8837 ****************************************************************************/
8839 static WERROR
enumprintmonitors_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8841 PRINTMONITOR_2
*info_2
;
8842 WERROR result
= WERR_OK
;
8845 if((info_2
= SMB_MALLOC_ARRAY(PRINTMONITOR_2
, 2)) == NULL
)
8850 init_unistr( &(info_2
[0].name
), SPL_LOCAL_PORT
);
8851 init_unistr( &(info_2
[0].environment
), "Windows NT X86" );
8852 init_unistr( &(info_2
[0].dll_name
), "localmon.dll" );
8854 init_unistr( &(info_2
[1].name
), SPL_TCPIP_PORT
);
8855 init_unistr( &(info_2
[1].environment
), "Windows NT X86" );
8856 init_unistr( &(info_2
[1].dll_name
), "tcpmon.dll" );
8858 for ( i
=0; i
<*returned
; i
++ ) {
8859 *needed
+= spoolss_size_printmonitor_info_2(&info_2
[i
]);
8862 if (*needed
> offered
) {
8863 result
= WERR_INSUFFICIENT_BUFFER
;
8867 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8868 result
= WERR_NOMEM
;
8872 for ( i
=0; i
<*returned
; i
++ ) {
8873 smb_io_printmonitor_info_2("", buffer
, &info_2
[i
], 0);
8879 if ( !W_ERROR_IS_OK(result
) )
8885 /****************************************************************************
8886 ****************************************************************************/
8888 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
8890 uint32 level
= q_u
->level
;
8891 RPC_BUFFER
*buffer
= NULL
;
8892 uint32 offered
= q_u
->offered
;
8893 uint32
*needed
= &r_u
->needed
;
8894 uint32
*returned
= &r_u
->returned
;
8896 /* that's an [in out] buffer */
8898 if (!q_u
->buffer
&& (offered
!=0)) {
8899 return WERR_INVALID_PARAM
;
8902 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8903 buffer
= r_u
->buffer
;
8905 DEBUG(5,("spoolss_enumprintmonitors\n"));
8908 * Enumerate the print monitors ...
8910 * Just reply with "Local Port", to keep NT happy
8911 * and I can use my nice printer checker.
8919 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
8921 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
8923 return WERR_UNKNOWN_LEVEL
;
8927 /****************************************************************************
8928 ****************************************************************************/
8930 static WERROR
getjob_level_1(print_queue_struct
**queue
, int count
, int snum
,
8931 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8932 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8937 JOB_INFO_1
*info_1
=NULL
;
8938 WERROR result
= WERR_OK
;
8940 info_1
=SMB_MALLOC_P(JOB_INFO_1
);
8942 if (info_1
== NULL
) {
8946 for (i
=0; i
<count
&& found
==False
; i
++) {
8947 if ((*queue
)[i
].job
==(int)jobid
)
8953 /* NT treats not found as bad param... yet another bad choice */
8954 return WERR_INVALID_PARAM
;
8957 fill_job_info_1( info_1
, &((*queue
)[i
-1]), i
, snum
, ntprinter
);
8959 *needed
+= spoolss_size_job_info_1(info_1
);
8961 if (*needed
> offered
) {
8962 result
= WERR_INSUFFICIENT_BUFFER
;
8966 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8967 result
= WERR_NOMEM
;
8971 smb_io_job_info_1("", buffer
, info_1
, 0);
8979 /****************************************************************************
8980 ****************************************************************************/
8982 static WERROR
getjob_level_2(print_queue_struct
**queue
, int count
, int snum
,
8983 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8984 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8991 DEVICEMODE
*devmode
= NULL
;
8992 NT_DEVICEMODE
*nt_devmode
= NULL
;
8994 if ( !(info_2
=SMB_MALLOC_P(JOB_INFO_2
)) )
8997 ZERO_STRUCTP(info_2
);
8999 for ( i
=0; i
<count
&& found
==False
; i
++ )
9001 if ((*queue
)[i
].job
== (int)jobid
)
9006 /* NT treats not found as bad param... yet another bad
9008 result
= WERR_INVALID_PARAM
;
9013 * if the print job does not have a DEVMODE associated with it,
9014 * just use the one for the printer. A NULL devicemode is not
9015 * a failure condition
9018 if ( !(nt_devmode
=print_job_devmode( lp_const_servicename(snum
), jobid
)) )
9019 devmode
= construct_dev_mode(lp_const_servicename(snum
));
9021 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) != NULL
) {
9022 ZERO_STRUCTP( devmode
);
9023 convert_nt_devicemode( devmode
, nt_devmode
);
9027 fill_job_info_2(info_2
, &((*queue
)[i
-1]), i
, snum
, ntprinter
, devmode
);
9029 *needed
+= spoolss_size_job_info_2(info_2
);
9031 if (*needed
> offered
) {
9032 result
= WERR_INSUFFICIENT_BUFFER
;
9036 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9037 result
= WERR_NOMEM
;
9041 smb_io_job_info_2("", buffer
, info_2
, 0);
9046 /* Cleanup allocated memory */
9048 free_job_info_2(info_2
); /* Also frees devmode */
9054 /****************************************************************************
9055 ****************************************************************************/
9057 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
9059 POLICY_HND
*handle
= &q_u
->handle
;
9060 uint32 jobid
= q_u
->jobid
;
9061 uint32 level
= q_u
->level
;
9062 RPC_BUFFER
*buffer
= NULL
;
9063 uint32 offered
= q_u
->offered
;
9064 uint32
*needed
= &r_u
->needed
;
9065 WERROR wstatus
= WERR_OK
;
9066 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9069 print_queue_struct
*queue
= NULL
;
9070 print_status_struct prt_status
;
9072 /* that's an [in out] buffer */
9074 if (!q_u
->buffer
&& (offered
!=0)) {
9075 return WERR_INVALID_PARAM
;
9078 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9079 buffer
= r_u
->buffer
;
9081 DEBUG(5,("spoolss_getjob\n"));
9085 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9088 wstatus
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9089 if ( !W_ERROR_IS_OK(wstatus
) )
9092 count
= print_queue_status(snum
, &queue
, &prt_status
);
9094 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9095 count
, prt_status
.status
, prt_status
.message
));
9099 wstatus
= getjob_level_1(&queue
, count
, snum
, ntprinter
, jobid
,
9100 buffer
, offered
, needed
);
9103 wstatus
= getjob_level_2(&queue
, count
, snum
, ntprinter
, jobid
,
9104 buffer
, offered
, needed
);
9107 wstatus
= WERR_UNKNOWN_LEVEL
;
9112 free_a_printer( &ntprinter
, 2 );
9117 /********************************************************************
9118 spoolss_getprinterdataex
9120 From MSDN documentation of GetPrinterDataEx: pass request
9121 to GetPrinterData if key is "PrinterDriverData".
9122 ********************************************************************/
9124 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
9126 POLICY_HND
*handle
= &q_u
->handle
;
9127 uint32 in_size
= q_u
->size
;
9128 uint32
*type
= &r_u
->type
;
9129 uint32
*out_size
= &r_u
->size
;
9130 uint8
**data
= &r_u
->data
;
9131 uint32
*needed
= &r_u
->needed
;
9132 fstring keyname
, valuename
;
9134 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9136 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9138 WERROR status
= WERR_OK
;
9140 DEBUG(4,("_spoolss_getprinterdataex\n"));
9142 unistr2_to_ascii(keyname
, &q_u
->keyname
, sizeof(keyname
));
9143 unistr2_to_ascii(valuename
, &q_u
->valuename
, sizeof(valuename
));
9145 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9146 keyname
, valuename
));
9148 /* in case of problem, return some default values */
9152 *out_size
= in_size
;
9155 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9156 status
= WERR_BADFID
;
9160 /* Is the handle to a printer or to the server? */
9162 if (Printer
->printer_type
== SPLHND_SERVER
) {
9163 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9164 status
= WERR_INVALID_PARAM
;
9168 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9171 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9172 if ( !W_ERROR_IS_OK(status
) )
9175 /* check to see if the keyname is valid */
9176 if ( !strlen(keyname
) ) {
9177 status
= WERR_INVALID_PARAM
;
9181 if ( lookup_printerkey( printer
->info_2
->data
, keyname
) == -1 ) {
9182 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname
));
9183 free_a_printer( &printer
, 2 );
9184 status
= WERR_BADFILE
;
9188 /* When given a new keyname, we should just create it */
9190 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
, type
, data
, needed
, in_size
);
9192 if (*needed
> *out_size
)
9193 status
= WERR_MORE_DATA
;
9196 if ( !W_ERROR_IS_OK(status
) )
9198 DEBUG(5, ("error: allocating %d\n", *out_size
));
9200 /* reply this param doesn't exist */
9204 if( (*data
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
) {
9205 status
= WERR_NOMEM
;
9214 free_a_printer( &printer
, 2 );
9219 /********************************************************************
9220 * spoolss_setprinterdataex
9221 ********************************************************************/
9223 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
9225 POLICY_HND
*handle
= &q_u
->handle
;
9226 uint32 type
= q_u
->type
;
9227 uint8
*data
= q_u
->data
;
9228 uint32 real_len
= q_u
->real_len
;
9230 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9232 WERROR status
= WERR_OK
;
9233 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9238 DEBUG(4,("_spoolss_setprinterdataex\n"));
9240 /* From MSDN documentation of SetPrinterDataEx: pass request to
9241 SetPrinterData if key is "PrinterDriverData" */
9244 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9248 if ( Printer
->printer_type
== SPLHND_SERVER
) {
9249 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9250 return WERR_INVALID_PARAM
;
9253 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9257 * Access check : NT returns "access denied" if you make a
9258 * SetPrinterData call without the necessary privildge.
9259 * we were originally returning OK if nothing changed
9260 * which made Win2k issue **a lot** of SetPrinterData
9261 * when connecting to a printer --jerry
9264 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
9266 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9267 return WERR_ACCESS_DENIED
;
9270 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9271 if (!W_ERROR_IS_OK(status
))
9274 unistr2_to_ascii( valuename
, &q_u
->value
, sizeof(valuename
));
9275 unistr2_to_ascii( keyname
, &q_u
->key
, sizeof(keyname
));
9277 /* check for OID in valuename */
9279 if ( (oid_string
= strchr( valuename
, ',' )) != NULL
)
9285 /* save the registry data */
9287 status
= set_printer_dataex( printer
, keyname
, valuename
, type
, data
, real_len
);
9289 if ( W_ERROR_IS_OK(status
) )
9291 /* save the OID if one was specified */
9293 fstrcat( keyname
, "\\" );
9294 fstrcat( keyname
, SPOOL_OID_KEY
);
9297 * I'm not checking the status here on purpose. Don't know
9298 * if this is right, but I'm returning the status from the
9299 * previous set_printer_dataex() call. I have no idea if
9300 * this is right. --jerry
9303 set_printer_dataex( printer
, keyname
, valuename
,
9304 REG_SZ
, (uint8
*)oid_string
,
9305 strlen(oid_string
)+1 );
9308 status
= mod_a_printer(printer
, 2);
9311 free_a_printer(&printer
, 2);
9317 /********************************************************************
9318 * spoolss_deleteprinterdataex
9319 ********************************************************************/
9321 WERROR
_spoolss_deleteprinterdataex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATAEX
*q_u
, SPOOL_R_DELETEPRINTERDATAEX
*r_u
)
9323 POLICY_HND
*handle
= &q_u
->handle
;
9324 UNISTR2
*value
= &q_u
->valuename
;
9325 UNISTR2
*key
= &q_u
->keyname
;
9327 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9329 WERROR status
= WERR_OK
;
9330 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
9331 char *valuename
= NULL
;
9332 char *keyname
= NULL
;
9333 TALLOC_CTX
*ctx
= p
->mem_ctx
;
9335 DEBUG(5,("spoolss_deleteprinterdataex\n"));
9338 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9342 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9345 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9346 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
9347 return WERR_ACCESS_DENIED
;
9350 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
9351 keyname
= unistr2_to_ascii_talloc(ctx
, key
);
9352 if (!valuename
|| !keyname
) {
9356 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9357 if (!W_ERROR_IS_OK(status
))
9360 status
= delete_printer_dataex( printer
, keyname
, valuename
);
9362 if ( W_ERROR_IS_OK(status
) )
9363 mod_a_printer( printer
, 2 );
9365 free_a_printer(&printer
, 2);
9370 /********************************************************************
9371 * spoolss_enumprinterkey
9372 ********************************************************************/
9375 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
9378 fstring
*keynames
= NULL
;
9379 uint16
*enumkeys
= NULL
;
9382 POLICY_HND
*handle
= &q_u
->handle
;
9383 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9384 NT_PRINTER_DATA
*data
;
9385 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9387 WERROR status
= WERR_BADFILE
;
9390 DEBUG(4,("_spoolss_enumprinterkey\n"));
9393 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9397 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9400 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9401 if (!W_ERROR_IS_OK(status
))
9404 /* get the list of subkey names */
9406 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9407 data
= printer
->info_2
->data
;
9409 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
9411 if ( num_keys
== -1 ) {
9412 status
= WERR_BADFILE
;
9416 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
9418 r_u
->needed
= printerkey_len
*2;
9420 if ( q_u
->size
< r_u
->needed
) {
9421 status
= WERR_MORE_DATA
;
9425 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
9426 status
= WERR_NOMEM
;
9432 if ( q_u
->size
< r_u
->needed
)
9433 status
= WERR_MORE_DATA
;
9436 free_a_printer( &printer
, 2 );
9437 SAFE_FREE( keynames
);
9442 /********************************************************************
9443 * spoolss_deleteprinterkey
9444 ********************************************************************/
9446 WERROR
_spoolss_deleteprinterkey(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERKEY
*q_u
, SPOOL_R_DELETEPRINTERKEY
*r_u
)
9448 POLICY_HND
*handle
= &q_u
->handle
;
9449 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9451 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9455 DEBUG(5,("spoolss_deleteprinterkey\n"));
9458 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9462 /* if keyname == NULL, return error */
9464 if ( !q_u
->keyname
.buffer
)
9465 return WERR_INVALID_PARAM
;
9467 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9470 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9471 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
9472 return WERR_ACCESS_DENIED
;
9475 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9476 if (!W_ERROR_IS_OK(status
))
9479 /* delete the key and all subneys */
9481 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
));
9483 status
= delete_all_printer_data( printer
->info_2
, key
);
9485 if ( W_ERROR_IS_OK(status
) )
9486 status
= mod_a_printer(printer
, 2);
9488 free_a_printer( &printer
, 2 );
9494 /********************************************************************
9495 * spoolss_enumprinterdataex
9496 ********************************************************************/
9498 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
9500 POLICY_HND
*handle
= &q_u
->handle
;
9501 uint32 in_size
= q_u
->size
;
9504 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9505 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
9506 NT_PRINTER_DATA
*p_data
;
9508 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9513 REGISTRY_VALUE
*val
;
9518 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9521 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
9526 * first check for a keyname of NULL or "". Win2k seems to send
9527 * this a lot and we should send back WERR_INVALID_PARAM
9528 * no need to spend time looking up the printer in this case.
9532 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9533 if ( !strlen(key
) ) {
9534 result
= WERR_INVALID_PARAM
;
9538 /* get the printer off of disk */
9540 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
9543 ZERO_STRUCT(printer
);
9544 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9545 if (!W_ERROR_IS_OK(result
))
9548 /* now look for a match on the key name */
9550 p_data
= printer
->info_2
->data
;
9552 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9553 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
9555 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
9556 result
= WERR_INVALID_PARAM
;
9563 /* allocate the memory for the array of pointers -- if necessary */
9565 num_entries
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
9568 if ( (enum_values
=TALLOC_ARRAY(p
->mem_ctx
, PRINTER_ENUM_VALUES
, num_entries
)) == NULL
)
9570 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9571 (unsigned long)num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
9572 result
= WERR_NOMEM
;
9576 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
9580 * loop through all params and build the array to pass
9581 * back to the client
9584 for ( i
=0; i
<num_entries
; i
++ )
9586 /* lookup the registry value */
9588 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
9589 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
9593 value_name
= regval_name( val
);
9594 init_unistr( &enum_values
[i
].valuename
, value_name
);
9595 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
9596 enum_values
[i
].type
= regval_type( val
);
9598 data_len
= regval_size( val
);
9600 if ( !(enum_values
[i
].data
= (uint8
*)TALLOC_MEMDUP(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
9602 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9604 result
= WERR_NOMEM
;
9608 enum_values
[i
].data_len
= data_len
;
9610 /* keep track of the size of the array in bytes */
9612 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
9615 /* housekeeping information in the reply */
9617 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9618 * the hand marshalled container size is a multiple
9619 * of 4 bytes for RPC alignment.
9623 needed
+= 4-(needed
% 4);
9626 r_u
->needed
= needed
;
9627 r_u
->returned
= num_entries
;
9629 if (needed
> in_size
) {
9630 result
= WERR_MORE_DATA
;
9634 /* copy data into the reply */
9636 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9637 response buffer size is != the offered buffer size
9639 r_u->ctr.size = r_u->needed;
9641 r_u
->ctr
.size
= in_size
;
9643 r_u
->ctr
.size_of_array
= r_u
->returned
;
9644 r_u
->ctr
.values
= enum_values
;
9648 free_a_printer(&printer
, 2);
9653 /****************************************************************************
9654 ****************************************************************************/
9656 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, const char *name
)
9658 init_unistr(&info
->name
, name
);
9661 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
9662 UNISTR2
*environment
,
9667 char *long_archi
= NULL
;
9668 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
9669 WERROR result
= WERR_OK
;
9670 TALLOC_CTX
*ctx
= talloc_tos();
9672 long_archi
= unistr2_to_ascii_talloc(ctx
, environment
);
9677 if (!get_short_archi(long_archi
))
9678 return WERR_INVALID_ENVIRONMENT
;
9680 if((info
=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1
)) == NULL
)
9683 fill_printprocessordirectory_1(info
, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9685 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
9687 if (*needed
> offered
) {
9688 result
= WERR_INSUFFICIENT_BUFFER
;
9692 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9693 result
= WERR_INSUFFICIENT_BUFFER
;
9697 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
9705 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
9707 uint32 level
= q_u
->level
;
9708 RPC_BUFFER
*buffer
= NULL
;
9709 uint32 offered
= q_u
->offered
;
9710 uint32
*needed
= &r_u
->needed
;
9713 /* that's an [in out] buffer */
9715 if (!q_u
->buffer
&& (offered
!=0)) {
9716 return WERR_INVALID_PARAM
;
9719 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9720 buffer
= r_u
->buffer
;
9722 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9728 result
= getprintprocessordirectory_level_1
9729 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
9732 result
= WERR_UNKNOWN_LEVEL
;
9738 /*******************************************************************
9739 Streams the monitor UI DLL name in UNICODE
9740 *******************************************************************/
9742 static WERROR
xcvtcp_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9743 RPC_BUFFER
*out
, uint32
*needed
)
9745 const char *dllname
= "tcpmonui.dll";
9747 *needed
= (strlen(dllname
)+1) * 2;
9749 if ( rpcbuf_get_size(out
) < *needed
) {
9750 return WERR_INSUFFICIENT_BUFFER
;
9753 if ( !make_monitorui_buf( out
, dllname
) ) {
9760 /*******************************************************************
9761 Create a new TCP/IP port
9762 *******************************************************************/
9764 static WERROR
xcvtcp_addport( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9765 RPC_BUFFER
*out
, uint32
*needed
)
9767 NT_PORT_DATA_1 port1
;
9768 TALLOC_CTX
*ctx
= talloc_tos();
9769 char *device_uri
= NULL
;
9771 ZERO_STRUCT( port1
);
9773 /* convert to our internal port data structure */
9775 if ( !convert_port_data_1( &port1
, in
) ) {
9779 /* create the device URI and call the add_port_hook() */
9781 switch ( port1
.protocol
) {
9782 case PORT_PROTOCOL_DIRECT
:
9783 device_uri
= talloc_asprintf(ctx
,
9784 "socket://%s:%d/", port1
.hostaddr
, port1
.port
);
9787 case PORT_PROTOCOL_LPR
:
9788 device_uri
= talloc_asprintf(ctx
,
9789 "lpr://%s/%s", port1
.hostaddr
, port1
.queue
);
9793 return WERR_UNKNOWN_PORT
;
9800 return add_port_hook(ctx
, token
, port1
.name
, device_uri
);
9803 /*******************************************************************
9804 *******************************************************************/
9806 struct xcv_api_table xcvtcp_cmds
[] = {
9807 { "MonitorUI", xcvtcp_monitorui
},
9808 { "AddPort", xcvtcp_addport
},
9812 static WERROR
process_xcvtcp_command( NT_USER_TOKEN
*token
, const char *command
,
9813 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9818 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9820 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9821 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9822 return xcvtcp_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9825 return WERR_BADFUNC
;
9828 /*******************************************************************
9829 *******************************************************************/
9830 #if 0 /* don't support management using the "Local Port" monitor */
9832 static WERROR
xcvlocal_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9833 RPC_BUFFER
*out
, uint32
*needed
)
9835 const char *dllname
= "localui.dll";
9837 *needed
= (strlen(dllname
)+1) * 2;
9839 if ( rpcbuf_get_size(out
) < *needed
) {
9840 return WERR_INSUFFICIENT_BUFFER
;
9843 if ( !make_monitorui_buf( out
, dllname
)) {
9850 /*******************************************************************
9851 *******************************************************************/
9853 struct xcv_api_table xcvlocal_cmds
[] = {
9854 { "MonitorUI", xcvlocal_monitorui
},
9858 struct xcv_api_table xcvlocal_cmds
[] = {
9865 /*******************************************************************
9866 *******************************************************************/
9868 static WERROR
process_xcvlocal_command( NT_USER_TOKEN
*token
, const char *command
,
9869 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9874 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9876 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9877 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9878 return xcvlocal_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9880 return WERR_BADFUNC
;
9883 /*******************************************************************
9884 *******************************************************************/
9886 WERROR
_spoolss_xcvdataport(pipes_struct
*p
, SPOOL_Q_XCVDATAPORT
*q_u
, SPOOL_R_XCVDATAPORT
*r_u
)
9888 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9892 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u
->handle
)));
9896 /* Has to be a handle to the TCP/IP port monitor */
9898 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9899 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9903 /* requires administrative access to the server */
9905 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9906 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9907 return WERR_ACCESS_DENIED
;
9910 /* Get the command name. There's numerous commands supported by the
9911 TCPMON interface. */
9913 rpcstr_pull(command
, q_u
->dataname
.buffer
, sizeof(command
),
9914 q_u
->dataname
.uni_str_len
*2, 0);
9916 /* Allocate the outgoing buffer */
9918 rpcbuf_init( &r_u
->outdata
, q_u
->offered
, p
->mem_ctx
);
9920 switch ( Printer
->printer_type
) {
9921 case SPLHND_PORTMON_TCP
:
9922 return process_xcvtcp_command( p
->pipe_user
.nt_user_token
, command
,
9923 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9924 case SPLHND_PORTMON_LOCAL
:
9925 return process_xcvlocal_command( p
->pipe_user
.nt_user_token
, command
,
9926 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9929 return WERR_INVALID_PRINT_MONITOR
;