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
));
524 result
= get_a_printer( NULL
, &printer
, 2, sname
);
525 if ( !W_ERROR_IS_OK(result
) ) {
526 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
527 sname
, dos_errstr(result
)));
531 /* printername is always returned as \\server\printername */
532 if ( !(printername
= strchr_m(&printer
->info_2
->printername
[2], '\\')) ) {
533 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
534 printer
->info_2
->printername
));
535 free_a_printer( &printer
, 2);
541 if ( strequal(printername
, aprinter
) ) {
542 free_a_printer( &printer
, 2);
547 DEBUGADD(10, ("printername: %s\n", printername
));
549 free_a_printer( &printer
, 2);
552 free_a_printer( &printer
, 2);
555 DEBUGADD(4,("Printer not found\n"));
559 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
561 fstrcpy(Printer
->sharename
, sname
);
566 /****************************************************************************
567 Find first available printer slot. creates a printer handle for you.
568 ****************************************************************************/
570 static bool open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
, uint32 access_granted
)
572 Printer_entry
*new_printer
;
574 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
576 if((new_printer
=SMB_MALLOC_P(Printer_entry
)) == NULL
)
579 ZERO_STRUCTP(new_printer
);
581 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
582 SAFE_FREE(new_printer
);
586 /* Add to the internal list. */
587 DLIST_ADD(printers_list
, new_printer
);
589 new_printer
->notify
.option
=NULL
;
591 if ( !(new_printer
->ctx
= talloc_init("Printer Entry [%p]", hnd
)) ) {
592 DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
593 close_printer_handle(p
, hnd
);
597 if (!set_printer_hnd_printertype(new_printer
, name
)) {
598 close_printer_handle(p
, hnd
);
602 if (!set_printer_hnd_name(new_printer
, name
)) {
603 close_printer_handle(p
, hnd
);
607 new_printer
->access_granted
= access_granted
;
609 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
614 /***************************************************************************
615 check to see if the client motify handle is monitoring the notification
616 given by (notify_type, notify_field).
617 **************************************************************************/
619 static bool is_monitoring_event_flags(uint32 flags
, uint16 notify_type
,
625 static bool is_monitoring_event(Printer_entry
*p
, uint16 notify_type
,
628 SPOOL_NOTIFY_OPTION
*option
= p
->notify
.option
;
632 * Flags should always be zero when the change notify
633 * is registered by the client's spooler. A user Win32 app
634 * might use the flags though instead of the NOTIFY_OPTION_INFO
643 return is_monitoring_event_flags(
644 p
->notify
.flags
, notify_type
, notify_field
);
646 for (i
= 0; i
< option
->count
; i
++) {
648 /* Check match for notify_type */
650 if (option
->ctr
.type
[i
].type
!= notify_type
)
653 /* Check match for field */
655 for (j
= 0; j
< option
->ctr
.type
[i
].count
; j
++) {
656 if (option
->ctr
.type
[i
].fields
[j
] == notify_field
) {
662 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
663 p
->servername
, p
->sharename
, notify_type
, notify_field
));
668 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
670 static void notify_one_value(struct spoolss_notify_msg
*msg
,
671 SPOOL_NOTIFY_INFO_DATA
*data
,
674 data
->notify_data
.value
[0] = msg
->notify
.value
[0];
675 data
->notify_data
.value
[1] = 0;
678 static void notify_string(struct spoolss_notify_msg
*msg
,
679 SPOOL_NOTIFY_INFO_DATA
*data
,
684 /* The length of the message includes the trailing \0 */
686 init_unistr2(&unistr
, msg
->notify
.data
, UNI_STR_TERMINATE
);
688 data
->notify_data
.data
.length
= msg
->len
* 2;
689 data
->notify_data
.data
.string
= TALLOC_ARRAY(mem_ctx
, uint16
, msg
->len
);
691 if (!data
->notify_data
.data
.string
) {
692 data
->notify_data
.data
.length
= 0;
696 memcpy(data
->notify_data
.data
.string
, unistr
.buffer
, msg
->len
* 2);
699 static void notify_system_time(struct spoolss_notify_msg
*msg
,
700 SPOOL_NOTIFY_INFO_DATA
*data
,
706 if (msg
->len
!= sizeof(time_t)) {
707 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
712 if (!prs_init(&ps
, RPC_MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
)) {
713 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
717 if (!make_systemtime(&systime
, gmtime((time_t *)msg
->notify
.data
))) {
718 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
723 if (!spoolss_io_system_time("", &ps
, 0, &systime
)) {
728 data
->notify_data
.data
.length
= prs_offset(&ps
);
729 if (prs_offset(&ps
)) {
730 data
->notify_data
.data
.string
= (uint16
*)
731 TALLOC(mem_ctx
, prs_offset(&ps
));
732 if (!data
->notify_data
.data
.string
) {
736 prs_copy_all_data_out((char *)data
->notify_data
.data
.string
, &ps
);
738 data
->notify_data
.data
.string
= NULL
;
744 struct notify2_message_table
{
746 void (*fn
)(struct spoolss_notify_msg
*msg
,
747 SPOOL_NOTIFY_INFO_DATA
*data
, TALLOC_CTX
*mem_ctx
);
750 static struct notify2_message_table printer_notify_table
[] = {
751 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string
},
752 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string
},
753 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string
},
754 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string
},
755 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string
},
756 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string
},
757 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string
},
758 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL
},
759 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string
},
760 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string
},
761 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL
},
762 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string
},
763 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
764 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value
},
765 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value
},
766 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL
},
767 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL
},
768 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL
},
769 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value
},
772 static struct notify2_message_table job_notify_table
[] = {
773 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL
},
774 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL
},
775 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL
},
776 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string
},
777 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL
},
778 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL
},
779 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL
},
780 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL
},
781 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL
},
782 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL
},
783 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value
},
784 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL
},
785 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
786 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string
},
787 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL
},
788 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL
},
789 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time
},
790 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL
},
791 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL
},
792 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL
},
793 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value
},
794 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL
},
795 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value
},
796 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL
},
800 /***********************************************************************
801 Allocate talloc context for container object
802 **********************************************************************/
804 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
809 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
814 /***********************************************************************
815 release all allocated memory and zero out structure
816 **********************************************************************/
818 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
824 talloc_destroy(ctr
->ctx
);
831 /***********************************************************************
832 **********************************************************************/
834 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
842 /***********************************************************************
843 **********************************************************************/
845 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
847 if ( !ctr
|| !ctr
->msg_groups
)
850 if ( idx
>= ctr
->num_groups
)
853 return &ctr
->msg_groups
[idx
];
857 /***********************************************************************
858 How many groups of change messages do we have ?
859 **********************************************************************/
861 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
866 return ctr
->num_groups
;
869 /***********************************************************************
870 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
871 **********************************************************************/
873 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
875 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
876 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
877 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
883 /* loop over all groups looking for a matching printer name */
885 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
886 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
890 /* add a new group? */
892 if ( i
== ctr
->num_groups
) {
895 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
896 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
899 ctr
->msg_groups
= groups
;
901 /* clear the new entry and set the printer name */
903 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
904 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
907 /* add the change messages; 'i' is the correct index now regardless */
909 msg_grp
= &ctr
->msg_groups
[i
];
913 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
914 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
917 msg_grp
->msgs
= msg_list
;
919 new_slot
= msg_grp
->num_msgs
-1;
920 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
922 /* need to allocate own copy of data */
925 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
926 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
928 return ctr
->num_groups
;
931 /***********************************************************************
932 Send a change notication message on all handles which have a call
934 **********************************************************************/
936 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
939 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
940 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
941 SPOOLSS_NOTIFY_MSG
*messages
;
942 int sending_msg_count
;
945 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
949 messages
= msg_group
->msgs
;
952 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
956 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
958 /* loop over all printers */
960 for (p
= printers_list
; p
; p
= p
->next
) {
961 SPOOL_NOTIFY_INFO_DATA
*data
;
966 /* Is there notification on this handle? */
968 if ( !p
->notify
.client_connected
)
971 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
973 /* For this printer? Print servers always receive
976 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
977 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
980 DEBUG(10,("Our printer\n"));
982 /* allocate the max entries possible */
984 data
= TALLOC_ARRAY( mem_ctx
, SPOOL_NOTIFY_INFO_DATA
, msg_group
->num_msgs
);
991 /* build the array of change notifications */
993 sending_msg_count
= 0;
995 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
996 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
998 /* Are we monitoring this event? */
1000 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1003 sending_msg_count
++;
1006 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1007 msg
->type
, msg
->field
, p
->sharename
));
1010 * if the is a printer notification handle and not a job notification
1011 * type, then set the id to 0. Other wise just use what was specified
1014 * When registering change notification on a print server handle
1015 * we always need to send back the id (snum) matching the printer
1016 * for which the change took place. For change notify registered
1017 * on a printer handle, this does not matter and the id should be 0.
1022 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1028 /* Convert unix jobid to smb jobid */
1030 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1031 id
= sysjob_to_jobid(msg
->id
);
1034 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1039 construct_info_data( &data
[data_len
], msg
->type
, msg
->field
, id
);
1042 case PRINTER_NOTIFY_TYPE
:
1043 if ( printer_notify_table
[msg
->field
].fn
)
1044 printer_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1047 case JOB_NOTIFY_TYPE
:
1048 if ( job_notify_table
[msg
->field
].fn
)
1049 job_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1053 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1060 if ( sending_msg_count
) {
1061 rpccli_spoolss_rrpcn( notify_cli_pipe
, mem_ctx
, &p
->notify
.client_hnd
,
1062 data_len
, data
, p
->notify
.change
, 0 );
1067 DEBUG(8,("send_notify2_changes: Exit...\n"));
1071 /***********************************************************************
1072 **********************************************************************/
1074 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1077 uint32 tv_sec
, tv_usec
;
1080 /* Unpack message */
1082 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "f",
1085 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "ddddddd",
1087 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1090 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "dd",
1091 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1093 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "B",
1094 &msg
->len
, &msg
->notify
.data
);
1096 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1097 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1099 tv
->tv_sec
= tv_sec
;
1100 tv
->tv_usec
= tv_usec
;
1103 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1104 msg
->notify
.value
[1]));
1106 dump_data(3, (uint8
*)msg
->notify
.data
, msg
->len
);
1111 /********************************************************************
1112 Receive a notify2 message list
1113 ********************************************************************/
1115 static void receive_notify2_message_list(struct messaging_context
*msg
,
1118 struct server_id server_id
,
1121 size_t msg_count
, i
;
1122 char *buf
= (char *)data
->data
;
1125 SPOOLSS_NOTIFY_MSG notify
;
1126 SPOOLSS_NOTIFY_MSG_CTR messages
;
1129 if (data
->length
< 4) {
1130 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1134 msg_count
= IVAL(buf
, 0);
1137 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1139 if (msg_count
== 0) {
1140 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1144 /* initialize the container */
1146 ZERO_STRUCT( messages
);
1147 notify_msg_ctr_init( &messages
);
1150 * build message groups for each printer identified
1151 * in a change_notify msg. Remember that a PCN message
1152 * includes the handle returned for the srv_spoolss_replyopenprinter()
1153 * call. Therefore messages are grouped according to printer handle.
1156 for ( i
=0; i
<msg_count
; i
++ ) {
1157 struct timeval msg_tv
;
1159 if (msg_ptr
+ 4 - buf
> data
->length
) {
1160 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1164 msg_len
= IVAL(msg_ptr
,0);
1167 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1168 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1172 /* unpack messages */
1174 ZERO_STRUCT( notify
);
1175 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1178 /* add to correct list in container */
1180 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1182 /* free memory that might have been allocated by notify2_unpack_msg() */
1184 if ( notify
.len
!= 0 )
1185 SAFE_FREE( notify
.notify
.data
);
1188 /* process each group of messages */
1190 num_groups
= notify_msg_ctr_numgroups( &messages
);
1191 for ( i
=0; i
<num_groups
; i
++ )
1192 send_notify2_changes( &messages
, i
);
1197 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32
)msg_count
));
1199 notify_msg_ctr_destroy( &messages
);
1204 /********************************************************************
1205 Send a message to ourself about new driver being installed
1206 so we can upgrade the information for each printer bound to this
1208 ********************************************************************/
1210 static bool srv_spoolss_drv_upgrade_printer(char* drivername
)
1212 int len
= strlen(drivername
);
1217 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1220 messaging_send_buf(smbd_messaging_context(), procid_self(),
1221 MSG_PRINTER_DRVUPGRADE
,
1222 (uint8
*)drivername
, len
+1);
1227 /**********************************************************************
1228 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1229 over all printers, upgrading ones as necessary
1230 **********************************************************************/
1232 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1235 struct server_id server_id
,
1240 int n_services
= lp_numservices();
1243 len
= MIN(data
->length
,sizeof(drivername
)-1);
1244 strncpy(drivername
, (const char *)data
->data
, len
);
1246 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1248 /* Iterate the printer list */
1250 for (snum
=0; snum
<n_services
; snum
++)
1252 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1255 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1257 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1258 if (!W_ERROR_IS_OK(result
))
1261 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1263 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1265 /* all we care about currently is the change_id */
1267 result
= mod_a_printer(printer
, 2);
1268 if (!W_ERROR_IS_OK(result
)) {
1269 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1270 dos_errstr(result
)));
1274 free_a_printer(&printer
, 2);
1281 /********************************************************************
1282 Update the cache for all printq's with a registered client
1284 ********************************************************************/
1286 void update_monitored_printq_cache( void )
1288 Printer_entry
*printer
= printers_list
;
1291 /* loop through all printers and update the cache where
1292 client_connected == True */
1295 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1296 && printer
->notify
.client_connected
)
1298 snum
= print_queue_snum(printer
->sharename
);
1299 print_queue_status( snum
, NULL
, NULL
);
1302 printer
= printer
->next
;
1307 /********************************************************************
1308 Send a message to ourself about new driver being installed
1309 so we can upgrade the information for each printer bound to this
1311 ********************************************************************/
1313 static bool srv_spoolss_reset_printerdata(char* drivername
)
1315 int len
= strlen(drivername
);
1320 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1323 messaging_send_buf(smbd_messaging_context(), procid_self(),
1324 MSG_PRINTERDATA_INIT_RESET
,
1325 (uint8
*)drivername
, len
+1);
1330 /**********************************************************************
1331 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1332 over all printers, resetting printer data as neessary
1333 **********************************************************************/
1335 void reset_all_printerdata(struct messaging_context
*msg
,
1338 struct server_id server_id
,
1343 int n_services
= lp_numservices();
1346 len
= MIN( data
->length
, sizeof(drivername
)-1 );
1347 strncpy( drivername
, (const char *)data
->data
, len
);
1349 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1351 /* Iterate the printer list */
1353 for ( snum
=0; snum
<n_services
; snum
++ )
1355 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1358 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1360 result
= get_a_printer( NULL
, &printer
, 2, lp_const_servicename(snum
) );
1361 if ( !W_ERROR_IS_OK(result
) )
1365 * if the printer is bound to the driver,
1366 * then reset to the new driver initdata
1369 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1371 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1373 if ( !set_driver_init(printer
, 2) ) {
1374 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1375 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1378 result
= mod_a_printer( printer
, 2 );
1379 if ( !W_ERROR_IS_OK(result
) ) {
1380 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1381 get_dos_error_msg(result
)));
1385 free_a_printer( &printer
, 2 );
1394 /********************************************************************
1395 Copy routines used by convert_to_openprinterex()
1396 *******************************************************************/
1398 static DEVICEMODE
* dup_devicemode(TALLOC_CTX
*ctx
, DEVICEMODE
*devmode
)
1406 DEBUG (8,("dup_devmode\n"));
1408 /* bulk copy first */
1410 d
= (DEVICEMODE
*)TALLOC_MEMDUP(ctx
, devmode
, sizeof(DEVICEMODE
));
1414 /* dup the pointer members separately */
1416 len
= unistrlen(devmode
->devicename
.buffer
);
1418 d
->devicename
.buffer
= TALLOC_ARRAY(ctx
, uint16
, len
);
1419 if (!d
->devicename
.buffer
) {
1422 if (unistrcpy(d
->devicename
.buffer
, devmode
->devicename
.buffer
) != len
)
1427 len
= unistrlen(devmode
->formname
.buffer
);
1429 d
->formname
.buffer
= TALLOC_ARRAY(ctx
, uint16
, len
);
1430 if (!d
->formname
.buffer
) {
1433 if (unistrcpy(d
->formname
.buffer
, devmode
->formname
.buffer
) != len
)
1437 if (devmode
->driverextra
) {
1438 d
->dev_private
= (uint8
*)TALLOC_MEMDUP(ctx
, devmode
->dev_private
,
1439 devmode
->driverextra
);
1440 if (!d
->dev_private
) {
1444 d
->dev_private
= NULL
;
1449 static void copy_devmode_ctr(TALLOC_CTX
*ctx
, DEVMODE_CTR
*new_ctr
, DEVMODE_CTR
*ctr
)
1451 if (!new_ctr
|| !ctr
)
1454 DEBUG(8,("copy_devmode_ctr\n"));
1456 new_ctr
->size
= ctr
->size
;
1457 new_ctr
->devmode_ptr
= ctr
->devmode_ptr
;
1459 if(ctr
->devmode_ptr
)
1460 new_ctr
->devmode
= dup_devicemode(ctx
, ctr
->devmode
);
1463 static void copy_printer_default(TALLOC_CTX
*ctx
, PRINTER_DEFAULT
*new_def
, PRINTER_DEFAULT
*def
)
1465 if (!new_def
|| !def
)
1468 DEBUG(8,("copy_printer_defaults\n"));
1470 new_def
->datatype_ptr
= def
->datatype_ptr
;
1472 if (def
->datatype_ptr
)
1473 copy_unistr2(&new_def
->datatype
, &def
->datatype
);
1475 copy_devmode_ctr(ctx
, &new_def
->devmode_cont
, &def
->devmode_cont
);
1477 new_def
->access_required
= def
->access_required
;
1480 /********************************************************************
1481 * Convert a SPOOL_Q_OPEN_PRINTER structure to a
1482 * SPOOL_Q_OPEN_PRINTER_EX structure
1483 ********************************************************************/
1485 static WERROR
convert_to_openprinterex(TALLOC_CTX
*ctx
, SPOOL_Q_OPEN_PRINTER_EX
*q_u_ex
, SPOOL_Q_OPEN_PRINTER
*q_u
)
1487 if (!q_u_ex
|| !q_u
)
1490 DEBUG(8,("convert_to_openprinterex\n"));
1492 if ( q_u
->printername
) {
1493 q_u_ex
->printername
= TALLOC_ZERO_P( ctx
, UNISTR2
);
1494 if (q_u_ex
->printername
== NULL
)
1496 copy_unistr2(q_u_ex
->printername
, q_u
->printername
);
1499 copy_printer_default(ctx
, &q_u_ex
->printer_default
, &q_u
->printer_default
);
1504 /********************************************************************
1505 * spoolss_open_printer
1507 * called from the spoolss dispatcher
1508 ********************************************************************/
1510 WERROR
_spoolss_open_printer(pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER
*q_u
, SPOOL_R_OPEN_PRINTER
*r_u
)
1512 SPOOL_Q_OPEN_PRINTER_EX q_u_ex
;
1513 SPOOL_R_OPEN_PRINTER_EX r_u_ex
;
1518 ZERO_STRUCT(q_u_ex
);
1519 ZERO_STRUCT(r_u_ex
);
1521 /* convert the OpenPrinter() call to OpenPrinterEx() */
1523 r_u_ex
.status
= convert_to_openprinterex(p
->mem_ctx
, &q_u_ex
, q_u
);
1524 if (!W_ERROR_IS_OK(r_u_ex
.status
))
1525 return r_u_ex
.status
;
1527 r_u_ex
.status
= _spoolss_open_printer_ex(p
, &q_u_ex
, &r_u_ex
);
1529 /* convert back to OpenPrinter() */
1531 memcpy(r_u
, &r_u_ex
, sizeof(*r_u
));
1533 if (W_ERROR_EQUAL(r_u
->status
, WERR_INVALID_PARAM
)) {
1534 /* OpenPrinterEx returns this for a bad
1535 * printer name. We must return WERR_INVALID_PRINTER_NAME
1538 r_u
->status
= WERR_INVALID_PRINTER_NAME
;
1543 /********************************************************************
1544 ********************************************************************/
1546 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
1548 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
1549 POLICY_HND
*handle
= &r_u
->handle
;
1553 Printer_entry
*Printer
=NULL
;
1555 if (!q_u
->printername
) {
1556 return WERR_INVALID_PARAM
;
1559 /* some sanity check because you can open a printer or a print server */
1560 /* aka: \\server\printer or \\server */
1562 unistr2_to_ascii(name
, q_u
->printername
, sizeof(name
));
1564 DEBUGADD(3,("checking name: %s\n",name
));
1566 if (!open_printer_hnd(p
, handle
, name
, 0)) {
1567 return WERR_INVALID_PARAM
;
1570 Printer
=find_printer_index_by_hnd(p
, handle
);
1572 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
1573 "handle we created for printer %s\n", name
));
1574 close_printer_handle(p
,handle
);
1575 return WERR_INVALID_PARAM
;
1579 * First case: the user is opening the print server:
1581 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1582 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1584 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1585 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1586 * or if the user is listed in the smb.conf printer admin parameter.
1588 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1589 * client view printer folder, but does not show the MSAPW.
1591 * Note: this test needs code to check access rights here too. Jeremy
1592 * could you look at this?
1594 * Second case: the user is opening a printer:
1595 * NT doesn't let us connect to a printer if the connecting user
1596 * doesn't have print permission.
1598 * Third case: user is opening a Port Monitor
1599 * access checks same as opening a handle to the print server.
1602 switch (Printer
->printer_type
)
1605 case SPLHND_PORTMON_TCP
:
1606 case SPLHND_PORTMON_LOCAL
:
1607 /* Printserver handles use global struct... */
1611 /* Map standard access rights to object specific access rights */
1613 se_map_standard(&printer_default
->access_required
,
1614 &printserver_std_mapping
);
1616 /* Deny any object specific bits that don't apply to print
1617 servers (i.e printer and job specific bits) */
1619 printer_default
->access_required
&= SPECIFIC_RIGHTS_MASK
;
1621 if (printer_default
->access_required
&
1622 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1623 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1624 close_printer_handle(p
, handle
);
1625 return WERR_ACCESS_DENIED
;
1628 /* Allow admin access */
1630 if ( printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
)
1632 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1634 if (!lp_ms_add_printer_wizard()) {
1635 close_printer_handle(p
, handle
);
1636 return WERR_ACCESS_DENIED
;
1639 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1640 and not a printer admin, then fail */
1642 if ((p
->pipe_user
.ut
.uid
!= 0) &&
1643 !user_has_privileges(p
->pipe_user
.nt_user_token
,
1645 !token_contains_name_in_list(
1646 uidtoname(p
->pipe_user
.ut
.uid
), NULL
,
1647 p
->pipe_user
.nt_user_token
,
1648 lp_printer_admin(snum
))) {
1649 close_printer_handle(p
, handle
);
1650 return WERR_ACCESS_DENIED
;
1653 printer_default
->access_required
= SERVER_ACCESS_ADMINISTER
;
1657 printer_default
->access_required
= SERVER_ACCESS_ENUMERATE
;
1660 DEBUG(4,("Setting print server access = %s\n", (printer_default
->access_required
== SERVER_ACCESS_ADMINISTER
)
1661 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1663 /* We fall through to return WERR_OK */
1666 case SPLHND_PRINTER
:
1667 /* NT doesn't let us connect to a printer if the connecting user
1668 doesn't have print permission. */
1670 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
1671 close_printer_handle(p
, handle
);
1675 se_map_standard(&printer_default
->access_required
, &printer_std_mapping
);
1677 /* map an empty access mask to the minimum access mask */
1678 if (printer_default
->access_required
== 0x0)
1679 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1682 * If we are not serving the printer driver for this printer,
1683 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1684 * will keep NT clients happy --jerry
1687 if (lp_use_client_driver(snum
)
1688 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
1690 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1693 /* check smb.conf parameters and the the sec_desc */
1695 if ( !check_access(smbd_server_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1696 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1697 return WERR_ACCESS_DENIED
;
1700 if (!user_ok_token(uidtoname(p
->pipe_user
.ut
.uid
),
1701 p
->pipe_user
.nt_user_token
, snum
) ||
1702 !print_access_check(&p
->pipe_user
, snum
,
1703 printer_default
->access_required
)) {
1704 DEBUG(3, ("access DENIED for printer open\n"));
1705 close_printer_handle(p
, handle
);
1706 return WERR_ACCESS_DENIED
;
1709 if ((printer_default
->access_required
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1710 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1711 close_printer_handle(p
, handle
);
1712 return WERR_ACCESS_DENIED
;
1715 if (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
)
1716 printer_default
->access_required
= PRINTER_ACCESS_ADMINISTER
;
1718 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1720 DEBUG(4,("Setting printer access = %s\n", (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1721 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1726 /* sanity check to prevent programmer error */
1730 Printer
->access_granted
= printer_default
->access_required
;
1733 * If the client sent a devmode in the OpenPrinter() call, then
1734 * save it here in case we get a job submission on this handle
1737 if ( (Printer
->printer_type
!= SPLHND_SERVER
)
1738 && q_u
->printer_default
.devmode_cont
.devmode_ptr
)
1740 convert_devicemode( Printer
->sharename
, q_u
->printer_default
.devmode_cont
.devmode
,
1741 &Printer
->nt_devmode
);
1744 #if 0 /* JERRY -- I'm doubtful this is really effective */
1745 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1746 optimization in Windows 2000 clients --jerry */
1748 if ( (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1749 && (RA_WIN2K
== get_remote_arch()) )
1751 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1752 sys_usleep( 500000 );
1759 /****************************************************************************
1760 ****************************************************************************/
1762 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
1763 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
1769 /* allocate memory if needed. Messy because
1770 convert_printer_info is used to update an existing
1771 printer or build a new one */
1773 if ( !printer
->info_2
) {
1774 printer
->info_2
= TALLOC_ZERO_P( printer
, NT_PRINTER_INFO_LEVEL_2
);
1775 if ( !printer
->info_2
) {
1776 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1781 ret
= uni_2_asc_printer_info_2(uni
->info_2
, printer
->info_2
);
1782 printer
->info_2
->setuptime
= time(NULL
);
1790 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
1791 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
1797 printer
->info_3
=NULL
;
1798 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
1802 printer
->info_6
=NULL
;
1803 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
1813 bool convert_devicemode(const char *printername
, const DEVICEMODE
*devmode
,
1814 NT_DEVICEMODE
**pp_nt_devmode
)
1816 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1819 * Ensure nt_devmode is a valid pointer
1820 * as we will be overwriting it.
1823 if (nt_devmode
== NULL
) {
1824 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1825 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1829 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
1830 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
1832 nt_devmode
->specversion
=devmode
->specversion
;
1833 nt_devmode
->driverversion
=devmode
->driverversion
;
1834 nt_devmode
->size
=devmode
->size
;
1835 nt_devmode
->fields
=devmode
->fields
;
1836 nt_devmode
->orientation
=devmode
->orientation
;
1837 nt_devmode
->papersize
=devmode
->papersize
;
1838 nt_devmode
->paperlength
=devmode
->paperlength
;
1839 nt_devmode
->paperwidth
=devmode
->paperwidth
;
1840 nt_devmode
->scale
=devmode
->scale
;
1841 nt_devmode
->copies
=devmode
->copies
;
1842 nt_devmode
->defaultsource
=devmode
->defaultsource
;
1843 nt_devmode
->printquality
=devmode
->printquality
;
1844 nt_devmode
->color
=devmode
->color
;
1845 nt_devmode
->duplex
=devmode
->duplex
;
1846 nt_devmode
->yresolution
=devmode
->yresolution
;
1847 nt_devmode
->ttoption
=devmode
->ttoption
;
1848 nt_devmode
->collate
=devmode
->collate
;
1850 nt_devmode
->logpixels
=devmode
->logpixels
;
1851 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
1852 nt_devmode
->pelswidth
=devmode
->pelswidth
;
1853 nt_devmode
->pelsheight
=devmode
->pelsheight
;
1854 nt_devmode
->displayflags
=devmode
->displayflags
;
1855 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
1856 nt_devmode
->icmmethod
=devmode
->icmmethod
;
1857 nt_devmode
->icmintent
=devmode
->icmintent
;
1858 nt_devmode
->mediatype
=devmode
->mediatype
;
1859 nt_devmode
->dithertype
=devmode
->dithertype
;
1860 nt_devmode
->reserved1
=devmode
->reserved1
;
1861 nt_devmode
->reserved2
=devmode
->reserved2
;
1862 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1863 nt_devmode
->panningheight
=devmode
->panningheight
;
1866 * Only change private and driverextra if the incoming devmode
1867 * has a new one. JRA.
1870 if ((devmode
->driverextra
!= 0) && (devmode
->dev_private
!= NULL
)) {
1871 SAFE_FREE(nt_devmode
->nt_dev_private
);
1872 nt_devmode
->driverextra
=devmode
->driverextra
;
1873 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1875 memcpy(nt_devmode
->nt_dev_private
, devmode
->dev_private
, nt_devmode
->driverextra
);
1878 *pp_nt_devmode
= nt_devmode
;
1883 /********************************************************************
1884 * _spoolss_enddocprinter_internal.
1885 ********************************************************************/
1887 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1889 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1893 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
1897 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
1900 Printer
->document_started
=False
;
1901 print_job_end(snum
, Printer
->jobid
,NORMAL_CLOSE
);
1902 /* error codes unhandled so far ... */
1907 /********************************************************************
1908 * api_spoolss_closeprinter
1909 ********************************************************************/
1911 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1913 POLICY_HND
*handle
= &q_u
->handle
;
1915 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1917 if (Printer
&& Printer
->document_started
)
1918 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1920 if (!close_printer_handle(p
, handle
))
1923 /* clear the returned printer handle. Observed behavior
1924 from Win2k server. Don't think this really matters.
1925 Previous code just copied the value of the closed
1928 memset(&r_u
->handle
, '\0', sizeof(r_u
->handle
));
1933 /********************************************************************
1934 * api_spoolss_deleteprinter
1936 ********************************************************************/
1938 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1940 POLICY_HND
*handle
= &q_u
->handle
;
1941 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1944 if (Printer
&& Printer
->document_started
)
1945 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1947 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1949 result
= delete_printer_handle(p
, handle
);
1951 update_c_setprinter(False
);
1956 /*******************************************************************
1957 * static function to lookup the version id corresponding to an
1958 * long architecture string
1959 ******************************************************************/
1961 static int get_version_id (char * arch
)
1964 struct table_node archi_table
[]= {
1966 {"Windows 4.0", "WIN40", 0 },
1967 {"Windows NT x86", "W32X86", 2 },
1968 {"Windows NT R4000", "W32MIPS", 2 },
1969 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1970 {"Windows NT PowerPC", "W32PPC", 2 },
1971 {"Windows IA64", "IA64", 3 },
1972 {"Windows x64", "x64", 3 },
1976 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1978 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1979 return (archi_table
[i
].version
);
1985 /********************************************************************
1986 * _spoolss_deleteprinterdriver
1987 ********************************************************************/
1989 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
, SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1993 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1994 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
1997 WERROR status_win2k
= WERR_ACCESS_DENIED
;
1998 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2000 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2001 and not a printer admin, then fail */
2003 if ( (p
->pipe_user
.ut
.uid
!= 0)
2004 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2005 && !token_contains_name_in_list( uidtoname(p
->pipe_user
.ut
.uid
),
2006 NULL
, p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2008 return WERR_ACCESS_DENIED
;
2011 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2012 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2014 /* check that we have a valid driver name first */
2016 if ((version
=get_version_id(arch
)) == -1)
2017 return WERR_INVALID_ENVIRONMENT
;
2020 ZERO_STRUCT(info_win2k
);
2022 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
2024 /* try for Win2k driver if "Windows NT x86" */
2026 if ( version
== 2 ) {
2028 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2029 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2033 /* otherwise it was a failure */
2035 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2041 if (printer_driver_in_use(info
.info_3
)) {
2042 status
= WERR_PRINTER_DRIVER_IN_USE
;
2048 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2050 /* if we get to here, we now have 2 driver info structures to remove */
2051 /* remove the Win2k driver first*/
2053 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, False
);
2054 free_a_printer_driver( info_win2k
, 3 );
2056 /* this should not have failed---if it did, report to client */
2057 if ( !W_ERROR_IS_OK(status_win2k
) )
2059 status
= status_win2k
;
2065 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, False
);
2067 /* if at least one of the deletes succeeded return OK */
2069 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2073 free_a_printer_driver( info
, 3 );
2078 /********************************************************************
2079 * spoolss_deleteprinterdriverex
2080 ********************************************************************/
2082 WERROR
_spoolss_deleteprinterdriverex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVEREX
*q_u
, SPOOL_R_DELETEPRINTERDRIVEREX
*r_u
)
2086 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2087 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2089 uint32 flags
= q_u
->delete_flags
;
2092 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2093 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2095 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2096 and not a printer admin, then fail */
2098 if ( (p
->pipe_user
.ut
.uid
!= 0)
2099 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2100 && !token_contains_name_in_list( uidtoname(p
->pipe_user
.ut
.uid
),
2101 NULL
, p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2103 return WERR_ACCESS_DENIED
;
2106 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2107 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2109 /* check that we have a valid driver name first */
2110 if ((version
=get_version_id(arch
)) == -1) {
2111 /* this is what NT returns */
2112 return WERR_INVALID_ENVIRONMENT
;
2115 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
2116 version
= q_u
->version
;
2119 ZERO_STRUCT(info_win2k
);
2121 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
2123 if ( !W_ERROR_IS_OK(status
) )
2126 * if the client asked for a specific version,
2127 * or this is something other than Windows NT x86,
2131 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2134 /* try for Win2k driver if "Windows NT x86" */
2137 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2138 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2143 if ( printer_driver_in_use(info
.info_3
) ) {
2144 status
= WERR_PRINTER_DRIVER_IN_USE
;
2149 * we have a couple of cases to consider.
2150 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2151 * then the delete should fail if **any** files overlap with
2153 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2154 * non-overlapping files
2155 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2156 * is set, the do not delete any files
2157 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2160 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2162 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2164 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2165 /* no idea of the correct error here */
2166 status
= WERR_ACCESS_DENIED
;
2171 /* also check for W32X86/3 if necessary; maybe we already have? */
2173 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2174 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2177 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2178 /* no idea of the correct error here */
2179 free_a_printer_driver( info_win2k
, 3 );
2180 status
= WERR_ACCESS_DENIED
;
2184 /* if we get to here, we now have 2 driver info structures to remove */
2185 /* remove the Win2k driver first*/
2187 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, delete_files
);
2188 free_a_printer_driver( info_win2k
, 3 );
2190 /* this should not have failed---if it did, report to client */
2192 if ( !W_ERROR_IS_OK(status_win2k
) )
2197 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, delete_files
);
2199 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2202 free_a_printer_driver( info
, 3 );
2208 /****************************************************************************
2209 Internal routine for retreiving printerdata
2210 ***************************************************************************/
2212 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2213 const char *key
, const char *value
, uint32
*type
, uint8
**data
,
2214 uint32
*needed
, uint32 in_size
)
2216 REGISTRY_VALUE
*val
;
2220 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2221 return WERR_BADFILE
;
2223 *type
= regval_type( val
);
2225 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2227 size
= regval_size( val
);
2229 /* copy the min(in_size, len) */
2232 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2234 /* special case for 0 length values */
2236 if ( (*data
= (uint8
*)TALLOC_MEMDUP(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2240 if ( (*data
= (uint8
*)TALLOC_ZERO(ctx
, in_size
)) == NULL
)
2249 DEBUG(5,("get_printer_dataex: copy done\n"));
2254 /****************************************************************************
2255 Internal routine for removing printerdata
2256 ***************************************************************************/
2258 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2260 return delete_printer_data( printer
->info_2
, key
, value
);
2263 /****************************************************************************
2264 Internal routine for storing printerdata
2265 ***************************************************************************/
2267 WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
,
2268 uint32 type
, uint8
*data
, int real_len
)
2270 /* the registry objects enforce uniqueness based on value name */
2272 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2275 /********************************************************************
2276 GetPrinterData on a printer server Handle.
2277 ********************************************************************/
2279 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2283 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2285 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2287 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2289 SIVAL(*data
, 0, 0x00);
2294 if (!StrCaseCmp(value
, "BeepEnabled")) {
2296 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2298 SIVAL(*data
, 0, 0x00);
2303 if (!StrCaseCmp(value
, "EventLog")) {
2305 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2307 /* formally was 0x1b */
2308 SIVAL(*data
, 0, 0x0);
2313 if (!StrCaseCmp(value
, "NetPopup")) {
2315 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2317 SIVAL(*data
, 0, 0x00);
2322 if (!StrCaseCmp(value
, "MajorVersion")) {
2324 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2327 /* Windows NT 4.0 seems to not allow uploading of drivers
2328 to a server that reports 0x3 as the MajorVersion.
2329 need to investigate more how Win2k gets around this .
2332 if ( RA_WINNT
== get_remote_arch() )
2341 if (!StrCaseCmp(value
, "MinorVersion")) {
2343 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2351 * uint32 size = 0x114
2353 * uint32 minor = [0|1]
2354 * uint32 build = [2195|2600]
2355 * extra unicode string = e.g. "Service Pack 3"
2357 if (!StrCaseCmp(value
, "OSVersion")) {
2361 if ( !(*data
= TALLOC_ZERO_ARRAY(ctx
, uint8
, (*needed
> in_size
) ? *needed
:in_size
)) )
2364 SIVAL(*data
, 0, *needed
); /* size */
2365 SIVAL(*data
, 4, 5); /* Windows 2000 == 5.0 */
2367 SIVAL(*data
, 12, 2195); /* build */
2369 /* leave extra string empty */
2375 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2376 const char *string
="C:\\PRINTERS";
2378 *needed
= 2*(strlen(string
)+1);
2379 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2381 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2383 /* it's done by hand ready to go on the wire */
2384 for (i
=0; i
<strlen(string
); i
++) {
2385 (*data
)[2*i
]=string
[i
];
2386 (*data
)[2*i
+1]='\0';
2391 if (!StrCaseCmp(value
, "Architecture")) {
2392 const char *string
="Windows NT x86";
2394 *needed
= 2*(strlen(string
)+1);
2395 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2397 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2398 for (i
=0; i
<strlen(string
); i
++) {
2399 (*data
)[2*i
]=string
[i
];
2400 (*data
)[2*i
+1]='\0';
2405 if (!StrCaseCmp(value
, "DsPresent")) {
2407 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2410 /* only show the publish check box if we are a
2411 memeber of a AD domain */
2413 if ( lp_security() == SEC_ADS
)
2414 SIVAL(*data
, 0, 0x01);
2416 SIVAL(*data
, 0, 0x00);
2422 if (!StrCaseCmp(value
, "DNSMachineName")) {
2423 const char *hostname
= get_mydnsfullname();
2426 return WERR_BADFILE
;
2428 *needed
= 2*(strlen(hostname
)+1);
2429 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2431 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2432 for (i
=0; i
<strlen(hostname
); i
++) {
2433 (*data
)[2*i
]=hostname
[i
];
2434 (*data
)[2*i
+1]='\0';
2440 return WERR_BADFILE
;
2443 /********************************************************************
2444 * spoolss_getprinterdata
2445 ********************************************************************/
2447 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2449 POLICY_HND
*handle
= &q_u
->handle
;
2450 UNISTR2
*valuename
= &q_u
->valuename
;
2451 uint32 in_size
= q_u
->size
;
2452 uint32
*type
= &r_u
->type
;
2453 uint32
*out_size
= &r_u
->size
;
2454 uint8
**data
= &r_u
->data
;
2455 uint32
*needed
= &r_u
->needed
;
2458 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2459 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2463 * Reminder: when it's a string, the length is in BYTES
2464 * even if UNICODE is negociated.
2469 *out_size
= in_size
;
2471 /* in case of problem, return some default values */
2476 DEBUG(4,("_spoolss_getprinterdata\n"));
2479 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2480 status
= WERR_BADFID
;
2484 unistr2_to_ascii(value
, valuename
, sizeof(value
));
2486 if ( Printer
->printer_type
== SPLHND_SERVER
)
2487 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2490 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) ) {
2491 status
= WERR_BADFID
;
2495 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2496 if ( !W_ERROR_IS_OK(status
) )
2499 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2501 if ( strequal(value
, "ChangeId") ) {
2503 *needed
= sizeof(uint32
);
2504 if ( (*data
= (uint8
*)TALLOC(p
->mem_ctx
, sizeof(uint32
))) == NULL
) {
2505 status
= WERR_NOMEM
;
2508 SIVAL( *data
, 0, printer
->info_2
->changeid
);
2512 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2515 if (*needed
> *out_size
)
2516 status
= WERR_MORE_DATA
;
2519 if ( !W_ERROR_IS_OK(status
) )
2521 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status
),*out_size
));
2523 /* reply this param doesn't exist */
2526 if((*data
=(uint8
*)TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint8
, *out_size
)) == NULL
) {
2528 free_a_printer( &printer
, 2 );
2536 /* cleanup & exit */
2539 free_a_printer( &printer
, 2 );
2544 /*********************************************************
2545 Connect to the client machine.
2546 **********************************************************/
2548 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2549 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2552 struct cli_state
*the_cli
;
2553 struct sockaddr_storage rm_addr
;
2555 if ( is_zero_addr(client_ss
) ) {
2556 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20) ) {
2557 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2561 if (ismyaddr(&rm_addr
)) {
2562 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2566 char addr
[INET6_ADDRSTRLEN
];
2567 rm_addr
= *client_ss
;
2568 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2569 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2573 /* setup the connection */
2575 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2576 &rm_addr
, 0, "IPC$", "IPC",
2580 0, lp_client_signing(), NULL
);
2582 if ( !NT_STATUS_IS_OK( ret
) ) {
2583 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2588 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2589 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2590 cli_shutdown(the_cli
);
2595 * Ok - we have an anonymous connection to the IPC$ share.
2596 * Now start the NT Domain stuff :-).
2599 if ( !(*pp_pipe
= cli_rpc_pipe_open_noauth(the_cli
, PI_SPOOLSS
, &ret
)) ) {
2600 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2601 remote_machine
, nt_errstr(ret
)));
2602 cli_shutdown(the_cli
);
2606 /* make sure to save the cli_state pointer. Keep its own talloc_ctx */
2608 (*pp_pipe
)->cli
= the_cli
;
2613 /***************************************************************************
2614 Connect to the client.
2615 ****************************************************************************/
2617 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2618 uint32 localprinter
, uint32 type
,
2619 POLICY_HND
*handle
, struct sockaddr_storage
*client_ss
)
2624 * If it's the first connection, contact the client
2625 * and connect to the IPC$ share anonymously
2627 if (smb_connections
==0) {
2628 fstring unix_printer
;
2630 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2632 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2635 messaging_register(smbd_messaging_context(), NULL
,
2636 MSG_PRINTER_NOTIFY2
,
2637 receive_notify2_message_list
);
2638 /* Tell the connections db we're now interested in printer
2639 * notify messages. */
2640 register_message_flags( True
, FLAG_MSG_PRINT_NOTIFY
);
2644 * Tell the specific printing tdb we want messages for this printer
2645 * by registering our PID.
2648 if (!print_notify_register_pid(snum
))
2649 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2653 result
= rpccli_spoolss_reply_open_printer(notify_cli_pipe
,
2660 if (!W_ERROR_IS_OK(result
))
2661 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2662 dos_errstr(result
)));
2664 return (W_ERROR_IS_OK(result
));
2667 /********************************************************************
2669 * ReplyFindFirstPrinterChangeNotifyEx
2671 * before replying OK: status=0 a rpc call is made to the workstation
2672 * asking ReplyOpenPrinter
2674 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2675 * called from api_spoolss_rffpcnex
2676 ********************************************************************/
2678 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
2680 POLICY_HND
*handle
= &q_u
->handle
;
2681 uint32 flags
= q_u
->flags
;
2682 uint32 options
= q_u
->options
;
2683 UNISTR2
*localmachine
= &q_u
->localmachine
;
2684 uint32 printerlocal
= q_u
->printerlocal
;
2686 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
2687 struct sockaddr_storage client_ss
;
2689 /* store the notify value in the printer struct */
2691 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2694 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2698 Printer
->notify
.flags
=flags
;
2699 Printer
->notify
.options
=options
;
2700 Printer
->notify
.printerlocal
=printerlocal
;
2702 if (Printer
->notify
.option
)
2703 free_spool_notify_option(&Printer
->notify
.option
);
2705 Printer
->notify
.option
=dup_spool_notify_option(option
);
2707 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
,
2708 sizeof(Printer
->notify
.localmachine
));
2710 /* Connect to the client machine and send a ReplyOpenPrinter */
2712 if ( Printer
->printer_type
== SPLHND_SERVER
)
2714 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2715 !get_printer_snum(p
, handle
, &snum
, NULL
) )
2718 if (!interpret_string_addr(&client_ss
,
2719 p
->conn
->client_address
,
2721 return WERR_SERVER_UNAVAILABLE
;
2724 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2725 Printer
->notify
.printerlocal
, 1,
2726 &Printer
->notify
.client_hnd
, &client_ss
))
2727 return WERR_SERVER_UNAVAILABLE
;
2729 Printer
->notify
.client_connected
=True
;
2734 /*******************************************************************
2735 * fill a notify_info_data with the servername
2736 ********************************************************************/
2738 void spoolss_notify_server_name(int snum
,
2739 SPOOL_NOTIFY_INFO_DATA
*data
,
2740 print_queue_struct
*queue
,
2741 NT_PRINTER_INFO_LEVEL
*printer
,
2742 TALLOC_CTX
*mem_ctx
)
2744 smb_ucs2_t
*temp
= NULL
;
2747 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->servername
);
2748 if (len
== (uint32
)-1) {
2752 data
->notify_data
.data
.length
= len
;
2754 data
->notify_data
.data
.string
= (uint16
*)temp
;
2756 data
->notify_data
.data
.string
= NULL
;
2760 /*******************************************************************
2761 * fill a notify_info_data with the printername (not including the servername).
2762 ********************************************************************/
2764 void spoolss_notify_printer_name(int snum
,
2765 SPOOL_NOTIFY_INFO_DATA
*data
,
2766 print_queue_struct
*queue
,
2767 NT_PRINTER_INFO_LEVEL
*printer
,
2768 TALLOC_CTX
*mem_ctx
)
2770 smb_ucs2_t
*temp
= NULL
;
2773 /* the notify name should not contain the \\server\ part */
2774 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2777 p
= printer
->info_2
->printername
;
2782 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
2783 if (len
== (uint32
)-1) {
2787 data
->notify_data
.data
.length
= len
;
2789 data
->notify_data
.data
.string
= (uint16
*)temp
;
2791 data
->notify_data
.data
.string
= NULL
;
2795 /*******************************************************************
2796 * fill a notify_info_data with the servicename
2797 ********************************************************************/
2799 void spoolss_notify_share_name(int snum
,
2800 SPOOL_NOTIFY_INFO_DATA
*data
,
2801 print_queue_struct
*queue
,
2802 NT_PRINTER_INFO_LEVEL
*printer
,
2803 TALLOC_CTX
*mem_ctx
)
2805 smb_ucs2_t
*temp
= NULL
;
2808 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_servicename(snum
));
2809 if (len
== (uint32
)-1) {
2813 data
->notify_data
.data
.length
= len
;
2815 data
->notify_data
.data
.string
= (uint16
*)temp
;
2817 data
->notify_data
.data
.string
= NULL
;
2822 /*******************************************************************
2823 * fill a notify_info_data with the port name
2824 ********************************************************************/
2826 void spoolss_notify_port_name(int snum
,
2827 SPOOL_NOTIFY_INFO_DATA
*data
,
2828 print_queue_struct
*queue
,
2829 NT_PRINTER_INFO_LEVEL
*printer
,
2830 TALLOC_CTX
*mem_ctx
)
2832 smb_ucs2_t
*temp
= NULL
;
2835 /* even if it's strange, that's consistant in all the code */
2837 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->portname
);
2838 if (len
== (uint32
)-1) {
2842 data
->notify_data
.data
.length
= len
;
2844 data
->notify_data
.data
.string
= (uint16
*)temp
;
2846 data
->notify_data
.data
.string
= NULL
;
2850 /*******************************************************************
2851 * fill a notify_info_data with the printername
2852 * but it doesn't exist, have to see what to do
2853 ********************************************************************/
2855 void spoolss_notify_driver_name(int snum
,
2856 SPOOL_NOTIFY_INFO_DATA
*data
,
2857 print_queue_struct
*queue
,
2858 NT_PRINTER_INFO_LEVEL
*printer
,
2859 TALLOC_CTX
*mem_ctx
)
2861 smb_ucs2_t
*temp
= NULL
;
2864 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->drivername
);
2865 if (len
== (uint32
)-1) {
2869 data
->notify_data
.data
.length
= len
;
2871 data
->notify_data
.data
.string
= (uint16
*)temp
;
2873 data
->notify_data
.data
.string
= NULL
;
2877 /*******************************************************************
2878 * fill a notify_info_data with the comment
2879 ********************************************************************/
2881 void spoolss_notify_comment(int snum
,
2882 SPOOL_NOTIFY_INFO_DATA
*data
,
2883 print_queue_struct
*queue
,
2884 NT_PRINTER_INFO_LEVEL
*printer
,
2885 TALLOC_CTX
*mem_ctx
)
2887 smb_ucs2_t
*temp
= NULL
;
2890 if (*printer
->info_2
->comment
== '\0')
2891 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_comment(snum
));
2893 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->comment
);
2895 if (len
== (uint32
)-1) {
2898 data
->notify_data
.data
.length
= len
;
2900 data
->notify_data
.data
.string
= (uint16
*)temp
;
2902 data
->notify_data
.data
.string
= NULL
;
2906 /*******************************************************************
2907 * fill a notify_info_data with the comment
2908 * location = "Room 1, floor 2, building 3"
2909 ********************************************************************/
2911 void spoolss_notify_location(int snum
,
2912 SPOOL_NOTIFY_INFO_DATA
*data
,
2913 print_queue_struct
*queue
,
2914 NT_PRINTER_INFO_LEVEL
*printer
,
2915 TALLOC_CTX
*mem_ctx
)
2917 smb_ucs2_t
*temp
= NULL
;
2920 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->location
);
2921 if (len
== (uint32
)-1) {
2925 data
->notify_data
.data
.length
= len
;
2927 data
->notify_data
.data
.string
= (uint16
*)temp
;
2929 data
->notify_data
.data
.string
= NULL
;
2933 /*******************************************************************
2934 * fill a notify_info_data with the device mode
2935 * jfm:xxxx don't to it for know but that's a real problem !!!
2936 ********************************************************************/
2938 static void spoolss_notify_devmode(int snum
,
2939 SPOOL_NOTIFY_INFO_DATA
*data
,
2940 print_queue_struct
*queue
,
2941 NT_PRINTER_INFO_LEVEL
*printer
,
2942 TALLOC_CTX
*mem_ctx
)
2944 /* for a dummy implementation we have to zero the fields */
2945 data
->notify_data
.data
.length
= 0;
2946 data
->notify_data
.data
.string
= NULL
;
2949 /*******************************************************************
2950 * fill a notify_info_data with the separator file name
2951 ********************************************************************/
2953 void spoolss_notify_sepfile(int snum
,
2954 SPOOL_NOTIFY_INFO_DATA
*data
,
2955 print_queue_struct
*queue
,
2956 NT_PRINTER_INFO_LEVEL
*printer
,
2957 TALLOC_CTX
*mem_ctx
)
2959 smb_ucs2_t
*temp
= NULL
;
2962 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->sepfile
);
2963 if (len
== (uint32
)-1) {
2967 data
->notify_data
.data
.length
= len
;
2969 data
->notify_data
.data
.string
= (uint16
*)temp
;
2971 data
->notify_data
.data
.string
= NULL
;
2975 /*******************************************************************
2976 * fill a notify_info_data with the print processor
2977 * jfm:xxxx return always winprint to indicate we don't do anything to it
2978 ********************************************************************/
2980 void spoolss_notify_print_processor(int snum
,
2981 SPOOL_NOTIFY_INFO_DATA
*data
,
2982 print_queue_struct
*queue
,
2983 NT_PRINTER_INFO_LEVEL
*printer
,
2984 TALLOC_CTX
*mem_ctx
)
2986 smb_ucs2_t
*temp
= NULL
;
2989 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->printprocessor
);
2990 if (len
== (uint32
)-1) {
2994 data
->notify_data
.data
.length
= len
;
2996 data
->notify_data
.data
.string
= (uint16
*)temp
;
2998 data
->notify_data
.data
.string
= NULL
;
3002 /*******************************************************************
3003 * fill a notify_info_data with the print processor options
3004 * jfm:xxxx send an empty string
3005 ********************************************************************/
3007 void spoolss_notify_parameters(int snum
,
3008 SPOOL_NOTIFY_INFO_DATA
*data
,
3009 print_queue_struct
*queue
,
3010 NT_PRINTER_INFO_LEVEL
*printer
,
3011 TALLOC_CTX
*mem_ctx
)
3013 smb_ucs2_t
*temp
= NULL
;
3016 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->parameters
);
3017 if (len
== (uint32
)-1) {
3021 data
->notify_data
.data
.length
= len
;
3023 data
->notify_data
.data
.string
= (uint16
*)temp
;
3025 data
->notify_data
.data
.string
= NULL
;
3029 /*******************************************************************
3030 * fill a notify_info_data with the data type
3031 * jfm:xxxx always send RAW as data type
3032 ********************************************************************/
3034 void spoolss_notify_datatype(int snum
,
3035 SPOOL_NOTIFY_INFO_DATA
*data
,
3036 print_queue_struct
*queue
,
3037 NT_PRINTER_INFO_LEVEL
*printer
,
3038 TALLOC_CTX
*mem_ctx
)
3040 smb_ucs2_t
*temp
= NULL
;
3043 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->datatype
);
3044 if (len
== (uint32
)-1) {
3048 data
->notify_data
.data
.length
= len
;
3050 data
->notify_data
.data
.string
= (uint16
*)temp
;
3052 data
->notify_data
.data
.string
= NULL
;
3056 /*******************************************************************
3057 * fill a notify_info_data with the security descriptor
3058 * jfm:xxxx send an null pointer to say no security desc
3059 * have to implement security before !
3060 ********************************************************************/
3062 static void spoolss_notify_security_desc(int snum
,
3063 SPOOL_NOTIFY_INFO_DATA
*data
,
3064 print_queue_struct
*queue
,
3065 NT_PRINTER_INFO_LEVEL
*printer
,
3066 TALLOC_CTX
*mem_ctx
)
3068 data
->notify_data
.sd
.size
= printer
->info_2
->secdesc_buf
->sd_size
;
3069 data
->notify_data
.sd
.desc
= dup_sec_desc( mem_ctx
, printer
->info_2
->secdesc_buf
->sd
) ;
3072 /*******************************************************************
3073 * fill a notify_info_data with the attributes
3074 * jfm:xxxx a samba printer is always shared
3075 ********************************************************************/
3077 void spoolss_notify_attributes(int snum
,
3078 SPOOL_NOTIFY_INFO_DATA
*data
,
3079 print_queue_struct
*queue
,
3080 NT_PRINTER_INFO_LEVEL
*printer
,
3081 TALLOC_CTX
*mem_ctx
)
3083 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
3084 data
->notify_data
.value
[1] = 0;
3087 /*******************************************************************
3088 * fill a notify_info_data with the priority
3089 ********************************************************************/
3091 static void spoolss_notify_priority(int snum
,
3092 SPOOL_NOTIFY_INFO_DATA
*data
,
3093 print_queue_struct
*queue
,
3094 NT_PRINTER_INFO_LEVEL
*printer
,
3095 TALLOC_CTX
*mem_ctx
)
3097 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
3098 data
->notify_data
.value
[1] = 0;
3101 /*******************************************************************
3102 * fill a notify_info_data with the default priority
3103 ********************************************************************/
3105 static void spoolss_notify_default_priority(int snum
,
3106 SPOOL_NOTIFY_INFO_DATA
*data
,
3107 print_queue_struct
*queue
,
3108 NT_PRINTER_INFO_LEVEL
*printer
,
3109 TALLOC_CTX
*mem_ctx
)
3111 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
3112 data
->notify_data
.value
[1] = 0;
3115 /*******************************************************************
3116 * fill a notify_info_data with the start time
3117 ********************************************************************/
3119 static void spoolss_notify_start_time(int snum
,
3120 SPOOL_NOTIFY_INFO_DATA
*data
,
3121 print_queue_struct
*queue
,
3122 NT_PRINTER_INFO_LEVEL
*printer
,
3123 TALLOC_CTX
*mem_ctx
)
3125 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
3126 data
->notify_data
.value
[1] = 0;
3129 /*******************************************************************
3130 * fill a notify_info_data with the until time
3131 ********************************************************************/
3133 static void spoolss_notify_until_time(int snum
,
3134 SPOOL_NOTIFY_INFO_DATA
*data
,
3135 print_queue_struct
*queue
,
3136 NT_PRINTER_INFO_LEVEL
*printer
,
3137 TALLOC_CTX
*mem_ctx
)
3139 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
3140 data
->notify_data
.value
[1] = 0;
3143 /*******************************************************************
3144 * fill a notify_info_data with the status
3145 ********************************************************************/
3147 static void spoolss_notify_status(int snum
,
3148 SPOOL_NOTIFY_INFO_DATA
*data
,
3149 print_queue_struct
*queue
,
3150 NT_PRINTER_INFO_LEVEL
*printer
,
3151 TALLOC_CTX
*mem_ctx
)
3153 print_status_struct status
;
3155 print_queue_length(snum
, &status
);
3156 data
->notify_data
.value
[0]=(uint32
) status
.status
;
3157 data
->notify_data
.value
[1] = 0;
3160 /*******************************************************************
3161 * fill a notify_info_data with the number of jobs queued
3162 ********************************************************************/
3164 void spoolss_notify_cjobs(int snum
,
3165 SPOOL_NOTIFY_INFO_DATA
*data
,
3166 print_queue_struct
*queue
,
3167 NT_PRINTER_INFO_LEVEL
*printer
,
3168 TALLOC_CTX
*mem_ctx
)
3170 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
3171 data
->notify_data
.value
[1] = 0;
3174 /*******************************************************************
3175 * fill a notify_info_data with the average ppm
3176 ********************************************************************/
3178 static void spoolss_notify_average_ppm(int snum
,
3179 SPOOL_NOTIFY_INFO_DATA
*data
,
3180 print_queue_struct
*queue
,
3181 NT_PRINTER_INFO_LEVEL
*printer
,
3182 TALLOC_CTX
*mem_ctx
)
3184 /* always respond 8 pages per minutes */
3185 /* a little hard ! */
3186 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
3187 data
->notify_data
.value
[1] = 0;
3190 /*******************************************************************
3191 * fill a notify_info_data with username
3192 ********************************************************************/
3194 static void spoolss_notify_username(int snum
,
3195 SPOOL_NOTIFY_INFO_DATA
*data
,
3196 print_queue_struct
*queue
,
3197 NT_PRINTER_INFO_LEVEL
*printer
,
3198 TALLOC_CTX
*mem_ctx
)
3200 smb_ucs2_t
*temp
= NULL
;
3203 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_user
);
3204 if (len
== (uint32
)-1) {
3208 data
->notify_data
.data
.length
= len
;
3210 data
->notify_data
.data
.string
= (uint16
*)temp
;
3212 data
->notify_data
.data
.string
= NULL
;
3216 /*******************************************************************
3217 * fill a notify_info_data with job status
3218 ********************************************************************/
3220 static void spoolss_notify_job_status(int snum
,
3221 SPOOL_NOTIFY_INFO_DATA
*data
,
3222 print_queue_struct
*queue
,
3223 NT_PRINTER_INFO_LEVEL
*printer
,
3224 TALLOC_CTX
*mem_ctx
)
3226 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
3227 data
->notify_data
.value
[1] = 0;
3230 /*******************************************************************
3231 * fill a notify_info_data with job name
3232 ********************************************************************/
3234 static void spoolss_notify_job_name(int snum
,
3235 SPOOL_NOTIFY_INFO_DATA
*data
,
3236 print_queue_struct
*queue
,
3237 NT_PRINTER_INFO_LEVEL
*printer
,
3238 TALLOC_CTX
*mem_ctx
)
3240 smb_ucs2_t
*temp
= NULL
;
3243 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_file
);
3244 if (len
== (uint32
)-1) {
3248 data
->notify_data
.data
.length
= len
;
3250 data
->notify_data
.data
.string
= (uint16
*)temp
;
3252 data
->notify_data
.data
.string
= NULL
;
3256 /*******************************************************************
3257 * fill a notify_info_data with job status
3258 ********************************************************************/
3260 static void spoolss_notify_job_status_string(int snum
,
3261 SPOOL_NOTIFY_INFO_DATA
*data
,
3262 print_queue_struct
*queue
,
3263 NT_PRINTER_INFO_LEVEL
*printer
,
3264 TALLOC_CTX
*mem_ctx
)
3267 * Now we're returning job status codes we just return a "" here. JRA.
3271 smb_ucs2_t
*temp
= NULL
;
3274 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3277 switch (queue
->status
) {
3282 p
= ""; /* NT provides the paused string */
3291 #endif /* NO LONGER NEEDED. */
3293 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
3294 if (len
== (uint32
)-1) {
3298 data
->notify_data
.data
.length
= len
;
3300 data
->notify_data
.data
.string
= (uint16
*)temp
;
3302 data
->notify_data
.data
.string
= NULL
;
3306 /*******************************************************************
3307 * fill a notify_info_data with job time
3308 ********************************************************************/
3310 static void spoolss_notify_job_time(int snum
,
3311 SPOOL_NOTIFY_INFO_DATA
*data
,
3312 print_queue_struct
*queue
,
3313 NT_PRINTER_INFO_LEVEL
*printer
,
3314 TALLOC_CTX
*mem_ctx
)
3316 data
->notify_data
.value
[0]=0x0;
3317 data
->notify_data
.value
[1]=0;
3320 /*******************************************************************
3321 * fill a notify_info_data with job size
3322 ********************************************************************/
3324 static void spoolss_notify_job_size(int snum
,
3325 SPOOL_NOTIFY_INFO_DATA
*data
,
3326 print_queue_struct
*queue
,
3327 NT_PRINTER_INFO_LEVEL
*printer
,
3328 TALLOC_CTX
*mem_ctx
)
3330 data
->notify_data
.value
[0]=queue
->size
;
3331 data
->notify_data
.value
[1]=0;
3334 /*******************************************************************
3335 * fill a notify_info_data with page info
3336 ********************************************************************/
3337 static void spoolss_notify_total_pages(int snum
,
3338 SPOOL_NOTIFY_INFO_DATA
*data
,
3339 print_queue_struct
*queue
,
3340 NT_PRINTER_INFO_LEVEL
*printer
,
3341 TALLOC_CTX
*mem_ctx
)
3343 data
->notify_data
.value
[0]=queue
->page_count
;
3344 data
->notify_data
.value
[1]=0;
3347 /*******************************************************************
3348 * fill a notify_info_data with pages printed info.
3349 ********************************************************************/
3350 static void spoolss_notify_pages_printed(int snum
,
3351 SPOOL_NOTIFY_INFO_DATA
*data
,
3352 print_queue_struct
*queue
,
3353 NT_PRINTER_INFO_LEVEL
*printer
,
3354 TALLOC_CTX
*mem_ctx
)
3356 data
->notify_data
.value
[0]=0; /* Add code when back-end tracks this */
3357 data
->notify_data
.value
[1]=0;
3360 /*******************************************************************
3361 Fill a notify_info_data with job position.
3362 ********************************************************************/
3364 static void spoolss_notify_job_position(int snum
,
3365 SPOOL_NOTIFY_INFO_DATA
*data
,
3366 print_queue_struct
*queue
,
3367 NT_PRINTER_INFO_LEVEL
*printer
,
3368 TALLOC_CTX
*mem_ctx
)
3370 data
->notify_data
.value
[0]=queue
->job
;
3371 data
->notify_data
.value
[1]=0;
3374 /*******************************************************************
3375 Fill a notify_info_data with submitted time.
3376 ********************************************************************/
3378 static void spoolss_notify_submitted_time(int snum
,
3379 SPOOL_NOTIFY_INFO_DATA
*data
,
3380 print_queue_struct
*queue
,
3381 NT_PRINTER_INFO_LEVEL
*printer
,
3382 TALLOC_CTX
*mem_ctx
)
3389 t
=gmtime(&queue
->time
);
3391 len
= sizeof(SYSTEMTIME
);
3393 data
->notify_data
.data
.length
= len
;
3394 data
->notify_data
.data
.string
= (uint16
*)TALLOC(mem_ctx
, len
);
3396 if (!data
->notify_data
.data
.string
) {
3397 data
->notify_data
.data
.length
= 0;
3401 make_systemtime(&st
, t
);
3404 * Systemtime must be linearized as a set of UINT16's.
3405 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3408 p
= (char *)data
->notify_data
.data
.string
;
3409 SSVAL(p
, 0, st
.year
);
3410 SSVAL(p
, 2, st
.month
);
3411 SSVAL(p
, 4, st
.dayofweek
);
3412 SSVAL(p
, 6, st
.day
);
3413 SSVAL(p
, 8, st
.hour
);
3414 SSVAL(p
, 10, st
.minute
);
3415 SSVAL(p
, 12, st
.second
);
3416 SSVAL(p
, 14, st
.milliseconds
);
3419 struct s_notify_info_data_table
3425 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
3426 print_queue_struct
*queue
,
3427 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3430 /* A table describing the various print notification constants and
3431 whether the notification data is a pointer to a variable sized
3432 buffer, a one value uint32 or a two value uint32. */
3434 static const struct s_notify_info_data_table notify_info_data_table
[] =
3436 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3437 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3438 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING
, spoolss_notify_share_name
},
3439 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3440 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3441 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING
, spoolss_notify_comment
},
3442 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING
, spoolss_notify_location
},
3443 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3444 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING
, spoolss_notify_sepfile
},
3445 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3446 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3447 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3448 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC
, spoolss_notify_security_desc
},
3449 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE
, spoolss_notify_attributes
},
3450 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3451 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_default_priority
},
3452 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3453 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3454 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_status
},
3455 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER
, NULL
},
3456 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE
, spoolss_notify_cjobs
},
3457 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE
, spoolss_notify_average_ppm
},
3458 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER
, NULL
},
3459 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER
, NULL
},
3460 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER
, NULL
},
3461 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER
, NULL
},
3462 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3463 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3464 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3465 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3466 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3467 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3468 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3469 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3470 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3471 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3472 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_job_status
},
3473 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING
, spoolss_notify_job_status_string
},
3474 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER
, NULL
},
3475 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING
, spoolss_notify_job_name
},
3476 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3477 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE
, spoolss_notify_job_position
},
3478 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER
, spoolss_notify_submitted_time
},
3479 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3480 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3481 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_job_time
},
3482 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE
, spoolss_notify_total_pages
},
3483 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE
, spoolss_notify_pages_printed
},
3484 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE
, spoolss_notify_job_size
},
3485 { PRINT_TABLE_END
, 0x0, NULL
, 0x0, NULL
},
3488 /*******************************************************************
3489 Return the size of info_data structure.
3490 ********************************************************************/
3492 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
3496 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3497 if ( (notify_info_data_table
[i
].type
== type
)
3498 && (notify_info_data_table
[i
].field
== field
) ) {
3499 switch(notify_info_data_table
[i
].size
) {
3500 case NOTIFY_ONE_VALUE
:
3501 case NOTIFY_TWO_VALUE
:
3506 /* The only pointer notify data I have seen on
3507 the wire is the submitted time and this has
3508 the notify size set to 4. -tpot */
3510 case NOTIFY_POINTER
:
3513 case NOTIFY_SECDESC
:
3519 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3524 /*******************************************************************
3525 Return the type of notify_info_data.
3526 ********************************************************************/
3528 static uint32
type_of_notify_info_data(uint16 type
, uint16 field
)
3532 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3533 if (notify_info_data_table
[i
].type
== type
&&
3534 notify_info_data_table
[i
].field
== field
)
3535 return notify_info_data_table
[i
].size
;
3541 /****************************************************************************
3542 ****************************************************************************/
3544 static bool search_notify(uint16 type
, uint16 field
, int *value
)
3548 for (i
= 0; notify_info_data_table
[i
].type
!= PRINT_TABLE_END
; i
++) {
3549 if (notify_info_data_table
[i
].type
== type
&&
3550 notify_info_data_table
[i
].field
== field
&&
3551 notify_info_data_table
[i
].fn
!= NULL
) {
3560 /****************************************************************************
3561 ****************************************************************************/
3563 void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
3565 info_data
->type
= type
;
3566 info_data
->field
= field
;
3567 info_data
->reserved
= 0;
3569 info_data
->size
= size_of_notify_info_data(type
, field
);
3570 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
3575 /*******************************************************************
3577 * fill a notify_info struct with info asked
3579 ********************************************************************/
3581 static bool construct_notify_printer_info(Printer_entry
*print_hnd
, SPOOL_NOTIFY_INFO
*info
, int
3582 snum
, SPOOL_NOTIFY_OPTION_TYPE
3583 *option_type
, uint32 id
,
3584 TALLOC_CTX
*mem_ctx
)
3590 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3591 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3592 print_queue_struct
*queue
=NULL
;
3594 type
=option_type
->type
;
3596 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3597 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3598 option_type
->count
, lp_servicename(snum
)));
3600 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3603 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3604 field
= option_type
->fields
[field_num
];
3606 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3608 if (!search_notify(type
, field
, &j
) )
3611 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3612 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3613 free_a_printer(&printer
, 2);
3617 current_data
= &info
->data
[info
->count
];
3619 construct_info_data(current_data
, type
, field
, id
);
3621 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3622 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3624 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3630 free_a_printer(&printer
, 2);
3634 /*******************************************************************
3636 * fill a notify_info struct with info asked
3638 ********************************************************************/
3640 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3641 SPOOL_NOTIFY_INFO
*info
,
3642 NT_PRINTER_INFO_LEVEL
*printer
,
3643 int snum
, SPOOL_NOTIFY_OPTION_TYPE
3644 *option_type
, uint32 id
,
3645 TALLOC_CTX
*mem_ctx
)
3651 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3653 DEBUG(4,("construct_notify_jobs_info\n"));
3655 type
= option_type
->type
;
3657 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3658 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3659 option_type
->count
));
3661 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3662 field
= option_type
->fields
[field_num
];
3664 if (!search_notify(type
, field
, &j
) )
3667 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3668 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3672 current_data
=&(info
->data
[info
->count
]);
3674 construct_info_data(current_data
, type
, field
, id
);
3675 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3684 * JFM: The enumeration is not that simple, it's even non obvious.
3686 * let's take an example: I want to monitor the PRINTER SERVER for
3687 * the printer's name and the number of jobs currently queued.
3688 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3689 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3691 * I have 3 printers on the back of my server.
3693 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3696 * 1 printer 1 name 1
3697 * 2 printer 1 cjob 1
3698 * 3 printer 2 name 2
3699 * 4 printer 2 cjob 2
3700 * 5 printer 3 name 3
3701 * 6 printer 3 name 3
3703 * that's the print server case, the printer case is even worse.
3706 /*******************************************************************
3708 * enumerate all printers on the printserver
3709 * fill a notify_info struct with info asked
3711 ********************************************************************/
3713 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
3714 SPOOL_NOTIFY_INFO
*info
,
3715 TALLOC_CTX
*mem_ctx
)
3718 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3719 int n_services
=lp_numservices();
3721 SPOOL_NOTIFY_OPTION
*option
;
3722 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3724 DEBUG(4,("printserver_notify_info\n"));
3729 option
=Printer
->notify
.option
;
3734 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3735 sending a ffpcn() request first */
3740 for (i
=0; i
<option
->count
; i
++) {
3741 option_type
=&(option
->ctr
.type
[i
]);
3743 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
3746 for (snum
=0; snum
<n_services
; snum
++)
3748 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3749 construct_notify_printer_info ( Printer
, info
, snum
, option_type
, snum
, mem_ctx
);
3755 * Debugging information, don't delete.
3758 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3759 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3760 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3762 for (i
=0; i
<info
->count
; i
++) {
3763 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3764 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3765 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3772 /*******************************************************************
3774 * fill a notify_info struct with info asked
3776 ********************************************************************/
3778 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
3779 TALLOC_CTX
*mem_ctx
)
3782 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3785 SPOOL_NOTIFY_OPTION
*option
;
3786 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3788 print_queue_struct
*queue
=NULL
;
3789 print_status_struct status
;
3791 DEBUG(4,("printer_notify_info\n"));
3796 option
=Printer
->notify
.option
;
3802 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3803 sending a ffpcn() request first */
3808 get_printer_snum(p
, hnd
, &snum
, NULL
);
3810 for (i
=0; i
<option
->count
; i
++) {
3811 option_type
=&option
->ctr
.type
[i
];
3813 switch ( option_type
->type
) {
3814 case PRINTER_NOTIFY_TYPE
:
3815 if(construct_notify_printer_info(Printer
, info
, snum
,
3821 case JOB_NOTIFY_TYPE
: {
3822 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3824 count
= print_queue_status(snum
, &queue
, &status
);
3826 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3829 for (j
=0; j
<count
; j
++) {
3830 construct_notify_jobs_info(&queue
[j
], info
,
3837 free_a_printer(&printer
, 2);
3847 * Debugging information, don't delete.
3850 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3851 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3852 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3854 for (i=0; i<info->count; i++) {
3855 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3856 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3857 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3863 /********************************************************************
3865 ********************************************************************/
3867 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
3869 POLICY_HND
*handle
= &q_u
->handle
;
3870 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
3872 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
3873 WERROR result
= WERR_BADFID
;
3875 /* we always have a NOTIFY_INFO struct */
3879 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3880 OUR_HANDLE(handle
)));
3884 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3887 * We are now using the change value, and
3888 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3889 * I don't have a global notification system, I'm sending back all the
3890 * informations even when _NOTHING_ has changed.
3893 /* We need to keep track of the change value to send back in
3894 RRPCN replies otherwise our updates are ignored. */
3896 Printer
->notify
.fnpcn
= True
;
3898 if (Printer
->notify
.client_connected
) {
3899 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u
->change
));
3900 Printer
->notify
.change
= q_u
->change
;
3903 /* just ignore the SPOOL_NOTIFY_OPTION */
3905 switch (Printer
->printer_type
) {
3907 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
3910 case SPLHND_PRINTER
:
3911 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
3915 Printer
->notify
.fnpcn
= False
;
3921 /********************************************************************
3922 * construct_printer_info_0
3923 * fill a printer_info_0 struct
3924 ********************************************************************/
3926 static bool construct_printer_info_0(Printer_entry
*print_hnd
, PRINTER_INFO_0
*printer
, int snum
)
3928 char *chaine
= NULL
;
3930 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3931 counter_printer_0
*session_counter
;
3932 uint32 global_counter
;
3935 print_status_struct status
;
3936 TALLOC_CTX
*ctx
= talloc_tos();
3938 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
3941 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
3943 chaine
= talloc_asprintf(ctx
, "\\\\%s", get_server_name(print_hnd
));
3945 free_a_printer(&ntprinter
,2);
3949 count
= print_queue_length(snum
, &status
);
3951 /* check if we already have a counter for this printer */
3952 for(session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3953 if (session_counter
->snum
== snum
)
3957 init_unistr(&printer
->servername
, chaine
);
3959 /* it's the first time, add it to the list */
3960 if (session_counter
==NULL
) {
3961 if((session_counter
=SMB_MALLOC_P(counter_printer_0
)) == NULL
) {
3962 free_a_printer(&ntprinter
, 2);
3965 ZERO_STRUCTP(session_counter
);
3966 session_counter
->snum
=snum
;
3967 session_counter
->counter
=0;
3968 DLIST_ADD(counter_list
, session_counter
);
3972 session_counter
->counter
++;
3975 * the global_counter should be stored in a TDB as it's common to all the clients
3976 * and should be zeroed on samba startup
3978 global_counter
=session_counter
->counter
;
3979 printer
->cjobs
= count
;
3980 printer
->total_jobs
= 0;
3981 printer
->total_bytes
= 0;
3983 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
3984 t
=gmtime(&setuptime
);
3986 printer
->year
= t
->tm_year
+1900;
3987 printer
->month
= t
->tm_mon
+1;
3988 printer
->dayofweek
= t
->tm_wday
;
3989 printer
->day
= t
->tm_mday
;
3990 printer
->hour
= t
->tm_hour
;
3991 printer
->minute
= t
->tm_min
;
3992 printer
->second
= t
->tm_sec
;
3993 printer
->milliseconds
= 0;
3995 printer
->global_counter
= global_counter
;
3996 printer
->total_pages
= 0;
3998 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3999 printer
->major_version
= 0x0005; /* NT 5 */
4000 printer
->build_version
= 0x0893; /* build 2195 */
4002 printer
->unknown7
= 0x1;
4003 printer
->unknown8
= 0x0;
4004 printer
->unknown9
= 0x0;
4005 printer
->session_counter
= session_counter
->counter
;
4006 printer
->unknown11
= 0x0;
4007 printer
->printer_errors
= 0x0; /* number of print failure */
4008 printer
->unknown13
= 0x0;
4009 printer
->unknown14
= 0x1;
4010 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
4011 printer
->unknown16
= 0x0;
4012 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
4013 printer
->unknown18
= 0x0;
4014 printer
->status
= nt_printq_status(status
.status
);
4015 printer
->unknown20
= 0x0;
4016 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4017 printer
->unknown22
= 0x0;
4018 printer
->unknown23
= 0x6; /* 6 ???*/
4019 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
4020 printer
->unknown25
= 0;
4021 printer
->unknown26
= 0;
4022 printer
->unknown27
= 0;
4023 printer
->unknown28
= 0;
4024 printer
->unknown29
= 0;
4026 free_a_printer(&ntprinter
,2);
4030 /********************************************************************
4031 * construct_printer_info_1
4032 * fill a printer_info_1 struct
4033 ********************************************************************/
4034 static bool construct_printer_info_1(Printer_entry
*print_hnd
, uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
4036 char *chaine
= NULL
;
4037 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4038 TALLOC_CTX
*ctx
= talloc_tos();
4040 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4043 printer
->flags
=flags
;
4045 if (*ntprinter
->info_2
->comment
== '\0') {
4046 init_unistr(&printer
->comment
, lp_comment(snum
));
4047 chaine
= talloc_asprintf(ctx
,
4048 "%s,%s,%s", ntprinter
->info_2
->printername
,
4049 ntprinter
->info_2
->drivername
, lp_comment(snum
));
4052 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4053 chaine
= talloc_asprintf(ctx
,
4054 "%s,%s,%s", ntprinter
->info_2
->printername
,
4055 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
4059 free_a_printer(&ntprinter
,2);
4063 init_unistr(&printer
->description
, chaine
);
4064 init_unistr(&printer
->name
, ntprinter
->info_2
->printername
);
4066 free_a_printer(&ntprinter
,2);
4071 /****************************************************************************
4072 Free a DEVMODE struct.
4073 ****************************************************************************/
4075 static void free_dev_mode(DEVICEMODE
*dev
)
4080 SAFE_FREE(dev
->dev_private
);
4085 /****************************************************************************
4086 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4087 should be valid upon entry
4088 ****************************************************************************/
4090 static bool convert_nt_devicemode( DEVICEMODE
*devmode
, NT_DEVICEMODE
*ntdevmode
)
4092 if ( !devmode
|| !ntdevmode
)
4095 init_unistr(&devmode
->devicename
, ntdevmode
->devicename
);
4097 init_unistr(&devmode
->formname
, ntdevmode
->formname
);
4099 devmode
->specversion
= ntdevmode
->specversion
;
4100 devmode
->driverversion
= ntdevmode
->driverversion
;
4101 devmode
->size
= ntdevmode
->size
;
4102 devmode
->driverextra
= ntdevmode
->driverextra
;
4103 devmode
->fields
= ntdevmode
->fields
;
4105 devmode
->orientation
= ntdevmode
->orientation
;
4106 devmode
->papersize
= ntdevmode
->papersize
;
4107 devmode
->paperlength
= ntdevmode
->paperlength
;
4108 devmode
->paperwidth
= ntdevmode
->paperwidth
;
4109 devmode
->scale
= ntdevmode
->scale
;
4110 devmode
->copies
= ntdevmode
->copies
;
4111 devmode
->defaultsource
= ntdevmode
->defaultsource
;
4112 devmode
->printquality
= ntdevmode
->printquality
;
4113 devmode
->color
= ntdevmode
->color
;
4114 devmode
->duplex
= ntdevmode
->duplex
;
4115 devmode
->yresolution
= ntdevmode
->yresolution
;
4116 devmode
->ttoption
= ntdevmode
->ttoption
;
4117 devmode
->collate
= ntdevmode
->collate
;
4118 devmode
->icmmethod
= ntdevmode
->icmmethod
;
4119 devmode
->icmintent
= ntdevmode
->icmintent
;
4120 devmode
->mediatype
= ntdevmode
->mediatype
;
4121 devmode
->dithertype
= ntdevmode
->dithertype
;
4123 if (ntdevmode
->nt_dev_private
!= NULL
) {
4124 if ((devmode
->dev_private
=(uint8
*)memdup(ntdevmode
->nt_dev_private
, ntdevmode
->driverextra
)) == NULL
)
4131 /****************************************************************************
4132 Create a DEVMODE struct. Returns malloced memory.
4133 ****************************************************************************/
4135 DEVICEMODE
*construct_dev_mode(const char *servicename
)
4137 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4138 DEVICEMODE
*devmode
= NULL
;
4140 DEBUG(7,("construct_dev_mode\n"));
4142 DEBUGADD(8,("getting printer characteristics\n"));
4144 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
4147 if ( !printer
->info_2
->devmode
) {
4148 DEBUG(5, ("BONG! There was no device mode!\n"));
4152 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) == NULL
) {
4153 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4157 ZERO_STRUCTP(devmode
);
4159 DEBUGADD(8,("loading DEVICEMODE\n"));
4161 if ( !convert_nt_devicemode( devmode
, printer
->info_2
->devmode
) ) {
4162 free_dev_mode( devmode
);
4167 free_a_printer(&printer
,2);
4172 /********************************************************************
4173 * construct_printer_info_2
4174 * fill a printer_info_2 struct
4175 ********************************************************************/
4177 static bool construct_printer_info_2(Printer_entry
*print_hnd
, PRINTER_INFO_2
*printer
, int snum
)
4180 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4182 print_status_struct status
;
4184 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4187 count
= print_queue_length(snum
, &status
);
4189 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4190 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4191 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
4192 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
4193 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
4195 if (*ntprinter
->info_2
->comment
== '\0')
4196 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
4198 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4200 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
4201 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
4202 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
4203 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
4204 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
4206 printer
->attributes
= ntprinter
->info_2
->attributes
;
4208 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
4209 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
4210 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
4211 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
4212 printer
->status
= nt_printq_status(status
.status
); /* status */
4213 printer
->cjobs
= count
; /* jobs */
4214 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
4216 if ( !(printer
->devmode
= construct_dev_mode(
4217 lp_const_servicename(snum
))) )
4218 DEBUG(8, ("Returning NULL Devicemode!\n"));
4220 printer
->secdesc
= NULL
;
4222 if ( ntprinter
->info_2
->secdesc_buf
4223 && ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0 )
4225 /* don't use talloc_steal() here unless you do a deep steal of all
4226 the SEC_DESC members */
4228 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4229 ntprinter
->info_2
->secdesc_buf
->sd
);
4232 free_a_printer(&ntprinter
, 2);
4237 /********************************************************************
4238 * construct_printer_info_3
4239 * fill a printer_info_3 struct
4240 ********************************************************************/
4242 static bool construct_printer_info_3(Printer_entry
*print_hnd
, PRINTER_INFO_3
**pp_printer
, int snum
)
4244 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4245 PRINTER_INFO_3
*printer
= NULL
;
4247 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4251 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_3
)) == NULL
) {
4252 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4253 free_a_printer(&ntprinter
, 2);
4257 ZERO_STRUCTP(printer
);
4259 /* These are the components of the SD we are returning. */
4261 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
4262 /* don't use talloc_steal() here unless you do a deep steal of all
4263 the SEC_DESC members */
4265 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4266 ntprinter
->info_2
->secdesc_buf
->sd
);
4269 free_a_printer(&ntprinter
, 2);
4271 *pp_printer
= printer
;
4275 /********************************************************************
4276 * construct_printer_info_4
4277 * fill a printer_info_4 struct
4278 ********************************************************************/
4280 static bool construct_printer_info_4(Printer_entry
*print_hnd
, PRINTER_INFO_4
*printer
, int snum
)
4282 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4284 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4287 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4288 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4289 printer
->attributes
= ntprinter
->info_2
->attributes
;
4291 free_a_printer(&ntprinter
, 2);
4295 /********************************************************************
4296 * construct_printer_info_5
4297 * fill a printer_info_5 struct
4298 ********************************************************************/
4300 static bool construct_printer_info_5(Printer_entry
*print_hnd
, PRINTER_INFO_5
*printer
, int snum
)
4302 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4304 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4307 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
4308 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
);
4309 printer
->attributes
= ntprinter
->info_2
->attributes
;
4311 /* these two are not used by NT+ according to MSDN */
4313 printer
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
4314 printer
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
4316 free_a_printer(&ntprinter
, 2);
4321 /********************************************************************
4322 * construct_printer_info_6
4323 * fill a printer_info_6 struct
4324 ********************************************************************/
4326 static bool construct_printer_info_6(Printer_entry
*print_hnd
,
4327 PRINTER_INFO_6
*printer
,
4330 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4332 print_status_struct status
;
4334 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2,
4335 lp_const_servicename(snum
))))
4338 count
= print_queue_length(snum
, &status
);
4340 printer
->status
= nt_printq_status(status
.status
);
4342 free_a_printer(&ntprinter
, 2);
4347 /********************************************************************
4348 * construct_printer_info_7
4349 * fill a printer_info_7 struct
4350 ********************************************************************/
4352 static bool construct_printer_info_7(Printer_entry
*print_hnd
, PRINTER_INFO_7
*printer
, int snum
)
4354 char *guid_str
= NULL
;
4357 if (is_printer_published(print_hnd
, snum
, &guid
)) {
4358 asprintf(&guid_str
, "{%s}",
4359 smb_uuid_string(talloc_tos(), guid
));
4360 strupper_m(guid_str
);
4361 init_unistr(&printer
->guid
, guid_str
);
4362 printer
->action
= SPOOL_DS_PUBLISH
;
4364 init_unistr(&printer
->guid
, "");
4365 printer
->action
= SPOOL_DS_UNPUBLISH
;
4371 /********************************************************************
4372 Spoolss_enumprinters.
4373 ********************************************************************/
4375 static WERROR
enum_all_printers_info_1(uint32 flags
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4379 int n_services
=lp_numservices();
4380 PRINTER_INFO_1
*printers
=NULL
;
4381 PRINTER_INFO_1 current_prt
;
4382 WERROR result
= WERR_OK
;
4384 DEBUG(4,("enum_all_printers_info_1\n"));
4386 for (snum
=0; snum
<n_services
; snum
++) {
4387 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4388 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4390 if (construct_printer_info_1(NULL
, flags
, ¤t_prt
, snum
)) {
4391 if((printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_1
, *returned
+1)) == NULL
) {
4392 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4396 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4398 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4404 /* check the required size. */
4405 for (i
=0; i
<*returned
; i
++)
4406 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4408 if (*needed
> offered
) {
4409 result
= WERR_INSUFFICIENT_BUFFER
;
4413 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4414 result
= WERR_NOMEM
;
4418 /* fill the buffer with the structures */
4419 for (i
=0; i
<*returned
; i
++)
4420 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4425 SAFE_FREE(printers
);
4427 if ( !W_ERROR_IS_OK(result
) )
4433 /********************************************************************
4434 enum_all_printers_info_1_local.
4435 *********************************************************************/
4437 static WERROR
enum_all_printers_info_1_local(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4439 DEBUG(4,("enum_all_printers_info_1_local\n"));
4441 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4444 /********************************************************************
4445 enum_all_printers_info_1_name.
4446 *********************************************************************/
4448 static WERROR
enum_all_printers_info_1_name(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4452 DEBUG(4,("enum_all_printers_info_1_name\n"));
4454 if ((name
[0] == '\\') && (name
[1] == '\\'))
4457 if (is_myname_or_ipaddr(s
)) {
4458 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4461 return WERR_INVALID_NAME
;
4464 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4465 /********************************************************************
4466 enum_all_printers_info_1_remote.
4467 *********************************************************************/
4469 static WERROR
enum_all_printers_info_1_remote(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4471 PRINTER_INFO_1
*printer
;
4472 fstring printername
;
4475 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4476 WERROR result
= WERR_OK
;
4478 /* JFM: currently it's more a place holder than anything else.
4479 * In the spooler world there is a notion of server registration.
4480 * the print servers are registered on the PDC (in the same domain)
4482 * We should have a TDB here. The registration is done thru an
4483 * undocumented RPC call.
4486 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4491 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", name
);
4492 slprintf(desc
, sizeof(desc
)-1,"%s", name
);
4493 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4495 init_unistr(&printer
->description
, desc
);
4496 init_unistr(&printer
->name
, printername
);
4497 init_unistr(&printer
->comment
, comment
);
4498 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4500 /* check the required size. */
4501 *needed
+= spoolss_size_printer_info_1(printer
);
4503 if (*needed
> offered
) {
4504 result
= WERR_INSUFFICIENT_BUFFER
;
4508 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4509 result
= WERR_NOMEM
;
4513 /* fill the buffer with the structures */
4514 smb_io_printer_info_1("", buffer
, printer
, 0);
4520 if ( !W_ERROR_IS_OK(result
) )
4528 /********************************************************************
4529 enum_all_printers_info_1_network.
4530 *********************************************************************/
4532 static WERROR
enum_all_printers_info_1_network(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4536 DEBUG(4,("enum_all_printers_info_1_network\n"));
4538 /* If we respond to a enum_printers level 1 on our name with flags
4539 set to PRINTER_ENUM_REMOTE with a list of printers then these
4540 printers incorrectly appear in the APW browse list.
4541 Specifically the printers for the server appear at the workgroup
4542 level where all the other servers in the domain are
4543 listed. Windows responds to this call with a
4544 WERR_CAN_NOT_COMPLETE so we should do the same. */
4546 if (name
[0] == '\\' && name
[1] == '\\')
4549 if (is_myname_or_ipaddr(s
))
4550 return WERR_CAN_NOT_COMPLETE
;
4552 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
4555 /********************************************************************
4556 * api_spoolss_enumprinters
4558 * called from api_spoolss_enumprinters (see this to understand)
4559 ********************************************************************/
4561 static WERROR
enum_all_printers_info_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4565 int n_services
=lp_numservices();
4566 PRINTER_INFO_2
*printers
=NULL
;
4567 PRINTER_INFO_2 current_prt
;
4568 WERROR result
= WERR_OK
;
4572 for (snum
=0; snum
<n_services
; snum
++) {
4573 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4574 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4576 if (construct_printer_info_2(NULL
, ¤t_prt
, snum
)) {
4577 if ( !(printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_2
, *returned
+1)) ) {
4578 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4583 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
+ 1));
4585 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4592 /* check the required size. */
4593 for (i
=0; i
<*returned
; i
++)
4594 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4596 if (*needed
> offered
) {
4597 result
= WERR_INSUFFICIENT_BUFFER
;
4601 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4602 result
= WERR_NOMEM
;
4606 /* fill the buffer with the structures */
4607 for (i
=0; i
<*returned
; i
++)
4608 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4613 for (i
=0; i
<*returned
; i
++)
4614 free_devmode(printers
[i
].devmode
);
4616 SAFE_FREE(printers
);
4618 if ( !W_ERROR_IS_OK(result
) )
4624 /********************************************************************
4625 * handle enumeration of printers at level 1
4626 ********************************************************************/
4628 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4629 RPC_BUFFER
*buffer
, uint32 offered
,
4630 uint32
*needed
, uint32
*returned
)
4632 /* Not all the flags are equals */
4634 if (flags
& PRINTER_ENUM_LOCAL
)
4635 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4637 if (flags
& PRINTER_ENUM_NAME
)
4638 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4640 #if 0 /* JERRY - disabled for now */
4641 if (flags
& PRINTER_ENUM_REMOTE
)
4642 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4645 if (flags
& PRINTER_ENUM_NETWORK
)
4646 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4648 return WERR_OK
; /* NT4sp5 does that */
4651 /********************************************************************
4652 * handle enumeration of printers at level 2
4653 ********************************************************************/
4655 static WERROR
enumprinters_level2( uint32 flags
, fstring servername
,
4656 RPC_BUFFER
*buffer
, uint32 offered
,
4657 uint32
*needed
, uint32
*returned
)
4659 char *s
= servername
;
4661 if (flags
& PRINTER_ENUM_LOCAL
) {
4662 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4665 if (flags
& PRINTER_ENUM_NAME
) {
4666 if ((servername
[0] == '\\') && (servername
[1] == '\\'))
4668 if (is_myname_or_ipaddr(s
))
4669 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4671 return WERR_INVALID_NAME
;
4674 if (flags
& PRINTER_ENUM_REMOTE
)
4675 return WERR_UNKNOWN_LEVEL
;
4680 /********************************************************************
4681 * handle enumeration of printers at level 5
4682 ********************************************************************/
4684 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
4685 RPC_BUFFER
*buffer
, uint32 offered
,
4686 uint32
*needed
, uint32
*returned
)
4688 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4692 /********************************************************************
4693 * api_spoolss_enumprinters
4695 * called from api_spoolss_enumprinters (see this to understand)
4696 ********************************************************************/
4698 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4700 uint32 flags
= q_u
->flags
;
4701 UNISTR2
*servername
= &q_u
->servername
;
4702 uint32 level
= q_u
->level
;
4703 RPC_BUFFER
*buffer
= NULL
;
4704 uint32 offered
= q_u
->offered
;
4705 uint32
*needed
= &r_u
->needed
;
4706 uint32
*returned
= &r_u
->returned
;
4710 /* that's an [in out] buffer */
4712 if (!q_u
->buffer
&& (offered
!=0)) {
4713 return WERR_INVALID_PARAM
;
4716 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
4717 buffer
= r_u
->buffer
;
4719 DEBUG(4,("_spoolss_enumprinters\n"));
4726 * flags==PRINTER_ENUM_NAME
4727 * if name=="" then enumerates all printers
4728 * if name!="" then enumerate the printer
4729 * flags==PRINTER_ENUM_REMOTE
4730 * name is NULL, enumerate printers
4731 * Level 2: name!="" enumerates printers, name can't be NULL
4732 * Level 3: doesn't exist
4733 * Level 4: does a local registry lookup
4734 * Level 5: same as Level 2
4737 unistr2_to_ascii(name
, servername
, sizeof(name
));
4742 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4744 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4746 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4751 return WERR_UNKNOWN_LEVEL
;
4754 /****************************************************************************
4755 ****************************************************************************/
4757 static WERROR
getprinter_level_0(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4759 PRINTER_INFO_0
*printer
=NULL
;
4760 WERROR result
= WERR_OK
;
4762 if((printer
=SMB_MALLOC_P(PRINTER_INFO_0
)) == NULL
)
4765 construct_printer_info_0(print_hnd
, printer
, snum
);
4767 /* check the required size. */
4768 *needed
+= spoolss_size_printer_info_0(printer
);
4770 if (*needed
> offered
) {
4771 result
= WERR_INSUFFICIENT_BUFFER
;
4775 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4776 result
= WERR_NOMEM
;
4780 /* fill the buffer with the structures */
4781 smb_io_printer_info_0("", buffer
, printer
, 0);
4791 /****************************************************************************
4792 ****************************************************************************/
4794 static WERROR
getprinter_level_1(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4796 PRINTER_INFO_1
*printer
=NULL
;
4797 WERROR result
= WERR_OK
;
4799 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4802 construct_printer_info_1(print_hnd
, PRINTER_ENUM_ICON8
, printer
, snum
);
4804 /* check the required size. */
4805 *needed
+= spoolss_size_printer_info_1(printer
);
4807 if (*needed
> offered
) {
4808 result
= WERR_INSUFFICIENT_BUFFER
;
4812 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4813 result
= WERR_NOMEM
;
4817 /* fill the buffer with the structures */
4818 smb_io_printer_info_1("", buffer
, printer
, 0);
4827 /****************************************************************************
4828 ****************************************************************************/
4830 static WERROR
getprinter_level_2(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4832 PRINTER_INFO_2
*printer
=NULL
;
4833 WERROR result
= WERR_OK
;
4835 if((printer
=SMB_MALLOC_P(PRINTER_INFO_2
))==NULL
)
4838 construct_printer_info_2(print_hnd
, printer
, snum
);
4840 /* check the required size. */
4841 *needed
+= spoolss_size_printer_info_2(printer
);
4843 if (*needed
> offered
) {
4844 result
= WERR_INSUFFICIENT_BUFFER
;
4848 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4849 result
= WERR_NOMEM
;
4853 /* fill the buffer with the structures */
4854 if (!smb_io_printer_info_2("", buffer
, printer
, 0))
4855 result
= WERR_NOMEM
;
4859 free_printer_info_2(printer
);
4864 /****************************************************************************
4865 ****************************************************************************/
4867 static WERROR
getprinter_level_3(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4869 PRINTER_INFO_3
*printer
=NULL
;
4870 WERROR result
= WERR_OK
;
4872 if (!construct_printer_info_3(print_hnd
, &printer
, snum
))
4875 /* check the required size. */
4876 *needed
+= spoolss_size_printer_info_3(printer
);
4878 if (*needed
> offered
) {
4879 result
= WERR_INSUFFICIENT_BUFFER
;
4883 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4884 result
= WERR_NOMEM
;
4888 /* fill the buffer with the structures */
4889 smb_io_printer_info_3("", buffer
, printer
, 0);
4893 free_printer_info_3(printer
);
4898 /****************************************************************************
4899 ****************************************************************************/
4901 static WERROR
getprinter_level_4(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4903 PRINTER_INFO_4
*printer
=NULL
;
4904 WERROR result
= WERR_OK
;
4906 if((printer
=SMB_MALLOC_P(PRINTER_INFO_4
))==NULL
)
4909 if (!construct_printer_info_4(print_hnd
, printer
, snum
)) {
4914 /* check the required size. */
4915 *needed
+= spoolss_size_printer_info_4(printer
);
4917 if (*needed
> offered
) {
4918 result
= WERR_INSUFFICIENT_BUFFER
;
4922 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4923 result
= WERR_NOMEM
;
4927 /* fill the buffer with the structures */
4928 smb_io_printer_info_4("", buffer
, printer
, 0);
4932 free_printer_info_4(printer
);
4937 /****************************************************************************
4938 ****************************************************************************/
4940 static WERROR
getprinter_level_5(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4942 PRINTER_INFO_5
*printer
=NULL
;
4943 WERROR result
= WERR_OK
;
4945 if((printer
=SMB_MALLOC_P(PRINTER_INFO_5
))==NULL
)
4948 if (!construct_printer_info_5(print_hnd
, printer
, snum
)) {
4949 free_printer_info_5(printer
);
4953 /* check the required size. */
4954 *needed
+= spoolss_size_printer_info_5(printer
);
4956 if (*needed
> offered
) {
4957 result
= WERR_INSUFFICIENT_BUFFER
;
4961 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4962 result
= WERR_NOMEM
;
4966 /* fill the buffer with the structures */
4967 smb_io_printer_info_5("", buffer
, printer
, 0);
4971 free_printer_info_5(printer
);
4976 static WERROR
getprinter_level_6(Printer_entry
*print_hnd
,
4978 RPC_BUFFER
*buffer
, uint32 offered
,
4981 PRINTER_INFO_6
*printer
;
4982 WERROR result
= WERR_OK
;
4984 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_6
)) == NULL
) {
4988 if (!construct_printer_info_6(print_hnd
, printer
, snum
)) {
4989 free_printer_info_6(printer
);
4993 /* check the required size. */
4994 *needed
+= spoolss_size_printer_info_6(printer
);
4996 if (*needed
> offered
) {
4997 result
= WERR_INSUFFICIENT_BUFFER
;
5001 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5002 result
= WERR_NOMEM
;
5006 /* fill the buffer with the structures */
5007 smb_io_printer_info_6("", buffer
, printer
, 0);
5011 free_printer_info_6(printer
);
5016 static WERROR
getprinter_level_7(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5018 PRINTER_INFO_7
*printer
=NULL
;
5019 WERROR result
= WERR_OK
;
5021 if((printer
=SMB_MALLOC_P(PRINTER_INFO_7
))==NULL
)
5024 if (!construct_printer_info_7(print_hnd
, printer
, snum
))
5027 /* check the required size. */
5028 *needed
+= spoolss_size_printer_info_7(printer
);
5030 if (*needed
> offered
) {
5031 result
= WERR_INSUFFICIENT_BUFFER
;
5035 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5036 result
= WERR_NOMEM
;
5041 /* fill the buffer with the structures */
5042 smb_io_printer_info_7("", buffer
, printer
, 0);
5046 free_printer_info_7(printer
);
5051 /****************************************************************************
5052 ****************************************************************************/
5054 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
5056 POLICY_HND
*handle
= &q_u
->handle
;
5057 uint32 level
= q_u
->level
;
5058 RPC_BUFFER
*buffer
= NULL
;
5059 uint32 offered
= q_u
->offered
;
5060 uint32
*needed
= &r_u
->needed
;
5061 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
5065 /* that's an [in out] buffer */
5067 if (!q_u
->buffer
&& (offered
!=0)) {
5068 return WERR_INVALID_PARAM
;
5071 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5072 buffer
= r_u
->buffer
;
5076 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5081 return getprinter_level_0(Printer
, snum
, buffer
, offered
, needed
);
5083 return getprinter_level_1(Printer
, snum
, buffer
, offered
, needed
);
5085 return getprinter_level_2(Printer
, snum
, buffer
, offered
, needed
);
5087 return getprinter_level_3(Printer
, snum
, buffer
, offered
, needed
);
5089 return getprinter_level_4(Printer
, snum
, buffer
, offered
, needed
);
5091 return getprinter_level_5(Printer
, snum
, buffer
, offered
, needed
);
5093 return getprinter_level_6(Printer
, snum
, buffer
, offered
, needed
);
5095 return getprinter_level_7(Printer
, snum
, buffer
, offered
, needed
);
5097 return WERR_UNKNOWN_LEVEL
;
5100 /********************************************************************
5101 * fill a DRIVER_INFO_1 struct
5102 ********************************************************************/
5104 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
5106 init_unistr( &info
->name
, driver
.info_3
->name
);
5109 /********************************************************************
5110 * construct_printer_driver_info_1
5111 ********************************************************************/
5113 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5115 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5116 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5118 ZERO_STRUCT(driver
);
5120 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5121 return WERR_INVALID_PRINTER_NAME
;
5123 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5124 free_a_printer(&printer
, 2);
5125 return WERR_UNKNOWN_PRINTER_DRIVER
;
5128 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
5130 free_a_printer(&printer
,2);
5135 /********************************************************************
5136 * construct_printer_driver_info_2
5137 * fill a printer_info_2 struct
5138 ********************************************************************/
5140 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5142 TALLOC_CTX
*ctx
= talloc_tos();
5145 info
->version
=driver
.info_3
->cversion
;
5147 init_unistr( &info
->name
, driver
.info_3
->name
);
5148 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5151 if (strlen(driver
.info_3
->driverpath
)) {
5152 temp
= talloc_asprintf(ctx
,
5155 driver
.info_3
->driverpath
);
5156 init_unistr( &info
->driverpath
, temp
);
5158 init_unistr( &info
->driverpath
, "" );
5162 if (strlen(driver
.info_3
->datafile
)) {
5163 temp
= talloc_asprintf(ctx
,
5166 driver
.info_3
->datafile
);
5167 init_unistr( &info
->datafile
, temp
);
5169 init_unistr( &info
->datafile
, "" );
5172 if (strlen(driver
.info_3
->configfile
)) {
5173 temp
= talloc_asprintf(ctx
,
5176 driver
.info_3
->configfile
);
5177 init_unistr( &info
->configfile
, temp
);
5179 init_unistr( &info
->configfile
, "" );
5182 /********************************************************************
5183 * construct_printer_driver_info_2
5184 * fill a printer_info_2 struct
5185 ********************************************************************/
5187 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5189 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5190 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5192 ZERO_STRUCT(printer
);
5193 ZERO_STRUCT(driver
);
5195 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5196 return WERR_INVALID_PRINTER_NAME
;
5198 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5199 free_a_printer(&printer
, 2);
5200 return WERR_UNKNOWN_PRINTER_DRIVER
;
5203 fill_printer_driver_info_2(info
, driver
, servername
);
5205 free_a_printer(&printer
,2);
5210 /********************************************************************
5211 * copy a strings array and convert to UNICODE
5213 * convert an array of ascii string to a UNICODE string
5214 ********************************************************************/
5216 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, const char *servername
)
5222 TALLOC_CTX
*ctx
= talloc_tos();
5224 DEBUG(6,("init_unistr_array\n"));
5228 if ( !char_array
) {
5233 v
= ""; /* hack to handle null lists */
5236 /* hack to allow this to be used in places other than when generating
5237 the list of dependent files */
5241 line
= talloc_asprintf(ctx
,
5246 line
= talloc_strdup(ctx
, v
);
5250 SAFE_FREE(*uni_array
);
5253 DEBUGADD(6,("%d:%s:%lu\n", i
, line
, (unsigned long)strlen(line
)));
5255 /* add one extra unit16 for the second terminating NULL */
5257 if ( (*uni_array
=SMB_REALLOC_ARRAY(*uni_array
, uint16
, j
+1+strlen(line
)+2)) == NULL
) {
5258 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5265 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
5270 /* special case for ""; we need to add both NULL's here */
5272 (*uni_array
)[j
++]=0x0000;
5273 (*uni_array
)[j
]=0x0000;
5276 DEBUGADD(6,("last one:done\n"));
5278 /* return size of array in uint16's */
5283 /********************************************************************
5284 * construct_printer_info_3
5285 * fill a printer_info_3 struct
5286 ********************************************************************/
5288 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5291 TALLOC_CTX
*ctx
= talloc_tos();
5295 info
->version
=driver
.info_3
->cversion
;
5297 init_unistr( &info
->name
, driver
.info_3
->name
);
5298 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5300 if (strlen(driver
.info_3
->driverpath
)) {
5301 temp
= talloc_asprintf(ctx
,
5304 driver
.info_3
->driverpath
);
5305 init_unistr( &info
->driverpath
, temp
);
5307 init_unistr( &info
->driverpath
, "" );
5310 if (strlen(driver
.info_3
->datafile
)) {
5311 temp
= talloc_asprintf(ctx
,
5314 driver
.info_3
->datafile
);
5315 init_unistr( &info
->datafile
, temp
);
5317 init_unistr( &info
->datafile
, "" );
5320 if (strlen(driver
.info_3
->configfile
)) {
5321 temp
= talloc_asprintf(ctx
,
5324 driver
.info_3
->configfile
);
5325 init_unistr( &info
->configfile
, temp
);
5327 init_unistr( &info
->configfile
, "" );
5330 if (strlen(driver
.info_3
->helpfile
)) {
5331 temp
= talloc_asprintf(ctx
,
5334 driver
.info_3
->helpfile
);
5335 init_unistr( &info
->helpfile
, temp
);
5337 init_unistr( &info
->helpfile
, "" );
5340 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5341 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5343 info
->dependentfiles
=NULL
;
5344 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5347 /********************************************************************
5348 * construct_printer_info_3
5349 * fill a printer_info_3 struct
5350 ********************************************************************/
5352 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
5354 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5355 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5357 ZERO_STRUCT(driver
);
5359 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5360 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5361 if (!W_ERROR_IS_OK(status
))
5362 return WERR_INVALID_PRINTER_NAME
;
5364 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5365 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5370 * I put this code in during testing. Helpful when commenting out the
5371 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5372 * as win2k always queries the driver using an infor level of 6.
5373 * I've left it in (but ifdef'd out) because I'll probably
5374 * use it in experimentation again in the future. --jerry 22/01/2002
5377 if (!W_ERROR_IS_OK(status
)) {
5379 * Is this a W2k client ?
5382 /* Yes - try again with a WinNT driver. */
5384 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5385 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5389 if (!W_ERROR_IS_OK(status
)) {
5390 free_a_printer(&printer
,2);
5391 return WERR_UNKNOWN_PRINTER_DRIVER
;
5399 fill_printer_driver_info_3(info
, driver
, servername
);
5401 free_a_printer(&printer
,2);
5406 /********************************************************************
5407 * construct_printer_info_6
5408 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5409 ********************************************************************/
5411 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
5415 TALLOC_CTX
*ctx
= talloc_tos();
5418 memset(&nullstr
, '\0', sizeof(fstring
));
5420 info
->version
=driver
.info_3
->cversion
;
5422 init_unistr( &info
->name
, driver
.info_3
->name
);
5423 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5425 if (strlen(driver
.info_3
->driverpath
)) {
5426 temp
= talloc_asprintf(ctx
,
5429 driver
.info_3
->driverpath
);
5430 init_unistr( &info
->driverpath
, temp
);
5432 init_unistr( &info
->driverpath
, "" );
5435 if (strlen(driver
.info_3
->datafile
)) {
5436 temp
= talloc_asprintf(ctx
,
5439 driver
.info_3
->datafile
);
5440 init_unistr( &info
->datafile
, temp
);
5442 init_unistr( &info
->datafile
, "" );
5445 if (strlen(driver
.info_3
->configfile
)) {
5446 temp
= talloc_asprintf(ctx
,
5449 driver
.info_3
->configfile
);
5450 init_unistr( &info
->configfile
, temp
);
5452 init_unistr( &info
->configfile
, "" );
5455 if (strlen(driver
.info_3
->helpfile
)) {
5456 temp
= talloc_asprintf(ctx
,
5459 driver
.info_3
->helpfile
);
5460 init_unistr( &info
->helpfile
, temp
);
5462 init_unistr( &info
->helpfile
, "" );
5465 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5466 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5468 info
->dependentfiles
= NULL
;
5469 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5471 info
->previousdrivernames
=NULL
;
5472 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
5474 info
->driver_date
=0;
5477 info
->driver_version_low
=0;
5478 info
->driver_version_high
=0;
5480 init_unistr( &info
->mfgname
, "");
5481 init_unistr( &info
->oem_url
, "");
5482 init_unistr( &info
->hardware_id
, "");
5483 init_unistr( &info
->provider
, "");
5486 /********************************************************************
5487 * construct_printer_info_6
5488 * fill a printer_info_6 struct
5489 ********************************************************************/
5491 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
5492 fstring servername
, fstring architecture
, uint32 version
)
5494 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5495 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5498 ZERO_STRUCT(driver
);
5500 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5502 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5504 if (!W_ERROR_IS_OK(status
))
5505 return WERR_INVALID_PRINTER_NAME
;
5507 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5509 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5511 if (!W_ERROR_IS_OK(status
))
5514 * Is this a W2k client ?
5518 free_a_printer(&printer
,2);
5519 return WERR_UNKNOWN_PRINTER_DRIVER
;
5522 /* Yes - try again with a WinNT driver. */
5524 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5525 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5526 if (!W_ERROR_IS_OK(status
)) {
5527 free_a_printer(&printer
,2);
5528 return WERR_UNKNOWN_PRINTER_DRIVER
;
5532 fill_printer_driver_info_6(info
, driver
, servername
);
5534 free_a_printer(&printer
,2);
5535 free_a_printer_driver(driver
, 3);
5540 /****************************************************************************
5541 ****************************************************************************/
5543 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5545 SAFE_FREE(info
->dependentfiles
);
5548 /****************************************************************************
5549 ****************************************************************************/
5551 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5553 SAFE_FREE(info
->dependentfiles
);
5556 /****************************************************************************
5557 ****************************************************************************/
5559 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5561 DRIVER_INFO_1
*info
=NULL
;
5564 if((info
=SMB_MALLOC_P(DRIVER_INFO_1
)) == NULL
)
5567 result
= construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5568 if (!W_ERROR_IS_OK(result
))
5571 /* check the required size. */
5572 *needed
+= spoolss_size_printer_driver_info_1(info
);
5574 if (*needed
> offered
) {
5575 result
= WERR_INSUFFICIENT_BUFFER
;
5579 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5580 result
= WERR_NOMEM
;
5584 /* fill the buffer with the structures */
5585 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5594 /****************************************************************************
5595 ****************************************************************************/
5597 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5599 DRIVER_INFO_2
*info
=NULL
;
5602 if((info
=SMB_MALLOC_P(DRIVER_INFO_2
)) == NULL
)
5605 result
= construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5606 if (!W_ERROR_IS_OK(result
))
5609 /* check the required size. */
5610 *needed
+= spoolss_size_printer_driver_info_2(info
);
5612 if (*needed
> offered
) {
5613 result
= WERR_INSUFFICIENT_BUFFER
;
5617 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5618 result
= WERR_NOMEM
;
5622 /* fill the buffer with the structures */
5623 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5632 /****************************************************************************
5633 ****************************************************************************/
5635 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5642 result
= construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5643 if (!W_ERROR_IS_OK(result
))
5646 /* check the required size. */
5647 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5649 if (*needed
> offered
) {
5650 result
= WERR_INSUFFICIENT_BUFFER
;
5654 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5655 result
= WERR_NOMEM
;
5659 /* fill the buffer with the structures */
5660 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5663 free_printer_driver_info_3(&info
);
5668 /****************************************************************************
5669 ****************************************************************************/
5671 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5678 result
= construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5679 if (!W_ERROR_IS_OK(result
))
5682 /* check the required size. */
5683 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5685 if (*needed
> offered
) {
5686 result
= WERR_INSUFFICIENT_BUFFER
;
5690 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5691 result
= WERR_NOMEM
;
5695 /* fill the buffer with the structures */
5696 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5699 free_printer_driver_info_6(&info
);
5704 /****************************************************************************
5705 ****************************************************************************/
5707 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5709 POLICY_HND
*handle
= &q_u
->handle
;
5710 UNISTR2
*uni_arch
= &q_u
->architecture
;
5711 uint32 level
= q_u
->level
;
5712 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5713 RPC_BUFFER
*buffer
= NULL
;
5714 uint32 offered
= q_u
->offered
;
5715 uint32
*needed
= &r_u
->needed
;
5716 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5717 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5718 Printer_entry
*printer
;
5721 fstring architecture
;
5724 /* that's an [in out] buffer */
5726 if (!q_u
->buffer
&& (offered
!=0)) {
5727 return WERR_INVALID_PARAM
;
5730 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5731 buffer
= r_u
->buffer
;
5733 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5735 if ( !(printer
= find_printer_index_by_hnd( p
, handle
)) ) {
5736 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5737 return WERR_INVALID_PRINTER_NAME
;
5741 *servermajorversion
= 0;
5742 *serverminorversion
= 0;
5744 fstrcpy(servername
, get_server_name( printer
));
5745 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
));
5747 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5752 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5754 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5756 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5758 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5761 /* apparently this call is the equivalent of
5762 EnumPrinterDataEx() for the DsDriver key */
5767 return WERR_UNKNOWN_LEVEL
;
5770 /****************************************************************************
5771 ****************************************************************************/
5773 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
5775 POLICY_HND
*handle
= &q_u
->handle
;
5777 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5780 DEBUG(3,("Error in startpageprinter printer handle\n"));
5784 Printer
->page_started
=True
;
5788 /****************************************************************************
5789 ****************************************************************************/
5791 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
5793 POLICY_HND
*handle
= &q_u
->handle
;
5796 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5799 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle
)));
5803 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5806 Printer
->page_started
=False
;
5807 print_job_endpage(snum
, Printer
->jobid
);
5812 /********************************************************************
5813 * api_spoolss_getprinter
5814 * called from the spoolss dispatcher
5816 ********************************************************************/
5818 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
5820 POLICY_HND
*handle
= &q_u
->handle
;
5821 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
5822 uint32
*jobid
= &r_u
->jobid
;
5823 TALLOC_CTX
*ctx
= p
->mem_ctx
;
5824 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
5826 char *jobname
= NULL
;
5828 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5831 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5836 * a nice thing with NT is it doesn't listen to what you tell it.
5837 * when asked to send _only_ RAW datas, it tries to send datas
5840 * So I add checks like in NT Server ...
5843 if (info_1
->p_datatype
!= 0) {
5844 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
5845 if (strcmp(datatype
, "RAW") != 0) {
5847 return WERR_INVALID_DATATYPE
;
5851 /* get the share number of the printer */
5852 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5856 jobname
= unistr2_to_ascii_talloc(ctx
, &info_1
->docname
);
5858 Printer
->jobid
= print_job_start(&p
->pipe_user
, snum
, jobname
, Printer
->nt_devmode
);
5860 /* An error occured in print_job_start() so return an appropriate
5863 if (Printer
->jobid
== -1) {
5864 return map_werror_from_unix(errno
);
5867 Printer
->document_started
=True
;
5868 (*jobid
) = Printer
->jobid
;
5873 /********************************************************************
5874 * api_spoolss_getprinter
5875 * called from the spoolss dispatcher
5877 ********************************************************************/
5879 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
5881 POLICY_HND
*handle
= &q_u
->handle
;
5883 return _spoolss_enddocprinter_internal(p
, handle
);
5886 /****************************************************************************
5887 ****************************************************************************/
5889 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
5891 POLICY_HND
*handle
= &q_u
->handle
;
5892 uint32 buffer_size
= q_u
->buffer_size
;
5893 uint8
*buffer
= q_u
->buffer
;
5894 uint32
*buffer_written
= &q_u
->buffer_size2
;
5896 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5899 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5900 r_u
->buffer_written
= q_u
->buffer_size2
;
5904 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5907 (*buffer_written
) = (uint32
)print_job_write(snum
, Printer
->jobid
, (const char *)buffer
,
5908 (SMB_OFF_T
)-1, (size_t)buffer_size
);
5909 if (*buffer_written
== (uint32
)-1) {
5910 r_u
->buffer_written
= 0;
5911 if (errno
== ENOSPC
)
5912 return WERR_NO_SPOOL_SPACE
;
5914 return WERR_ACCESS_DENIED
;
5917 r_u
->buffer_written
= q_u
->buffer_size2
;
5922 /********************************************************************
5923 * api_spoolss_getprinter
5924 * called from the spoolss dispatcher
5926 ********************************************************************/
5928 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5932 WERROR errcode
= WERR_BADFUNC
;
5933 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5936 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5940 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5944 case PRINTER_CONTROL_PAUSE
:
5945 if (print_queue_pause(&p
->pipe_user
, snum
, &errcode
)) {
5949 case PRINTER_CONTROL_RESUME
:
5950 case PRINTER_CONTROL_UNPAUSE
:
5951 if (print_queue_resume(&p
->pipe_user
, snum
, &errcode
)) {
5955 case PRINTER_CONTROL_PURGE
:
5956 if (print_queue_purge(&p
->pipe_user
, snum
, &errcode
)) {
5961 return WERR_UNKNOWN_LEVEL
;
5967 /********************************************************************
5968 * api_spoolss_abortprinter
5969 * From MSDN: "Deletes printer's spool file if printer is configured
5971 ********************************************************************/
5973 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
5975 POLICY_HND
*handle
= &q_u
->handle
;
5976 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5978 WERROR errcode
= WERR_OK
;
5981 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5985 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5988 print_job_delete( &p
->pipe_user
, snum
, Printer
->jobid
, &errcode
);
5993 /********************************************************************
5994 * called by spoolss_api_setprinter
5995 * when updating a printer description
5996 ********************************************************************/
5998 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
5999 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6000 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
6002 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
6006 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6008 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
6009 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6010 OUR_HANDLE(handle
)));
6012 result
= WERR_BADFID
;
6017 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6018 result
= WERR_INVALID_PARAM
;
6022 /* Check the user has permissions to change the security
6023 descriptor. By experimentation with two NT machines, the user
6024 requires Full Access to the printer to change security
6027 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6028 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6029 result
= WERR_ACCESS_DENIED
;
6033 /* NT seems to like setting the security descriptor even though
6034 nothing may have actually changed. */
6036 nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
);
6038 if (DEBUGLEVEL
>= 10) {
6042 the_acl
= old_secdesc_ctr
->sd
->dacl
;
6043 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6044 PRINTERNAME(snum
), the_acl
->num_aces
));
6046 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6047 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6048 &the_acl
->aces
[i
].trustee
),
6049 the_acl
->aces
[i
].access_mask
));
6052 the_acl
= secdesc_ctr
->sd
->dacl
;
6055 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6056 PRINTERNAME(snum
), the_acl
->num_aces
));
6058 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6059 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6060 &the_acl
->aces
[i
].trustee
),
6061 the_acl
->aces
[i
].access_mask
));
6064 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6068 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
6069 if (!new_secdesc_ctr
) {
6070 result
= WERR_NOMEM
;
6074 if (sec_desc_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
6079 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
6086 /********************************************************************
6087 Canonicalize printer info from a client
6089 ATTN: It does not matter what we set the servername to hear
6090 since we do the necessary work in get_a_printer() to set it to
6091 the correct value based on what the client sent in the
6092 _spoolss_open_printer_ex().
6093 ********************************************************************/
6095 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
6097 fstring printername
;
6100 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6101 "portname=%s drivername=%s comment=%s location=%s\n",
6102 info
->servername
, info
->printername
, info
->sharename
,
6103 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
6105 /* we force some elements to "correct" values */
6106 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
6107 fstrcpy(info
->sharename
, lp_servicename(snum
));
6109 /* check to see if we allow printername != sharename */
6111 if ( lp_force_printername(snum
) ) {
6112 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6113 global_myname(), info
->sharename
);
6116 /* make sure printername is in \\server\printername format */
6118 fstrcpy( printername
, info
->printername
);
6120 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
6121 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
6125 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6126 global_myname(), p
);
6129 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
6130 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
6137 /****************************************************************************
6138 ****************************************************************************/
6140 WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
6142 char *cmd
= lp_addport_cmd();
6143 char *command
= NULL
;
6146 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6147 bool is_print_op
= False
;
6150 return WERR_ACCESS_DENIED
;
6153 command
= talloc_asprintf(ctx
,
6154 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
6160 is_print_op
= user_has_privileges( token
, &se_printop
);
6162 DEBUG(10,("Running [%s]\n", command
));
6164 /********* BEGIN SePrintOperatorPrivilege **********/
6169 ret
= smbrun(command
, &fd
);
6174 /********* END SePrintOperatorPrivilege **********/
6176 DEBUGADD(10,("returned [%d]\n", ret
));
6178 TALLOC_FREE(command
);
6183 return WERR_ACCESS_DENIED
;
6189 /****************************************************************************
6190 ****************************************************************************/
6192 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
6194 char *cmd
= lp_addprinter_cmd();
6196 char *command
= NULL
;
6200 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6201 bool is_print_op
= False
;
6202 char *remote_machine
= talloc_strdup(ctx
, "%m");
6204 if (!remote_machine
) {
6207 remote_machine
= talloc_sub_basic(ctx
,
6208 current_user_info
.smb_name
,
6209 current_user_info
.domain
,
6211 if (!remote_machine
) {
6215 command
= talloc_asprintf(ctx
,
6216 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6217 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6218 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6219 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6225 is_print_op
= user_has_privileges( token
, &se_printop
);
6227 DEBUG(10,("Running [%s]\n", command
));
6229 /********* BEGIN SePrintOperatorPrivilege **********/
6234 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6235 /* Tell everyone we updated smb.conf. */
6236 message_send_all(smbd_messaging_context(),
6237 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6243 /********* END SePrintOperatorPrivilege **********/
6245 DEBUGADD(10,("returned [%d]\n", ret
));
6247 TALLOC_FREE(command
);
6248 TALLOC_FREE(remote_machine
);
6256 /* reload our services immediately */
6257 reload_services( False
);
6260 /* Get lines and convert them back to dos-codepage */
6261 qlines
= fd_lines_load(fd
, &numlines
, 0);
6262 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6265 /* Set the portname to what the script says the portname should be. */
6266 /* but don't require anything to be return from the script exit a good error code */
6269 /* Set the portname to what the script says the portname should be. */
6270 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6271 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6274 file_lines_free(qlines
);
6279 /********************************************************************
6280 * Called by spoolss_api_setprinter
6281 * when updating a printer description.
6282 ********************************************************************/
6284 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
6285 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6286 DEVICEMODE
*devmode
)
6289 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6290 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6295 DEBUG(8,("update_printer\n"));
6300 result
= WERR_BADFID
;
6304 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6305 result
= WERR_BADFID
;
6309 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6310 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6311 result
= WERR_BADFID
;
6315 DEBUGADD(8,("Converting info_2 struct\n"));
6318 * convert_printer_info converts the incoming
6319 * info from the client and overwrites the info
6320 * just read from the tdb in the pointer 'printer'.
6323 if (!convert_printer_info(info
, printer
, level
)) {
6324 result
= WERR_NOMEM
;
6329 /* we have a valid devmode
6330 convert it and link it*/
6332 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6333 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6334 &printer
->info_2
->devmode
)) {
6335 result
= WERR_NOMEM
;
6340 /* Do sanity check on the requested changes for Samba */
6342 if (!check_printer_ok(printer
->info_2
, snum
)) {
6343 result
= WERR_INVALID_PARAM
;
6347 /* FIXME!!! If the driver has changed we really should verify that
6348 it is installed before doing much else --jerry */
6350 /* Check calling user has permission to update printer description */
6352 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6353 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6354 result
= WERR_ACCESS_DENIED
;
6358 /* Call addprinter hook */
6359 /* Check changes to see if this is really needed */
6361 if ( *lp_addprinter_cmd()
6362 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6363 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6364 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6365 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6367 /* add_printer_hook() will call reload_services() */
6369 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
6370 result
= WERR_ACCESS_DENIED
;
6376 * When a *new* driver is bound to a printer, the drivername is used to
6377 * lookup previously saved driver initialization info, which is then
6378 * bound to the printer, simulating what happens in the Windows arch.
6380 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6382 if (!set_driver_init(printer
, 2))
6384 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6385 printer
->info_2
->drivername
));
6388 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6389 printer
->info_2
->drivername
));
6391 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6395 * flag which changes actually occured. This is a small subset of
6396 * all the possible changes. We also have to update things in the
6400 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6401 init_unistr2( &buffer
, printer
->info_2
->comment
, UNI_STR_TERMINATE
);
6402 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6403 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6405 notify_printer_comment(snum
, printer
->info_2
->comment
);
6408 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6409 init_unistr2( &buffer
, printer
->info_2
->sharename
, UNI_STR_TERMINATE
);
6410 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6411 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6413 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6416 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6419 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6422 pname
= printer
->info_2
->printername
;
6425 init_unistr2( &buffer
, pname
, UNI_STR_TERMINATE
);
6426 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6427 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6429 notify_printer_printername( snum
, pname
);
6432 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6433 init_unistr2( &buffer
, printer
->info_2
->portname
, UNI_STR_TERMINATE
);
6434 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6435 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6437 notify_printer_port(snum
, printer
->info_2
->portname
);
6440 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6441 init_unistr2( &buffer
, printer
->info_2
->location
, UNI_STR_TERMINATE
);
6442 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6443 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6445 notify_printer_location(snum
, printer
->info_2
->location
);
6448 /* here we need to update some more DsSpooler keys */
6449 /* uNCName, serverName, shortServerName */
6451 init_unistr2( &buffer
, global_myname(), UNI_STR_TERMINATE
);
6452 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6453 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6454 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6455 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6457 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6458 global_myname(), printer
->info_2
->sharename
);
6459 init_unistr2( &buffer
, asc_buffer
, UNI_STR_TERMINATE
);
6460 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6461 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6463 /* Update printer info */
6464 result
= mod_a_printer(printer
, 2);
6467 free_a_printer(&printer
, 2);
6468 free_a_printer(&old_printer
, 2);
6474 /****************************************************************************
6475 ****************************************************************************/
6476 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6477 const SPOOL_PRINTER_INFO_LEVEL
*info
)
6480 SPOOL_PRINTER_INFO_LEVEL_7
*info7
= info
->info_7
;
6482 Printer_entry
*Printer
;
6484 if ( lp_security() != SEC_ADS
) {
6485 return WERR_UNKNOWN_LEVEL
;
6488 Printer
= find_printer_index_by_hnd(p
, handle
);
6490 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6495 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6498 nt_printer_publish(Printer
, snum
, info7
->action
);
6502 return WERR_UNKNOWN_LEVEL
;
6505 /****************************************************************************
6506 ****************************************************************************/
6508 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
6510 POLICY_HND
*handle
= &q_u
->handle
;
6511 uint32 level
= q_u
->level
;
6512 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
6513 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
6514 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
6515 uint32 command
= q_u
->command
;
6518 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6521 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6525 /* check the level */
6528 return control_printer(handle
, command
, p
);
6530 result
= update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
6531 if (!W_ERROR_IS_OK(result
))
6534 result
= update_printer_sec(handle
, level
, info
, p
, secdesc_ctr
);
6537 return update_printer_sec(handle
, level
, info
, p
,
6540 return publish_or_unpublish_printer(p
, handle
, info
);
6542 return WERR_UNKNOWN_LEVEL
;
6546 /****************************************************************************
6547 ****************************************************************************/
6549 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
6551 POLICY_HND
*handle
= &q_u
->handle
;
6552 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6555 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6559 if (Printer
->notify
.client_connected
==True
) {
6562 if ( Printer
->printer_type
== SPLHND_SERVER
)
6564 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6565 !get_printer_snum(p
, handle
, &snum
, NULL
) )
6568 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6571 Printer
->notify
.flags
=0;
6572 Printer
->notify
.options
=0;
6573 Printer
->notify
.localmachine
[0]='\0';
6574 Printer
->notify
.printerlocal
=0;
6575 if (Printer
->notify
.option
)
6576 free_spool_notify_option(&Printer
->notify
.option
);
6577 Printer
->notify
.client_connected
=False
;
6582 /****************************************************************************
6583 ****************************************************************************/
6585 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
6587 /* that's an [in out] buffer */
6589 if (!q_u
->buffer
&& (q_u
->offered
!=0)) {
6590 return WERR_INVALID_PARAM
;
6593 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6596 return WERR_INVALID_PARAM
; /* this is what a NT server
6597 returns for AddJob. AddJob
6598 must fail on non-local
6602 /****************************************************************************
6603 ****************************************************************************/
6605 static void fill_job_info_1(JOB_INFO_1
*job_info
, const print_queue_struct
*queue
,
6606 int position
, int snum
,
6607 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6611 t
=gmtime(&queue
->time
);
6613 job_info
->jobid
=queue
->job
;
6614 init_unistr(&job_info
->printername
, lp_servicename(snum
));
6615 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6616 init_unistr(&job_info
->username
, queue
->fs_user
);
6617 init_unistr(&job_info
->document
, queue
->fs_file
);
6618 init_unistr(&job_info
->datatype
, "RAW");
6619 init_unistr(&job_info
->text_status
, "");
6620 job_info
->status
=nt_printj_status(queue
->status
);
6621 job_info
->priority
=queue
->priority
;
6622 job_info
->position
=position
;
6623 job_info
->totalpages
=queue
->page_count
;
6624 job_info
->pagesprinted
=0;
6626 make_systemtime(&job_info
->submitted
, t
);
6629 /****************************************************************************
6630 ****************************************************************************/
6632 static bool fill_job_info_2(JOB_INFO_2
*job_info
, const print_queue_struct
*queue
,
6633 int position
, int snum
,
6634 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6635 DEVICEMODE
*devmode
)
6639 t
=gmtime(&queue
->time
);
6641 job_info
->jobid
=queue
->job
;
6643 init_unistr(&job_info
->printername
, ntprinter
->info_2
->printername
);
6645 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6646 init_unistr(&job_info
->username
, queue
->fs_user
);
6647 init_unistr(&job_info
->document
, queue
->fs_file
);
6648 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
6649 init_unistr(&job_info
->datatype
, "RAW");
6650 init_unistr(&job_info
->printprocessor
, "winprint");
6651 init_unistr(&job_info
->parameters
, "");
6652 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
6653 init_unistr(&job_info
->text_status
, "");
6655 /* and here the security descriptor */
6657 job_info
->status
=nt_printj_status(queue
->status
);
6658 job_info
->priority
=queue
->priority
;
6659 job_info
->position
=position
;
6660 job_info
->starttime
=0;
6661 job_info
->untiltime
=0;
6662 job_info
->totalpages
=queue
->page_count
;
6663 job_info
->size
=queue
->size
;
6664 make_systemtime(&(job_info
->submitted
), t
);
6665 job_info
->timeelapsed
=0;
6666 job_info
->pagesprinted
=0;
6668 job_info
->devmode
= devmode
;
6673 /****************************************************************************
6674 Enumjobs at level 1.
6675 ****************************************************************************/
6677 static WERROR
enumjobs_level1(const print_queue_struct
*queue
, int snum
,
6678 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6679 RPC_BUFFER
*buffer
, uint32 offered
,
6680 uint32
*needed
, uint32
*returned
)
6684 WERROR result
= WERR_OK
;
6686 info
=SMB_MALLOC_ARRAY(JOB_INFO_1
,*returned
);
6692 for (i
=0; i
<*returned
; i
++)
6693 fill_job_info_1( &info
[i
], &queue
[i
], i
, snum
, ntprinter
);
6695 /* check the required size. */
6696 for (i
=0; i
<*returned
; i
++)
6697 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
6699 if (*needed
> offered
) {
6700 result
= WERR_INSUFFICIENT_BUFFER
;
6704 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6705 result
= WERR_NOMEM
;
6709 /* fill the buffer with the structures */
6710 for (i
=0; i
<*returned
; i
++)
6711 smb_io_job_info_1("", buffer
, &info
[i
], 0);
6717 if ( !W_ERROR_IS_OK(result
) )
6723 /****************************************************************************
6724 Enumjobs at level 2.
6725 ****************************************************************************/
6727 static WERROR
enumjobs_level2(const print_queue_struct
*queue
, int snum
,
6728 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6729 RPC_BUFFER
*buffer
, uint32 offered
,
6730 uint32
*needed
, uint32
*returned
)
6732 JOB_INFO_2
*info
= NULL
;
6734 WERROR result
= WERR_OK
;
6735 DEVICEMODE
*devmode
= NULL
;
6737 if ( !(info
= SMB_MALLOC_ARRAY(JOB_INFO_2
,*returned
)) ) {
6742 /* this should not be a failure condition if the devmode is NULL */
6744 devmode
= construct_dev_mode(lp_const_servicename(snum
));
6746 for (i
=0; i
<*returned
; i
++)
6747 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
, devmode
);
6749 /* check the required size. */
6750 for (i
=0; i
<*returned
; i
++)
6751 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6753 if (*needed
> offered
) {
6754 result
= WERR_INSUFFICIENT_BUFFER
;
6758 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6759 result
= WERR_NOMEM
;
6763 /* fill the buffer with the structures */
6764 for (i
=0; i
<*returned
; i
++)
6765 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6768 free_devmode(devmode
);
6771 if ( !W_ERROR_IS_OK(result
) )
6778 /****************************************************************************
6780 ****************************************************************************/
6782 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6784 POLICY_HND
*handle
= &q_u
->handle
;
6785 uint32 level
= q_u
->level
;
6786 RPC_BUFFER
*buffer
= NULL
;
6787 uint32 offered
= q_u
->offered
;
6788 uint32
*needed
= &r_u
->needed
;
6789 uint32
*returned
= &r_u
->returned
;
6791 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6793 print_status_struct prt_status
;
6794 print_queue_struct
*queue
=NULL
;
6796 /* that's an [in out] buffer */
6798 if (!q_u
->buffer
&& (offered
!=0)) {
6799 return WERR_INVALID_PARAM
;
6802 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6803 buffer
= r_u
->buffer
;
6805 DEBUG(4,("_spoolss_enumjobs\n"));
6810 /* lookup the printer snum and tdb entry */
6812 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6815 wret
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6816 if ( !W_ERROR_IS_OK(wret
) )
6819 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6820 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6822 if (*returned
== 0) {
6824 free_a_printer(&ntprinter
, 2);
6830 wret
= enumjobs_level1(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6833 wret
= enumjobs_level2(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6837 wret
= WERR_UNKNOWN_LEVEL
;
6842 free_a_printer( &ntprinter
, 2 );
6846 /****************************************************************************
6847 ****************************************************************************/
6849 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
6854 /****************************************************************************
6855 ****************************************************************************/
6857 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
6859 POLICY_HND
*handle
= &q_u
->handle
;
6860 uint32 jobid
= q_u
->jobid
;
6861 uint32 command
= q_u
->command
;
6864 WERROR errcode
= WERR_BADFUNC
;
6866 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6870 if (!print_job_exists(lp_const_servicename(snum
), jobid
)) {
6871 return WERR_INVALID_PRINTER_NAME
;
6875 case JOB_CONTROL_CANCEL
:
6876 case JOB_CONTROL_DELETE
:
6877 if (print_job_delete(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6881 case JOB_CONTROL_PAUSE
:
6882 if (print_job_pause(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6886 case JOB_CONTROL_RESTART
:
6887 case JOB_CONTROL_RESUME
:
6888 if (print_job_resume(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6893 return WERR_UNKNOWN_LEVEL
;
6899 /****************************************************************************
6900 Enumerates all printer drivers at level 1.
6901 ****************************************************************************/
6903 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6908 fstring
*list
= NULL
;
6909 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6910 DRIVER_INFO_1
*driver_info_1
=NULL
;
6911 WERROR result
= WERR_OK
;
6915 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6917 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6918 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6920 if(ndrivers
== -1) {
6921 SAFE_FREE(driver_info_1
);
6926 if((driver_info_1
=SMB_REALLOC_ARRAY(driver_info_1
, DRIVER_INFO_1
, *returned
+ndrivers
)) == NULL
) {
6927 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6933 for (i
=0; i
<ndrivers
; i
++) {
6935 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6936 ZERO_STRUCT(driver
);
6937 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6938 architecture
, version
);
6939 if (!W_ERROR_IS_OK(status
)) {
6941 SAFE_FREE(driver_info_1
);
6944 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6945 free_a_printer_driver(driver
, 3);
6948 *returned
+=ndrivers
;
6952 /* check the required size. */
6953 for (i
=0; i
<*returned
; i
++) {
6954 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6955 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6958 if (*needed
> offered
) {
6959 result
= WERR_INSUFFICIENT_BUFFER
;
6963 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6964 result
= WERR_NOMEM
;
6968 /* fill the buffer with the driver structures */
6969 for (i
=0; i
<*returned
; i
++) {
6970 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6971 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
6975 SAFE_FREE(driver_info_1
);
6977 if ( !W_ERROR_IS_OK(result
) )
6983 /****************************************************************************
6984 Enumerates all printer drivers at level 2.
6985 ****************************************************************************/
6987 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6992 fstring
*list
= NULL
;
6993 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6994 DRIVER_INFO_2
*driver_info_2
=NULL
;
6995 WERROR result
= WERR_OK
;
6999 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7001 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7002 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7004 if(ndrivers
== -1) {
7005 SAFE_FREE(driver_info_2
);
7010 if((driver_info_2
=SMB_REALLOC_ARRAY(driver_info_2
, DRIVER_INFO_2
, *returned
+ndrivers
)) == NULL
) {
7011 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7017 for (i
=0; i
<ndrivers
; i
++) {
7020 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7021 ZERO_STRUCT(driver
);
7022 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7023 architecture
, version
);
7024 if (!W_ERROR_IS_OK(status
)) {
7026 SAFE_FREE(driver_info_2
);
7029 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
7030 free_a_printer_driver(driver
, 3);
7033 *returned
+=ndrivers
;
7037 /* check the required size. */
7038 for (i
=0; i
<*returned
; i
++) {
7039 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7040 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
7043 if (*needed
> offered
) {
7044 result
= WERR_INSUFFICIENT_BUFFER
;
7048 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7049 result
= WERR_NOMEM
;
7053 /* fill the buffer with the form structures */
7054 for (i
=0; i
<*returned
; i
++) {
7055 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7056 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
7060 SAFE_FREE(driver_info_2
);
7062 if ( !W_ERROR_IS_OK(result
) )
7068 /****************************************************************************
7069 Enumerates all printer drivers at level 3.
7070 ****************************************************************************/
7072 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7077 fstring
*list
= NULL
;
7078 DRIVER_INFO_3
*driver_info_3
=NULL
;
7079 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7080 WERROR result
= WERR_OK
;
7084 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7086 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7087 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7089 if(ndrivers
== -1) {
7090 SAFE_FREE(driver_info_3
);
7095 if((driver_info_3
=SMB_REALLOC_ARRAY(driver_info_3
, DRIVER_INFO_3
, *returned
+ndrivers
)) == NULL
) {
7096 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7102 for (i
=0; i
<ndrivers
; i
++) {
7105 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7106 ZERO_STRUCT(driver
);
7107 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7108 architecture
, version
);
7109 if (!W_ERROR_IS_OK(status
)) {
7111 SAFE_FREE(driver_info_3
);
7114 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
7115 free_a_printer_driver(driver
, 3);
7118 *returned
+=ndrivers
;
7122 /* check the required size. */
7123 for (i
=0; i
<*returned
; i
++) {
7124 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7125 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
7128 if (*needed
> offered
) {
7129 result
= WERR_INSUFFICIENT_BUFFER
;
7133 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7134 result
= WERR_NOMEM
;
7138 /* fill the buffer with the driver structures */
7139 for (i
=0; i
<*returned
; i
++) {
7140 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7141 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
7145 for (i
=0; i
<*returned
; i
++) {
7146 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
7149 SAFE_FREE(driver_info_3
);
7151 if ( !W_ERROR_IS_OK(result
) )
7157 /****************************************************************************
7158 Enumerates all printer drivers.
7159 ****************************************************************************/
7161 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
7163 uint32 level
= q_u
->level
;
7164 RPC_BUFFER
*buffer
= NULL
;
7165 uint32 offered
= q_u
->offered
;
7166 uint32
*needed
= &r_u
->needed
;
7167 uint32
*returned
= &r_u
->returned
;
7170 fstring architecture
;
7172 /* that's an [in out] buffer */
7174 if (!q_u
->buffer
&& (offered
!=0)) {
7175 return WERR_INVALID_PARAM
;
7178 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7179 buffer
= r_u
->buffer
;
7181 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7186 unistr2_to_ascii(architecture
, &q_u
->environment
, sizeof(architecture
));
7187 unistr2_to_ascii(servername
, &q_u
->name
, sizeof(servername
));
7189 if ( !is_myname_or_ipaddr( servername
) )
7190 return WERR_UNKNOWN_PRINTER_DRIVER
;
7194 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
7196 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
7198 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
7200 return WERR_UNKNOWN_LEVEL
;
7204 /****************************************************************************
7205 ****************************************************************************/
7207 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
7209 form
->flag
=list
->flag
;
7210 init_unistr(&form
->name
, list
->name
);
7211 form
->width
=list
->width
;
7212 form
->length
=list
->length
;
7213 form
->left
=list
->left
;
7214 form
->top
=list
->top
;
7215 form
->right
=list
->right
;
7216 form
->bottom
=list
->bottom
;
7219 /****************************************************************************
7220 ****************************************************************************/
7222 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
7224 uint32 level
= q_u
->level
;
7225 RPC_BUFFER
*buffer
= NULL
;
7226 uint32 offered
= q_u
->offered
;
7227 uint32
*needed
= &r_u
->needed
;
7228 uint32
*numofforms
= &r_u
->numofforms
;
7229 uint32 numbuiltinforms
;
7231 nt_forms_struct
*list
=NULL
;
7232 nt_forms_struct
*builtinlist
=NULL
;
7237 /* that's an [in out] buffer */
7239 if (!q_u
->buffer
&& (offered
!=0) ) {
7240 return WERR_INVALID_PARAM
;
7243 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7244 buffer
= r_u
->buffer
;
7246 DEBUG(4,("_spoolss_enumforms\n"));
7247 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7248 DEBUGADD(5,("Info level [%d]\n", level
));
7250 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
7251 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
7252 *numofforms
= get_ntforms(&list
);
7253 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
7254 *numofforms
+= numbuiltinforms
;
7256 if (*numofforms
== 0) {
7257 SAFE_FREE(builtinlist
);
7259 return WERR_NO_MORE_ITEMS
;
7264 if ((forms_1
=SMB_MALLOC_ARRAY(FORM_1
, *numofforms
)) == NULL
) {
7265 SAFE_FREE(builtinlist
);
7271 /* construct the list of form structures */
7272 for (i
=0; i
<numbuiltinforms
; i
++) {
7273 DEBUGADD(6,("Filling form number [%d]\n",i
));
7274 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
7277 SAFE_FREE(builtinlist
);
7279 for (; i
<*numofforms
; i
++) {
7280 DEBUGADD(6,("Filling form number [%d]\n",i
));
7281 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
7286 /* check the required size. */
7287 for (i
=0; i
<numbuiltinforms
; i
++) {
7288 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7289 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7291 for (; i
<*numofforms
; i
++) {
7292 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7293 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7296 *needed
=buffer_size
;
7298 if (*needed
> offered
) {
7301 return WERR_INSUFFICIENT_BUFFER
;
7304 if (!rpcbuf_alloc_size(buffer
, buffer_size
)){
7310 /* fill the buffer with the form structures */
7311 for (i
=0; i
<numbuiltinforms
; i
++) {
7312 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7313 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7315 for (; i
<*numofforms
; i
++) {
7316 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7317 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7326 SAFE_FREE(builtinlist
);
7327 return WERR_UNKNOWN_LEVEL
;
7331 /****************************************************************************
7332 ****************************************************************************/
7334 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
7336 uint32 level
= q_u
->level
;
7337 UNISTR2
*uni_formname
= &q_u
->formname
;
7338 RPC_BUFFER
*buffer
= NULL
;
7339 uint32 offered
= q_u
->offered
;
7340 uint32
*needed
= &r_u
->needed
;
7342 nt_forms_struct
*list
=NULL
;
7343 nt_forms_struct builtin_form
;
7348 int numofforms
=0, i
=0;
7350 /* that's an [in out] buffer */
7352 if (!q_u
->buffer
&& (offered
!=0)) {
7353 return WERR_INVALID_PARAM
;
7356 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7357 buffer
= r_u
->buffer
;
7359 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
));
7361 DEBUG(4,("_spoolss_getform\n"));
7362 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7363 DEBUGADD(5,("Info level [%d]\n", level
));
7365 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
7366 if (!foundBuiltin
) {
7367 numofforms
= get_ntforms(&list
);
7368 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
7370 if (numofforms
== 0)
7377 fill_form_1(&form_1
, &builtin_form
);
7380 /* Check if the requested name is in the list of form structures */
7381 for (i
=0; i
<numofforms
; i
++) {
7383 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
7385 if (strequal(form_name
, list
[i
].name
)) {
7386 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
7387 fill_form_1(&form_1
, &list
[i
]);
7393 if (i
== numofforms
) {
7397 /* check the required size. */
7399 *needed
=spoolss_size_form_1(&form_1
);
7401 if (*needed
> offered
)
7402 return WERR_INSUFFICIENT_BUFFER
;
7404 if (!rpcbuf_alloc_size(buffer
, buffer_size
))
7407 /* fill the buffer with the form structures */
7408 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
7409 smb_io_form_1("", buffer
, &form_1
, 0);
7415 return WERR_UNKNOWN_LEVEL
;
7419 /****************************************************************************
7420 ****************************************************************************/
7422 static void fill_port_1(PORT_INFO_1
*port
, const char *name
)
7424 init_unistr(&port
->port_name
, name
);
7427 /****************************************************************************
7428 TODO: This probably needs distinguish between TCP/IP and Local ports
7430 ****************************************************************************/
7432 static void fill_port_2(PORT_INFO_2
*port
, const char *name
)
7434 init_unistr(&port
->port_name
, name
);
7435 init_unistr(&port
->monitor_name
, "Local Monitor");
7436 init_unistr(&port
->description
, SPL_LOCAL_PORT
);
7437 port
->port_type
=PORT_TYPE_WRITE
;
7442 /****************************************************************************
7443 wrapper around the enumer ports command
7444 ****************************************************************************/
7446 WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7448 char *cmd
= lp_enumports_cmd();
7449 char **qlines
= NULL
;
7450 char *command
= NULL
;
7458 /* if no hook then just fill in the default port */
7461 if (!(qlines
= SMB_MALLOC_ARRAY( char*, 2 ))) {
7464 if (!(qlines
[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME
))) {
7472 /* we have a valid enumport command */
7474 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7479 DEBUG(10,("Running [%s]\n", command
));
7480 ret
= smbrun(command
, &fd
);
7481 DEBUG(10,("Returned [%d]\n", ret
));
7482 TALLOC_FREE(command
);
7487 return WERR_ACCESS_DENIED
;
7491 qlines
= fd_lines_load(fd
, &numlines
, 0);
7492 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7502 /****************************************************************************
7504 ****************************************************************************/
7506 static WERROR
enumports_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7508 PORT_INFO_1
*ports
=NULL
;
7510 WERROR result
= WERR_OK
;
7511 char **qlines
= NULL
;
7514 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7515 if (!W_ERROR_IS_OK(result
)) {
7516 file_lines_free(qlines
);
7521 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_1
, numlines
)) == NULL
) {
7522 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7523 dos_errstr(WERR_NOMEM
)));
7524 file_lines_free(qlines
);
7528 for (i
=0; i
<numlines
; i
++) {
7529 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7530 fill_port_1(&ports
[i
], qlines
[i
]);
7533 file_lines_free(qlines
);
7535 *returned
= numlines
;
7537 /* check the required size. */
7538 for (i
=0; i
<*returned
; i
++) {
7539 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7540 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
7543 if (*needed
> offered
) {
7544 result
= WERR_INSUFFICIENT_BUFFER
;
7548 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7549 result
= WERR_NOMEM
;
7553 /* fill the buffer with the ports structures */
7554 for (i
=0; i
<*returned
; i
++) {
7555 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7556 smb_io_port_1("", buffer
, &ports
[i
], 0);
7562 if ( !W_ERROR_IS_OK(result
) )
7568 /****************************************************************************
7570 ****************************************************************************/
7572 static WERROR
enumports_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7574 PORT_INFO_2
*ports
=NULL
;
7576 WERROR result
= WERR_OK
;
7577 char **qlines
= NULL
;
7580 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7581 if ( !W_ERROR_IS_OK(result
)) {
7582 file_lines_free(qlines
);
7587 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_2
, numlines
)) == NULL
) {
7588 file_lines_free(qlines
);
7592 for (i
=0; i
<numlines
; i
++) {
7593 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7594 fill_port_2(&(ports
[i
]), qlines
[i
]);
7598 file_lines_free(qlines
);
7600 *returned
= numlines
;
7602 /* check the required size. */
7603 for (i
=0; i
<*returned
; i
++) {
7604 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7605 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
7608 if (*needed
> offered
) {
7609 result
= WERR_INSUFFICIENT_BUFFER
;
7613 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7614 result
= WERR_NOMEM
;
7618 /* fill the buffer with the ports structures */
7619 for (i
=0; i
<*returned
; i
++) {
7620 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7621 smb_io_port_2("", buffer
, &ports
[i
], 0);
7627 if ( !W_ERROR_IS_OK(result
) )
7633 /****************************************************************************
7635 ****************************************************************************/
7637 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
7639 uint32 level
= q_u
->level
;
7640 RPC_BUFFER
*buffer
= NULL
;
7641 uint32 offered
= q_u
->offered
;
7642 uint32
*needed
= &r_u
->needed
;
7643 uint32
*returned
= &r_u
->returned
;
7645 /* that's an [in out] buffer */
7647 if (!q_u
->buffer
&& (offered
!=0)) {
7648 return WERR_INVALID_PARAM
;
7651 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7652 buffer
= r_u
->buffer
;
7654 DEBUG(4,("_spoolss_enumports\n"));
7661 return enumports_level_1(buffer
, offered
, needed
, returned
);
7663 return enumports_level_2(buffer
, offered
, needed
, returned
);
7665 return WERR_UNKNOWN_LEVEL
;
7669 /****************************************************************************
7670 ****************************************************************************/
7672 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
7673 const SPOOL_PRINTER_INFO_LEVEL
*info
,
7674 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
7675 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
7678 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7681 WERROR err
= WERR_OK
;
7683 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7684 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7688 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7689 if (!convert_printer_info(info
, printer
, 2)) {
7690 free_a_printer(&printer
, 2);
7694 /* check to see if the printer already exists */
7696 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7697 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7698 printer
->info_2
->sharename
));
7699 free_a_printer(&printer
, 2);
7700 return WERR_PRINTER_ALREADY_EXISTS
;
7703 /* FIXME!!! smbd should check to see if the driver is installed before
7704 trying to add a printer like this --jerry */
7706 if (*lp_addprinter_cmd() ) {
7707 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
7708 free_a_printer(&printer
,2);
7709 return WERR_ACCESS_DENIED
;
7712 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7713 "smb.conf parameter \"addprinter command\" is defined. This"
7714 "parameter must exist for this call to succeed\n",
7715 printer
->info_2
->sharename
));
7718 /* use our primary netbios name since get_a_printer() will convert
7719 it to what the client expects on a case by case basis */
7721 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7722 printer
->info_2
->sharename
);
7725 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7726 free_a_printer(&printer
,2);
7727 return WERR_ACCESS_DENIED
;
7730 /* you must be a printer admin to add a new printer */
7731 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7732 free_a_printer(&printer
,2);
7733 return WERR_ACCESS_DENIED
;
7737 * Do sanity check on the requested changes for Samba.
7740 if (!check_printer_ok(printer
->info_2
, snum
)) {
7741 free_a_printer(&printer
,2);
7742 return WERR_INVALID_PARAM
;
7746 * When a printer is created, the drivername bound to the printer is used
7747 * to lookup previously saved driver initialization info, which is then
7748 * bound to the new printer, simulating what happens in the Windows arch.
7753 set_driver_init(printer
, 2);
7757 /* A valid devmode was included, convert and link it
7759 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7761 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
7762 &printer
->info_2
->devmode
))
7766 /* write the ASCII on disk */
7767 err
= mod_a_printer(printer
, 2);
7768 if (!W_ERROR_IS_OK(err
)) {
7769 free_a_printer(&printer
,2);
7773 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7774 /* Handle open failed - remove addition. */
7775 del_a_printer(printer
->info_2
->sharename
);
7776 free_a_printer(&printer
,2);
7777 return WERR_ACCESS_DENIED
;
7780 update_c_setprinter(False
);
7781 free_a_printer(&printer
,2);
7786 /****************************************************************************
7787 ****************************************************************************/
7789 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
7791 UNISTR2
*uni_srv_name
= q_u
->server_name
;
7792 uint32 level
= q_u
->level
;
7793 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
7794 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
7795 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
7796 uint32 user_switch
= q_u
->user_switch
;
7797 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
7798 POLICY_HND
*handle
= &r_u
->handle
;
7802 /* we don't handle yet */
7803 /* but I know what to do ... */
7804 return WERR_UNKNOWN_LEVEL
;
7806 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
7808 user_switch
, user
, handle
);
7810 return WERR_UNKNOWN_LEVEL
;
7814 /****************************************************************************
7815 ****************************************************************************/
7817 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
7819 uint32 level
= q_u
->level
;
7820 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
7821 WERROR err
= WERR_OK
;
7822 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7823 fstring driver_name
;
7826 ZERO_STRUCT(driver
);
7828 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7833 DEBUG(5,("Cleaning driver's information\n"));
7834 err
= clean_up_driver_struct(driver
, level
, &p
->pipe_user
);
7835 if (!W_ERROR_IS_OK(err
))
7838 DEBUG(5,("Moving driver to final destination\n"));
7839 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(driver
, level
, &p
->pipe_user
, &err
)) ) {
7843 if (add_a_printer_driver(driver
, level
)!=0) {
7844 err
= WERR_ACCESS_DENIED
;
7849 * I think this is where he DrvUpgradePrinter() hook would be
7850 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7851 * server. Right now, we just need to send ourselves a message
7852 * to update each printer bound to this driver. --jerry
7855 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7856 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7861 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7862 * decide if the driver init data should be deleted. The rules are:
7863 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7864 * 2) delete init data only if there is no 2k/Xp driver
7865 * 3) always delete init data
7866 * The generalized rule is always use init data from the highest order driver.
7867 * It is necessary to follow the driver install by an initialization step to
7868 * finish off this process.
7871 version
= driver
.info_3
->cversion
;
7872 else if (level
== 6)
7873 version
= driver
.info_6
->version
;
7878 * 9x printer driver - never delete init data
7881 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7886 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7887 * there is no 2k/Xp driver init data for this driver name.
7891 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7893 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7895 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7897 if (!del_driver_init(driver_name
))
7898 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name
));
7901 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7903 free_a_printer_driver(driver1
,3);
7904 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7911 * 2k or Xp printer driver - always delete init data
7914 if (!del_driver_init(driver_name
))
7915 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name
));
7919 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level
));
7925 free_a_printer_driver(driver
, level
);
7929 /********************************************************************
7930 * spoolss_addprinterdriverex
7931 ********************************************************************/
7933 WERROR
_spoolss_addprinterdriverex(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVEREX
*q_u
, SPOOL_R_ADDPRINTERDRIVEREX
*r_u
)
7935 SPOOL_Q_ADDPRINTERDRIVER q_u_local
;
7936 SPOOL_R_ADDPRINTERDRIVER r_u_local
;
7939 * we only support the semantics of AddPrinterDriver()
7940 * i.e. only copy files that are newer than existing ones
7943 if ( q_u
->copy_flags
!= APD_COPY_NEW_FILES
)
7944 return WERR_ACCESS_DENIED
;
7946 ZERO_STRUCT(q_u_local
);
7947 ZERO_STRUCT(r_u_local
);
7949 /* just pass the information off to _spoolss_addprinterdriver() */
7950 q_u_local
.server_name_ptr
= q_u
->server_name_ptr
;
7951 copy_unistr2(&q_u_local
.server_name
, &q_u
->server_name
);
7952 q_u_local
.level
= q_u
->level
;
7953 memcpy( &q_u_local
.info
, &q_u
->info
, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL
) );
7955 return _spoolss_addprinterdriver( p
, &q_u_local
, &r_u_local
);
7958 /****************************************************************************
7959 ****************************************************************************/
7961 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
7963 init_unistr(&info
->name
, name
);
7966 /****************************************************************************
7967 ****************************************************************************/
7969 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
7972 char *long_archi
= NULL
;
7973 char *servername
= NULL
;
7974 char *pservername
= NULL
;
7975 const char *short_archi
;
7976 DRIVER_DIRECTORY_1
*info
=NULL
;
7977 WERROR result
= WERR_OK
;
7978 TALLOC_CTX
*ctx
= talloc_tos();
7980 servername
= unistr2_to_ascii_talloc(ctx
, name
);
7984 long_archi
= unistr2_to_ascii_talloc(ctx
, uni_environment
);
7989 /* check for beginning double '\'s and that the server
7992 pservername
= servername
;
7993 if ( *pservername
== '\\' && strlen(servername
)>2 ) {
7997 if ( !is_myname_or_ipaddr( pservername
) )
7998 return WERR_INVALID_PARAM
;
8000 if (!(short_archi
= get_short_archi(long_archi
)))
8001 return WERR_INVALID_ENVIRONMENT
;
8003 if((info
=SMB_MALLOC_P(DRIVER_DIRECTORY_1
)) == NULL
)
8006 path
= talloc_asprintf(ctx
,
8007 "\\\\%s\\print$\\%s", pservername
, short_archi
);
8009 result
= WERR_NOMEM
;
8013 DEBUG(4,("printer driver directory: [%s]\n", path
));
8015 fill_driverdir_1(info
, path
);
8017 *needed
+= spoolss_size_driverdir_info_1(info
);
8019 if (*needed
> offered
) {
8020 result
= WERR_INSUFFICIENT_BUFFER
;
8024 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8025 result
= WERR_NOMEM
;
8029 smb_io_driverdir_1("", buffer
, info
, 0);
8037 /****************************************************************************
8038 ****************************************************************************/
8040 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
8042 UNISTR2
*name
= &q_u
->name
;
8043 UNISTR2
*uni_environment
= &q_u
->environment
;
8044 uint32 level
= q_u
->level
;
8045 RPC_BUFFER
*buffer
= NULL
;
8046 uint32 offered
= q_u
->offered
;
8047 uint32
*needed
= &r_u
->needed
;
8049 /* that's an [in out] buffer */
8051 if (!q_u
->buffer
&& (offered
!=0)) {
8052 return WERR_INVALID_PARAM
;
8055 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8056 buffer
= r_u
->buffer
;
8058 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8064 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
8066 return WERR_UNKNOWN_LEVEL
;
8070 /****************************************************************************
8071 ****************************************************************************/
8073 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
8075 POLICY_HND
*handle
= &q_u
->handle
;
8076 uint32 idx
= q_u
->index
;
8077 uint32 in_value_len
= q_u
->valuesize
;
8078 uint32 in_data_len
= q_u
->datasize
;
8079 uint32
*out_max_value_len
= &r_u
->valuesize
;
8080 uint16
**out_value
= &r_u
->value
;
8081 uint32
*out_value_len
= &r_u
->realvaluesize
;
8082 uint32
*out_type
= &r_u
->type
;
8083 uint32
*out_max_data_len
= &r_u
->datasize
;
8084 uint8
**data_out
= &r_u
->data
;
8085 uint32
*out_data_len
= &r_u
->realdatasize
;
8087 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8089 uint32 biggest_valuesize
;
8090 uint32 biggest_datasize
;
8092 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8095 REGISTRY_VALUE
*val
= NULL
;
8096 NT_PRINTER_DATA
*p_data
;
8097 int i
, key_index
, num_values
;
8102 *out_max_data_len
= 0;
8106 DEBUG(5,("spoolss_enumprinterdata\n"));
8109 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8113 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8116 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8117 if (!W_ERROR_IS_OK(result
))
8120 p_data
= printer
->info_2
->data
;
8121 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8126 * The NT machine wants to know the biggest size of value and data
8128 * cf: MSDN EnumPrinterData remark section
8131 if ( !in_value_len
&& !in_data_len
&& (key_index
!= -1) )
8133 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8135 biggest_valuesize
= 0;
8136 biggest_datasize
= 0;
8138 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8140 for ( i
=0; i
<num_values
; i
++ )
8142 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8144 name_length
= strlen(val
->valuename
);
8145 if ( strlen(val
->valuename
) > biggest_valuesize
)
8146 biggest_valuesize
= name_length
;
8148 if ( val
->size
> biggest_datasize
)
8149 biggest_datasize
= val
->size
;
8151 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8155 /* the value is an UNICODE string but real_value_size is the length
8156 in bytes including the trailing 0 */
8158 *out_value_len
= 2 * (1+biggest_valuesize
);
8159 *out_data_len
= biggest_datasize
;
8161 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
8167 * the value len is wrong in NT sp3
8168 * that's the number of bytes not the number of unicode chars
8171 if ( key_index
!= -1 )
8172 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, idx
);
8177 /* out_value should default to "" or else NT4 has
8178 problems unmarshalling the response */
8180 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8183 if((*out_value
=(uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8185 result
= WERR_NOMEM
;
8188 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
8194 /* the data is counted in bytes */
8196 *out_max_data_len
= in_data_len
;
8197 *out_data_len
= in_data_len
;
8199 /* only allocate when given a non-zero data_len */
8201 if ( in_data_len
&& ((*data_out
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
8203 result
= WERR_NOMEM
;
8207 result
= WERR_NO_MORE_ITEMS
;
8213 * - counted in bytes in the request
8214 * - counted in UNICODE chars in the max reply
8215 * - counted in bytes in the real size
8217 * take a pause *before* coding not *during* coding
8221 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8223 if ( (*out_value
= (uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8225 result
= WERR_NOMEM
;
8229 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), (size_t)in_value_len
, 0);
8237 *out_type
= regval_type( val
);
8239 /* data - counted in bytes */
8241 *out_max_data_len
= in_data_len
;
8242 if ( in_data_len
&& (*data_out
= (uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
8244 result
= WERR_NOMEM
;
8247 data_len
= regval_size(val
);
8248 if ( *data_out
&& data_len
)
8249 memcpy( *data_out
, regval_data_p(val
), data_len
);
8250 *out_data_len
= data_len
;
8254 free_a_printer(&printer
, 2);
8258 /****************************************************************************
8259 ****************************************************************************/
8261 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
8263 POLICY_HND
*handle
= &q_u
->handle
;
8264 UNISTR2
*value
= &q_u
->value
;
8265 uint32 type
= q_u
->type
;
8266 uint8
*data
= q_u
->data
;
8267 uint32 real_len
= q_u
->real_len
;
8269 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8271 WERROR status
= WERR_OK
;
8272 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8275 DEBUG(5,("spoolss_setprinterdata\n"));
8278 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8282 if ( Printer
->printer_type
== SPLHND_SERVER
) {
8283 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8284 return WERR_INVALID_PARAM
;
8287 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8291 * Access check : NT returns "access denied" if you make a
8292 * SetPrinterData call without the necessary privildge.
8293 * we were originally returning OK if nothing changed
8294 * which made Win2k issue **a lot** of SetPrinterData
8295 * when connecting to a printer --jerry
8298 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8300 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8301 status
= WERR_ACCESS_DENIED
;
8305 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8306 if (!W_ERROR_IS_OK(status
))
8309 unistr2_to_ascii(valuename
, value
, sizeof(valuename
));
8312 * When client side code sets a magic printer data key, detect it and save
8313 * the current printer data and the magic key's data (its the DEVMODE) for
8314 * future printer/driver initializations.
8316 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
8318 /* Set devmode and printer initialization info */
8319 status
= save_driver_init( printer
, 2, data
, real_len
);
8321 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
8325 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
8326 type
, data
, real_len
);
8327 if ( W_ERROR_IS_OK(status
) )
8328 status
= mod_a_printer(printer
, 2);
8332 free_a_printer(&printer
, 2);
8337 /****************************************************************************
8338 ****************************************************************************/
8340 WERROR
_spoolss_resetprinter(pipes_struct
*p
, SPOOL_Q_RESETPRINTER
*q_u
, SPOOL_R_RESETPRINTER
*r_u
)
8342 POLICY_HND
*handle
= &q_u
->handle
;
8343 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8346 DEBUG(5,("_spoolss_resetprinter\n"));
8349 * All we do is to check to see if the handle and queue is valid.
8350 * This call really doesn't mean anything to us because we only
8351 * support RAW printing. --jerry
8355 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8359 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8363 /* blindly return success */
8368 /****************************************************************************
8369 ****************************************************************************/
8371 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
8373 POLICY_HND
*handle
= &q_u
->handle
;
8374 UNISTR2
*value
= &q_u
->valuename
;
8376 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8378 WERROR status
= WERR_OK
;
8379 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8380 char *valuename
= NULL
;
8381 TALLOC_CTX
*ctx
= p
->mem_ctx
;
8383 DEBUG(5,("spoolss_deleteprinterdata\n"));
8386 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8390 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
8393 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8394 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
8395 return WERR_ACCESS_DENIED
;
8398 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8399 if (!W_ERROR_IS_OK(status
))
8402 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
8404 free_a_printer(&printer
, 2);
8408 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
);
8410 if ( W_ERROR_IS_OK(status
) )
8411 mod_a_printer( printer
, 2 );
8413 free_a_printer(&printer
, 2);
8414 TALLOC_FREE(valuename
);
8419 /****************************************************************************
8420 ****************************************************************************/
8422 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
8424 POLICY_HND
*handle
= &q_u
->handle
;
8425 FORM
*form
= &q_u
->form
;
8426 nt_forms_struct tmpForm
;
8428 WERROR status
= WERR_OK
;
8429 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8432 nt_forms_struct
*list
=NULL
;
8433 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8435 DEBUG(5,("spoolss_addform\n"));
8438 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8443 /* forms can be added on printer of on the print server handle */
8445 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8447 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8450 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8451 if (!W_ERROR_IS_OK(status
))
8455 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8456 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8457 status
= WERR_ACCESS_DENIED
;
8461 /* can't add if builtin */
8463 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8464 status
= WERR_ALREADY_EXISTS
;
8468 count
= get_ntforms(&list
);
8470 if(!add_a_form(&list
, form
, &count
)) {
8471 status
= WERR_NOMEM
;
8475 write_ntforms(&list
, count
);
8478 * ChangeID must always be set if this is a printer
8481 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8482 status
= mod_a_printer(printer
, 2);
8486 free_a_printer(&printer
, 2);
8492 /****************************************************************************
8493 ****************************************************************************/
8495 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
8497 POLICY_HND
*handle
= &q_u
->handle
;
8498 UNISTR2
*form_name
= &q_u
->name
;
8499 nt_forms_struct tmpForm
;
8501 nt_forms_struct
*list
=NULL
;
8502 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8504 WERROR status
= WERR_OK
;
8505 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8507 DEBUG(5,("spoolss_deleteform\n"));
8510 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8514 /* forms can be deleted on printer of on the print server handle */
8516 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8518 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8521 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8522 if (!W_ERROR_IS_OK(status
))
8526 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8527 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n"));
8528 status
= WERR_ACCESS_DENIED
;
8532 /* can't delete if builtin */
8534 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
8535 status
= WERR_INVALID_PARAM
;
8539 count
= get_ntforms(&list
);
8541 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
8545 * ChangeID must always be set if this is a printer
8548 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8549 status
= mod_a_printer(printer
, 2);
8553 free_a_printer(&printer
, 2);
8559 /****************************************************************************
8560 ****************************************************************************/
8562 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
8564 POLICY_HND
*handle
= &q_u
->handle
;
8565 FORM
*form
= &q_u
->form
;
8566 nt_forms_struct tmpForm
;
8568 WERROR status
= WERR_OK
;
8569 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8572 nt_forms_struct
*list
=NULL
;
8573 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8575 DEBUG(5,("spoolss_setform\n"));
8578 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8582 /* forms can be modified on printer of on the print server handle */
8584 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8586 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8589 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8590 if (!W_ERROR_IS_OK(status
))
8594 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8595 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
8596 status
= WERR_ACCESS_DENIED
;
8600 /* can't set if builtin */
8601 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8602 status
= WERR_INVALID_PARAM
;
8606 count
= get_ntforms(&list
);
8607 update_a_form(&list
, form
, count
);
8608 write_ntforms(&list
, count
);
8611 * ChangeID must always be set if this is a printer
8614 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8615 status
= mod_a_printer(printer
, 2);
8620 free_a_printer(&printer
, 2);
8626 /****************************************************************************
8627 enumprintprocessors level 1.
8628 ****************************************************************************/
8630 static WERROR
enumprintprocessors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8632 PRINTPROCESSOR_1
*info_1
=NULL
;
8633 WERROR result
= WERR_OK
;
8635 if((info_1
= SMB_MALLOC_P(PRINTPROCESSOR_1
)) == NULL
)
8640 init_unistr(&info_1
->name
, "winprint");
8642 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
8644 if (*needed
> offered
) {
8645 result
= WERR_INSUFFICIENT_BUFFER
;
8649 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8650 result
= WERR_NOMEM
;
8654 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
8659 if ( !W_ERROR_IS_OK(result
) )
8665 /****************************************************************************
8666 ****************************************************************************/
8668 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
8670 uint32 level
= q_u
->level
;
8671 RPC_BUFFER
*buffer
= NULL
;
8672 uint32 offered
= q_u
->offered
;
8673 uint32
*needed
= &r_u
->needed
;
8674 uint32
*returned
= &r_u
->returned
;
8676 /* that's an [in out] buffer */
8678 if (!q_u
->buffer
&& (offered
!=0)) {
8679 return WERR_INVALID_PARAM
;
8682 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8683 buffer
= r_u
->buffer
;
8685 DEBUG(5,("spoolss_enumprintprocessors\n"));
8688 * Enumerate the print processors ...
8690 * Just reply with "winprint", to keep NT happy
8691 * and I can use my nice printer checker.
8699 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
8701 return WERR_UNKNOWN_LEVEL
;
8705 /****************************************************************************
8706 enumprintprocdatatypes level 1.
8707 ****************************************************************************/
8709 static WERROR
enumprintprocdatatypes_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8711 PRINTPROCDATATYPE_1
*info_1
=NULL
;
8712 WERROR result
= WERR_OK
;
8714 if((info_1
= SMB_MALLOC_P(PRINTPROCDATATYPE_1
)) == NULL
)
8719 init_unistr(&info_1
->name
, "RAW");
8721 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
8723 if (*needed
> offered
) {
8724 result
= WERR_INSUFFICIENT_BUFFER
;
8728 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8729 result
= WERR_NOMEM
;
8733 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
8738 if ( !W_ERROR_IS_OK(result
) )
8744 /****************************************************************************
8745 ****************************************************************************/
8747 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
8749 uint32 level
= q_u
->level
;
8750 RPC_BUFFER
*buffer
= NULL
;
8751 uint32 offered
= q_u
->offered
;
8752 uint32
*needed
= &r_u
->needed
;
8753 uint32
*returned
= &r_u
->returned
;
8755 /* that's an [in out] buffer */
8757 if (!q_u
->buffer
&& (offered
!=0)) {
8758 return WERR_INVALID_PARAM
;
8761 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8762 buffer
= r_u
->buffer
;
8764 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8771 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
8773 return WERR_UNKNOWN_LEVEL
;
8777 /****************************************************************************
8778 enumprintmonitors level 1.
8779 ****************************************************************************/
8781 static WERROR
enumprintmonitors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8783 PRINTMONITOR_1
*info_1
;
8784 WERROR result
= WERR_OK
;
8787 if((info_1
= SMB_MALLOC_ARRAY(PRINTMONITOR_1
, 2)) == NULL
)
8792 init_unistr(&(info_1
[0].name
), SPL_LOCAL_PORT
);
8793 init_unistr(&(info_1
[1].name
), SPL_TCPIP_PORT
);
8795 for ( i
=0; i
<*returned
; i
++ ) {
8796 *needed
+= spoolss_size_printmonitor_info_1(&info_1
[i
]);
8799 if (*needed
> offered
) {
8800 result
= WERR_INSUFFICIENT_BUFFER
;
8804 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8805 result
= WERR_NOMEM
;
8809 for ( i
=0; i
<*returned
; i
++ ) {
8810 smb_io_printmonitor_info_1("", buffer
, &info_1
[i
], 0);
8816 if ( !W_ERROR_IS_OK(result
) )
8822 /****************************************************************************
8823 enumprintmonitors level 2.
8824 ****************************************************************************/
8826 static WERROR
enumprintmonitors_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8828 PRINTMONITOR_2
*info_2
;
8829 WERROR result
= WERR_OK
;
8832 if((info_2
= SMB_MALLOC_ARRAY(PRINTMONITOR_2
, 2)) == NULL
)
8837 init_unistr( &(info_2
[0].name
), SPL_LOCAL_PORT
);
8838 init_unistr( &(info_2
[0].environment
), "Windows NT X86" );
8839 init_unistr( &(info_2
[0].dll_name
), "localmon.dll" );
8841 init_unistr( &(info_2
[1].name
), SPL_TCPIP_PORT
);
8842 init_unistr( &(info_2
[1].environment
), "Windows NT X86" );
8843 init_unistr( &(info_2
[1].dll_name
), "tcpmon.dll" );
8845 for ( i
=0; i
<*returned
; i
++ ) {
8846 *needed
+= spoolss_size_printmonitor_info_2(&info_2
[i
]);
8849 if (*needed
> offered
) {
8850 result
= WERR_INSUFFICIENT_BUFFER
;
8854 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8855 result
= WERR_NOMEM
;
8859 for ( i
=0; i
<*returned
; i
++ ) {
8860 smb_io_printmonitor_info_2("", buffer
, &info_2
[i
], 0);
8866 if ( !W_ERROR_IS_OK(result
) )
8872 /****************************************************************************
8873 ****************************************************************************/
8875 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
8877 uint32 level
= q_u
->level
;
8878 RPC_BUFFER
*buffer
= NULL
;
8879 uint32 offered
= q_u
->offered
;
8880 uint32
*needed
= &r_u
->needed
;
8881 uint32
*returned
= &r_u
->returned
;
8883 /* that's an [in out] buffer */
8885 if (!q_u
->buffer
&& (offered
!=0)) {
8886 return WERR_INVALID_PARAM
;
8889 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8890 buffer
= r_u
->buffer
;
8892 DEBUG(5,("spoolss_enumprintmonitors\n"));
8895 * Enumerate the print monitors ...
8897 * Just reply with "Local Port", to keep NT happy
8898 * and I can use my nice printer checker.
8906 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
8908 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
8910 return WERR_UNKNOWN_LEVEL
;
8914 /****************************************************************************
8915 ****************************************************************************/
8917 static WERROR
getjob_level_1(print_queue_struct
**queue
, int count
, int snum
,
8918 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8919 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8924 JOB_INFO_1
*info_1
=NULL
;
8925 WERROR result
= WERR_OK
;
8927 info_1
=SMB_MALLOC_P(JOB_INFO_1
);
8929 if (info_1
== NULL
) {
8933 for (i
=0; i
<count
&& found
==False
; i
++) {
8934 if ((*queue
)[i
].job
==(int)jobid
)
8940 /* NT treats not found as bad param... yet another bad choice */
8941 return WERR_INVALID_PARAM
;
8944 fill_job_info_1( info_1
, &((*queue
)[i
-1]), i
, snum
, ntprinter
);
8946 *needed
+= spoolss_size_job_info_1(info_1
);
8948 if (*needed
> offered
) {
8949 result
= WERR_INSUFFICIENT_BUFFER
;
8953 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8954 result
= WERR_NOMEM
;
8958 smb_io_job_info_1("", buffer
, info_1
, 0);
8966 /****************************************************************************
8967 ****************************************************************************/
8969 static WERROR
getjob_level_2(print_queue_struct
**queue
, int count
, int snum
,
8970 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8971 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8978 DEVICEMODE
*devmode
= NULL
;
8979 NT_DEVICEMODE
*nt_devmode
= NULL
;
8981 if ( !(info_2
=SMB_MALLOC_P(JOB_INFO_2
)) )
8984 ZERO_STRUCTP(info_2
);
8986 for ( i
=0; i
<count
&& found
==False
; i
++ )
8988 if ((*queue
)[i
].job
== (int)jobid
)
8993 /* NT treats not found as bad param... yet another bad
8995 result
= WERR_INVALID_PARAM
;
9000 * if the print job does not have a DEVMODE associated with it,
9001 * just use the one for the printer. A NULL devicemode is not
9002 * a failure condition
9005 if ( !(nt_devmode
=print_job_devmode( lp_const_servicename(snum
), jobid
)) )
9006 devmode
= construct_dev_mode(lp_const_servicename(snum
));
9008 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) != NULL
) {
9009 ZERO_STRUCTP( devmode
);
9010 convert_nt_devicemode( devmode
, nt_devmode
);
9014 fill_job_info_2(info_2
, &((*queue
)[i
-1]), i
, snum
, ntprinter
, devmode
);
9016 *needed
+= spoolss_size_job_info_2(info_2
);
9018 if (*needed
> offered
) {
9019 result
= WERR_INSUFFICIENT_BUFFER
;
9023 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9024 result
= WERR_NOMEM
;
9028 smb_io_job_info_2("", buffer
, info_2
, 0);
9033 /* Cleanup allocated memory */
9035 free_job_info_2(info_2
); /* Also frees devmode */
9041 /****************************************************************************
9042 ****************************************************************************/
9044 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
9046 POLICY_HND
*handle
= &q_u
->handle
;
9047 uint32 jobid
= q_u
->jobid
;
9048 uint32 level
= q_u
->level
;
9049 RPC_BUFFER
*buffer
= NULL
;
9050 uint32 offered
= q_u
->offered
;
9051 uint32
*needed
= &r_u
->needed
;
9052 WERROR wstatus
= WERR_OK
;
9053 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9056 print_queue_struct
*queue
= NULL
;
9057 print_status_struct prt_status
;
9059 /* that's an [in out] buffer */
9061 if (!q_u
->buffer
&& (offered
!=0)) {
9062 return WERR_INVALID_PARAM
;
9065 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9066 buffer
= r_u
->buffer
;
9068 DEBUG(5,("spoolss_getjob\n"));
9072 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9075 wstatus
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9076 if ( !W_ERROR_IS_OK(wstatus
) )
9079 count
= print_queue_status(snum
, &queue
, &prt_status
);
9081 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9082 count
, prt_status
.status
, prt_status
.message
));
9086 wstatus
= getjob_level_1(&queue
, count
, snum
, ntprinter
, jobid
,
9087 buffer
, offered
, needed
);
9090 wstatus
= getjob_level_2(&queue
, count
, snum
, ntprinter
, jobid
,
9091 buffer
, offered
, needed
);
9094 wstatus
= WERR_UNKNOWN_LEVEL
;
9099 free_a_printer( &ntprinter
, 2 );
9104 /********************************************************************
9105 spoolss_getprinterdataex
9107 From MSDN documentation of GetPrinterDataEx: pass request
9108 to GetPrinterData if key is "PrinterDriverData".
9109 ********************************************************************/
9111 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
9113 POLICY_HND
*handle
= &q_u
->handle
;
9114 uint32 in_size
= q_u
->size
;
9115 uint32
*type
= &r_u
->type
;
9116 uint32
*out_size
= &r_u
->size
;
9117 uint8
**data
= &r_u
->data
;
9118 uint32
*needed
= &r_u
->needed
;
9119 fstring keyname
, valuename
;
9121 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9123 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9125 WERROR status
= WERR_OK
;
9127 DEBUG(4,("_spoolss_getprinterdataex\n"));
9129 unistr2_to_ascii(keyname
, &q_u
->keyname
, sizeof(keyname
));
9130 unistr2_to_ascii(valuename
, &q_u
->valuename
, sizeof(valuename
));
9132 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9133 keyname
, valuename
));
9135 /* in case of problem, return some default values */
9139 *out_size
= in_size
;
9142 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9143 status
= WERR_BADFID
;
9147 /* Is the handle to a printer or to the server? */
9149 if (Printer
->printer_type
== SPLHND_SERVER
) {
9150 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9151 status
= WERR_INVALID_PARAM
;
9155 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9158 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9159 if ( !W_ERROR_IS_OK(status
) )
9162 /* check to see if the keyname is valid */
9163 if ( !strlen(keyname
) ) {
9164 status
= WERR_INVALID_PARAM
;
9168 if ( lookup_printerkey( printer
->info_2
->data
, keyname
) == -1 ) {
9169 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname
));
9170 free_a_printer( &printer
, 2 );
9171 status
= WERR_BADFILE
;
9175 /* When given a new keyname, we should just create it */
9177 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
, type
, data
, needed
, in_size
);
9179 if (*needed
> *out_size
)
9180 status
= WERR_MORE_DATA
;
9183 if ( !W_ERROR_IS_OK(status
) )
9185 DEBUG(5, ("error: allocating %d\n", *out_size
));
9187 /* reply this param doesn't exist */
9191 if( (*data
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
) {
9192 status
= WERR_NOMEM
;
9201 free_a_printer( &printer
, 2 );
9206 /********************************************************************
9207 * spoolss_setprinterdataex
9208 ********************************************************************/
9210 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
9212 POLICY_HND
*handle
= &q_u
->handle
;
9213 uint32 type
= q_u
->type
;
9214 uint8
*data
= q_u
->data
;
9215 uint32 real_len
= q_u
->real_len
;
9217 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9219 WERROR status
= WERR_OK
;
9220 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9225 DEBUG(4,("_spoolss_setprinterdataex\n"));
9227 /* From MSDN documentation of SetPrinterDataEx: pass request to
9228 SetPrinterData if key is "PrinterDriverData" */
9231 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9235 if ( Printer
->printer_type
== SPLHND_SERVER
) {
9236 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9237 return WERR_INVALID_PARAM
;
9240 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9244 * Access check : NT returns "access denied" if you make a
9245 * SetPrinterData call without the necessary privildge.
9246 * we were originally returning OK if nothing changed
9247 * which made Win2k issue **a lot** of SetPrinterData
9248 * when connecting to a printer --jerry
9251 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
9253 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9254 return WERR_ACCESS_DENIED
;
9257 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9258 if (!W_ERROR_IS_OK(status
))
9261 unistr2_to_ascii( valuename
, &q_u
->value
, sizeof(valuename
));
9262 unistr2_to_ascii( keyname
, &q_u
->key
, sizeof(keyname
));
9264 /* check for OID in valuename */
9266 if ( (oid_string
= strchr( valuename
, ',' )) != NULL
)
9272 /* save the registry data */
9274 status
= set_printer_dataex( printer
, keyname
, valuename
, type
, data
, real_len
);
9276 if ( W_ERROR_IS_OK(status
) )
9278 /* save the OID if one was specified */
9280 fstrcat( keyname
, "\\" );
9281 fstrcat( keyname
, SPOOL_OID_KEY
);
9284 * I'm not checking the status here on purpose. Don't know
9285 * if this is right, but I'm returning the status from the
9286 * previous set_printer_dataex() call. I have no idea if
9287 * this is right. --jerry
9290 set_printer_dataex( printer
, keyname
, valuename
,
9291 REG_SZ
, (uint8
*)oid_string
,
9292 strlen(oid_string
)+1 );
9295 status
= mod_a_printer(printer
, 2);
9298 free_a_printer(&printer
, 2);
9304 /********************************************************************
9305 * spoolss_deleteprinterdataex
9306 ********************************************************************/
9308 WERROR
_spoolss_deleteprinterdataex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATAEX
*q_u
, SPOOL_R_DELETEPRINTERDATAEX
*r_u
)
9310 POLICY_HND
*handle
= &q_u
->handle
;
9311 UNISTR2
*value
= &q_u
->valuename
;
9312 UNISTR2
*key
= &q_u
->keyname
;
9314 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9316 WERROR status
= WERR_OK
;
9317 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
9318 char *valuename
= NULL
;
9319 char *keyname
= NULL
;
9320 TALLOC_CTX
*ctx
= p
->mem_ctx
;
9322 DEBUG(5,("spoolss_deleteprinterdataex\n"));
9325 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9329 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9332 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9333 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
9334 return WERR_ACCESS_DENIED
;
9337 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
9338 keyname
= unistr2_to_ascii_talloc(ctx
, key
);
9339 if (!valuename
|| !keyname
) {
9343 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9344 if (!W_ERROR_IS_OK(status
))
9347 status
= delete_printer_dataex( printer
, keyname
, valuename
);
9349 if ( W_ERROR_IS_OK(status
) )
9350 mod_a_printer( printer
, 2 );
9352 free_a_printer(&printer
, 2);
9357 /********************************************************************
9358 * spoolss_enumprinterkey
9359 ********************************************************************/
9362 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
9365 fstring
*keynames
= NULL
;
9366 uint16
*enumkeys
= NULL
;
9369 POLICY_HND
*handle
= &q_u
->handle
;
9370 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9371 NT_PRINTER_DATA
*data
;
9372 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9374 WERROR status
= WERR_BADFILE
;
9377 DEBUG(4,("_spoolss_enumprinterkey\n"));
9380 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9384 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9387 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9388 if (!W_ERROR_IS_OK(status
))
9391 /* get the list of subkey names */
9393 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9394 data
= printer
->info_2
->data
;
9396 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
9398 if ( num_keys
== -1 ) {
9399 status
= WERR_BADFILE
;
9403 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
9405 r_u
->needed
= printerkey_len
*2;
9407 if ( q_u
->size
< r_u
->needed
) {
9408 status
= WERR_MORE_DATA
;
9412 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
9413 status
= WERR_NOMEM
;
9419 if ( q_u
->size
< r_u
->needed
)
9420 status
= WERR_MORE_DATA
;
9423 free_a_printer( &printer
, 2 );
9424 SAFE_FREE( keynames
);
9429 /********************************************************************
9430 * spoolss_deleteprinterkey
9431 ********************************************************************/
9433 WERROR
_spoolss_deleteprinterkey(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERKEY
*q_u
, SPOOL_R_DELETEPRINTERKEY
*r_u
)
9435 POLICY_HND
*handle
= &q_u
->handle
;
9436 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9438 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9442 DEBUG(5,("spoolss_deleteprinterkey\n"));
9445 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9449 /* if keyname == NULL, return error */
9451 if ( !q_u
->keyname
.buffer
)
9452 return WERR_INVALID_PARAM
;
9454 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9457 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9458 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
9459 return WERR_ACCESS_DENIED
;
9462 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9463 if (!W_ERROR_IS_OK(status
))
9466 /* delete the key and all subneys */
9468 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
));
9470 status
= delete_all_printer_data( printer
->info_2
, key
);
9472 if ( W_ERROR_IS_OK(status
) )
9473 status
= mod_a_printer(printer
, 2);
9475 free_a_printer( &printer
, 2 );
9481 /********************************************************************
9482 * spoolss_enumprinterdataex
9483 ********************************************************************/
9485 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
9487 POLICY_HND
*handle
= &q_u
->handle
;
9488 uint32 in_size
= q_u
->size
;
9491 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9492 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
9493 NT_PRINTER_DATA
*p_data
;
9495 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9500 REGISTRY_VALUE
*val
;
9505 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9508 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
9513 * first check for a keyname of NULL or "". Win2k seems to send
9514 * this a lot and we should send back WERR_INVALID_PARAM
9515 * no need to spend time looking up the printer in this case.
9519 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9520 if ( !strlen(key
) ) {
9521 result
= WERR_INVALID_PARAM
;
9525 /* get the printer off of disk */
9527 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
9530 ZERO_STRUCT(printer
);
9531 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9532 if (!W_ERROR_IS_OK(result
))
9535 /* now look for a match on the key name */
9537 p_data
= printer
->info_2
->data
;
9539 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9540 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
9542 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
9543 result
= WERR_INVALID_PARAM
;
9550 /* allocate the memory for the array of pointers -- if necessary */
9552 num_entries
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
9555 if ( (enum_values
=TALLOC_ARRAY(p
->mem_ctx
, PRINTER_ENUM_VALUES
, num_entries
)) == NULL
)
9557 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9558 (unsigned long)num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
9559 result
= WERR_NOMEM
;
9563 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
9567 * loop through all params and build the array to pass
9568 * back to the client
9571 for ( i
=0; i
<num_entries
; i
++ )
9573 /* lookup the registry value */
9575 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
9576 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
9580 value_name
= regval_name( val
);
9581 init_unistr( &enum_values
[i
].valuename
, value_name
);
9582 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
9583 enum_values
[i
].type
= regval_type( val
);
9585 data_len
= regval_size( val
);
9587 if ( !(enum_values
[i
].data
= (uint8
*)TALLOC_MEMDUP(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
9589 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9591 result
= WERR_NOMEM
;
9595 enum_values
[i
].data_len
= data_len
;
9597 /* keep track of the size of the array in bytes */
9599 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
9602 /* housekeeping information in the reply */
9604 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9605 * the hand marshalled container size is a multiple
9606 * of 4 bytes for RPC alignment.
9610 needed
+= 4-(needed
% 4);
9613 r_u
->needed
= needed
;
9614 r_u
->returned
= num_entries
;
9616 if (needed
> in_size
) {
9617 result
= WERR_MORE_DATA
;
9621 /* copy data into the reply */
9623 r_u
->ctr
.size
= r_u
->needed
;
9625 r_u
->ctr
.size_of_array
= r_u
->returned
;
9626 r_u
->ctr
.values
= enum_values
;
9632 free_a_printer(&printer
, 2);
9637 /****************************************************************************
9638 ****************************************************************************/
9640 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, const char *name
)
9642 init_unistr(&info
->name
, name
);
9645 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
9646 UNISTR2
*environment
,
9651 char *long_archi
= NULL
;
9652 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
9653 WERROR result
= WERR_OK
;
9654 TALLOC_CTX
*ctx
= talloc_tos();
9656 long_archi
= unistr2_to_ascii_talloc(ctx
, environment
);
9661 if (!get_short_archi(long_archi
))
9662 return WERR_INVALID_ENVIRONMENT
;
9664 if((info
=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1
)) == NULL
)
9667 fill_printprocessordirectory_1(info
, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9669 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
9671 if (*needed
> offered
) {
9672 result
= WERR_INSUFFICIENT_BUFFER
;
9676 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9677 result
= WERR_INSUFFICIENT_BUFFER
;
9681 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
9689 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
9691 uint32 level
= q_u
->level
;
9692 RPC_BUFFER
*buffer
= NULL
;
9693 uint32 offered
= q_u
->offered
;
9694 uint32
*needed
= &r_u
->needed
;
9697 /* that's an [in out] buffer */
9699 if (!q_u
->buffer
&& (offered
!=0)) {
9700 return WERR_INVALID_PARAM
;
9703 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9704 buffer
= r_u
->buffer
;
9706 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9712 result
= getprintprocessordirectory_level_1
9713 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
9716 result
= WERR_UNKNOWN_LEVEL
;
9722 /*******************************************************************
9723 Streams the monitor UI DLL name in UNICODE
9724 *******************************************************************/
9726 static WERROR
xcvtcp_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9727 RPC_BUFFER
*out
, uint32
*needed
)
9729 const char *dllname
= "tcpmonui.dll";
9731 *needed
= (strlen(dllname
)+1) * 2;
9733 if ( rpcbuf_get_size(out
) < *needed
) {
9734 return WERR_INSUFFICIENT_BUFFER
;
9737 if ( !make_monitorui_buf( out
, dllname
) ) {
9744 /*******************************************************************
9745 Create a new TCP/IP port
9746 *******************************************************************/
9748 static WERROR
xcvtcp_addport( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9749 RPC_BUFFER
*out
, uint32
*needed
)
9751 NT_PORT_DATA_1 port1
;
9752 TALLOC_CTX
*ctx
= talloc_tos();
9753 char *device_uri
= NULL
;
9755 ZERO_STRUCT( port1
);
9757 /* convert to our internal port data structure */
9759 if ( !convert_port_data_1( &port1
, in
) ) {
9763 /* create the device URI and call the add_port_hook() */
9765 switch ( port1
.protocol
) {
9766 case PORT_PROTOCOL_DIRECT
:
9767 device_uri
= talloc_asprintf(ctx
,
9768 "socket://%s:%d/", port1
.hostaddr
, port1
.port
);
9771 case PORT_PROTOCOL_LPR
:
9772 device_uri
= talloc_asprintf(ctx
,
9773 "lpr://%s/%s", port1
.hostaddr
, port1
.queue
);
9777 return WERR_UNKNOWN_PORT
;
9784 return add_port_hook(ctx
, token
, port1
.name
, device_uri
);
9787 /*******************************************************************
9788 *******************************************************************/
9790 struct xcv_api_table xcvtcp_cmds
[] = {
9791 { "MonitorUI", xcvtcp_monitorui
},
9792 { "AddPort", xcvtcp_addport
},
9796 static WERROR
process_xcvtcp_command( NT_USER_TOKEN
*token
, const char *command
,
9797 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9802 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9804 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9805 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9806 return xcvtcp_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9809 return WERR_BADFUNC
;
9812 /*******************************************************************
9813 *******************************************************************/
9814 #if 0 /* don't support management using the "Local Port" monitor */
9816 static WERROR
xcvlocal_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9817 RPC_BUFFER
*out
, uint32
*needed
)
9819 const char *dllname
= "localui.dll";
9821 *needed
= (strlen(dllname
)+1) * 2;
9823 if ( rpcbuf_get_size(out
) < *needed
) {
9824 return WERR_INSUFFICIENT_BUFFER
;
9827 if ( !make_monitorui_buf( out
, dllname
)) {
9834 /*******************************************************************
9835 *******************************************************************/
9837 struct xcv_api_table xcvlocal_cmds
[] = {
9838 { "MonitorUI", xcvlocal_monitorui
},
9842 struct xcv_api_table xcvlocal_cmds
[] = {
9849 /*******************************************************************
9850 *******************************************************************/
9852 static WERROR
process_xcvlocal_command( NT_USER_TOKEN
*token
, const char *command
,
9853 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9858 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9860 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9861 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9862 return xcvlocal_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9864 return WERR_BADFUNC
;
9867 /*******************************************************************
9868 *******************************************************************/
9870 WERROR
_spoolss_xcvdataport(pipes_struct
*p
, SPOOL_Q_XCVDATAPORT
*q_u
, SPOOL_R_XCVDATAPORT
*r_u
)
9872 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9876 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u
->handle
)));
9880 /* Has to be a handle to the TCP/IP port monitor */
9882 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9883 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9887 /* requires administrative access to the server */
9889 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9890 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9891 return WERR_ACCESS_DENIED
;
9894 /* Get the command name. There's numerous commands supported by the
9895 TCPMON interface. */
9897 rpcstr_pull(command
, q_u
->dataname
.buffer
, sizeof(command
),
9898 q_u
->dataname
.uni_str_len
*2, 0);
9900 /* Allocate the outgoing buffer */
9902 rpcbuf_init( &r_u
->outdata
, q_u
->offered
, p
->mem_ctx
);
9904 switch ( Printer
->printer_type
) {
9905 case SPLHND_PORTMON_TCP
:
9906 return process_xcvtcp_command( p
->pipe_user
.nt_user_token
, command
,
9907 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9908 case SPLHND_PORTMON_LOCAL
:
9909 return process_xcvlocal_command( p
->pipe_user
.nt_user_token
, command
,
9910 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9913 return WERR_INVALID_PRINT_MONITOR
;