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( notify_cli_pipe
->cli
);
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
), NULL
,
1653 p
->pipe_user
.nt_user_token
,
1654 lp_printer_admin(snum
))) {
1655 close_printer_handle(p
, handle
);
1656 return WERR_ACCESS_DENIED
;
1659 printer_default
->access_required
= SERVER_ACCESS_ADMINISTER
;
1663 printer_default
->access_required
= SERVER_ACCESS_ENUMERATE
;
1666 DEBUG(4,("Setting print server access = %s\n", (printer_default
->access_required
== SERVER_ACCESS_ADMINISTER
)
1667 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1669 /* We fall through to return WERR_OK */
1672 case SPLHND_PRINTER
:
1673 /* NT doesn't let us connect to a printer if the connecting user
1674 doesn't have print permission. */
1676 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
1677 close_printer_handle(p
, handle
);
1681 se_map_standard(&printer_default
->access_required
, &printer_std_mapping
);
1683 /* map an empty access mask to the minimum access mask */
1684 if (printer_default
->access_required
== 0x0)
1685 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1688 * If we are not serving the printer driver for this printer,
1689 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1690 * will keep NT clients happy --jerry
1693 if (lp_use_client_driver(snum
)
1694 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
1696 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1699 /* check smb.conf parameters and the the sec_desc */
1701 if ( !check_access(smbd_server_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1702 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1703 return WERR_ACCESS_DENIED
;
1706 if (!user_ok_token(uidtoname(p
->pipe_user
.ut
.uid
),
1707 p
->pipe_user
.nt_user_token
, snum
) ||
1708 !print_access_check(&p
->pipe_user
, snum
,
1709 printer_default
->access_required
)) {
1710 DEBUG(3, ("access DENIED for printer open\n"));
1711 close_printer_handle(p
, handle
);
1712 return WERR_ACCESS_DENIED
;
1715 if ((printer_default
->access_required
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1716 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1717 close_printer_handle(p
, handle
);
1718 return WERR_ACCESS_DENIED
;
1721 if (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
)
1722 printer_default
->access_required
= PRINTER_ACCESS_ADMINISTER
;
1724 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1726 DEBUG(4,("Setting printer access = %s\n", (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1727 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1732 /* sanity check to prevent programmer error */
1736 Printer
->access_granted
= printer_default
->access_required
;
1739 * If the client sent a devmode in the OpenPrinter() call, then
1740 * save it here in case we get a job submission on this handle
1743 if ( (Printer
->printer_type
!= SPLHND_SERVER
)
1744 && q_u
->printer_default
.devmode_cont
.devmode_ptr
)
1746 convert_devicemode( Printer
->sharename
, q_u
->printer_default
.devmode_cont
.devmode
,
1747 &Printer
->nt_devmode
);
1750 #if 0 /* JERRY -- I'm doubtful this is really effective */
1751 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1752 optimization in Windows 2000 clients --jerry */
1754 if ( (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1755 && (RA_WIN2K
== get_remote_arch()) )
1757 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1758 sys_usleep( 500000 );
1765 /****************************************************************************
1766 ****************************************************************************/
1768 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
1769 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
1775 /* allocate memory if needed. Messy because
1776 convert_printer_info is used to update an existing
1777 printer or build a new one */
1779 if ( !printer
->info_2
) {
1780 printer
->info_2
= TALLOC_ZERO_P( printer
, NT_PRINTER_INFO_LEVEL_2
);
1781 if ( !printer
->info_2
) {
1782 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1787 ret
= uni_2_asc_printer_info_2(uni
->info_2
, printer
->info_2
);
1788 printer
->info_2
->setuptime
= time(NULL
);
1796 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
1797 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
1803 printer
->info_3
=NULL
;
1804 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
1808 printer
->info_6
=NULL
;
1809 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
1819 bool convert_devicemode(const char *printername
, const DEVICEMODE
*devmode
,
1820 NT_DEVICEMODE
**pp_nt_devmode
)
1822 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1825 * Ensure nt_devmode is a valid pointer
1826 * as we will be overwriting it.
1829 if (nt_devmode
== NULL
) {
1830 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1831 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1835 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
1836 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
1838 nt_devmode
->specversion
=devmode
->specversion
;
1839 nt_devmode
->driverversion
=devmode
->driverversion
;
1840 nt_devmode
->size
=devmode
->size
;
1841 nt_devmode
->fields
=devmode
->fields
;
1842 nt_devmode
->orientation
=devmode
->orientation
;
1843 nt_devmode
->papersize
=devmode
->papersize
;
1844 nt_devmode
->paperlength
=devmode
->paperlength
;
1845 nt_devmode
->paperwidth
=devmode
->paperwidth
;
1846 nt_devmode
->scale
=devmode
->scale
;
1847 nt_devmode
->copies
=devmode
->copies
;
1848 nt_devmode
->defaultsource
=devmode
->defaultsource
;
1849 nt_devmode
->printquality
=devmode
->printquality
;
1850 nt_devmode
->color
=devmode
->color
;
1851 nt_devmode
->duplex
=devmode
->duplex
;
1852 nt_devmode
->yresolution
=devmode
->yresolution
;
1853 nt_devmode
->ttoption
=devmode
->ttoption
;
1854 nt_devmode
->collate
=devmode
->collate
;
1856 nt_devmode
->logpixels
=devmode
->logpixels
;
1857 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
1858 nt_devmode
->pelswidth
=devmode
->pelswidth
;
1859 nt_devmode
->pelsheight
=devmode
->pelsheight
;
1860 nt_devmode
->displayflags
=devmode
->displayflags
;
1861 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
1862 nt_devmode
->icmmethod
=devmode
->icmmethod
;
1863 nt_devmode
->icmintent
=devmode
->icmintent
;
1864 nt_devmode
->mediatype
=devmode
->mediatype
;
1865 nt_devmode
->dithertype
=devmode
->dithertype
;
1866 nt_devmode
->reserved1
=devmode
->reserved1
;
1867 nt_devmode
->reserved2
=devmode
->reserved2
;
1868 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1869 nt_devmode
->panningheight
=devmode
->panningheight
;
1872 * Only change private and driverextra if the incoming devmode
1873 * has a new one. JRA.
1876 if ((devmode
->driverextra
!= 0) && (devmode
->dev_private
!= NULL
)) {
1877 SAFE_FREE(nt_devmode
->nt_dev_private
);
1878 nt_devmode
->driverextra
=devmode
->driverextra
;
1879 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1881 memcpy(nt_devmode
->nt_dev_private
, devmode
->dev_private
, nt_devmode
->driverextra
);
1884 *pp_nt_devmode
= nt_devmode
;
1889 /********************************************************************
1890 * _spoolss_enddocprinter_internal.
1891 ********************************************************************/
1893 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1895 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1899 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
1903 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
1906 Printer
->document_started
=False
;
1907 print_job_end(snum
, Printer
->jobid
,NORMAL_CLOSE
);
1908 /* error codes unhandled so far ... */
1913 /********************************************************************
1914 * api_spoolss_closeprinter
1915 ********************************************************************/
1917 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1919 POLICY_HND
*handle
= &q_u
->handle
;
1921 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1923 if (Printer
&& Printer
->document_started
)
1924 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1926 if (!close_printer_handle(p
, handle
))
1929 /* clear the returned printer handle. Observed behavior
1930 from Win2k server. Don't think this really matters.
1931 Previous code just copied the value of the closed
1934 memset(&r_u
->handle
, '\0', sizeof(r_u
->handle
));
1939 /********************************************************************
1940 * api_spoolss_deleteprinter
1942 ********************************************************************/
1944 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1946 POLICY_HND
*handle
= &q_u
->handle
;
1947 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1950 if (Printer
&& Printer
->document_started
)
1951 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1953 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1955 result
= delete_printer_handle(p
, handle
);
1957 update_c_setprinter(False
);
1962 /*******************************************************************
1963 * static function to lookup the version id corresponding to an
1964 * long architecture string
1965 ******************************************************************/
1967 static int get_version_id (char * arch
)
1970 struct table_node archi_table
[]= {
1972 {"Windows 4.0", "WIN40", 0 },
1973 {"Windows NT x86", "W32X86", 2 },
1974 {"Windows NT R4000", "W32MIPS", 2 },
1975 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1976 {"Windows NT PowerPC", "W32PPC", 2 },
1977 {"Windows IA64", "IA64", 3 },
1978 {"Windows x64", "x64", 3 },
1982 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1984 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1985 return (archi_table
[i
].version
);
1991 /********************************************************************
1992 * _spoolss_deleteprinterdriver
1993 ********************************************************************/
1995 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
, SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1999 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2000 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2003 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2004 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2006 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2007 and not a printer admin, then fail */
2009 if ( (p
->pipe_user
.ut
.uid
!= 0)
2010 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2011 && !token_contains_name_in_list( uidtoname(p
->pipe_user
.ut
.uid
),
2012 NULL
, p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2014 return WERR_ACCESS_DENIED
;
2017 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2018 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2020 /* check that we have a valid driver name first */
2022 if ((version
=get_version_id(arch
)) == -1)
2023 return WERR_INVALID_ENVIRONMENT
;
2026 ZERO_STRUCT(info_win2k
);
2028 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
2030 /* try for Win2k driver if "Windows NT x86" */
2032 if ( version
== 2 ) {
2034 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2035 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2039 /* otherwise it was a failure */
2041 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2047 if (printer_driver_in_use(info
.info_3
)) {
2048 status
= WERR_PRINTER_DRIVER_IN_USE
;
2054 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2056 /* if we get to here, we now have 2 driver info structures to remove */
2057 /* remove the Win2k driver first*/
2059 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, False
);
2060 free_a_printer_driver( info_win2k
, 3 );
2062 /* this should not have failed---if it did, report to client */
2063 if ( !W_ERROR_IS_OK(status_win2k
) )
2065 status
= status_win2k
;
2071 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, False
);
2073 /* if at least one of the deletes succeeded return OK */
2075 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2079 free_a_printer_driver( info
, 3 );
2084 /********************************************************************
2085 * spoolss_deleteprinterdriverex
2086 ********************************************************************/
2088 WERROR
_spoolss_deleteprinterdriverex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVEREX
*q_u
, SPOOL_R_DELETEPRINTERDRIVEREX
*r_u
)
2092 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2093 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2095 uint32 flags
= q_u
->delete_flags
;
2098 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2099 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2101 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2102 and not a printer admin, then fail */
2104 if ( (p
->pipe_user
.ut
.uid
!= 0)
2105 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2106 && !token_contains_name_in_list( uidtoname(p
->pipe_user
.ut
.uid
),
2107 NULL
, p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2109 return WERR_ACCESS_DENIED
;
2112 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2113 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2115 /* check that we have a valid driver name first */
2116 if ((version
=get_version_id(arch
)) == -1) {
2117 /* this is what NT returns */
2118 return WERR_INVALID_ENVIRONMENT
;
2121 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
2122 version
= q_u
->version
;
2125 ZERO_STRUCT(info_win2k
);
2127 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
2129 if ( !W_ERROR_IS_OK(status
) )
2132 * if the client asked for a specific version,
2133 * or this is something other than Windows NT x86,
2137 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2140 /* try for Win2k driver if "Windows NT x86" */
2143 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2144 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2149 if ( printer_driver_in_use(info
.info_3
) ) {
2150 status
= WERR_PRINTER_DRIVER_IN_USE
;
2155 * we have a couple of cases to consider.
2156 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2157 * then the delete should fail if **any** files overlap with
2159 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2160 * non-overlapping files
2161 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2162 * is set, the do not delete any files
2163 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2166 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2168 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2170 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2171 /* no idea of the correct error here */
2172 status
= WERR_ACCESS_DENIED
;
2177 /* also check for W32X86/3 if necessary; maybe we already have? */
2179 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2180 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2183 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2184 /* no idea of the correct error here */
2185 free_a_printer_driver( info_win2k
, 3 );
2186 status
= WERR_ACCESS_DENIED
;
2190 /* if we get to here, we now have 2 driver info structures to remove */
2191 /* remove the Win2k driver first*/
2193 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, delete_files
);
2194 free_a_printer_driver( info_win2k
, 3 );
2196 /* this should not have failed---if it did, report to client */
2198 if ( !W_ERROR_IS_OK(status_win2k
) )
2203 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, delete_files
);
2205 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2208 free_a_printer_driver( info
, 3 );
2214 /****************************************************************************
2215 Internal routine for retreiving printerdata
2216 ***************************************************************************/
2218 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2219 const char *key
, const char *value
, uint32
*type
, uint8
**data
,
2220 uint32
*needed
, uint32 in_size
)
2222 REGISTRY_VALUE
*val
;
2226 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2227 return WERR_BADFILE
;
2229 *type
= regval_type( val
);
2231 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2233 size
= regval_size( val
);
2235 /* copy the min(in_size, len) */
2238 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2240 /* special case for 0 length values */
2242 if ( (*data
= (uint8
*)TALLOC_MEMDUP(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2246 if ( (*data
= (uint8
*)TALLOC_ZERO(ctx
, in_size
)) == NULL
)
2255 DEBUG(5,("get_printer_dataex: copy done\n"));
2260 /****************************************************************************
2261 Internal routine for removing printerdata
2262 ***************************************************************************/
2264 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2266 return delete_printer_data( printer
->info_2
, key
, value
);
2269 /****************************************************************************
2270 Internal routine for storing printerdata
2271 ***************************************************************************/
2273 WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
,
2274 uint32 type
, uint8
*data
, int real_len
)
2276 /* the registry objects enforce uniqueness based on value name */
2278 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2281 /********************************************************************
2282 GetPrinterData on a printer server Handle.
2283 ********************************************************************/
2285 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2289 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2291 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2293 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2295 SIVAL(*data
, 0, 0x00);
2300 if (!StrCaseCmp(value
, "BeepEnabled")) {
2302 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2304 SIVAL(*data
, 0, 0x00);
2309 if (!StrCaseCmp(value
, "EventLog")) {
2311 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2313 /* formally was 0x1b */
2314 SIVAL(*data
, 0, 0x0);
2319 if (!StrCaseCmp(value
, "NetPopup")) {
2321 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2323 SIVAL(*data
, 0, 0x00);
2328 if (!StrCaseCmp(value
, "MajorVersion")) {
2330 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2333 /* Windows NT 4.0 seems to not allow uploading of drivers
2334 to a server that reports 0x3 as the MajorVersion.
2335 need to investigate more how Win2k gets around this .
2338 if ( RA_WINNT
== get_remote_arch() )
2347 if (!StrCaseCmp(value
, "MinorVersion")) {
2349 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2357 * uint32 size = 0x114
2359 * uint32 minor = [0|1]
2360 * uint32 build = [2195|2600]
2361 * extra unicode string = e.g. "Service Pack 3"
2363 if (!StrCaseCmp(value
, "OSVersion")) {
2367 if ( !(*data
= TALLOC_ZERO_ARRAY(ctx
, uint8
, (*needed
> in_size
) ? *needed
:in_size
)) )
2370 SIVAL(*data
, 0, *needed
); /* size */
2371 SIVAL(*data
, 4, 5); /* Windows 2000 == 5.0 */
2373 SIVAL(*data
, 12, 2195); /* build */
2375 /* leave extra string empty */
2381 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2382 const char *string
="C:\\PRINTERS";
2384 *needed
= 2*(strlen(string
)+1);
2385 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2387 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2389 /* it's done by hand ready to go on the wire */
2390 for (i
=0; i
<strlen(string
); i
++) {
2391 (*data
)[2*i
]=string
[i
];
2392 (*data
)[2*i
+1]='\0';
2397 if (!StrCaseCmp(value
, "Architecture")) {
2398 const char *string
="Windows NT x86";
2400 *needed
= 2*(strlen(string
)+1);
2401 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2403 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2404 for (i
=0; i
<strlen(string
); i
++) {
2405 (*data
)[2*i
]=string
[i
];
2406 (*data
)[2*i
+1]='\0';
2411 if (!StrCaseCmp(value
, "DsPresent")) {
2413 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2416 /* only show the publish check box if we are a
2417 memeber of a AD domain */
2419 if ( lp_security() == SEC_ADS
)
2420 SIVAL(*data
, 0, 0x01);
2422 SIVAL(*data
, 0, 0x00);
2428 if (!StrCaseCmp(value
, "DNSMachineName")) {
2429 const char *hostname
= get_mydnsfullname();
2432 return WERR_BADFILE
;
2434 *needed
= 2*(strlen(hostname
)+1);
2435 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2437 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2438 for (i
=0; i
<strlen(hostname
); i
++) {
2439 (*data
)[2*i
]=hostname
[i
];
2440 (*data
)[2*i
+1]='\0';
2446 return WERR_BADFILE
;
2449 /********************************************************************
2450 * spoolss_getprinterdata
2451 ********************************************************************/
2453 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2455 POLICY_HND
*handle
= &q_u
->handle
;
2456 UNISTR2
*valuename
= &q_u
->valuename
;
2457 uint32 in_size
= q_u
->size
;
2458 uint32
*type
= &r_u
->type
;
2459 uint32
*out_size
= &r_u
->size
;
2460 uint8
**data
= &r_u
->data
;
2461 uint32
*needed
= &r_u
->needed
;
2464 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2465 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2469 * Reminder: when it's a string, the length is in BYTES
2470 * even if UNICODE is negociated.
2475 *out_size
= in_size
;
2477 /* in case of problem, return some default values */
2482 DEBUG(4,("_spoolss_getprinterdata\n"));
2485 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2486 status
= WERR_BADFID
;
2490 unistr2_to_ascii(value
, valuename
, sizeof(value
));
2492 if ( Printer
->printer_type
== SPLHND_SERVER
)
2493 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2496 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) ) {
2497 status
= WERR_BADFID
;
2501 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2502 if ( !W_ERROR_IS_OK(status
) )
2505 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2507 if ( strequal(value
, "ChangeId") ) {
2509 *needed
= sizeof(uint32
);
2510 if ( (*data
= (uint8
*)TALLOC(p
->mem_ctx
, sizeof(uint32
))) == NULL
) {
2511 status
= WERR_NOMEM
;
2514 SIVAL( *data
, 0, printer
->info_2
->changeid
);
2518 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2521 if (*needed
> *out_size
)
2522 status
= WERR_MORE_DATA
;
2525 if ( !W_ERROR_IS_OK(status
) )
2527 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status
),*out_size
));
2529 /* reply this param doesn't exist */
2532 if((*data
=(uint8
*)TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint8
, *out_size
)) == NULL
) {
2534 free_a_printer( &printer
, 2 );
2542 /* cleanup & exit */
2545 free_a_printer( &printer
, 2 );
2550 /*********************************************************
2551 Connect to the client machine.
2552 **********************************************************/
2554 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2555 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2558 struct cli_state
*the_cli
;
2559 struct sockaddr_storage rm_addr
;
2561 if ( is_zero_addr(client_ss
) ) {
2562 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20) ) {
2563 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2567 if (ismyaddr(&rm_addr
)) {
2568 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2572 char addr
[INET6_ADDRSTRLEN
];
2573 rm_addr
= *client_ss
;
2574 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2575 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2579 /* setup the connection */
2581 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2582 &rm_addr
, 0, "IPC$", "IPC",
2586 0, lp_client_signing(), NULL
);
2588 if ( !NT_STATUS_IS_OK( ret
) ) {
2589 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2594 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2595 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2596 cli_shutdown(the_cli
);
2601 * Ok - we have an anonymous connection to the IPC$ share.
2602 * Now start the NT Domain stuff :-).
2605 if ( !(*pp_pipe
= cli_rpc_pipe_open_noauth(the_cli
, PI_SPOOLSS
, &ret
)) ) {
2606 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2607 remote_machine
, nt_errstr(ret
)));
2608 cli_shutdown(the_cli
);
2612 /* make sure to save the cli_state pointer. Keep its own talloc_ctx */
2614 (*pp_pipe
)->cli
= 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 asprintf(&guid_str
, "{%s}",
4365 smb_uuid_string(talloc_tos(), guid
));
4366 strupper_m(guid_str
);
4367 init_unistr(&printer
->guid
, guid_str
);
4368 printer
->action
= SPOOL_DS_PUBLISH
;
4370 init_unistr(&printer
->guid
, "");
4371 printer
->action
= SPOOL_DS_UNPUBLISH
;
4377 /********************************************************************
4378 Spoolss_enumprinters.
4379 ********************************************************************/
4381 static WERROR
enum_all_printers_info_1(uint32 flags
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4385 int n_services
=lp_numservices();
4386 PRINTER_INFO_1
*printers
=NULL
;
4387 PRINTER_INFO_1 current_prt
;
4388 WERROR result
= WERR_OK
;
4390 DEBUG(4,("enum_all_printers_info_1\n"));
4392 for (snum
=0; snum
<n_services
; snum
++) {
4393 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4394 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4396 if (construct_printer_info_1(NULL
, flags
, ¤t_prt
, snum
)) {
4397 if((printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_1
, *returned
+1)) == NULL
) {
4398 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4402 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4404 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4410 /* check the required size. */
4411 for (i
=0; i
<*returned
; i
++)
4412 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4414 if (*needed
> offered
) {
4415 result
= WERR_INSUFFICIENT_BUFFER
;
4419 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4420 result
= WERR_NOMEM
;
4424 /* fill the buffer with the structures */
4425 for (i
=0; i
<*returned
; i
++)
4426 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4431 SAFE_FREE(printers
);
4433 if ( !W_ERROR_IS_OK(result
) )
4439 /********************************************************************
4440 enum_all_printers_info_1_local.
4441 *********************************************************************/
4443 static WERROR
enum_all_printers_info_1_local(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4445 DEBUG(4,("enum_all_printers_info_1_local\n"));
4447 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4450 /********************************************************************
4451 enum_all_printers_info_1_name.
4452 *********************************************************************/
4454 static WERROR
enum_all_printers_info_1_name(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4458 DEBUG(4,("enum_all_printers_info_1_name\n"));
4460 if ((name
[0] == '\\') && (name
[1] == '\\'))
4463 if (is_myname_or_ipaddr(s
)) {
4464 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4467 return WERR_INVALID_NAME
;
4470 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4471 /********************************************************************
4472 enum_all_printers_info_1_remote.
4473 *********************************************************************/
4475 static WERROR
enum_all_printers_info_1_remote(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4477 PRINTER_INFO_1
*printer
;
4478 fstring printername
;
4481 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4482 WERROR result
= WERR_OK
;
4484 /* JFM: currently it's more a place holder than anything else.
4485 * In the spooler world there is a notion of server registration.
4486 * the print servers are registered on the PDC (in the same domain)
4488 * We should have a TDB here. The registration is done thru an
4489 * undocumented RPC call.
4492 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4497 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", name
);
4498 slprintf(desc
, sizeof(desc
)-1,"%s", name
);
4499 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4501 init_unistr(&printer
->description
, desc
);
4502 init_unistr(&printer
->name
, printername
);
4503 init_unistr(&printer
->comment
, comment
);
4504 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4506 /* check the required size. */
4507 *needed
+= spoolss_size_printer_info_1(printer
);
4509 if (*needed
> offered
) {
4510 result
= WERR_INSUFFICIENT_BUFFER
;
4514 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4515 result
= WERR_NOMEM
;
4519 /* fill the buffer with the structures */
4520 smb_io_printer_info_1("", buffer
, printer
, 0);
4526 if ( !W_ERROR_IS_OK(result
) )
4534 /********************************************************************
4535 enum_all_printers_info_1_network.
4536 *********************************************************************/
4538 static WERROR
enum_all_printers_info_1_network(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4542 DEBUG(4,("enum_all_printers_info_1_network\n"));
4544 /* If we respond to a enum_printers level 1 on our name with flags
4545 set to PRINTER_ENUM_REMOTE with a list of printers then these
4546 printers incorrectly appear in the APW browse list.
4547 Specifically the printers for the server appear at the workgroup
4548 level where all the other servers in the domain are
4549 listed. Windows responds to this call with a
4550 WERR_CAN_NOT_COMPLETE so we should do the same. */
4552 if (name
[0] == '\\' && name
[1] == '\\')
4555 if (is_myname_or_ipaddr(s
))
4556 return WERR_CAN_NOT_COMPLETE
;
4558 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
4561 /********************************************************************
4562 * api_spoolss_enumprinters
4564 * called from api_spoolss_enumprinters (see this to understand)
4565 ********************************************************************/
4567 static WERROR
enum_all_printers_info_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4571 int n_services
=lp_numservices();
4572 PRINTER_INFO_2
*printers
=NULL
;
4573 PRINTER_INFO_2 current_prt
;
4574 WERROR result
= WERR_OK
;
4578 for (snum
=0; snum
<n_services
; snum
++) {
4579 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4580 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4582 if (construct_printer_info_2(NULL
, ¤t_prt
, snum
)) {
4583 if ( !(printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_2
, *returned
+1)) ) {
4584 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4589 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
+ 1));
4591 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4598 /* check the required size. */
4599 for (i
=0; i
<*returned
; i
++)
4600 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4602 if (*needed
> offered
) {
4603 result
= WERR_INSUFFICIENT_BUFFER
;
4607 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4608 result
= WERR_NOMEM
;
4612 /* fill the buffer with the structures */
4613 for (i
=0; i
<*returned
; i
++)
4614 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4619 for (i
=0; i
<*returned
; i
++)
4620 free_devmode(printers
[i
].devmode
);
4622 SAFE_FREE(printers
);
4624 if ( !W_ERROR_IS_OK(result
) )
4630 /********************************************************************
4631 * handle enumeration of printers at level 1
4632 ********************************************************************/
4634 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4635 RPC_BUFFER
*buffer
, uint32 offered
,
4636 uint32
*needed
, uint32
*returned
)
4638 /* Not all the flags are equals */
4640 if (flags
& PRINTER_ENUM_LOCAL
)
4641 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4643 if (flags
& PRINTER_ENUM_NAME
)
4644 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4646 #if 0 /* JERRY - disabled for now */
4647 if (flags
& PRINTER_ENUM_REMOTE
)
4648 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4651 if (flags
& PRINTER_ENUM_NETWORK
)
4652 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4654 return WERR_OK
; /* NT4sp5 does that */
4657 /********************************************************************
4658 * handle enumeration of printers at level 2
4659 ********************************************************************/
4661 static WERROR
enumprinters_level2( uint32 flags
, fstring servername
,
4662 RPC_BUFFER
*buffer
, uint32 offered
,
4663 uint32
*needed
, uint32
*returned
)
4665 char *s
= servername
;
4667 if (flags
& PRINTER_ENUM_LOCAL
) {
4668 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4671 if (flags
& PRINTER_ENUM_NAME
) {
4672 if ((servername
[0] == '\\') && (servername
[1] == '\\'))
4674 if (is_myname_or_ipaddr(s
))
4675 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4677 return WERR_INVALID_NAME
;
4680 if (flags
& PRINTER_ENUM_REMOTE
)
4681 return WERR_UNKNOWN_LEVEL
;
4686 /********************************************************************
4687 * handle enumeration of printers at level 5
4688 ********************************************************************/
4690 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
4691 RPC_BUFFER
*buffer
, uint32 offered
,
4692 uint32
*needed
, uint32
*returned
)
4694 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4698 /********************************************************************
4699 * api_spoolss_enumprinters
4701 * called from api_spoolss_enumprinters (see this to understand)
4702 ********************************************************************/
4704 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4706 uint32 flags
= q_u
->flags
;
4707 UNISTR2
*servername
= &q_u
->servername
;
4708 uint32 level
= q_u
->level
;
4709 RPC_BUFFER
*buffer
= NULL
;
4710 uint32 offered
= q_u
->offered
;
4711 uint32
*needed
= &r_u
->needed
;
4712 uint32
*returned
= &r_u
->returned
;
4716 /* that's an [in out] buffer */
4718 if (!q_u
->buffer
&& (offered
!=0)) {
4719 return WERR_INVALID_PARAM
;
4722 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
4723 buffer
= r_u
->buffer
;
4725 DEBUG(4,("_spoolss_enumprinters\n"));
4732 * flags==PRINTER_ENUM_NAME
4733 * if name=="" then enumerates all printers
4734 * if name!="" then enumerate the printer
4735 * flags==PRINTER_ENUM_REMOTE
4736 * name is NULL, enumerate printers
4737 * Level 2: name!="" enumerates printers, name can't be NULL
4738 * Level 3: doesn't exist
4739 * Level 4: does a local registry lookup
4740 * Level 5: same as Level 2
4743 unistr2_to_ascii(name
, servername
, sizeof(name
));
4748 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4750 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4752 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4757 return WERR_UNKNOWN_LEVEL
;
4760 /****************************************************************************
4761 ****************************************************************************/
4763 static WERROR
getprinter_level_0(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4765 PRINTER_INFO_0
*printer
=NULL
;
4766 WERROR result
= WERR_OK
;
4768 if((printer
=SMB_MALLOC_P(PRINTER_INFO_0
)) == NULL
)
4771 construct_printer_info_0(print_hnd
, printer
, snum
);
4773 /* check the required size. */
4774 *needed
+= spoolss_size_printer_info_0(printer
);
4776 if (*needed
> offered
) {
4777 result
= WERR_INSUFFICIENT_BUFFER
;
4781 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4782 result
= WERR_NOMEM
;
4786 /* fill the buffer with the structures */
4787 smb_io_printer_info_0("", buffer
, printer
, 0);
4797 /****************************************************************************
4798 ****************************************************************************/
4800 static WERROR
getprinter_level_1(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4802 PRINTER_INFO_1
*printer
=NULL
;
4803 WERROR result
= WERR_OK
;
4805 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4808 construct_printer_info_1(print_hnd
, PRINTER_ENUM_ICON8
, printer
, snum
);
4810 /* check the required size. */
4811 *needed
+= spoolss_size_printer_info_1(printer
);
4813 if (*needed
> offered
) {
4814 result
= WERR_INSUFFICIENT_BUFFER
;
4818 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4819 result
= WERR_NOMEM
;
4823 /* fill the buffer with the structures */
4824 smb_io_printer_info_1("", buffer
, printer
, 0);
4833 /****************************************************************************
4834 ****************************************************************************/
4836 static WERROR
getprinter_level_2(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4838 PRINTER_INFO_2
*printer
=NULL
;
4839 WERROR result
= WERR_OK
;
4841 if((printer
=SMB_MALLOC_P(PRINTER_INFO_2
))==NULL
)
4844 construct_printer_info_2(print_hnd
, printer
, snum
);
4846 /* check the required size. */
4847 *needed
+= spoolss_size_printer_info_2(printer
);
4849 if (*needed
> offered
) {
4850 result
= WERR_INSUFFICIENT_BUFFER
;
4854 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4855 result
= WERR_NOMEM
;
4859 /* fill the buffer with the structures */
4860 if (!smb_io_printer_info_2("", buffer
, printer
, 0))
4861 result
= WERR_NOMEM
;
4865 free_printer_info_2(printer
);
4870 /****************************************************************************
4871 ****************************************************************************/
4873 static WERROR
getprinter_level_3(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4875 PRINTER_INFO_3
*printer
=NULL
;
4876 WERROR result
= WERR_OK
;
4878 if (!construct_printer_info_3(print_hnd
, &printer
, snum
))
4881 /* check the required size. */
4882 *needed
+= spoolss_size_printer_info_3(printer
);
4884 if (*needed
> offered
) {
4885 result
= WERR_INSUFFICIENT_BUFFER
;
4889 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4890 result
= WERR_NOMEM
;
4894 /* fill the buffer with the structures */
4895 smb_io_printer_info_3("", buffer
, printer
, 0);
4899 free_printer_info_3(printer
);
4904 /****************************************************************************
4905 ****************************************************************************/
4907 static WERROR
getprinter_level_4(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4909 PRINTER_INFO_4
*printer
=NULL
;
4910 WERROR result
= WERR_OK
;
4912 if((printer
=SMB_MALLOC_P(PRINTER_INFO_4
))==NULL
)
4915 if (!construct_printer_info_4(print_hnd
, printer
, snum
)) {
4920 /* check the required size. */
4921 *needed
+= spoolss_size_printer_info_4(printer
);
4923 if (*needed
> offered
) {
4924 result
= WERR_INSUFFICIENT_BUFFER
;
4928 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4929 result
= WERR_NOMEM
;
4933 /* fill the buffer with the structures */
4934 smb_io_printer_info_4("", buffer
, printer
, 0);
4938 free_printer_info_4(printer
);
4943 /****************************************************************************
4944 ****************************************************************************/
4946 static WERROR
getprinter_level_5(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4948 PRINTER_INFO_5
*printer
=NULL
;
4949 WERROR result
= WERR_OK
;
4951 if((printer
=SMB_MALLOC_P(PRINTER_INFO_5
))==NULL
)
4954 if (!construct_printer_info_5(print_hnd
, printer
, snum
)) {
4955 free_printer_info_5(printer
);
4959 /* check the required size. */
4960 *needed
+= spoolss_size_printer_info_5(printer
);
4962 if (*needed
> offered
) {
4963 result
= WERR_INSUFFICIENT_BUFFER
;
4967 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4968 result
= WERR_NOMEM
;
4972 /* fill the buffer with the structures */
4973 smb_io_printer_info_5("", buffer
, printer
, 0);
4977 free_printer_info_5(printer
);
4982 static WERROR
getprinter_level_6(Printer_entry
*print_hnd
,
4984 RPC_BUFFER
*buffer
, uint32 offered
,
4987 PRINTER_INFO_6
*printer
;
4988 WERROR result
= WERR_OK
;
4990 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_6
)) == NULL
) {
4994 if (!construct_printer_info_6(print_hnd
, printer
, snum
)) {
4995 free_printer_info_6(printer
);
4999 /* check the required size. */
5000 *needed
+= spoolss_size_printer_info_6(printer
);
5002 if (*needed
> offered
) {
5003 result
= WERR_INSUFFICIENT_BUFFER
;
5007 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5008 result
= WERR_NOMEM
;
5012 /* fill the buffer with the structures */
5013 smb_io_printer_info_6("", buffer
, printer
, 0);
5017 free_printer_info_6(printer
);
5022 static WERROR
getprinter_level_7(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5024 PRINTER_INFO_7
*printer
=NULL
;
5025 WERROR result
= WERR_OK
;
5027 if((printer
=SMB_MALLOC_P(PRINTER_INFO_7
))==NULL
)
5030 if (!construct_printer_info_7(print_hnd
, printer
, snum
))
5033 /* check the required size. */
5034 *needed
+= spoolss_size_printer_info_7(printer
);
5036 if (*needed
> offered
) {
5037 result
= WERR_INSUFFICIENT_BUFFER
;
5041 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5042 result
= WERR_NOMEM
;
5047 /* fill the buffer with the structures */
5048 smb_io_printer_info_7("", buffer
, printer
, 0);
5052 free_printer_info_7(printer
);
5057 /****************************************************************************
5058 ****************************************************************************/
5060 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
5062 POLICY_HND
*handle
= &q_u
->handle
;
5063 uint32 level
= q_u
->level
;
5064 RPC_BUFFER
*buffer
= NULL
;
5065 uint32 offered
= q_u
->offered
;
5066 uint32
*needed
= &r_u
->needed
;
5067 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
5071 /* that's an [in out] buffer */
5073 if (!q_u
->buffer
&& (offered
!=0)) {
5074 return WERR_INVALID_PARAM
;
5077 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5078 buffer
= r_u
->buffer
;
5082 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5087 return getprinter_level_0(Printer
, snum
, buffer
, offered
, needed
);
5089 return getprinter_level_1(Printer
, snum
, buffer
, offered
, needed
);
5091 return getprinter_level_2(Printer
, snum
, buffer
, offered
, needed
);
5093 return getprinter_level_3(Printer
, snum
, buffer
, offered
, needed
);
5095 return getprinter_level_4(Printer
, snum
, buffer
, offered
, needed
);
5097 return getprinter_level_5(Printer
, snum
, buffer
, offered
, needed
);
5099 return getprinter_level_6(Printer
, snum
, buffer
, offered
, needed
);
5101 return getprinter_level_7(Printer
, snum
, buffer
, offered
, needed
);
5103 return WERR_UNKNOWN_LEVEL
;
5106 /********************************************************************
5107 * fill a DRIVER_INFO_1 struct
5108 ********************************************************************/
5110 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
5112 init_unistr( &info
->name
, driver
.info_3
->name
);
5115 /********************************************************************
5116 * construct_printer_driver_info_1
5117 ********************************************************************/
5119 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5121 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5122 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5124 ZERO_STRUCT(driver
);
5126 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5127 return WERR_INVALID_PRINTER_NAME
;
5129 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5130 free_a_printer(&printer
, 2);
5131 return WERR_UNKNOWN_PRINTER_DRIVER
;
5134 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
5136 free_a_printer(&printer
,2);
5141 /********************************************************************
5142 * construct_printer_driver_info_2
5143 * fill a printer_info_2 struct
5144 ********************************************************************/
5146 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5148 TALLOC_CTX
*ctx
= talloc_tos();
5151 info
->version
=driver
.info_3
->cversion
;
5153 init_unistr( &info
->name
, driver
.info_3
->name
);
5154 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5157 if (strlen(driver
.info_3
->driverpath
)) {
5158 temp
= talloc_asprintf(ctx
,
5161 driver
.info_3
->driverpath
);
5162 init_unistr( &info
->driverpath
, temp
);
5164 init_unistr( &info
->driverpath
, "" );
5168 if (strlen(driver
.info_3
->datafile
)) {
5169 temp
= talloc_asprintf(ctx
,
5172 driver
.info_3
->datafile
);
5173 init_unistr( &info
->datafile
, temp
);
5175 init_unistr( &info
->datafile
, "" );
5178 if (strlen(driver
.info_3
->configfile
)) {
5179 temp
= talloc_asprintf(ctx
,
5182 driver
.info_3
->configfile
);
5183 init_unistr( &info
->configfile
, temp
);
5185 init_unistr( &info
->configfile
, "" );
5188 /********************************************************************
5189 * construct_printer_driver_info_2
5190 * fill a printer_info_2 struct
5191 ********************************************************************/
5193 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5195 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5196 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5198 ZERO_STRUCT(printer
);
5199 ZERO_STRUCT(driver
);
5201 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5202 return WERR_INVALID_PRINTER_NAME
;
5204 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5205 free_a_printer(&printer
, 2);
5206 return WERR_UNKNOWN_PRINTER_DRIVER
;
5209 fill_printer_driver_info_2(info
, driver
, servername
);
5211 free_a_printer(&printer
,2);
5216 /********************************************************************
5217 * copy a strings array and convert to UNICODE
5219 * convert an array of ascii string to a UNICODE string
5220 ********************************************************************/
5222 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, const char *servername
)
5228 TALLOC_CTX
*ctx
= talloc_tos();
5230 DEBUG(6,("init_unistr_array\n"));
5234 if ( !char_array
) {
5239 v
= ""; /* hack to handle null lists */
5242 /* hack to allow this to be used in places other than when generating
5243 the list of dependent files */
5247 line
= talloc_asprintf(ctx
,
5252 line
= talloc_strdup(ctx
, v
);
5256 SAFE_FREE(*uni_array
);
5259 DEBUGADD(6,("%d:%s:%lu\n", i
, line
, (unsigned long)strlen(line
)));
5261 /* add one extra unit16 for the second terminating NULL */
5263 if ( (*uni_array
=SMB_REALLOC_ARRAY(*uni_array
, uint16
, j
+1+strlen(line
)+2)) == NULL
) {
5264 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5271 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
5276 /* special case for ""; we need to add both NULL's here */
5278 (*uni_array
)[j
++]=0x0000;
5279 (*uni_array
)[j
]=0x0000;
5282 DEBUGADD(6,("last one:done\n"));
5284 /* return size of array in uint16's */
5289 /********************************************************************
5290 * construct_printer_info_3
5291 * fill a printer_info_3 struct
5292 ********************************************************************/
5294 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5297 TALLOC_CTX
*ctx
= talloc_tos();
5301 info
->version
=driver
.info_3
->cversion
;
5303 init_unistr( &info
->name
, driver
.info_3
->name
);
5304 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5306 if (strlen(driver
.info_3
->driverpath
)) {
5307 temp
= talloc_asprintf(ctx
,
5310 driver
.info_3
->driverpath
);
5311 init_unistr( &info
->driverpath
, temp
);
5313 init_unistr( &info
->driverpath
, "" );
5316 if (strlen(driver
.info_3
->datafile
)) {
5317 temp
= talloc_asprintf(ctx
,
5320 driver
.info_3
->datafile
);
5321 init_unistr( &info
->datafile
, temp
);
5323 init_unistr( &info
->datafile
, "" );
5326 if (strlen(driver
.info_3
->configfile
)) {
5327 temp
= talloc_asprintf(ctx
,
5330 driver
.info_3
->configfile
);
5331 init_unistr( &info
->configfile
, temp
);
5333 init_unistr( &info
->configfile
, "" );
5336 if (strlen(driver
.info_3
->helpfile
)) {
5337 temp
= talloc_asprintf(ctx
,
5340 driver
.info_3
->helpfile
);
5341 init_unistr( &info
->helpfile
, temp
);
5343 init_unistr( &info
->helpfile
, "" );
5346 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5347 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5349 info
->dependentfiles
=NULL
;
5350 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5353 /********************************************************************
5354 * construct_printer_info_3
5355 * fill a printer_info_3 struct
5356 ********************************************************************/
5358 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5360 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5361 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5363 ZERO_STRUCT(driver
);
5365 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5366 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5367 if (!W_ERROR_IS_OK(status
))
5368 return WERR_INVALID_PRINTER_NAME
;
5370 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5371 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5376 * I put this code in during testing. Helpful when commenting out the
5377 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5378 * as win2k always queries the driver using an infor level of 6.
5379 * I've left it in (but ifdef'd out) because I'll probably
5380 * use it in experimentation again in the future. --jerry 22/01/2002
5383 if (!W_ERROR_IS_OK(status
)) {
5385 * Is this a W2k client ?
5388 /* Yes - try again with a WinNT driver. */
5390 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5391 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5395 if (!W_ERROR_IS_OK(status
)) {
5396 free_a_printer(&printer
,2);
5397 return WERR_UNKNOWN_PRINTER_DRIVER
;
5405 fill_printer_driver_info_3(info
, driver
, servername
);
5407 free_a_printer(&printer
,2);
5412 /********************************************************************
5413 * construct_printer_info_6
5414 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5415 ********************************************************************/
5417 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5421 TALLOC_CTX
*ctx
= talloc_tos();
5424 memset(&nullstr
, '\0', sizeof(fstring
));
5426 info
->version
=driver
.info_3
->cversion
;
5428 init_unistr( &info
->name
, driver
.info_3
->name
);
5429 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5431 if (strlen(driver
.info_3
->driverpath
)) {
5432 temp
= talloc_asprintf(ctx
,
5435 driver
.info_3
->driverpath
);
5436 init_unistr( &info
->driverpath
, temp
);
5438 init_unistr( &info
->driverpath
, "" );
5441 if (strlen(driver
.info_3
->datafile
)) {
5442 temp
= talloc_asprintf(ctx
,
5445 driver
.info_3
->datafile
);
5446 init_unistr( &info
->datafile
, temp
);
5448 init_unistr( &info
->datafile
, "" );
5451 if (strlen(driver
.info_3
->configfile
)) {
5452 temp
= talloc_asprintf(ctx
,
5455 driver
.info_3
->configfile
);
5456 init_unistr( &info
->configfile
, temp
);
5458 init_unistr( &info
->configfile
, "" );
5461 if (strlen(driver
.info_3
->helpfile
)) {
5462 temp
= talloc_asprintf(ctx
,
5465 driver
.info_3
->helpfile
);
5466 init_unistr( &info
->helpfile
, temp
);
5468 init_unistr( &info
->helpfile
, "" );
5471 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5472 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5474 info
->dependentfiles
= NULL
;
5475 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5477 info
->previousdrivernames
=NULL
;
5478 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
5480 info
->driver_date
=0;
5483 info
->driver_version_low
=0;
5484 info
->driver_version_high
=0;
5486 init_unistr( &info
->mfgname
, "");
5487 init_unistr( &info
->oem_url
, "");
5488 init_unistr( &info
->hardware_id
, "");
5489 init_unistr( &info
->provider
, "");
5492 /********************************************************************
5493 * construct_printer_info_6
5494 * fill a printer_info_6 struct
5495 ********************************************************************/
5497 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
5498 fstring servername
, fstring architecture
, uint32 version
)
5500 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5501 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5504 ZERO_STRUCT(driver
);
5506 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5508 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5510 if (!W_ERROR_IS_OK(status
))
5511 return WERR_INVALID_PRINTER_NAME
;
5513 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5515 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5517 if (!W_ERROR_IS_OK(status
))
5520 * Is this a W2k client ?
5524 free_a_printer(&printer
,2);
5525 return WERR_UNKNOWN_PRINTER_DRIVER
;
5528 /* Yes - try again with a WinNT driver. */
5530 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5531 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5532 if (!W_ERROR_IS_OK(status
)) {
5533 free_a_printer(&printer
,2);
5534 return WERR_UNKNOWN_PRINTER_DRIVER
;
5538 fill_printer_driver_info_6(info
, driver
, servername
);
5540 free_a_printer(&printer
,2);
5541 free_a_printer_driver(driver
, 3);
5546 /****************************************************************************
5547 ****************************************************************************/
5549 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5551 SAFE_FREE(info
->dependentfiles
);
5554 /****************************************************************************
5555 ****************************************************************************/
5557 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5559 SAFE_FREE(info
->dependentfiles
);
5562 /****************************************************************************
5563 ****************************************************************************/
5565 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5567 DRIVER_INFO_1
*info
=NULL
;
5570 if((info
=SMB_MALLOC_P(DRIVER_INFO_1
)) == NULL
)
5573 result
= construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5574 if (!W_ERROR_IS_OK(result
))
5577 /* check the required size. */
5578 *needed
+= spoolss_size_printer_driver_info_1(info
);
5580 if (*needed
> offered
) {
5581 result
= WERR_INSUFFICIENT_BUFFER
;
5585 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5586 result
= WERR_NOMEM
;
5590 /* fill the buffer with the structures */
5591 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5600 /****************************************************************************
5601 ****************************************************************************/
5603 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5605 DRIVER_INFO_2
*info
=NULL
;
5608 if((info
=SMB_MALLOC_P(DRIVER_INFO_2
)) == NULL
)
5611 result
= construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5612 if (!W_ERROR_IS_OK(result
))
5615 /* check the required size. */
5616 *needed
+= spoolss_size_printer_driver_info_2(info
);
5618 if (*needed
> offered
) {
5619 result
= WERR_INSUFFICIENT_BUFFER
;
5623 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5624 result
= WERR_NOMEM
;
5628 /* fill the buffer with the structures */
5629 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5638 /****************************************************************************
5639 ****************************************************************************/
5641 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5648 result
= construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5649 if (!W_ERROR_IS_OK(result
))
5652 /* check the required size. */
5653 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5655 if (*needed
> offered
) {
5656 result
= WERR_INSUFFICIENT_BUFFER
;
5660 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5661 result
= WERR_NOMEM
;
5665 /* fill the buffer with the structures */
5666 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5669 free_printer_driver_info_3(&info
);
5674 /****************************************************************************
5675 ****************************************************************************/
5677 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5684 result
= construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5685 if (!W_ERROR_IS_OK(result
))
5688 /* check the required size. */
5689 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5691 if (*needed
> offered
) {
5692 result
= WERR_INSUFFICIENT_BUFFER
;
5696 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5697 result
= WERR_NOMEM
;
5701 /* fill the buffer with the structures */
5702 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5705 free_printer_driver_info_6(&info
);
5710 /****************************************************************************
5711 ****************************************************************************/
5713 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5715 POLICY_HND
*handle
= &q_u
->handle
;
5716 UNISTR2
*uni_arch
= &q_u
->architecture
;
5717 uint32 level
= q_u
->level
;
5718 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5719 RPC_BUFFER
*buffer
= NULL
;
5720 uint32 offered
= q_u
->offered
;
5721 uint32
*needed
= &r_u
->needed
;
5722 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5723 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5724 Printer_entry
*printer
;
5727 fstring architecture
;
5730 /* that's an [in out] buffer */
5732 if (!q_u
->buffer
&& (offered
!=0)) {
5733 return WERR_INVALID_PARAM
;
5736 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5737 buffer
= r_u
->buffer
;
5739 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5741 if ( !(printer
= find_printer_index_by_hnd( p
, handle
)) ) {
5742 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5743 return WERR_INVALID_PRINTER_NAME
;
5747 *servermajorversion
= 0;
5748 *serverminorversion
= 0;
5750 fstrcpy(servername
, get_server_name( printer
));
5751 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
));
5753 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5758 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5760 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5762 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5764 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5767 /* apparently this call is the equivalent of
5768 EnumPrinterDataEx() for the DsDriver key */
5773 return WERR_UNKNOWN_LEVEL
;
5776 /****************************************************************************
5777 ****************************************************************************/
5779 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
5781 POLICY_HND
*handle
= &q_u
->handle
;
5783 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5786 DEBUG(3,("Error in startpageprinter printer handle\n"));
5790 Printer
->page_started
=True
;
5794 /****************************************************************************
5795 ****************************************************************************/
5797 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
5799 POLICY_HND
*handle
= &q_u
->handle
;
5802 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5805 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle
)));
5809 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5812 Printer
->page_started
=False
;
5813 print_job_endpage(snum
, Printer
->jobid
);
5818 /********************************************************************
5819 * api_spoolss_getprinter
5820 * called from the spoolss dispatcher
5822 ********************************************************************/
5824 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
5826 POLICY_HND
*handle
= &q_u
->handle
;
5827 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
5828 uint32
*jobid
= &r_u
->jobid
;
5829 TALLOC_CTX
*ctx
= p
->mem_ctx
;
5830 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
5832 char *jobname
= NULL
;
5834 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5837 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5842 * a nice thing with NT is it doesn't listen to what you tell it.
5843 * when asked to send _only_ RAW datas, it tries to send datas
5846 * So I add checks like in NT Server ...
5849 if (info_1
->p_datatype
!= 0) {
5850 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
5851 if (strcmp(datatype
, "RAW") != 0) {
5853 return WERR_INVALID_DATATYPE
;
5857 /* get the share number of the printer */
5858 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5862 jobname
= unistr2_to_ascii_talloc(ctx
, &info_1
->docname
);
5864 Printer
->jobid
= print_job_start(&p
->pipe_user
, snum
, jobname
, Printer
->nt_devmode
);
5866 /* An error occured in print_job_start() so return an appropriate
5869 if (Printer
->jobid
== -1) {
5870 return map_werror_from_unix(errno
);
5873 Printer
->document_started
=True
;
5874 (*jobid
) = Printer
->jobid
;
5879 /********************************************************************
5880 * api_spoolss_getprinter
5881 * called from the spoolss dispatcher
5883 ********************************************************************/
5885 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
5887 POLICY_HND
*handle
= &q_u
->handle
;
5889 return _spoolss_enddocprinter_internal(p
, handle
);
5892 /****************************************************************************
5893 ****************************************************************************/
5895 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
5897 POLICY_HND
*handle
= &q_u
->handle
;
5898 uint32 buffer_size
= q_u
->buffer_size
;
5899 uint8
*buffer
= q_u
->buffer
;
5900 uint32
*buffer_written
= &q_u
->buffer_size2
;
5902 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5905 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5906 r_u
->buffer_written
= q_u
->buffer_size2
;
5910 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5913 (*buffer_written
) = (uint32
)print_job_write(snum
, Printer
->jobid
, (const char *)buffer
,
5914 (SMB_OFF_T
)-1, (size_t)buffer_size
);
5915 if (*buffer_written
== (uint32
)-1) {
5916 r_u
->buffer_written
= 0;
5917 if (errno
== ENOSPC
)
5918 return WERR_NO_SPOOL_SPACE
;
5920 return WERR_ACCESS_DENIED
;
5923 r_u
->buffer_written
= q_u
->buffer_size2
;
5928 /********************************************************************
5929 * api_spoolss_getprinter
5930 * called from the spoolss dispatcher
5932 ********************************************************************/
5934 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5938 WERROR errcode
= WERR_BADFUNC
;
5939 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5942 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5946 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5950 case PRINTER_CONTROL_PAUSE
:
5951 if (print_queue_pause(&p
->pipe_user
, snum
, &errcode
)) {
5955 case PRINTER_CONTROL_RESUME
:
5956 case PRINTER_CONTROL_UNPAUSE
:
5957 if (print_queue_resume(&p
->pipe_user
, snum
, &errcode
)) {
5961 case PRINTER_CONTROL_PURGE
:
5962 if (print_queue_purge(&p
->pipe_user
, snum
, &errcode
)) {
5967 return WERR_UNKNOWN_LEVEL
;
5973 /********************************************************************
5974 * api_spoolss_abortprinter
5975 * From MSDN: "Deletes printer's spool file if printer is configured
5977 ********************************************************************/
5979 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
5981 POLICY_HND
*handle
= &q_u
->handle
;
5982 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5984 WERROR errcode
= WERR_OK
;
5987 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5991 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5994 print_job_delete( &p
->pipe_user
, snum
, Printer
->jobid
, &errcode
);
5999 /********************************************************************
6000 * called by spoolss_api_setprinter
6001 * when updating a printer description
6002 ********************************************************************/
6004 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
6005 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6006 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
6008 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
6012 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6014 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
6015 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6016 OUR_HANDLE(handle
)));
6018 result
= WERR_BADFID
;
6023 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6024 result
= WERR_INVALID_PARAM
;
6028 /* Check the user has permissions to change the security
6029 descriptor. By experimentation with two NT machines, the user
6030 requires Full Access to the printer to change security
6033 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6034 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6035 result
= WERR_ACCESS_DENIED
;
6039 /* NT seems to like setting the security descriptor even though
6040 nothing may have actually changed. */
6042 if ( !nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
)) {
6043 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6044 result
= WERR_BADFID
;
6048 if (DEBUGLEVEL
>= 10) {
6052 the_acl
= old_secdesc_ctr
->sd
->dacl
;
6053 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6054 PRINTERNAME(snum
), the_acl
->num_aces
));
6056 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6057 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6058 &the_acl
->aces
[i
].trustee
),
6059 the_acl
->aces
[i
].access_mask
));
6062 the_acl
= secdesc_ctr
->sd
->dacl
;
6065 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6066 PRINTERNAME(snum
), the_acl
->num_aces
));
6068 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6069 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6070 &the_acl
->aces
[i
].trustee
),
6071 the_acl
->aces
[i
].access_mask
));
6074 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6078 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
6079 if (!new_secdesc_ctr
) {
6080 result
= WERR_NOMEM
;
6084 if (sec_desc_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
6089 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
6096 /********************************************************************
6097 Canonicalize printer info from a client
6099 ATTN: It does not matter what we set the servername to hear
6100 since we do the necessary work in get_a_printer() to set it to
6101 the correct value based on what the client sent in the
6102 _spoolss_open_printer_ex().
6103 ********************************************************************/
6105 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
6107 fstring printername
;
6110 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6111 "portname=%s drivername=%s comment=%s location=%s\n",
6112 info
->servername
, info
->printername
, info
->sharename
,
6113 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
6115 /* we force some elements to "correct" values */
6116 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
6117 fstrcpy(info
->sharename
, lp_servicename(snum
));
6119 /* check to see if we allow printername != sharename */
6121 if ( lp_force_printername(snum
) ) {
6122 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6123 global_myname(), info
->sharename
);
6126 /* make sure printername is in \\server\printername format */
6128 fstrcpy( printername
, info
->printername
);
6130 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
6131 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
6135 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6136 global_myname(), p
);
6139 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
6140 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
6147 /****************************************************************************
6148 ****************************************************************************/
6150 WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
6152 char *cmd
= lp_addport_cmd();
6153 char *command
= NULL
;
6156 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6157 bool is_print_op
= False
;
6160 return WERR_ACCESS_DENIED
;
6163 command
= talloc_asprintf(ctx
,
6164 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
6170 is_print_op
= user_has_privileges( token
, &se_printop
);
6172 DEBUG(10,("Running [%s]\n", command
));
6174 /********* BEGIN SePrintOperatorPrivilege **********/
6179 ret
= smbrun(command
, &fd
);
6184 /********* END SePrintOperatorPrivilege **********/
6186 DEBUGADD(10,("returned [%d]\n", ret
));
6188 TALLOC_FREE(command
);
6193 return WERR_ACCESS_DENIED
;
6199 /****************************************************************************
6200 ****************************************************************************/
6202 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
6204 char *cmd
= lp_addprinter_cmd();
6206 char *command
= NULL
;
6210 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6211 bool is_print_op
= False
;
6212 char *remote_machine
= talloc_strdup(ctx
, "%m");
6214 if (!remote_machine
) {
6217 remote_machine
= talloc_sub_basic(ctx
,
6218 current_user_info
.smb_name
,
6219 current_user_info
.domain
,
6221 if (!remote_machine
) {
6225 command
= talloc_asprintf(ctx
,
6226 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6227 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6228 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6229 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6235 is_print_op
= user_has_privileges( token
, &se_printop
);
6237 DEBUG(10,("Running [%s]\n", command
));
6239 /********* BEGIN SePrintOperatorPrivilege **********/
6244 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6245 /* Tell everyone we updated smb.conf. */
6246 message_send_all(smbd_messaging_context(),
6247 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6253 /********* END SePrintOperatorPrivilege **********/
6255 DEBUGADD(10,("returned [%d]\n", ret
));
6257 TALLOC_FREE(command
);
6258 TALLOC_FREE(remote_machine
);
6266 /* reload our services immediately */
6267 reload_services( False
);
6270 /* Get lines and convert them back to dos-codepage */
6271 qlines
= fd_lines_load(fd
, &numlines
, 0);
6272 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6275 /* Set the portname to what the script says the portname should be. */
6276 /* but don't require anything to be return from the script exit a good error code */
6279 /* Set the portname to what the script says the portname should be. */
6280 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6281 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6284 file_lines_free(qlines
);
6289 /********************************************************************
6290 * Called by spoolss_api_setprinter
6291 * when updating a printer description.
6292 ********************************************************************/
6294 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
6295 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6296 DEVICEMODE
*devmode
)
6299 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6300 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6305 DEBUG(8,("update_printer\n"));
6310 result
= WERR_BADFID
;
6314 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6315 result
= WERR_BADFID
;
6319 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6320 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6321 result
= WERR_BADFID
;
6325 DEBUGADD(8,("Converting info_2 struct\n"));
6328 * convert_printer_info converts the incoming
6329 * info from the client and overwrites the info
6330 * just read from the tdb in the pointer 'printer'.
6333 if (!convert_printer_info(info
, printer
, level
)) {
6334 result
= WERR_NOMEM
;
6339 /* we have a valid devmode
6340 convert it and link it*/
6342 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6343 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6344 &printer
->info_2
->devmode
)) {
6345 result
= WERR_NOMEM
;
6350 /* Do sanity check on the requested changes for Samba */
6352 if (!check_printer_ok(printer
->info_2
, snum
)) {
6353 result
= WERR_INVALID_PARAM
;
6357 /* FIXME!!! If the driver has changed we really should verify that
6358 it is installed before doing much else --jerry */
6360 /* Check calling user has permission to update printer description */
6362 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6363 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6364 result
= WERR_ACCESS_DENIED
;
6368 /* Call addprinter hook */
6369 /* Check changes to see if this is really needed */
6371 if ( *lp_addprinter_cmd()
6372 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6373 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6374 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6375 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6377 /* add_printer_hook() will call reload_services() */
6379 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
6380 result
= WERR_ACCESS_DENIED
;
6386 * When a *new* driver is bound to a printer, the drivername is used to
6387 * lookup previously saved driver initialization info, which is then
6388 * bound to the printer, simulating what happens in the Windows arch.
6390 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6392 if (!set_driver_init(printer
, 2))
6394 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6395 printer
->info_2
->drivername
));
6398 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6399 printer
->info_2
->drivername
));
6401 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6405 * flag which changes actually occured. This is a small subset of
6406 * all the possible changes. We also have to update things in the
6410 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6411 init_unistr2( &buffer
, printer
->info_2
->comment
, UNI_STR_TERMINATE
);
6412 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6413 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6415 notify_printer_comment(snum
, printer
->info_2
->comment
);
6418 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6419 init_unistr2( &buffer
, printer
->info_2
->sharename
, UNI_STR_TERMINATE
);
6420 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6421 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6423 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6426 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6429 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6432 pname
= printer
->info_2
->printername
;
6435 init_unistr2( &buffer
, pname
, UNI_STR_TERMINATE
);
6436 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6437 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6439 notify_printer_printername( snum
, pname
);
6442 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6443 init_unistr2( &buffer
, printer
->info_2
->portname
, UNI_STR_TERMINATE
);
6444 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6445 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6447 notify_printer_port(snum
, printer
->info_2
->portname
);
6450 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6451 init_unistr2( &buffer
, printer
->info_2
->location
, UNI_STR_TERMINATE
);
6452 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6453 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6455 notify_printer_location(snum
, printer
->info_2
->location
);
6458 /* here we need to update some more DsSpooler keys */
6459 /* uNCName, serverName, shortServerName */
6461 init_unistr2( &buffer
, global_myname(), UNI_STR_TERMINATE
);
6462 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6463 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6464 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6465 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6467 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6468 global_myname(), printer
->info_2
->sharename
);
6469 init_unistr2( &buffer
, asc_buffer
, UNI_STR_TERMINATE
);
6470 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6471 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6473 /* Update printer info */
6474 result
= mod_a_printer(printer
, 2);
6477 free_a_printer(&printer
, 2);
6478 free_a_printer(&old_printer
, 2);
6484 /****************************************************************************
6485 ****************************************************************************/
6486 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6487 const SPOOL_PRINTER_INFO_LEVEL
*info
)
6490 SPOOL_PRINTER_INFO_LEVEL_7
*info7
= info
->info_7
;
6492 Printer_entry
*Printer
;
6494 if ( lp_security() != SEC_ADS
) {
6495 return WERR_UNKNOWN_LEVEL
;
6498 Printer
= find_printer_index_by_hnd(p
, handle
);
6500 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6505 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6508 nt_printer_publish(Printer
, snum
, info7
->action
);
6512 return WERR_UNKNOWN_LEVEL
;
6515 /****************************************************************************
6516 ****************************************************************************/
6518 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
6520 POLICY_HND
*handle
= &q_u
->handle
;
6521 uint32 level
= q_u
->level
;
6522 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
6523 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
6524 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
6525 uint32 command
= q_u
->command
;
6528 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6531 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6535 /* check the level */
6538 return control_printer(handle
, command
, p
);
6540 result
= update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
6541 if (!W_ERROR_IS_OK(result
))
6544 result
= update_printer_sec(handle
, level
, info
, p
, secdesc_ctr
);
6547 return update_printer_sec(handle
, level
, info
, p
,
6550 return publish_or_unpublish_printer(p
, handle
, info
);
6552 return WERR_UNKNOWN_LEVEL
;
6556 /****************************************************************************
6557 ****************************************************************************/
6559 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
6561 POLICY_HND
*handle
= &q_u
->handle
;
6562 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6565 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6569 if (Printer
->notify
.client_connected
==True
) {
6572 if ( Printer
->printer_type
== SPLHND_SERVER
)
6574 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6575 !get_printer_snum(p
, handle
, &snum
, NULL
) )
6578 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6581 Printer
->notify
.flags
=0;
6582 Printer
->notify
.options
=0;
6583 Printer
->notify
.localmachine
[0]='\0';
6584 Printer
->notify
.printerlocal
=0;
6585 if (Printer
->notify
.option
)
6586 free_spool_notify_option(&Printer
->notify
.option
);
6587 Printer
->notify
.client_connected
=False
;
6592 /****************************************************************************
6593 ****************************************************************************/
6595 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
6597 /* that's an [in out] buffer */
6599 if (!q_u
->buffer
&& (q_u
->offered
!=0)) {
6600 return WERR_INVALID_PARAM
;
6603 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6606 return WERR_INVALID_PARAM
; /* this is what a NT server
6607 returns for AddJob. AddJob
6608 must fail on non-local
6612 /****************************************************************************
6613 ****************************************************************************/
6615 static void fill_job_info_1(JOB_INFO_1
*job_info
, const print_queue_struct
*queue
,
6616 int position
, int snum
,
6617 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6621 t
=gmtime(&queue
->time
);
6623 job_info
->jobid
=queue
->job
;
6624 init_unistr(&job_info
->printername
, lp_servicename(snum
));
6625 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6626 init_unistr(&job_info
->username
, queue
->fs_user
);
6627 init_unistr(&job_info
->document
, queue
->fs_file
);
6628 init_unistr(&job_info
->datatype
, "RAW");
6629 init_unistr(&job_info
->text_status
, "");
6630 job_info
->status
=nt_printj_status(queue
->status
);
6631 job_info
->priority
=queue
->priority
;
6632 job_info
->position
=position
;
6633 job_info
->totalpages
=queue
->page_count
;
6634 job_info
->pagesprinted
=0;
6636 make_systemtime(&job_info
->submitted
, t
);
6639 /****************************************************************************
6640 ****************************************************************************/
6642 static bool fill_job_info_2(JOB_INFO_2
*job_info
, const print_queue_struct
*queue
,
6643 int position
, int snum
,
6644 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6645 DEVICEMODE
*devmode
)
6649 t
=gmtime(&queue
->time
);
6651 job_info
->jobid
=queue
->job
;
6653 init_unistr(&job_info
->printername
, ntprinter
->info_2
->printername
);
6655 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6656 init_unistr(&job_info
->username
, queue
->fs_user
);
6657 init_unistr(&job_info
->document
, queue
->fs_file
);
6658 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
6659 init_unistr(&job_info
->datatype
, "RAW");
6660 init_unistr(&job_info
->printprocessor
, "winprint");
6661 init_unistr(&job_info
->parameters
, "");
6662 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
6663 init_unistr(&job_info
->text_status
, "");
6665 /* and here the security descriptor */
6667 job_info
->status
=nt_printj_status(queue
->status
);
6668 job_info
->priority
=queue
->priority
;
6669 job_info
->position
=position
;
6670 job_info
->starttime
=0;
6671 job_info
->untiltime
=0;
6672 job_info
->totalpages
=queue
->page_count
;
6673 job_info
->size
=queue
->size
;
6674 make_systemtime(&(job_info
->submitted
), t
);
6675 job_info
->timeelapsed
=0;
6676 job_info
->pagesprinted
=0;
6678 job_info
->devmode
= devmode
;
6683 /****************************************************************************
6684 Enumjobs at level 1.
6685 ****************************************************************************/
6687 static WERROR
enumjobs_level1(const print_queue_struct
*queue
, int snum
,
6688 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6689 RPC_BUFFER
*buffer
, uint32 offered
,
6690 uint32
*needed
, uint32
*returned
)
6694 WERROR result
= WERR_OK
;
6696 info
=SMB_MALLOC_ARRAY(JOB_INFO_1
,*returned
);
6702 for (i
=0; i
<*returned
; i
++)
6703 fill_job_info_1( &info
[i
], &queue
[i
], i
, snum
, ntprinter
);
6705 /* check the required size. */
6706 for (i
=0; i
<*returned
; i
++)
6707 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
6709 if (*needed
> offered
) {
6710 result
= WERR_INSUFFICIENT_BUFFER
;
6714 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6715 result
= WERR_NOMEM
;
6719 /* fill the buffer with the structures */
6720 for (i
=0; i
<*returned
; i
++)
6721 smb_io_job_info_1("", buffer
, &info
[i
], 0);
6727 if ( !W_ERROR_IS_OK(result
) )
6733 /****************************************************************************
6734 Enumjobs at level 2.
6735 ****************************************************************************/
6737 static WERROR
enumjobs_level2(const print_queue_struct
*queue
, int snum
,
6738 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6739 RPC_BUFFER
*buffer
, uint32 offered
,
6740 uint32
*needed
, uint32
*returned
)
6742 JOB_INFO_2
*info
= NULL
;
6744 WERROR result
= WERR_OK
;
6745 DEVICEMODE
*devmode
= NULL
;
6747 if ( !(info
= SMB_MALLOC_ARRAY(JOB_INFO_2
,*returned
)) ) {
6752 /* this should not be a failure condition if the devmode is NULL */
6754 devmode
= construct_dev_mode(lp_const_servicename(snum
));
6756 for (i
=0; i
<*returned
; i
++)
6757 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
, devmode
);
6759 /* check the required size. */
6760 for (i
=0; i
<*returned
; i
++)
6761 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6763 if (*needed
> offered
) {
6764 result
= WERR_INSUFFICIENT_BUFFER
;
6768 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6769 result
= WERR_NOMEM
;
6773 /* fill the buffer with the structures */
6774 for (i
=0; i
<*returned
; i
++)
6775 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6778 free_devmode(devmode
);
6781 if ( !W_ERROR_IS_OK(result
) )
6788 /****************************************************************************
6790 ****************************************************************************/
6792 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6794 POLICY_HND
*handle
= &q_u
->handle
;
6795 uint32 level
= q_u
->level
;
6796 RPC_BUFFER
*buffer
= NULL
;
6797 uint32 offered
= q_u
->offered
;
6798 uint32
*needed
= &r_u
->needed
;
6799 uint32
*returned
= &r_u
->returned
;
6801 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6803 print_status_struct prt_status
;
6804 print_queue_struct
*queue
=NULL
;
6806 /* that's an [in out] buffer */
6808 if (!q_u
->buffer
&& (offered
!=0)) {
6809 return WERR_INVALID_PARAM
;
6812 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6813 buffer
= r_u
->buffer
;
6815 DEBUG(4,("_spoolss_enumjobs\n"));
6820 /* lookup the printer snum and tdb entry */
6822 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6825 wret
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6826 if ( !W_ERROR_IS_OK(wret
) )
6829 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6830 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6832 if (*returned
== 0) {
6834 free_a_printer(&ntprinter
, 2);
6840 wret
= enumjobs_level1(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6843 wret
= enumjobs_level2(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6847 wret
= WERR_UNKNOWN_LEVEL
;
6852 free_a_printer( &ntprinter
, 2 );
6856 /****************************************************************************
6857 ****************************************************************************/
6859 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
6864 /****************************************************************************
6865 ****************************************************************************/
6867 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
6869 POLICY_HND
*handle
= &q_u
->handle
;
6870 uint32 jobid
= q_u
->jobid
;
6871 uint32 command
= q_u
->command
;
6874 WERROR errcode
= WERR_BADFUNC
;
6876 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6880 if (!print_job_exists(lp_const_servicename(snum
), jobid
)) {
6881 return WERR_INVALID_PRINTER_NAME
;
6885 case JOB_CONTROL_CANCEL
:
6886 case JOB_CONTROL_DELETE
:
6887 if (print_job_delete(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6891 case JOB_CONTROL_PAUSE
:
6892 if (print_job_pause(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6896 case JOB_CONTROL_RESTART
:
6897 case JOB_CONTROL_RESUME
:
6898 if (print_job_resume(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6903 return WERR_UNKNOWN_LEVEL
;
6909 /****************************************************************************
6910 Enumerates all printer drivers at level 1.
6911 ****************************************************************************/
6913 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6918 fstring
*list
= NULL
;
6919 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6920 DRIVER_INFO_1
*driver_info_1
=NULL
;
6921 WERROR result
= WERR_OK
;
6925 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6927 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6928 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6930 if(ndrivers
== -1) {
6931 SAFE_FREE(driver_info_1
);
6936 if((driver_info_1
=SMB_REALLOC_ARRAY(driver_info_1
, DRIVER_INFO_1
, *returned
+ndrivers
)) == NULL
) {
6937 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6943 for (i
=0; i
<ndrivers
; i
++) {
6945 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6946 ZERO_STRUCT(driver
);
6947 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6948 architecture
, version
);
6949 if (!W_ERROR_IS_OK(status
)) {
6951 SAFE_FREE(driver_info_1
);
6954 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6955 free_a_printer_driver(driver
, 3);
6958 *returned
+=ndrivers
;
6962 /* check the required size. */
6963 for (i
=0; i
<*returned
; i
++) {
6964 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6965 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6968 if (*needed
> offered
) {
6969 result
= WERR_INSUFFICIENT_BUFFER
;
6973 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6974 result
= WERR_NOMEM
;
6978 /* fill the buffer with the driver structures */
6979 for (i
=0; i
<*returned
; i
++) {
6980 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6981 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
6985 SAFE_FREE(driver_info_1
);
6987 if ( !W_ERROR_IS_OK(result
) )
6993 /****************************************************************************
6994 Enumerates all printer drivers at level 2.
6995 ****************************************************************************/
6997 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7002 fstring
*list
= NULL
;
7003 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7004 DRIVER_INFO_2
*driver_info_2
=NULL
;
7005 WERROR result
= WERR_OK
;
7009 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7011 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7012 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7014 if(ndrivers
== -1) {
7015 SAFE_FREE(driver_info_2
);
7020 if((driver_info_2
=SMB_REALLOC_ARRAY(driver_info_2
, DRIVER_INFO_2
, *returned
+ndrivers
)) == NULL
) {
7021 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7027 for (i
=0; i
<ndrivers
; i
++) {
7030 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7031 ZERO_STRUCT(driver
);
7032 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7033 architecture
, version
);
7034 if (!W_ERROR_IS_OK(status
)) {
7036 SAFE_FREE(driver_info_2
);
7039 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
7040 free_a_printer_driver(driver
, 3);
7043 *returned
+=ndrivers
;
7047 /* check the required size. */
7048 for (i
=0; i
<*returned
; i
++) {
7049 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7050 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
7053 if (*needed
> offered
) {
7054 result
= WERR_INSUFFICIENT_BUFFER
;
7058 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7059 result
= WERR_NOMEM
;
7063 /* fill the buffer with the form structures */
7064 for (i
=0; i
<*returned
; i
++) {
7065 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7066 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
7070 SAFE_FREE(driver_info_2
);
7072 if ( !W_ERROR_IS_OK(result
) )
7078 /****************************************************************************
7079 Enumerates all printer drivers at level 3.
7080 ****************************************************************************/
7082 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7087 fstring
*list
= NULL
;
7088 DRIVER_INFO_3
*driver_info_3
=NULL
;
7089 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7090 WERROR result
= WERR_OK
;
7094 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7096 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7097 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7099 if(ndrivers
== -1) {
7100 SAFE_FREE(driver_info_3
);
7105 if((driver_info_3
=SMB_REALLOC_ARRAY(driver_info_3
, DRIVER_INFO_3
, *returned
+ndrivers
)) == NULL
) {
7106 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7112 for (i
=0; i
<ndrivers
; i
++) {
7115 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7116 ZERO_STRUCT(driver
);
7117 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7118 architecture
, version
);
7119 if (!W_ERROR_IS_OK(status
)) {
7121 SAFE_FREE(driver_info_3
);
7124 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
7125 free_a_printer_driver(driver
, 3);
7128 *returned
+=ndrivers
;
7132 /* check the required size. */
7133 for (i
=0; i
<*returned
; i
++) {
7134 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7135 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
7138 if (*needed
> offered
) {
7139 result
= WERR_INSUFFICIENT_BUFFER
;
7143 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7144 result
= WERR_NOMEM
;
7148 /* fill the buffer with the driver structures */
7149 for (i
=0; i
<*returned
; i
++) {
7150 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7151 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
7155 for (i
=0; i
<*returned
; i
++) {
7156 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
7159 SAFE_FREE(driver_info_3
);
7161 if ( !W_ERROR_IS_OK(result
) )
7167 /****************************************************************************
7168 Enumerates all printer drivers.
7169 ****************************************************************************/
7171 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
7173 uint32 level
= q_u
->level
;
7174 RPC_BUFFER
*buffer
= NULL
;
7175 uint32 offered
= q_u
->offered
;
7176 uint32
*needed
= &r_u
->needed
;
7177 uint32
*returned
= &r_u
->returned
;
7180 fstring architecture
;
7182 /* that's an [in out] buffer */
7184 if (!q_u
->buffer
&& (offered
!=0)) {
7185 return WERR_INVALID_PARAM
;
7188 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7189 buffer
= r_u
->buffer
;
7191 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7196 unistr2_to_ascii(architecture
, &q_u
->environment
, sizeof(architecture
));
7197 unistr2_to_ascii(servername
, &q_u
->name
, sizeof(servername
));
7199 if ( !is_myname_or_ipaddr( servername
) )
7200 return WERR_UNKNOWN_PRINTER_DRIVER
;
7204 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
7206 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
7208 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
7210 return WERR_UNKNOWN_LEVEL
;
7214 /****************************************************************************
7215 ****************************************************************************/
7217 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
7219 form
->flag
=list
->flag
;
7220 init_unistr(&form
->name
, list
->name
);
7221 form
->width
=list
->width
;
7222 form
->length
=list
->length
;
7223 form
->left
=list
->left
;
7224 form
->top
=list
->top
;
7225 form
->right
=list
->right
;
7226 form
->bottom
=list
->bottom
;
7229 /****************************************************************************
7230 ****************************************************************************/
7232 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
7234 uint32 level
= q_u
->level
;
7235 RPC_BUFFER
*buffer
= NULL
;
7236 uint32 offered
= q_u
->offered
;
7237 uint32
*needed
= &r_u
->needed
;
7238 uint32
*numofforms
= &r_u
->numofforms
;
7239 uint32 numbuiltinforms
;
7241 nt_forms_struct
*list
=NULL
;
7242 nt_forms_struct
*builtinlist
=NULL
;
7247 /* that's an [in out] buffer */
7249 if (!q_u
->buffer
&& (offered
!=0) ) {
7250 return WERR_INVALID_PARAM
;
7253 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7254 buffer
= r_u
->buffer
;
7256 DEBUG(4,("_spoolss_enumforms\n"));
7257 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7258 DEBUGADD(5,("Info level [%d]\n", level
));
7260 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
7261 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
7262 *numofforms
= get_ntforms(&list
);
7263 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
7264 *numofforms
+= numbuiltinforms
;
7266 if (*numofforms
== 0) {
7267 SAFE_FREE(builtinlist
);
7269 return WERR_NO_MORE_ITEMS
;
7274 if ((forms_1
=SMB_MALLOC_ARRAY(FORM_1
, *numofforms
)) == NULL
) {
7275 SAFE_FREE(builtinlist
);
7281 /* construct the list of form structures */
7282 for (i
=0; i
<numbuiltinforms
; i
++) {
7283 DEBUGADD(6,("Filling form number [%d]\n",i
));
7284 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
7287 SAFE_FREE(builtinlist
);
7289 for (; i
<*numofforms
; i
++) {
7290 DEBUGADD(6,("Filling form number [%d]\n",i
));
7291 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
7296 /* check the required size. */
7297 for (i
=0; i
<numbuiltinforms
; i
++) {
7298 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7299 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7301 for (; i
<*numofforms
; i
++) {
7302 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7303 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7306 *needed
=buffer_size
;
7308 if (*needed
> offered
) {
7311 return WERR_INSUFFICIENT_BUFFER
;
7314 if (!rpcbuf_alloc_size(buffer
, buffer_size
)){
7320 /* fill the buffer with the form structures */
7321 for (i
=0; i
<numbuiltinforms
; i
++) {
7322 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7323 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7325 for (; i
<*numofforms
; i
++) {
7326 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7327 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7336 SAFE_FREE(builtinlist
);
7337 return WERR_UNKNOWN_LEVEL
;
7341 /****************************************************************************
7342 ****************************************************************************/
7344 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
7346 uint32 level
= q_u
->level
;
7347 UNISTR2
*uni_formname
= &q_u
->formname
;
7348 RPC_BUFFER
*buffer
= NULL
;
7349 uint32 offered
= q_u
->offered
;
7350 uint32
*needed
= &r_u
->needed
;
7352 nt_forms_struct
*list
=NULL
;
7353 nt_forms_struct builtin_form
;
7358 int numofforms
=0, i
=0;
7360 /* that's an [in out] buffer */
7362 if (!q_u
->buffer
&& (offered
!=0)) {
7363 return WERR_INVALID_PARAM
;
7366 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7367 buffer
= r_u
->buffer
;
7369 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
));
7371 DEBUG(4,("_spoolss_getform\n"));
7372 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7373 DEBUGADD(5,("Info level [%d]\n", level
));
7375 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
7376 if (!foundBuiltin
) {
7377 numofforms
= get_ntforms(&list
);
7378 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
7380 if (numofforms
== 0)
7387 fill_form_1(&form_1
, &builtin_form
);
7390 /* Check if the requested name is in the list of form structures */
7391 for (i
=0; i
<numofforms
; i
++) {
7393 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
7395 if (strequal(form_name
, list
[i
].name
)) {
7396 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
7397 fill_form_1(&form_1
, &list
[i
]);
7403 if (i
== numofforms
) {
7407 /* check the required size. */
7409 *needed
=spoolss_size_form_1(&form_1
);
7411 if (*needed
> offered
)
7412 return WERR_INSUFFICIENT_BUFFER
;
7414 if (!rpcbuf_alloc_size(buffer
, buffer_size
))
7417 /* fill the buffer with the form structures */
7418 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
7419 smb_io_form_1("", buffer
, &form_1
, 0);
7425 return WERR_UNKNOWN_LEVEL
;
7429 /****************************************************************************
7430 ****************************************************************************/
7432 static void fill_port_1(PORT_INFO_1
*port
, const char *name
)
7434 init_unistr(&port
->port_name
, name
);
7437 /****************************************************************************
7438 TODO: This probably needs distinguish between TCP/IP and Local ports
7440 ****************************************************************************/
7442 static void fill_port_2(PORT_INFO_2
*port
, const char *name
)
7444 init_unistr(&port
->port_name
, name
);
7445 init_unistr(&port
->monitor_name
, "Local Monitor");
7446 init_unistr(&port
->description
, SPL_LOCAL_PORT
);
7447 port
->port_type
=PORT_TYPE_WRITE
;
7452 /****************************************************************************
7453 wrapper around the enumer ports command
7454 ****************************************************************************/
7456 WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7458 char *cmd
= lp_enumports_cmd();
7459 char **qlines
= NULL
;
7460 char *command
= NULL
;
7468 /* if no hook then just fill in the default port */
7471 if (!(qlines
= SMB_MALLOC_ARRAY( char*, 2 ))) {
7474 if (!(qlines
[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME
))) {
7482 /* we have a valid enumport command */
7484 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7489 DEBUG(10,("Running [%s]\n", command
));
7490 ret
= smbrun(command
, &fd
);
7491 DEBUG(10,("Returned [%d]\n", ret
));
7492 TALLOC_FREE(command
);
7497 return WERR_ACCESS_DENIED
;
7501 qlines
= fd_lines_load(fd
, &numlines
, 0);
7502 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7512 /****************************************************************************
7514 ****************************************************************************/
7516 static WERROR
enumports_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7518 PORT_INFO_1
*ports
=NULL
;
7520 WERROR result
= WERR_OK
;
7521 char **qlines
= NULL
;
7524 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7525 if (!W_ERROR_IS_OK(result
)) {
7526 file_lines_free(qlines
);
7531 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_1
, numlines
)) == NULL
) {
7532 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7533 dos_errstr(WERR_NOMEM
)));
7534 file_lines_free(qlines
);
7538 for (i
=0; i
<numlines
; i
++) {
7539 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7540 fill_port_1(&ports
[i
], qlines
[i
]);
7543 file_lines_free(qlines
);
7545 *returned
= numlines
;
7547 /* check the required size. */
7548 for (i
=0; i
<*returned
; i
++) {
7549 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7550 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
7553 if (*needed
> offered
) {
7554 result
= WERR_INSUFFICIENT_BUFFER
;
7558 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7559 result
= WERR_NOMEM
;
7563 /* fill the buffer with the ports structures */
7564 for (i
=0; i
<*returned
; i
++) {
7565 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7566 smb_io_port_1("", buffer
, &ports
[i
], 0);
7572 if ( !W_ERROR_IS_OK(result
) )
7578 /****************************************************************************
7580 ****************************************************************************/
7582 static WERROR
enumports_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7584 PORT_INFO_2
*ports
=NULL
;
7586 WERROR result
= WERR_OK
;
7587 char **qlines
= NULL
;
7590 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7591 if ( !W_ERROR_IS_OK(result
)) {
7592 file_lines_free(qlines
);
7597 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_2
, numlines
)) == NULL
) {
7598 file_lines_free(qlines
);
7602 for (i
=0; i
<numlines
; i
++) {
7603 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7604 fill_port_2(&(ports
[i
]), qlines
[i
]);
7608 file_lines_free(qlines
);
7610 *returned
= numlines
;
7612 /* check the required size. */
7613 for (i
=0; i
<*returned
; i
++) {
7614 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7615 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
7618 if (*needed
> offered
) {
7619 result
= WERR_INSUFFICIENT_BUFFER
;
7623 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7624 result
= WERR_NOMEM
;
7628 /* fill the buffer with the ports structures */
7629 for (i
=0; i
<*returned
; i
++) {
7630 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7631 smb_io_port_2("", buffer
, &ports
[i
], 0);
7637 if ( !W_ERROR_IS_OK(result
) )
7643 /****************************************************************************
7645 ****************************************************************************/
7647 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
7649 uint32 level
= q_u
->level
;
7650 RPC_BUFFER
*buffer
= NULL
;
7651 uint32 offered
= q_u
->offered
;
7652 uint32
*needed
= &r_u
->needed
;
7653 uint32
*returned
= &r_u
->returned
;
7655 /* that's an [in out] buffer */
7657 if (!q_u
->buffer
&& (offered
!=0)) {
7658 return WERR_INVALID_PARAM
;
7661 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7662 buffer
= r_u
->buffer
;
7664 DEBUG(4,("_spoolss_enumports\n"));
7671 return enumports_level_1(buffer
, offered
, needed
, returned
);
7673 return enumports_level_2(buffer
, offered
, needed
, returned
);
7675 return WERR_UNKNOWN_LEVEL
;
7679 /****************************************************************************
7680 ****************************************************************************/
7682 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
7683 const SPOOL_PRINTER_INFO_LEVEL
*info
,
7684 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
7685 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
7688 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7691 WERROR err
= WERR_OK
;
7693 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7694 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7698 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7699 if (!convert_printer_info(info
, printer
, 2)) {
7700 free_a_printer(&printer
, 2);
7704 /* check to see if the printer already exists */
7706 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7707 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7708 printer
->info_2
->sharename
));
7709 free_a_printer(&printer
, 2);
7710 return WERR_PRINTER_ALREADY_EXISTS
;
7713 /* FIXME!!! smbd should check to see if the driver is installed before
7714 trying to add a printer like this --jerry */
7716 if (*lp_addprinter_cmd() ) {
7717 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
7718 free_a_printer(&printer
,2);
7719 return WERR_ACCESS_DENIED
;
7722 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7723 "smb.conf parameter \"addprinter command\" is defined. This"
7724 "parameter must exist for this call to succeed\n",
7725 printer
->info_2
->sharename
));
7728 /* use our primary netbios name since get_a_printer() will convert
7729 it to what the client expects on a case by case basis */
7731 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7732 printer
->info_2
->sharename
);
7735 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7736 free_a_printer(&printer
,2);
7737 return WERR_ACCESS_DENIED
;
7740 /* you must be a printer admin to add a new printer */
7741 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7742 free_a_printer(&printer
,2);
7743 return WERR_ACCESS_DENIED
;
7747 * Do sanity check on the requested changes for Samba.
7750 if (!check_printer_ok(printer
->info_2
, snum
)) {
7751 free_a_printer(&printer
,2);
7752 return WERR_INVALID_PARAM
;
7756 * When a printer is created, the drivername bound to the printer is used
7757 * to lookup previously saved driver initialization info, which is then
7758 * bound to the new printer, simulating what happens in the Windows arch.
7763 set_driver_init(printer
, 2);
7767 /* A valid devmode was included, convert and link it
7769 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7771 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
7772 &printer
->info_2
->devmode
))
7776 /* write the ASCII on disk */
7777 err
= mod_a_printer(printer
, 2);
7778 if (!W_ERROR_IS_OK(err
)) {
7779 free_a_printer(&printer
,2);
7783 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7784 /* Handle open failed - remove addition. */
7785 del_a_printer(printer
->info_2
->sharename
);
7786 free_a_printer(&printer
,2);
7787 return WERR_ACCESS_DENIED
;
7790 update_c_setprinter(False
);
7791 free_a_printer(&printer
,2);
7796 /****************************************************************************
7797 ****************************************************************************/
7799 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
7801 UNISTR2
*uni_srv_name
= q_u
->server_name
;
7802 uint32 level
= q_u
->level
;
7803 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
7804 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
7805 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
7806 uint32 user_switch
= q_u
->user_switch
;
7807 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
7808 POLICY_HND
*handle
= &r_u
->handle
;
7812 /* we don't handle yet */
7813 /* but I know what to do ... */
7814 return WERR_UNKNOWN_LEVEL
;
7816 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
7818 user_switch
, user
, handle
);
7820 return WERR_UNKNOWN_LEVEL
;
7824 /****************************************************************************
7825 ****************************************************************************/
7827 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
7829 uint32 level
= q_u
->level
;
7830 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
7831 WERROR err
= WERR_OK
;
7832 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7833 fstring driver_name
;
7836 ZERO_STRUCT(driver
);
7838 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7843 DEBUG(5,("Cleaning driver's information\n"));
7844 err
= clean_up_driver_struct(driver
, level
, &p
->pipe_user
);
7845 if (!W_ERROR_IS_OK(err
))
7848 DEBUG(5,("Moving driver to final destination\n"));
7849 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(driver
, level
, &p
->pipe_user
, &err
)) ) {
7853 if (add_a_printer_driver(driver
, level
)!=0) {
7854 err
= WERR_ACCESS_DENIED
;
7859 * I think this is where he DrvUpgradePrinter() hook would be
7860 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7861 * server. Right now, we just need to send ourselves a message
7862 * to update each printer bound to this driver. --jerry
7865 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7866 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7871 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7872 * decide if the driver init data should be deleted. The rules are:
7873 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7874 * 2) delete init data only if there is no 2k/Xp driver
7875 * 3) always delete init data
7876 * The generalized rule is always use init data from the highest order driver.
7877 * It is necessary to follow the driver install by an initialization step to
7878 * finish off this process.
7881 version
= driver
.info_3
->cversion
;
7882 else if (level
== 6)
7883 version
= driver
.info_6
->version
;
7888 * 9x printer driver - never delete init data
7891 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7896 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7897 * there is no 2k/Xp driver init data for this driver name.
7901 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7903 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7905 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7907 if (!del_driver_init(driver_name
))
7908 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name
));
7911 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7913 free_a_printer_driver(driver1
,3);
7914 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7921 * 2k or Xp printer driver - always delete init data
7924 if (!del_driver_init(driver_name
))
7925 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name
));
7929 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level
));
7935 free_a_printer_driver(driver
, level
);
7939 /********************************************************************
7940 * spoolss_addprinterdriverex
7941 ********************************************************************/
7943 WERROR
_spoolss_addprinterdriverex(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVEREX
*q_u
, SPOOL_R_ADDPRINTERDRIVEREX
*r_u
)
7945 SPOOL_Q_ADDPRINTERDRIVER q_u_local
;
7946 SPOOL_R_ADDPRINTERDRIVER r_u_local
;
7949 * we only support the semantics of AddPrinterDriver()
7950 * i.e. only copy files that are newer than existing ones
7953 if ( q_u
->copy_flags
!= APD_COPY_NEW_FILES
)
7954 return WERR_ACCESS_DENIED
;
7956 ZERO_STRUCT(q_u_local
);
7957 ZERO_STRUCT(r_u_local
);
7959 /* just pass the information off to _spoolss_addprinterdriver() */
7960 q_u_local
.server_name_ptr
= q_u
->server_name_ptr
;
7961 copy_unistr2(&q_u_local
.server_name
, &q_u
->server_name
);
7962 q_u_local
.level
= q_u
->level
;
7963 memcpy( &q_u_local
.info
, &q_u
->info
, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL
) );
7965 return _spoolss_addprinterdriver( p
, &q_u_local
, &r_u_local
);
7968 /****************************************************************************
7969 ****************************************************************************/
7971 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
7973 init_unistr(&info
->name
, name
);
7976 /****************************************************************************
7977 ****************************************************************************/
7979 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
7982 char *long_archi
= NULL
;
7983 char *servername
= NULL
;
7984 char *pservername
= NULL
;
7985 const char *short_archi
;
7986 DRIVER_DIRECTORY_1
*info
=NULL
;
7987 WERROR result
= WERR_OK
;
7988 TALLOC_CTX
*ctx
= talloc_tos();
7990 servername
= unistr2_to_ascii_talloc(ctx
, name
);
7994 long_archi
= unistr2_to_ascii_talloc(ctx
, uni_environment
);
7999 /* check for beginning double '\'s and that the server
8002 pservername
= servername
;
8003 if ( *pservername
== '\\' && strlen(servername
)>2 ) {
8007 if ( !is_myname_or_ipaddr( pservername
) )
8008 return WERR_INVALID_PARAM
;
8010 if (!(short_archi
= get_short_archi(long_archi
)))
8011 return WERR_INVALID_ENVIRONMENT
;
8013 if((info
=SMB_MALLOC_P(DRIVER_DIRECTORY_1
)) == NULL
)
8016 path
= talloc_asprintf(ctx
,
8017 "\\\\%s\\print$\\%s", pservername
, short_archi
);
8019 result
= WERR_NOMEM
;
8023 DEBUG(4,("printer driver directory: [%s]\n", path
));
8025 fill_driverdir_1(info
, path
);
8027 *needed
+= spoolss_size_driverdir_info_1(info
);
8029 if (*needed
> offered
) {
8030 result
= WERR_INSUFFICIENT_BUFFER
;
8034 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8035 result
= WERR_NOMEM
;
8039 smb_io_driverdir_1("", buffer
, info
, 0);
8047 /****************************************************************************
8048 ****************************************************************************/
8050 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
8052 UNISTR2
*name
= &q_u
->name
;
8053 UNISTR2
*uni_environment
= &q_u
->environment
;
8054 uint32 level
= q_u
->level
;
8055 RPC_BUFFER
*buffer
= NULL
;
8056 uint32 offered
= q_u
->offered
;
8057 uint32
*needed
= &r_u
->needed
;
8059 /* that's an [in out] buffer */
8061 if (!q_u
->buffer
&& (offered
!=0)) {
8062 return WERR_INVALID_PARAM
;
8065 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8066 buffer
= r_u
->buffer
;
8068 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8074 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
8076 return WERR_UNKNOWN_LEVEL
;
8080 /****************************************************************************
8081 ****************************************************************************/
8083 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
8085 POLICY_HND
*handle
= &q_u
->handle
;
8086 uint32 idx
= q_u
->index
;
8087 uint32 in_value_len
= q_u
->valuesize
;
8088 uint32 in_data_len
= q_u
->datasize
;
8089 uint32
*out_max_value_len
= &r_u
->valuesize
;
8090 uint16
**out_value
= &r_u
->value
;
8091 uint32
*out_value_len
= &r_u
->realvaluesize
;
8092 uint32
*out_type
= &r_u
->type
;
8093 uint32
*out_max_data_len
= &r_u
->datasize
;
8094 uint8
**data_out
= &r_u
->data
;
8095 uint32
*out_data_len
= &r_u
->realdatasize
;
8097 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8099 uint32 biggest_valuesize
;
8100 uint32 biggest_datasize
;
8102 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8105 REGISTRY_VALUE
*val
= NULL
;
8106 NT_PRINTER_DATA
*p_data
;
8107 int i
, key_index
, num_values
;
8112 *out_max_data_len
= 0;
8116 DEBUG(5,("spoolss_enumprinterdata\n"));
8119 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8123 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8126 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8127 if (!W_ERROR_IS_OK(result
))
8130 p_data
= printer
->info_2
->data
;
8131 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8136 * The NT machine wants to know the biggest size of value and data
8138 * cf: MSDN EnumPrinterData remark section
8141 if ( !in_value_len
&& !in_data_len
&& (key_index
!= -1) )
8143 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8145 biggest_valuesize
= 0;
8146 biggest_datasize
= 0;
8148 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8150 for ( i
=0; i
<num_values
; i
++ )
8152 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8154 name_length
= strlen(val
->valuename
);
8155 if ( strlen(val
->valuename
) > biggest_valuesize
)
8156 biggest_valuesize
= name_length
;
8158 if ( val
->size
> biggest_datasize
)
8159 biggest_datasize
= val
->size
;
8161 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8165 /* the value is an UNICODE string but real_value_size is the length
8166 in bytes including the trailing 0 */
8168 *out_value_len
= 2 * (1+biggest_valuesize
);
8169 *out_data_len
= biggest_datasize
;
8171 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
8177 * the value len is wrong in NT sp3
8178 * that's the number of bytes not the number of unicode chars
8181 if ( key_index
!= -1 )
8182 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, idx
);
8187 /* out_value should default to "" or else NT4 has
8188 problems unmarshalling the response */
8190 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8193 if((*out_value
=(uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8195 result
= WERR_NOMEM
;
8198 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
8204 /* the data is counted in bytes */
8206 *out_max_data_len
= in_data_len
;
8207 *out_data_len
= in_data_len
;
8209 /* only allocate when given a non-zero data_len */
8211 if ( in_data_len
&& ((*data_out
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
8213 result
= WERR_NOMEM
;
8217 result
= WERR_NO_MORE_ITEMS
;
8223 * - counted in bytes in the request
8224 * - counted in UNICODE chars in the max reply
8225 * - counted in bytes in the real size
8227 * take a pause *before* coding not *during* coding
8231 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8233 if ( (*out_value
= (uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8235 result
= WERR_NOMEM
;
8239 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), (size_t)in_value_len
, 0);
8247 *out_type
= regval_type( val
);
8249 /* data - counted in bytes */
8251 *out_max_data_len
= in_data_len
;
8252 if ( in_data_len
&& (*data_out
= (uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
8254 result
= WERR_NOMEM
;
8257 data_len
= regval_size(val
);
8258 if ( *data_out
&& data_len
)
8259 memcpy( *data_out
, regval_data_p(val
), data_len
);
8260 *out_data_len
= data_len
;
8264 free_a_printer(&printer
, 2);
8268 /****************************************************************************
8269 ****************************************************************************/
8271 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
8273 POLICY_HND
*handle
= &q_u
->handle
;
8274 UNISTR2
*value
= &q_u
->value
;
8275 uint32 type
= q_u
->type
;
8276 uint8
*data
= q_u
->data
;
8277 uint32 real_len
= q_u
->real_len
;
8279 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8281 WERROR status
= WERR_OK
;
8282 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8285 DEBUG(5,("spoolss_setprinterdata\n"));
8288 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8292 if ( Printer
->printer_type
== SPLHND_SERVER
) {
8293 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8294 return WERR_INVALID_PARAM
;
8297 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8301 * Access check : NT returns "access denied" if you make a
8302 * SetPrinterData call without the necessary privildge.
8303 * we were originally returning OK if nothing changed
8304 * which made Win2k issue **a lot** of SetPrinterData
8305 * when connecting to a printer --jerry
8308 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8310 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8311 status
= WERR_ACCESS_DENIED
;
8315 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8316 if (!W_ERROR_IS_OK(status
))
8319 unistr2_to_ascii(valuename
, value
, sizeof(valuename
));
8322 * When client side code sets a magic printer data key, detect it and save
8323 * the current printer data and the magic key's data (its the DEVMODE) for
8324 * future printer/driver initializations.
8326 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
8328 /* Set devmode and printer initialization info */
8329 status
= save_driver_init( printer
, 2, data
, real_len
);
8331 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
8335 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
8336 type
, data
, real_len
);
8337 if ( W_ERROR_IS_OK(status
) )
8338 status
= mod_a_printer(printer
, 2);
8342 free_a_printer(&printer
, 2);
8347 /****************************************************************************
8348 ****************************************************************************/
8350 WERROR
_spoolss_resetprinter(pipes_struct
*p
, SPOOL_Q_RESETPRINTER
*q_u
, SPOOL_R_RESETPRINTER
*r_u
)
8352 POLICY_HND
*handle
= &q_u
->handle
;
8353 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8356 DEBUG(5,("_spoolss_resetprinter\n"));
8359 * All we do is to check to see if the handle and queue is valid.
8360 * This call really doesn't mean anything to us because we only
8361 * support RAW printing. --jerry
8365 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8369 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8373 /* blindly return success */
8378 /****************************************************************************
8379 ****************************************************************************/
8381 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
8383 POLICY_HND
*handle
= &q_u
->handle
;
8384 UNISTR2
*value
= &q_u
->valuename
;
8386 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8388 WERROR status
= WERR_OK
;
8389 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8390 char *valuename
= NULL
;
8391 TALLOC_CTX
*ctx
= p
->mem_ctx
;
8393 DEBUG(5,("spoolss_deleteprinterdata\n"));
8396 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8400 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
8403 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8404 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
8405 return WERR_ACCESS_DENIED
;
8408 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8409 if (!W_ERROR_IS_OK(status
))
8412 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
8414 free_a_printer(&printer
, 2);
8418 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
);
8420 if ( W_ERROR_IS_OK(status
) )
8421 mod_a_printer( printer
, 2 );
8423 free_a_printer(&printer
, 2);
8424 TALLOC_FREE(valuename
);
8429 /****************************************************************************
8430 ****************************************************************************/
8432 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
8434 POLICY_HND
*handle
= &q_u
->handle
;
8435 FORM
*form
= &q_u
->form
;
8436 nt_forms_struct tmpForm
;
8438 WERROR status
= WERR_OK
;
8439 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8442 nt_forms_struct
*list
=NULL
;
8443 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8445 DEBUG(5,("spoolss_addform\n"));
8448 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8453 /* forms can be added on printer of on the print server handle */
8455 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8457 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8460 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8461 if (!W_ERROR_IS_OK(status
))
8465 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8466 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8467 status
= WERR_ACCESS_DENIED
;
8471 /* can't add if builtin */
8473 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8474 status
= WERR_ALREADY_EXISTS
;
8478 count
= get_ntforms(&list
);
8480 if(!add_a_form(&list
, form
, &count
)) {
8481 status
= WERR_NOMEM
;
8485 write_ntforms(&list
, count
);
8488 * ChangeID must always be set if this is a printer
8491 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8492 status
= mod_a_printer(printer
, 2);
8496 free_a_printer(&printer
, 2);
8502 /****************************************************************************
8503 ****************************************************************************/
8505 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
8507 POLICY_HND
*handle
= &q_u
->handle
;
8508 UNISTR2
*form_name
= &q_u
->name
;
8509 nt_forms_struct tmpForm
;
8511 nt_forms_struct
*list
=NULL
;
8512 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8514 WERROR status
= WERR_OK
;
8515 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8517 DEBUG(5,("spoolss_deleteform\n"));
8520 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8524 /* forms can be deleted on printer of on the print server handle */
8526 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8528 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8531 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8532 if (!W_ERROR_IS_OK(status
))
8536 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8537 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n"));
8538 status
= WERR_ACCESS_DENIED
;
8542 /* can't delete if builtin */
8544 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
8545 status
= WERR_INVALID_PARAM
;
8549 count
= get_ntforms(&list
);
8551 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
8555 * ChangeID must always be set if this is a printer
8558 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8559 status
= mod_a_printer(printer
, 2);
8563 free_a_printer(&printer
, 2);
8569 /****************************************************************************
8570 ****************************************************************************/
8572 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
8574 POLICY_HND
*handle
= &q_u
->handle
;
8575 FORM
*form
= &q_u
->form
;
8576 nt_forms_struct tmpForm
;
8578 WERROR status
= WERR_OK
;
8579 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8582 nt_forms_struct
*list
=NULL
;
8583 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8585 DEBUG(5,("spoolss_setform\n"));
8588 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8592 /* forms can be modified on printer of on the print server handle */
8594 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8596 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8599 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8600 if (!W_ERROR_IS_OK(status
))
8604 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8605 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
8606 status
= WERR_ACCESS_DENIED
;
8610 /* can't set if builtin */
8611 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8612 status
= WERR_INVALID_PARAM
;
8616 count
= get_ntforms(&list
);
8617 update_a_form(&list
, form
, count
);
8618 write_ntforms(&list
, count
);
8621 * ChangeID must always be set if this is a printer
8624 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8625 status
= mod_a_printer(printer
, 2);
8630 free_a_printer(&printer
, 2);
8636 /****************************************************************************
8637 enumprintprocessors level 1.
8638 ****************************************************************************/
8640 static WERROR
enumprintprocessors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8642 PRINTPROCESSOR_1
*info_1
=NULL
;
8643 WERROR result
= WERR_OK
;
8645 if((info_1
= SMB_MALLOC_P(PRINTPROCESSOR_1
)) == NULL
)
8650 init_unistr(&info_1
->name
, "winprint");
8652 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
8654 if (*needed
> offered
) {
8655 result
= WERR_INSUFFICIENT_BUFFER
;
8659 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8660 result
= WERR_NOMEM
;
8664 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
8669 if ( !W_ERROR_IS_OK(result
) )
8675 /****************************************************************************
8676 ****************************************************************************/
8678 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
8680 uint32 level
= q_u
->level
;
8681 RPC_BUFFER
*buffer
= NULL
;
8682 uint32 offered
= q_u
->offered
;
8683 uint32
*needed
= &r_u
->needed
;
8684 uint32
*returned
= &r_u
->returned
;
8686 /* that's an [in out] buffer */
8688 if (!q_u
->buffer
&& (offered
!=0)) {
8689 return WERR_INVALID_PARAM
;
8692 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8693 buffer
= r_u
->buffer
;
8695 DEBUG(5,("spoolss_enumprintprocessors\n"));
8698 * Enumerate the print processors ...
8700 * Just reply with "winprint", to keep NT happy
8701 * and I can use my nice printer checker.
8709 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
8711 return WERR_UNKNOWN_LEVEL
;
8715 /****************************************************************************
8716 enumprintprocdatatypes level 1.
8717 ****************************************************************************/
8719 static WERROR
enumprintprocdatatypes_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8721 PRINTPROCDATATYPE_1
*info_1
=NULL
;
8722 WERROR result
= WERR_OK
;
8724 if((info_1
= SMB_MALLOC_P(PRINTPROCDATATYPE_1
)) == NULL
)
8729 init_unistr(&info_1
->name
, "RAW");
8731 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
8733 if (*needed
> offered
) {
8734 result
= WERR_INSUFFICIENT_BUFFER
;
8738 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8739 result
= WERR_NOMEM
;
8743 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
8748 if ( !W_ERROR_IS_OK(result
) )
8754 /****************************************************************************
8755 ****************************************************************************/
8757 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
8759 uint32 level
= q_u
->level
;
8760 RPC_BUFFER
*buffer
= NULL
;
8761 uint32 offered
= q_u
->offered
;
8762 uint32
*needed
= &r_u
->needed
;
8763 uint32
*returned
= &r_u
->returned
;
8765 /* that's an [in out] buffer */
8767 if (!q_u
->buffer
&& (offered
!=0)) {
8768 return WERR_INVALID_PARAM
;
8771 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8772 buffer
= r_u
->buffer
;
8774 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8781 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
8783 return WERR_UNKNOWN_LEVEL
;
8787 /****************************************************************************
8788 enumprintmonitors level 1.
8789 ****************************************************************************/
8791 static WERROR
enumprintmonitors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8793 PRINTMONITOR_1
*info_1
;
8794 WERROR result
= WERR_OK
;
8797 if((info_1
= SMB_MALLOC_ARRAY(PRINTMONITOR_1
, 2)) == NULL
)
8802 init_unistr(&(info_1
[0].name
), SPL_LOCAL_PORT
);
8803 init_unistr(&(info_1
[1].name
), SPL_TCPIP_PORT
);
8805 for ( i
=0; i
<*returned
; i
++ ) {
8806 *needed
+= spoolss_size_printmonitor_info_1(&info_1
[i
]);
8809 if (*needed
> offered
) {
8810 result
= WERR_INSUFFICIENT_BUFFER
;
8814 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8815 result
= WERR_NOMEM
;
8819 for ( i
=0; i
<*returned
; i
++ ) {
8820 smb_io_printmonitor_info_1("", buffer
, &info_1
[i
], 0);
8826 if ( !W_ERROR_IS_OK(result
) )
8832 /****************************************************************************
8833 enumprintmonitors level 2.
8834 ****************************************************************************/
8836 static WERROR
enumprintmonitors_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8838 PRINTMONITOR_2
*info_2
;
8839 WERROR result
= WERR_OK
;
8842 if((info_2
= SMB_MALLOC_ARRAY(PRINTMONITOR_2
, 2)) == NULL
)
8847 init_unistr( &(info_2
[0].name
), SPL_LOCAL_PORT
);
8848 init_unistr( &(info_2
[0].environment
), "Windows NT X86" );
8849 init_unistr( &(info_2
[0].dll_name
), "localmon.dll" );
8851 init_unistr( &(info_2
[1].name
), SPL_TCPIP_PORT
);
8852 init_unistr( &(info_2
[1].environment
), "Windows NT X86" );
8853 init_unistr( &(info_2
[1].dll_name
), "tcpmon.dll" );
8855 for ( i
=0; i
<*returned
; i
++ ) {
8856 *needed
+= spoolss_size_printmonitor_info_2(&info_2
[i
]);
8859 if (*needed
> offered
) {
8860 result
= WERR_INSUFFICIENT_BUFFER
;
8864 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8865 result
= WERR_NOMEM
;
8869 for ( i
=0; i
<*returned
; i
++ ) {
8870 smb_io_printmonitor_info_2("", buffer
, &info_2
[i
], 0);
8876 if ( !W_ERROR_IS_OK(result
) )
8882 /****************************************************************************
8883 ****************************************************************************/
8885 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
8887 uint32 level
= q_u
->level
;
8888 RPC_BUFFER
*buffer
= NULL
;
8889 uint32 offered
= q_u
->offered
;
8890 uint32
*needed
= &r_u
->needed
;
8891 uint32
*returned
= &r_u
->returned
;
8893 /* that's an [in out] buffer */
8895 if (!q_u
->buffer
&& (offered
!=0)) {
8896 return WERR_INVALID_PARAM
;
8899 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8900 buffer
= r_u
->buffer
;
8902 DEBUG(5,("spoolss_enumprintmonitors\n"));
8905 * Enumerate the print monitors ...
8907 * Just reply with "Local Port", to keep NT happy
8908 * and I can use my nice printer checker.
8916 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
8918 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
8920 return WERR_UNKNOWN_LEVEL
;
8924 /****************************************************************************
8925 ****************************************************************************/
8927 static WERROR
getjob_level_1(print_queue_struct
**queue
, int count
, int snum
,
8928 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8929 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8934 JOB_INFO_1
*info_1
=NULL
;
8935 WERROR result
= WERR_OK
;
8937 info_1
=SMB_MALLOC_P(JOB_INFO_1
);
8939 if (info_1
== NULL
) {
8943 for (i
=0; i
<count
&& found
==False
; i
++) {
8944 if ((*queue
)[i
].job
==(int)jobid
)
8950 /* NT treats not found as bad param... yet another bad choice */
8951 return WERR_INVALID_PARAM
;
8954 fill_job_info_1( info_1
, &((*queue
)[i
-1]), i
, snum
, ntprinter
);
8956 *needed
+= spoolss_size_job_info_1(info_1
);
8958 if (*needed
> offered
) {
8959 result
= WERR_INSUFFICIENT_BUFFER
;
8963 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8964 result
= WERR_NOMEM
;
8968 smb_io_job_info_1("", buffer
, info_1
, 0);
8976 /****************************************************************************
8977 ****************************************************************************/
8979 static WERROR
getjob_level_2(print_queue_struct
**queue
, int count
, int snum
,
8980 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8981 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8988 DEVICEMODE
*devmode
= NULL
;
8989 NT_DEVICEMODE
*nt_devmode
= NULL
;
8991 if ( !(info_2
=SMB_MALLOC_P(JOB_INFO_2
)) )
8994 ZERO_STRUCTP(info_2
);
8996 for ( i
=0; i
<count
&& found
==False
; i
++ )
8998 if ((*queue
)[i
].job
== (int)jobid
)
9003 /* NT treats not found as bad param... yet another bad
9005 result
= WERR_INVALID_PARAM
;
9010 * if the print job does not have a DEVMODE associated with it,
9011 * just use the one for the printer. A NULL devicemode is not
9012 * a failure condition
9015 if ( !(nt_devmode
=print_job_devmode( lp_const_servicename(snum
), jobid
)) )
9016 devmode
= construct_dev_mode(lp_const_servicename(snum
));
9018 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) != NULL
) {
9019 ZERO_STRUCTP( devmode
);
9020 convert_nt_devicemode( devmode
, nt_devmode
);
9024 fill_job_info_2(info_2
, &((*queue
)[i
-1]), i
, snum
, ntprinter
, devmode
);
9026 *needed
+= spoolss_size_job_info_2(info_2
);
9028 if (*needed
> offered
) {
9029 result
= WERR_INSUFFICIENT_BUFFER
;
9033 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9034 result
= WERR_NOMEM
;
9038 smb_io_job_info_2("", buffer
, info_2
, 0);
9043 /* Cleanup allocated memory */
9045 free_job_info_2(info_2
); /* Also frees devmode */
9051 /****************************************************************************
9052 ****************************************************************************/
9054 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
9056 POLICY_HND
*handle
= &q_u
->handle
;
9057 uint32 jobid
= q_u
->jobid
;
9058 uint32 level
= q_u
->level
;
9059 RPC_BUFFER
*buffer
= NULL
;
9060 uint32 offered
= q_u
->offered
;
9061 uint32
*needed
= &r_u
->needed
;
9062 WERROR wstatus
= WERR_OK
;
9063 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9066 print_queue_struct
*queue
= NULL
;
9067 print_status_struct prt_status
;
9069 /* that's an [in out] buffer */
9071 if (!q_u
->buffer
&& (offered
!=0)) {
9072 return WERR_INVALID_PARAM
;
9075 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9076 buffer
= r_u
->buffer
;
9078 DEBUG(5,("spoolss_getjob\n"));
9082 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9085 wstatus
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9086 if ( !W_ERROR_IS_OK(wstatus
) )
9089 count
= print_queue_status(snum
, &queue
, &prt_status
);
9091 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9092 count
, prt_status
.status
, prt_status
.message
));
9096 wstatus
= getjob_level_1(&queue
, count
, snum
, ntprinter
, jobid
,
9097 buffer
, offered
, needed
);
9100 wstatus
= getjob_level_2(&queue
, count
, snum
, ntprinter
, jobid
,
9101 buffer
, offered
, needed
);
9104 wstatus
= WERR_UNKNOWN_LEVEL
;
9109 free_a_printer( &ntprinter
, 2 );
9114 /********************************************************************
9115 spoolss_getprinterdataex
9117 From MSDN documentation of GetPrinterDataEx: pass request
9118 to GetPrinterData if key is "PrinterDriverData".
9119 ********************************************************************/
9121 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
9123 POLICY_HND
*handle
= &q_u
->handle
;
9124 uint32 in_size
= q_u
->size
;
9125 uint32
*type
= &r_u
->type
;
9126 uint32
*out_size
= &r_u
->size
;
9127 uint8
**data
= &r_u
->data
;
9128 uint32
*needed
= &r_u
->needed
;
9129 fstring keyname
, valuename
;
9131 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9133 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9135 WERROR status
= WERR_OK
;
9137 DEBUG(4,("_spoolss_getprinterdataex\n"));
9139 unistr2_to_ascii(keyname
, &q_u
->keyname
, sizeof(keyname
));
9140 unistr2_to_ascii(valuename
, &q_u
->valuename
, sizeof(valuename
));
9142 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9143 keyname
, valuename
));
9145 /* in case of problem, return some default values */
9149 *out_size
= in_size
;
9152 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9153 status
= WERR_BADFID
;
9157 /* Is the handle to a printer or to the server? */
9159 if (Printer
->printer_type
== SPLHND_SERVER
) {
9160 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9161 status
= WERR_INVALID_PARAM
;
9165 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9168 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9169 if ( !W_ERROR_IS_OK(status
) )
9172 /* check to see if the keyname is valid */
9173 if ( !strlen(keyname
) ) {
9174 status
= WERR_INVALID_PARAM
;
9178 if ( lookup_printerkey( printer
->info_2
->data
, keyname
) == -1 ) {
9179 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname
));
9180 free_a_printer( &printer
, 2 );
9181 status
= WERR_BADFILE
;
9185 /* When given a new keyname, we should just create it */
9187 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
, type
, data
, needed
, in_size
);
9189 if (*needed
> *out_size
)
9190 status
= WERR_MORE_DATA
;
9193 if ( !W_ERROR_IS_OK(status
) )
9195 DEBUG(5, ("error: allocating %d\n", *out_size
));
9197 /* reply this param doesn't exist */
9201 if( (*data
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
) {
9202 status
= WERR_NOMEM
;
9211 free_a_printer( &printer
, 2 );
9216 /********************************************************************
9217 * spoolss_setprinterdataex
9218 ********************************************************************/
9220 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
9222 POLICY_HND
*handle
= &q_u
->handle
;
9223 uint32 type
= q_u
->type
;
9224 uint8
*data
= q_u
->data
;
9225 uint32 real_len
= q_u
->real_len
;
9227 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9229 WERROR status
= WERR_OK
;
9230 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9235 DEBUG(4,("_spoolss_setprinterdataex\n"));
9237 /* From MSDN documentation of SetPrinterDataEx: pass request to
9238 SetPrinterData if key is "PrinterDriverData" */
9241 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9245 if ( Printer
->printer_type
== SPLHND_SERVER
) {
9246 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9247 return WERR_INVALID_PARAM
;
9250 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9254 * Access check : NT returns "access denied" if you make a
9255 * SetPrinterData call without the necessary privildge.
9256 * we were originally returning OK if nothing changed
9257 * which made Win2k issue **a lot** of SetPrinterData
9258 * when connecting to a printer --jerry
9261 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
9263 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9264 return WERR_ACCESS_DENIED
;
9267 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9268 if (!W_ERROR_IS_OK(status
))
9271 unistr2_to_ascii( valuename
, &q_u
->value
, sizeof(valuename
));
9272 unistr2_to_ascii( keyname
, &q_u
->key
, sizeof(keyname
));
9274 /* check for OID in valuename */
9276 if ( (oid_string
= strchr( valuename
, ',' )) != NULL
)
9282 /* save the registry data */
9284 status
= set_printer_dataex( printer
, keyname
, valuename
, type
, data
, real_len
);
9286 if ( W_ERROR_IS_OK(status
) )
9288 /* save the OID if one was specified */
9290 fstrcat( keyname
, "\\" );
9291 fstrcat( keyname
, SPOOL_OID_KEY
);
9294 * I'm not checking the status here on purpose. Don't know
9295 * if this is right, but I'm returning the status from the
9296 * previous set_printer_dataex() call. I have no idea if
9297 * this is right. --jerry
9300 set_printer_dataex( printer
, keyname
, valuename
,
9301 REG_SZ
, (uint8
*)oid_string
,
9302 strlen(oid_string
)+1 );
9305 status
= mod_a_printer(printer
, 2);
9308 free_a_printer(&printer
, 2);
9314 /********************************************************************
9315 * spoolss_deleteprinterdataex
9316 ********************************************************************/
9318 WERROR
_spoolss_deleteprinterdataex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATAEX
*q_u
, SPOOL_R_DELETEPRINTERDATAEX
*r_u
)
9320 POLICY_HND
*handle
= &q_u
->handle
;
9321 UNISTR2
*value
= &q_u
->valuename
;
9322 UNISTR2
*key
= &q_u
->keyname
;
9324 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9326 WERROR status
= WERR_OK
;
9327 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
9328 char *valuename
= NULL
;
9329 char *keyname
= NULL
;
9330 TALLOC_CTX
*ctx
= p
->mem_ctx
;
9332 DEBUG(5,("spoolss_deleteprinterdataex\n"));
9335 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9339 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9342 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9343 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
9344 return WERR_ACCESS_DENIED
;
9347 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
9348 keyname
= unistr2_to_ascii_talloc(ctx
, key
);
9349 if (!valuename
|| !keyname
) {
9353 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9354 if (!W_ERROR_IS_OK(status
))
9357 status
= delete_printer_dataex( printer
, keyname
, valuename
);
9359 if ( W_ERROR_IS_OK(status
) )
9360 mod_a_printer( printer
, 2 );
9362 free_a_printer(&printer
, 2);
9367 /********************************************************************
9368 * spoolss_enumprinterkey
9369 ********************************************************************/
9372 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
9375 fstring
*keynames
= NULL
;
9376 uint16
*enumkeys
= NULL
;
9379 POLICY_HND
*handle
= &q_u
->handle
;
9380 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9381 NT_PRINTER_DATA
*data
;
9382 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9384 WERROR status
= WERR_BADFILE
;
9387 DEBUG(4,("_spoolss_enumprinterkey\n"));
9390 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9394 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9397 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9398 if (!W_ERROR_IS_OK(status
))
9401 /* get the list of subkey names */
9403 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9404 data
= printer
->info_2
->data
;
9406 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
9408 if ( num_keys
== -1 ) {
9409 status
= WERR_BADFILE
;
9413 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
9415 r_u
->needed
= printerkey_len
*2;
9417 if ( q_u
->size
< r_u
->needed
) {
9418 status
= WERR_MORE_DATA
;
9422 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
9423 status
= WERR_NOMEM
;
9429 if ( q_u
->size
< r_u
->needed
)
9430 status
= WERR_MORE_DATA
;
9433 free_a_printer( &printer
, 2 );
9434 SAFE_FREE( keynames
);
9439 /********************************************************************
9440 * spoolss_deleteprinterkey
9441 ********************************************************************/
9443 WERROR
_spoolss_deleteprinterkey(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERKEY
*q_u
, SPOOL_R_DELETEPRINTERKEY
*r_u
)
9445 POLICY_HND
*handle
= &q_u
->handle
;
9446 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9448 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9452 DEBUG(5,("spoolss_deleteprinterkey\n"));
9455 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9459 /* if keyname == NULL, return error */
9461 if ( !q_u
->keyname
.buffer
)
9462 return WERR_INVALID_PARAM
;
9464 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9467 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9468 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
9469 return WERR_ACCESS_DENIED
;
9472 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9473 if (!W_ERROR_IS_OK(status
))
9476 /* delete the key and all subneys */
9478 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
));
9480 status
= delete_all_printer_data( printer
->info_2
, key
);
9482 if ( W_ERROR_IS_OK(status
) )
9483 status
= mod_a_printer(printer
, 2);
9485 free_a_printer( &printer
, 2 );
9491 /********************************************************************
9492 * spoolss_enumprinterdataex
9493 ********************************************************************/
9495 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
9497 POLICY_HND
*handle
= &q_u
->handle
;
9498 uint32 in_size
= q_u
->size
;
9501 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9502 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
9503 NT_PRINTER_DATA
*p_data
;
9505 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9510 REGISTRY_VALUE
*val
;
9515 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9518 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
9523 * first check for a keyname of NULL or "". Win2k seems to send
9524 * this a lot and we should send back WERR_INVALID_PARAM
9525 * no need to spend time looking up the printer in this case.
9529 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9530 if ( !strlen(key
) ) {
9531 result
= WERR_INVALID_PARAM
;
9535 /* get the printer off of disk */
9537 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
9540 ZERO_STRUCT(printer
);
9541 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9542 if (!W_ERROR_IS_OK(result
))
9545 /* now look for a match on the key name */
9547 p_data
= printer
->info_2
->data
;
9549 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9550 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
9552 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
9553 result
= WERR_INVALID_PARAM
;
9560 /* allocate the memory for the array of pointers -- if necessary */
9562 num_entries
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
9565 if ( (enum_values
=TALLOC_ARRAY(p
->mem_ctx
, PRINTER_ENUM_VALUES
, num_entries
)) == NULL
)
9567 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9568 (unsigned long)num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
9569 result
= WERR_NOMEM
;
9573 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
9577 * loop through all params and build the array to pass
9578 * back to the client
9581 for ( i
=0; i
<num_entries
; i
++ )
9583 /* lookup the registry value */
9585 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
9586 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
9590 value_name
= regval_name( val
);
9591 init_unistr( &enum_values
[i
].valuename
, value_name
);
9592 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
9593 enum_values
[i
].type
= regval_type( val
);
9595 data_len
= regval_size( val
);
9597 if ( !(enum_values
[i
].data
= (uint8
*)TALLOC_MEMDUP(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
9599 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9601 result
= WERR_NOMEM
;
9605 enum_values
[i
].data_len
= data_len
;
9607 /* keep track of the size of the array in bytes */
9609 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
9612 /* housekeeping information in the reply */
9614 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9615 * the hand marshalled container size is a multiple
9616 * of 4 bytes for RPC alignment.
9620 needed
+= 4-(needed
% 4);
9623 r_u
->needed
= needed
;
9624 r_u
->returned
= num_entries
;
9626 if (needed
> in_size
) {
9627 result
= WERR_MORE_DATA
;
9631 /* copy data into the reply */
9633 r_u
->ctr
.size
= r_u
->needed
;
9635 r_u
->ctr
.size_of_array
= r_u
->returned
;
9636 r_u
->ctr
.values
= enum_values
;
9642 free_a_printer(&printer
, 2);
9647 /****************************************************************************
9648 ****************************************************************************/
9650 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, const char *name
)
9652 init_unistr(&info
->name
, name
);
9655 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
9656 UNISTR2
*environment
,
9661 char *long_archi
= NULL
;
9662 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
9663 WERROR result
= WERR_OK
;
9664 TALLOC_CTX
*ctx
= talloc_tos();
9666 long_archi
= unistr2_to_ascii_talloc(ctx
, environment
);
9671 if (!get_short_archi(long_archi
))
9672 return WERR_INVALID_ENVIRONMENT
;
9674 if((info
=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1
)) == NULL
)
9677 fill_printprocessordirectory_1(info
, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9679 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
9681 if (*needed
> offered
) {
9682 result
= WERR_INSUFFICIENT_BUFFER
;
9686 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9687 result
= WERR_INSUFFICIENT_BUFFER
;
9691 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
9699 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
9701 uint32 level
= q_u
->level
;
9702 RPC_BUFFER
*buffer
= NULL
;
9703 uint32 offered
= q_u
->offered
;
9704 uint32
*needed
= &r_u
->needed
;
9707 /* that's an [in out] buffer */
9709 if (!q_u
->buffer
&& (offered
!=0)) {
9710 return WERR_INVALID_PARAM
;
9713 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9714 buffer
= r_u
->buffer
;
9716 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9722 result
= getprintprocessordirectory_level_1
9723 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
9726 result
= WERR_UNKNOWN_LEVEL
;
9732 /*******************************************************************
9733 Streams the monitor UI DLL name in UNICODE
9734 *******************************************************************/
9736 static WERROR
xcvtcp_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9737 RPC_BUFFER
*out
, uint32
*needed
)
9739 const char *dllname
= "tcpmonui.dll";
9741 *needed
= (strlen(dllname
)+1) * 2;
9743 if ( rpcbuf_get_size(out
) < *needed
) {
9744 return WERR_INSUFFICIENT_BUFFER
;
9747 if ( !make_monitorui_buf( out
, dllname
) ) {
9754 /*******************************************************************
9755 Create a new TCP/IP port
9756 *******************************************************************/
9758 static WERROR
xcvtcp_addport( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9759 RPC_BUFFER
*out
, uint32
*needed
)
9761 NT_PORT_DATA_1 port1
;
9762 TALLOC_CTX
*ctx
= talloc_tos();
9763 char *device_uri
= NULL
;
9765 ZERO_STRUCT( port1
);
9767 /* convert to our internal port data structure */
9769 if ( !convert_port_data_1( &port1
, in
) ) {
9773 /* create the device URI and call the add_port_hook() */
9775 switch ( port1
.protocol
) {
9776 case PORT_PROTOCOL_DIRECT
:
9777 device_uri
= talloc_asprintf(ctx
,
9778 "socket://%s:%d/", port1
.hostaddr
, port1
.port
);
9781 case PORT_PROTOCOL_LPR
:
9782 device_uri
= talloc_asprintf(ctx
,
9783 "lpr://%s/%s", port1
.hostaddr
, port1
.queue
);
9787 return WERR_UNKNOWN_PORT
;
9794 return add_port_hook(ctx
, token
, port1
.name
, device_uri
);
9797 /*******************************************************************
9798 *******************************************************************/
9800 struct xcv_api_table xcvtcp_cmds
[] = {
9801 { "MonitorUI", xcvtcp_monitorui
},
9802 { "AddPort", xcvtcp_addport
},
9806 static WERROR
process_xcvtcp_command( NT_USER_TOKEN
*token
, const char *command
,
9807 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9812 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9814 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9815 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9816 return xcvtcp_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9819 return WERR_BADFUNC
;
9822 /*******************************************************************
9823 *******************************************************************/
9824 #if 0 /* don't support management using the "Local Port" monitor */
9826 static WERROR
xcvlocal_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9827 RPC_BUFFER
*out
, uint32
*needed
)
9829 const char *dllname
= "localui.dll";
9831 *needed
= (strlen(dllname
)+1) * 2;
9833 if ( rpcbuf_get_size(out
) < *needed
) {
9834 return WERR_INSUFFICIENT_BUFFER
;
9837 if ( !make_monitorui_buf( out
, dllname
)) {
9844 /*******************************************************************
9845 *******************************************************************/
9847 struct xcv_api_table xcvlocal_cmds
[] = {
9848 { "MonitorUI", xcvlocal_monitorui
},
9852 struct xcv_api_table xcvlocal_cmds
[] = {
9859 /*******************************************************************
9860 *******************************************************************/
9862 static WERROR
process_xcvlocal_command( NT_USER_TOKEN
*token
, const char *command
,
9863 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9868 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9870 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9871 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9872 return xcvlocal_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9874 return WERR_BADFUNC
;
9877 /*******************************************************************
9878 *******************************************************************/
9880 WERROR
_spoolss_xcvdataport(pipes_struct
*p
, SPOOL_Q_XCVDATAPORT
*q_u
, SPOOL_R_XCVDATAPORT
*r_u
)
9882 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9886 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u
->handle
)));
9890 /* Has to be a handle to the TCP/IP port monitor */
9892 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9893 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9897 /* requires administrative access to the server */
9899 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9900 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9901 return WERR_ACCESS_DENIED
;
9904 /* Get the command name. There's numerous commands supported by the
9905 TCPMON interface. */
9907 rpcstr_pull(command
, q_u
->dataname
.buffer
, sizeof(command
),
9908 q_u
->dataname
.uni_str_len
*2, 0);
9910 /* Allocate the outgoing buffer */
9912 rpcbuf_init( &r_u
->outdata
, q_u
->offered
, p
->mem_ctx
);
9914 switch ( Printer
->printer_type
) {
9915 case SPLHND_PORTMON_TCP
:
9916 return process_xcvtcp_command( p
->pipe_user
.nt_user_token
, command
,
9917 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9918 case SPLHND_PORTMON_LOCAL
:
9919 return process_xcvlocal_command( p
->pipe_user
.nt_user_token
, command
,
9920 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9923 return WERR_INVALID_PRINT_MONITOR
;